(四)OpenCV-Python學習—形態學處理

  經過閾值化分割能夠獲得二值圖,但每每會出現圖像中物體形態不完整,變的殘缺,能夠經過形態學處理,使其變得豐滿,或者去除掉多餘的像素。經常使用的形態學處理算法包括:腐蝕,膨脹,開運算,閉運算,形態學梯度,頂帽運算和底帽運算。算法

1. 腐蝕ide

   腐蝕操做相似於中值平滑,也有一個核,但不進行卷積運算,而是取核中像素值的最小值代替錨點位置的像素值,這樣就會使圖像中較暗的區域面積增大,較亮的的區域面積減少。若是是一張黑底,白色前景的二值圖,就會使白色的前景物體顏色變小,就像被腐蝕了同樣。函數

   進行腐蝕操做的核,不只能夠是矩形,還能夠是十字形和橢圓形,opencv提供getStructuringElement()函數來得到核,其參數以下:字體

kernel=cv2.getStructuringElement(shape,ksize,anchor)
        shape:核的形狀
                cv2.MORPH_RECT: 矩形
                cv2.MORPH_CROSS: 十字形(以矩形的錨點爲中心的十字架)
                cv2.MORPH_ELLIPSE:橢圓(矩形的內切橢圓)
                
        ksize: 核的大小,矩形的寬,高格式爲(width,height)
        anchor: 核的錨點,默認值爲(-1,-1),即核的中心點

   opencv提供erode()函數進行腐蝕操做,其對應參數以下:spa

dst=cv2.erode(src,kernel,anchor,iterations,borderType,borderValue):
        src: 輸入圖像對象矩陣,爲二值化圖像
        kernel:進行腐蝕操做的核,能夠經過函數getStructuringElement()得到
        anchor:錨點,默認爲(-1,-1)
        iterations:腐蝕操做的次數,默認爲1
        borderType: 邊界種類,有默認值
        borderValue:邊界值,有默認值

   腐蝕操做的代碼和效果以下:3d

   能夠看到二值化圖像中白色的opencv字體面積變小了,就像被腐蝕了。注意這是黑底白字,若是是白底黑字,效果會相反,字體反而會膨脹。code

#coding:utf-8


import cv2 as cv

img = cv.imread(r"C:\Users\Administrator\Desktop\logo.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,200,255,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,5))
dst = cv.erode(img_thr,kernel,iterations=1)

cv.imshow("img",img)
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()
cv2.erode()

2.膨脹對象

  膨脹操做和腐蝕操做正好相反,是取核中像素值的最大值代替錨點位置的像素值,這樣會使圖像中較亮的區域增大,較暗的區域減少。若是是一張黑底,白色前景的二值圖,就會使白色的前景物體顏色面積變大,就像膨脹了同樣blog

    opencv提供dilate()函數進行膨脹操做,其對應參數以下:圖片

dst = cv2.dilate(src,kernel,anchor,iterations,borderType,borderValue)
        src: 輸入圖像對象矩陣,爲二值化圖像
        kernel:進行腐蝕操做的核,能夠經過函數getStructuringElement()得到
        anchor:錨點,默認爲(-1,-1)
        iterations:腐蝕操做的次數,默認爲1
        borderType: 邊界種類
        borderValue:邊界值

    膨脹操做的代碼和效果以下:

    能夠看到二值化圖像中白色的opencv字體面積變大了,就像膨脹了

#coding:utf-8


import cv2 as cv


img = cv.imread(r"C:\Users\Administrator\Desktop\logo.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,200,255,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,5))
dst = cv.dilate(img_thr,kernel,iterations=1)

cv.imshow("img",img)
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()
cv2.dilate()

 

3.開運算,閉運算,頂帽,頂帽

  開運算:先進行腐蝕操做,後進行膨脹操做,主要用來去除一些較亮的部分,即先腐蝕掉不要的部分,再進行膨脹。

  閉運算:先進行膨脹操做,後進行腐蝕操做,主要用來去除一些較暗的部分。

  形態學梯度:膨脹運算結果減去腐蝕運算結果,能夠拿到輪廓信息。

  頂帽運算:原圖像減去開運算結果。

  底帽運算:原圖像減去閉運算結果。  

  進行開運算,閉運算,頂帽運算,底帽運算,形態學梯度,opencv提供了一個統一的函數cv2.morphologyEx(),其對應參數以下:

dst = cv2.morphologyEx(src,op,kernel,anchor,iterations,borderType,borderValue)
        src: 輸入圖像對象矩陣,爲二值化圖像
        op: 形態學操做類型
            cv2.MORPH_OPEN    開運算
            cv2.MORPH_CLOSE   閉運算
            cv2.MORPH_GRADIENT 形態梯度
            cv2.MORPH_TOPHAT   頂帽運算
            cv2.MORPH_BLACKHAT  底帽運算
            
        kernel:進行腐蝕操做的核,能夠經過函數getStructuringElement()得到
        anchor:錨點,默認爲(-1,-1)
        iterations:腐蝕操做的次數,默認爲1
        borderType: 邊界種類
        borderValue:邊界值

   使用代碼和對應效果以下:

#coding:utf-8


import cv2 as cv
import matplotlib.pyplot as plt

img = cv.imread(r"C:\Users\Administrator\Desktop\logo.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,200,255,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,5))
open = cv.morphologyEx(img_thr,cv.MORPH_OPEN,kernel,iterations=1)
close = cv.morphologyEx(img_thr,cv.MORPH_CLOSE,kernel,iterations=1)
gradient = cv.morphologyEx(img_thr,cv.MORPH_GRADIENT,kernel,iterations=1)
tophat = cv.morphologyEx(img_thr,cv.MORPH_TOPHAT,kernel,iterations=1)
blackhat = cv.morphologyEx(img_thr,cv.MORPH_BLACKHAT,kernel,iterations=1)

images=[img_thr,open,close,gradient,tophat,blackhat]
titles=["img_thr","open","close","gradient","tophat","blackhat"]
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()
cv2.morphologyEx()

 

4.應用實例

  有以下一張中文圖片,當咱們進行字符切割時,常須要知道其中的漢字是否帶下劃線,方便進行後續處理。

  咱們首先想到的多是使用霍夫直線檢測算法,可是直接檢測時,會有不少干擾。咱們能夠經過採用一個橫向的矩陣核,來腐蝕字體,使圖片中只剩下下劃線,而後再進行霍夫直線檢測,這樣干擾小,準確度會高不少。具體實現代碼和效果以下:

#coding:utf-8

import cv2 as cv

img = cv.imread(r"C:\Users\Administrator\Desktop\chinese.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,100,255,cv.THRESH_BINARY)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(30,1)) #因爲是1*30的矩陣,字體會被橫向空隙的白色腐蝕掉,而下劃線橫向都是黑色,不會腐蝕
dst = cv.dilate(img_thr,kernel,iterations=1)  #因爲是白底黑字,全部進行膨脹操做來去除黑色字體
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey(0)
cv.destroyAllWindows()

  

相關文章
相關標籤/搜索