Python_opencv4.0 常用操作及注意事項

一、基本操作
1、讀、寫、顯示操作

#讀取圖像
I = cv2.imread('C:\\photo\\logo.jpg',1)#參數一爲讀取文件位置,參數二爲讀取方式
#(對於參數二:當爲0時則以灰度圖的形式讀取,當爲1時則以BGR方式讀取,當爲2時)


#顯示圖像
cv2.imshow('img1',I)#參數一爲顯示窗口名字
cv2.imshow('img2',I)#這就可以顯示兩個窗口
cv2.waitKey(0)#這是等待操作,可以延時(如參數填寫爲1000就延時1000ms)
#也可以等待相關鍵的按下,參數填寫爲0就是按下任意鍵,如要等待‘q’,則語句應爲
while True:
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
'''#或者
k = cv2.waitKey(0)
if k == 27: # 等待ESC退出,ESC的ACCI碼爲27
	cv2.destroyAllWindows()
elif k == ord('s'): # 等待關鍵字,保存和退出
	print ('Saved!')
	cv2.destroyAllWindows()
'''
cv2.destroyAllWindows()#這個破壞所有窗口
cv2.destroyWindow('img1')#破壞名稱爲‘img1’的窗口
#利用opencv顯示圖像時必須包括上述三個語句,不然顯示不出
#當然也可以利用matplotlib,這時要轉成RGB(原來是BGR),若是灰度圖就沒關係
b, g, r = cv2.split(I)
I1 = cv2.merge([r, g, b])
plt.imshow(I1)


#寫出圖像
cv2.imwrite('C:\\photo\\logo_write.jpg', I)
#當寫出圖像成功時,會返回一個True值

注:Opencv中的路徑不能包括中文,所以都用英文吧
2、圖像基本信息

#訪問圖像尺寸信息
I.shape#顯示(行數,列數,通道數)
I.size#圖像像素總數
I.dtype#圖像數據類型
I[h1:h2, w1:w2]#獲取指定區域圖像
b,g,r = cv2.split(I)#獲取b/g/r各通道信息
'''#也可通過如下操作, 下述操作比較有效率
b = I[:, :, 0]
g = I[:, :, 1]
r = I[:, :, 2]
''' 
I = cv.merge((b,g,r))#由各個通道合成一幅圖像

3、顏色空間轉換

I_out = cv2.cvtColor(I_in, cv2.COLOR_BGR2GRAY)#參數二爲顏色空間轉換類型,常用包括如下:
#cv2.COLOR_BGR2GRAY  BGR空間》灰度
#cv2.COLOR_BGR2HSV  BGR空間》HSV空間(HSV的色相H範圍爲[0,179],飽和度S範圍爲[0,255],明度V值範圍爲[0,255])
#在HSV空間中對顏色比較敏感,故常在HSV中對顏色進行操作

4、圖像加減處理

cv2.add(I1, I2)#實現I1+I2, 兩幅圖像尺寸、類型一致,並且對>255的值限制在255
cv2.subtract(I1, I2)#實現I1-I2, 兩幅圖像尺寸、類型一致,並且對<0的值限制在0
cv2.addWeighted(I1, 0.7, I2, 0.3, 0)
#實現圖像融合,I_out = I1xa1 + I2xa2 + b  其中參數分別對應上述參數,一般取a1+ a2 = 1

注:兩幅圖像尺寸、類型一致
5、圖像按位運算

cv2.bitwise_not(I)#對I圖像按位取反運算,1變0,0變1

cv2.bitwise_and(I1, I2, mask = mask1)
#對掩碼區域mask1中的I1 和 I2 取與運算(mask尺寸與處理圖像的一樣,只不過其是經過處理後獲得感興趣區域的而已)
# mask起掩碼作用,當mask像素不爲0時,做正常與操作,當mask像素爲0時直接做0處理
# 當mask爲黑白圖像時:純白色部分進行正常的按位操作,mask爲黑色部分設置爲0即黑色
# 說白了就是I1 與 I2運算後的區域像素再與mask做與運算
# cv2.bitwise_or類似

注:mask應與處理圖像一樣尺寸大小
6、圖像變換

#幾何變換
cv2.resize(參數1,參數2,參數3,參數4,參數5)
'''
參數1:輸入圖像
參數2:輸出圖像的尺寸如(200,300)爲寬爲200,高爲300,這裏與平常先高後寬有所區別
參數3:沿水平軸的比例因子,也就是縮放倍數,如fx=0.5
參數4:沿垂直軸的比例因子,也就是縮放倍數,如fy=0.5
參數5:內插類型,如interpolation=INTER_LINEAR
包括以下5種
INTER_NEAREST:最近鄰插值法
INTER_LINEAR:雙線性插值法(默認)
INTER_AREA:基於局部像素的重採樣
INTER_CUBIC:基於4x4像素鄰域的3次插值法
INTER_LANCZOS4:基於8x8像素鄰域的Lanczos插值
'''


#

7、圖像閾值處理

#直接閾值(給定閾值處理)
ret,thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY)#ret爲閾值大小,thresh爲閾值處理後的圖像,下同
#閾值爲參數二此處即爲127,當像素值小於127則輸出爲0,超過的則爲255
cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
#閾值爲參數二此處即爲127,當像素值小於127則輸出爲255,超過的則爲0,與上述相反

cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
#閾值爲參數二此處即爲127,像素值的大小隨與閾值相差距離的大小變化而變化

cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
#閾值爲參數二此處即爲127,像素值大於閾值的像素不變,小於的則爲0
cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
#閾值爲參數二此處即爲127,像素值大於閾值的像素爲0,小於的則不變,與上述相反


#自適應閾值(也可以叫局部性閾值處理,局部閾值可能不同,效果更佳)
dst = cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)
'''
參數1:src: 輸入圖,只能輸入單通道圖像,通常來說爲灰度圖
參數2:maxval: 當像素值超過了閾值(或者小於閾值,根據type來決定),所賦予的值
參數3:thresh_type: 閾值的計算方法,包含以下2種類型:
cv2.ADAPTIVE_THRESH_MEAN_C#區域內均值
cv2.ADAPTIVE_THRESH_GAUSSIAN_C#區域內像素點加權和,權重爲一個高斯窗口,這個效果較佳
參數4:type:二值化操作的類型,與固定閾值函數相同,用於控制參數2 maxval,包含以下5種類型:
cv2.THRESH_BINARY#黑白二值
cv2.THRESH_BINARY_INV#黑白二值反轉
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
參數5:Block Size: 圖片中區域的大小,窗口大小常取11,當越小時,所得圖像越細膩,越大時,效果越接近於全局閾值的效果,應爲奇數
參數6:C :閾值計算方法中的常數項,常取2
'''

#Otsu大津法:避免手工設置全局閾值,自動獲取閾值,可以看作是對直方圖具有兩個峯值中取二者之間的一個適應值的過程
blur = cv2.GaussianBlur(I,(5,5),0)#一般高斯濾波後效果會更好
ret,th = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

8、圖像濾波增強

#基於卷積核圖像濾波
kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)
#該濾波算法效果會隨着卷積核不同而不同,此處的卷積核是一個均勻卷積核其實現的是平滑操作
#當然如果選擇卷積核爲Canny算子那麼其效果爲提取邊緣
#所以要確定不同的濾波功能就要確定不同的卷積核

#平均平滑濾波
blur = cv2.blur(img,(5,5)
#其實現效果與上述類似,這裏的參數二爲卷積核尺寸大小,一般爲奇數

#高斯平滑濾波
blur = cv2.GaussianBlur(img,(5,5),0)
#該卷積核換爲高斯核,其濾波效果更加
#參數二爲卷積核尺寸大小,應爲奇數,越大平滑程度越深
#參數三、四分別爲x方向和y方向的方差大小,一般只寫參數三,默認兩者相當,當其越大時越接近於平均平滑濾波

#中值平滑濾波
median = cv2.medianBlur(img,5)
#參數二爲濾波器大小,該濾波對椒鹽或者脈衝噪聲濾除效果好
#和常規的中值濾波器相比,自適應中值濾波器能夠更好的保護圖像中的邊緣細節部分

#雙邊濾波
blur = cv2.bilateralFilter(img,9,75,75)
#能夠在去除噪聲的同時保持邊緣清晰銳利,但速度慢

9、形態學處理

#腐蝕
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
#當核經過某個像素時,只有當該像素對應核模板下所有的像素值與核像素對應時,該像素才保留,否則歸零
#效果:它有助於去除小的白色噪聲,分離兩個連接的對象等

#膨脹
dilation = cv2.dilate(img,kernel,iterations = 1)
#當核經過某個像素時,只有當該像素對應核模板下所有的像素值只要有一個與核像素對應時,該像素就保留,否則歸零
#效果:它有助於擴大圖像中的白色區域或增加前景對象的大小

#開運算
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#先腐蝕後膨脹
#效果:它有助於消除噪聲,去除斷點

#閉運算
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#先膨脹後腐蝕
#效果:它有助於填補小孔,連接對象

#形態學梯度
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
#獲取二值圖邊緣

#頂帽
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
#輸入圖像和圖像開運算之差

#底帽
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
#輸入圖像和圖像閉運算之差

注:核的設置可利用np模塊手動設置,也可以利用下述語句設置
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))#矩形
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))#橢圓形
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))#十字交叉形

10、圖像梯度

#Laplacian 算子
laplacian=cv2.Laplacian(img,cv2.CV_64F)
#cv2.CV_64F 輸出圖像的深度(數據類型),可以使用-1, 與原圖像保持一致 np.uint8

#Sobel算子
# 參數 1,0 爲只在 x 方向求一階導數,最大可以求 2 階導數。
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
# 參數 0,1 爲只在 y 方向求一階導數,最大可以求 2 階導數。
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)

#Canny算子
edge = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])
'''
image:源圖像
threshold1:閾值1,越大越細節的邊緣會沒有
threshold2:閾值2,越大越細節的邊緣會沒有,即越大就只檢測出較明顯的邊緣
具體來說:強度梯度大於 閾值2 的任何邊緣必定是邊緣,小於 閾值1 的那些邊緣必定是非邊緣
介於這兩個閾值之間的對象根據其連通性被分類爲邊緣或非邊緣。如果將它們連接
到“邊緣”像素,則將它們視爲邊緣的一部分。否則,它們也將被丟棄

apertureSize:可選參數,Sobel算子的大小,默認值爲 3
函數返回的是二值圖,包含檢測出的邊緣
常選前三個參數如edge = cv2.Canny(image, threshold1, threshold2)
'''
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章