opencv-03-圖像處理

圖像處理

圖像閾值

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')

原始

三種算子

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章