圖像處理
圖像閾值
ret, dst = cv2.threshold(src, thresh, maxval, type)
- src: 輸入圖,只能輸入單通道圖像,通常來說爲灰度圖
- dst: 輸出圖
- thresh: 閾值
- maxval: 當像素值超過了閾值(或者小於閾值,根據type來決定),所賦予的值
- type:二值化操作的類型,包含以下5種類型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
- cv2.THRESH_BINARY 超過閾值部分取maxval(最大值),否則取0
- cv2.THRESH_BINARY_INV THRESH_BINARY的反轉
- cv2.THRESH_TRUNC 大於閾值部分設爲閾值,否則不變
- cv2.THRESH_TOZERO 大於閾值部分不改變,否則設爲0
- cv2.THRESH_TOZERO_INV THRESH_TOZERO的反轉
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
圖像平滑
- 均值濾波
- 方框濾波
- 高斯濾波
- 中值濾波
img = cv2.imread('lenaNoise.png')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 均值濾波
# 簡單的平均卷積操作
blur = cv2.blur(img, (3, 3))
cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 方框濾波
# 基本和均值一樣,可以選擇歸一化
box = cv2.boxFilter(img,-1,(3,3), normalize=True)
cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 方框濾波
# 基本和均值一樣,可以選擇歸一化,容易越界
box = cv2.boxFilter(img,-1,(3,3), normalize=False)
cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 高斯濾波
# 高斯模糊的卷積核裏的數值是滿足高斯分佈,相當於更重視中間的
aussian = cv2.GaussianBlur(img, (5, 5), 1)
cv2.imshow('aussian', aussian)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 中值濾波
# 相當於用中值代替
median = cv2.medianBlur(img, 5) # 中值濾波
cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 展示所有的
res = np.hstack((blur,aussian,median))
#print (res)
cv2.imshow('median vs average', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
腐蝕操作
腐蝕原理:
腐蝕:局部最小值(與膨脹相反);
①定義一個卷積核B,核可以是任何的形狀和大小,且擁有一個單獨定義出來的參考點 - 錨點(anchorpoint);
通常和爲帶參考點的正方形或者圓盤,可將核稱爲模板或掩膜;
②將核乙與圖像甲進行卷積,計算核乙覆蓋區域的像素點最小值;
③將這個最小值賦值給參考點指定的像素;
因此,圖像中的高亮區域逐漸減小。
膨脹操作
膨脹就是求局部最大值的操作。
按數學方面來說,膨脹或者腐蝕操作就是將圖像(或圖像的一部分區域,我們稱之爲A)與核(我們稱之爲B)進行卷積。
核可以是任何的形狀和大小,它擁有一個單獨定義出來的參考點,我們稱其爲錨點(anchorpoint)。多數情況下,核是一個小的中間帶有參考點和實心正方形或者圓盤,其實,我們可以把核視爲模板或者掩碼。
而膨脹就是求局部最大值的操作,核B與圖形卷積,即計算核B覆蓋的區域的像素點的最大值,並把這個最大值賦值給參考點指定的像素。這樣就會使圖像中的高亮區域逐漸增長。如下圖所示,這就是膨脹操作的初衷。
開運算:
開運算(Open Operation):先腐蝕後膨脹的過程;
功能:
-
消除小物體;
-
在纖細處分離物體;
-
平滑較大的邊界並不明顯改變其面積;
閉運算:
閉運算(Closing Openration),先膨脹後腐蝕;
功能:
- 排除小型黑洞(黑斑);
梯度運算
- 梯度=膨脹-腐蝕
# 梯度=膨脹-腐蝕
pie = cv2.imread('pie.png')
kernel = np.ones((7,7),np.uint8)
dilate = cv2.dilate(pie,kernel,iterations = 5)
erosion = cv2.erode(pie,kernel,iterations = 5)
res = np.hstack((dilate,erosion))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('gradient', gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()
禮帽與黑帽
- 禮帽 = 原始輸入-開運算結果
- 黑帽 = 閉運算-原始輸入
#禮帽
img = cv2.imread('dige.png')
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat', tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()
#黑帽
img = cv2.imread('dige.png')
blackhat = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('blackhat ', blackhat )
cv2.waitKey(0)
cv2.destroyAllWindows()
圖像梯度-算子
圖像梯度-Sobel算子
img = cv2.imread('pie.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
- ddepth:圖像的深度
- dx和dy分別表示水平和豎直方向
- ksize是Sobel算子的大小
def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
cv_show(sobelx,'sobelx')
白到黑是正數,黑到白就是負數了,所有的負數會被截斷成0,所以要取絕對值
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx')
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
cv_show(sobely,'sobely')
分別計算x和y,再求和
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')
不建議直接計算
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
cv_show(sobelxy,'sobelxy')
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
cv_show(img,'img')
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')
圖像梯度-Scharr算子
圖像梯度-laplacian算子
laplacian算子,對噪音點比較敏感,有個二階導
在裏面
#不同算子的差異
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((sobelxy,scharrxy,laplacian))
cv_show(res,'res')
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
cv_show(img,'img')