OpenCV育成學習:
這是本喵自學的一點基礎知識,希望對初學圖像處理的同學一點幫助。
本喵用的版本是 opencv-python 3.4.1.15版本的,個人感覺4.0以上版本的不太適合我們這些初學者。
1、使用opencv訪問圖片:
在此我們只需要導入一下PIL跟numpy還有matplotlib的包(此三者版本不限)
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
path=r'd:/cat.jpg' #這裏強調一下爲什麼加個‘r’,這是爲了防止編譯時‘/’和‘\’造成的影響,統一處理讓機器自動無視這個/和\
img=np.array(Image.open(path))
plt.figure("你想要的展示的名字")
plt.imshow(img) #這個imshow並不能展示圖片,它只是對圖片進行處理,展示其格式
plt.axis('off') #關閉座標軸
plt.show() #這個纔是展示圖片的
運行結果如下:
2、使用opencv進行圖像中的像素訪問
只要在上述代碼基礎上加上如下代碼:
print(img) #輸出構成圖片的矩陣,也就是他的像素
print(img.shape) #輸出形狀信息
print(img.dtype) #輸出類型信息
print(img.size) #輸出大小
print(type(img)) #輸出矩陣類型
執行結果如下:
[[[ 2 1 15]
[ 1 0 14]
[ 0 0 13]
…
[ 0 3 6]
[ 0 4 7]
[ 1 5 8]]
[[ 89 88 102]
[ 88 87 101]
[ 87 86 100]
…
[ 45 49 52]
[ 45 48 53]
[ 46 50 53]]
[[ 86 88 103]
[ 85 87 102]
[ 83 85 100]
…
[ 49 52 57]
[ 49 52 59]
[ 51 54 59]]
…
[[ 65 68 73]
[ 64 67 72]
[ 63 66 71]
…
[ 37 47 57]
[ 39 47 58]
[ 40 48 59]]
[[ 65 68 73]
[ 64 67 72]
[ 63 66 71]
…
[ 39 49 59]
[ 41 49 60]
[ 41 49 60]]
[[ 64 67 72]
[ 63 66 71]
[ 63 66 71]
…
[ 39 52 61]
[ 43 51 62]
[ 43 51 62]]]
(640, 640, 3)
uint8
1228800
<class ‘numpy.ndarray’>
還有幾個其他的信息可以查看,例如
img.mode 圖片的模式
img.format 圖片的格式
圖片的保存方法:
圖片保存時直接在save()方法裏面輸入地址就行
例:img.save(r’d:/cat.jpg’) 保存在我的D盤,命名爲cat.jpg
3、使用opencv圖像的縮放和旋轉:
opencv提供的“resize()”方法可以對圖片大小進行設置:
例如我想將我的貓從720x720放大到1200x900
然後使用“imwrite()”方法將圖片保存到我想要的位置
import cv2 #這裏如果安裝好了opencv-python的話可以直接這麼導入cv2了
image=cv2.imread('d:/cat.jpg')
response=cv2.resize(img,(1200,900),interpolation=cv2.INTER_CUBIC)
cv2.imwrite('C:/Users/Administrator/Desktop/cat.jpg')
如果需要對圖片進行**“批量resize”**的話可以試試我的代碼:
path='C:/Users/Administrator/Desktop/new/' #我的圖片存放地址
ImageNames=os.listdir(path) #使用os.listdir()方法獲取目錄底下所有文件名
for file in ImageNames:
image=cv2.imread(os.path.join(path,file)) #這裏使用os.join()方法對其進行路徑拼接,讓cv2可以直接找到圖片
rsp=cv2.resize(image,(1200,900),interpolation=cv2.INTER_CUBIC)
cv2.imwrite('C:/Users/Administrator/Desktop/new/'+file,rsp) #保存時保留原來的圖片名稱
4、使用opencv訪問和修改像素值
import cv2
img=cv2.imread('D:/cat.jpg')
px=img[100,100]
print(px) #可以通過行和列座標訪問像素值。對於BGR圖像,它返回一個藍色,綠色,紅色值的數組
blue=img[100,100,0] #這裏面的0是個索引,輸入1的話會打印綠色
print(blue)
打印的結果爲:
通過座標修改像素的方式可以直接對其進行賦值
例如我可以直接讓 img[100,100]=[255,255,255] 便可以簡單的完成對像素的更改。
這裏說明一下,numpy是一個用於快速陣列計算的優化庫。因此,簡單地訪問每個像素值並對其進行修改將非常緩慢。
上述方法通常用於選擇數組的區域,比如前五行和後三列,對於單個像素訪問,numpy數組方法,array.item()和array.itemset()被認爲是更好地,因爲他們總是返回一個標量,如果要訪問所有B,G,R值,則需要分別爲所有人調用array.item().
更好的相符訪問和編輯方法:
#訪問RED(R通道)值
print(img.item(10,10,2))
70
print(img.itemset((10,10,2),50))
50
5、使用opencv圖像投資回報率(P圖)
有時,您不得不玩某些圖像區域,對於圖像中的眼睛檢測,在整個圖像上進行第一次面部檢測。當獲得面部時,我們單獨選擇面部區域並在其內部搜索眼睛而不是搜索整個圖像。他提高了準確性(因爲眼睛總是在臉上)和表現(因爲我們在一個小區域搜索)
比如我想截取圖片的某一部分並放在圖片的某個位置
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
img=np.array(Image.open(r'D:/cat.jpg'))
eye=img[225:284,208:303]#注意先取Y的取值範圍,再取X的取值範圍
img[157:216,310:405]=eye#這兩個之間的差值必須同步
plt.imshow(img)
plt.show()
6、使用opencv拆分和合並RGB通道
有時我們需要在B,G,R通道圖像上單獨工作,這種情況下,需要將BGR圖像分割。
import cv2
img=cv2.imread(r'd:/cat.jpg')
b,g,r=cv2.split(img)#拆分
merged=cv2.merge([b,g,r])#合併
# cv2.imshow('red',r)
# cv2.imshow('green',g)
# cv2.imshow('blue',b)
cv2.imshow('merged',merged)
cv2.waitKey(0)
這分別是R,G,B三個通道跟通道合併的執行結果:
7、使用opencv製作圖像邊框
opencv爲我們提供了copyMakeBorder()方法可以讓我們爲圖像添加邊框:
copyMakeBorder爲我們提供了集中邊框的屬性參數:
cv2.BORDER_CONSTANT - 添加一個恆定的彩色邊框。該值應作爲下一個參數給出。
cv2.BORDER_REFLECT - 邊框將是邊框元素的鏡像反射,如下所示: fedcba | abcdefgh | hgfedcb
cv2.BORDER_REFLECT_101或 cv.BORDER_DEFAULT - 與上面相同,但略有改動,如下所示: gfedcb | abcdefgh | gfedcba
cv2.BORDER_REPLICATE - 最後一個元素被複制,如下所示: aaaaaa | abcdefgh | hhhhhhh
cv2.BORDER_WRAP - 無法解釋,它看起來像這樣: cdefgh | abcdefgh | abcdefg
import cv2
import numpy as np
from matplotlib import pyplot as plt
#使用cv2.copyMakeBorder()
BLUE=[255,0,0] #我想創建一個藍色的邊框
img=cv2.imread(r'D:/cat.jpg')
constant=cv2.copyMakeBorder(img,20,20,20,20,cv2.BORDER_CONSTANT,value=BLUE)#這裏面的20,20,20,20,是頂部,底部,左側,右側 - 相應方向上的像素數的邊框寬度
# plt.subplot(236)
# plt.imshow(constant,'gray')
# plt.title('CONSTANT')
# plt.show() #plt方法的話是按R,G,B順序上色,爲了方便記憶我還是採用cv2.imshow的B,G,R順序上色
cv2.imshow('gray',constant)
cv2.waitKey(0)
運行效果:
ok,關於圖像的基本操作就這麼多。後面還有圖像的算術運算等學習會相繼更新。