形態學操作主要包含:腐蝕、膨脹、開運算、閉運算、形態學梯度運算、頂帽運算(禮帽運算)、黑帽運算等操作
其中腐蝕操作和膨脹操作是形態學的基礎
腐蝕操作能夠將圖像的邊界點消除,將圖像沿着邊界點向內收縮,也可以將小於指定結構的部分消除,即可以把圖像細化,
除去噪聲
該操作是逐個像素點來決定值,每次判定的點都是結構元中心點所對應的點
函數形式
dst = cv2.erode(src , kernel [ , anchor [ , interations [, borderType [ , borderValue]]]])
dst 為腐蝕后輸出的目標圖像,與原始圖像的類型和大小一樣
src 所需要腐蝕的圖像,圖像的通道數可以任意, 但要求圖像深度必須是CV_8U , CV_16U , CV_16S , CV_32F , CV_64F中的一種
kernel代表腐蝕操作時所采用的結構類型, 可以自定義生成, 也可以通過函數,cv2.getStructuringEleMent()
anchor代表結構中錨點的位置,默認為( - 1 , - 1 ) 即核的中心位置
interations腐蝕操作迭代的次數, 默認為1
borderType代表邊界樣式,當結構元為3x3時處理邊界時會出現有一行未處理,當為5x5時有兩行 既有以下的邊界處理方式
| 類型 | 說明 |
| cv2.BORDER_CONSTANT | iiiiii|abcdefgh|iiiiii 特定值i |
| cv2.BORDER_REPLICATE | aaaaaa|abcdefgh| hhhhhh |
| cv2.BORDER_REFLECT | fedcba|abcdefgh|hgfedcb |
| cv2.BORDER_WRAP | cdefgh|abcdefgh|abcdefg |
| cv2.BORDER_REFLECT_101 | gfedcb|abcdefgh| gfedcba |
| cv2.BORDER_TRANSPARENT | uvwxyz|abcdefgh| ijklmno |
| cv2.BORDER_REFLECT101 | 與cv2.BORDER_REFLECT_101 相同 |
| cv2.BORDER_DEFAULT | 與cv2.BORDER_REFLECT_101 相同 |
| cv2.BORDER_ISOLATED | 不考慮ROI之外的區域 |
以上的說明中的豎線中間的字母即代表圖像的像素點, 而兩邊的字母即代表邊界樣式和像素點之間的關系
例如cv2.BORDER_CONSTANT即是特定值處理, 而cv2.BORDER_REPLICATE 即是將邊緣樣式處理為圖像邊緣的像素點
borderValue一般為默認值
1 import cv2 2 import numpy as np 3 img = np.zeros((5,5) , np.uint8) 4 img[1:4,1:4] = 1 5 kernel = np.ones((3,1) , np.uint8) 6 erosion = cv2.erode(img , kernel) 7 print("img =\n" , img) 8 print("kernel =\n" , kernel) 9 print("erosion =\n" , erosion)
img = [[0 0 0 0 0] [0 1 1 1 0] [0 1 1 1 0] [0 1 1 1 0] [0 0 0 0 0]] kernel = [[1] [1] [1]] erosion = [[0 0 0 0 0] [0 0 0 0 0] [0 1 1 1 0] [0 0 0 0 0] [0 0 0 0 0]]
如上代碼結果所顯示只有當整個結構元都在圖像內時 , 結構元中心點才會保留, 如果結構元部分在或者完全不在,
則結構元中心點就會被處理為背景色。
代碼中只有結構元的中心點 kernel[1,0] 在img[2,1] , img[2,3] , img[2,4] 的時候, 整個結構元才在前景圖像中,
這三個點被處理為1
1 import cv2 2 import numpy as np 3 o = cv2.imread("/home/miao/img/chap8/erode.bmp") 4 kernel = np.ones((5,5) , np.uint8) 5 erosion = cv2.erode(o,kernel) 6 cv2.imshow("original" , o) 7 cv2.imshow("erosion" , erosion) 8 cv2.waitKey() 9 cv2.destroyAllWindows()
原圖

處理之后 該代碼中生成的5x5的核

1 import cv2 2 import numpy as np 3 o = cv2.imread("/home/miao/img/chap8/erode.bmp" , cv2.IMREAD_UNCHANGED) 4 kernel = np.ones((9,9) , np.uint8) 5 erosion = cv2.erode(o,kernel , iterations = 5) 6 cv2.imshow("original" , o) 7 cv2.imshow("erosion" , erosion) 8 cv2.waitKey() 9 cv2.destroyAllWindows()
這是用的9x9的核,並且迭代的5次

膨脹
膨脹的作用和腐蝕的作用是相反的,膨脹操作對當前圖像將圖像的邊界擴張,即將背景點處理為前景圖
處理方式為如果結構元中任意一點在前景圖像中即將錨點處理為前景色,
如果完全處於背景圖像值哦哦嗯,則將結果圖像中的錨點處理為背景色
函數形式
dst = cv2.dilate( src , kernel [. anchor [, interations [ , borderType [, borderValue]]]])
參數和cv2.erode()中相應參數含義一致
1 import cv2 2 import numpy as np 3 img = np.zeros((5,5) , np.uint8) 4 img[2:3 , 1:4] = 1 5 kernel = np.ones((3,1) , np.uint8) 6 dilation = cv2.dilate(img , kernel) 7 print("img =\n", img) 8 print("kernel =\n" , kernel) 9 print("dilation =\n" , dilation)
img = [[0 0 0 0 0] [0 0 0 0 0] [0 1 1 1 0] [0 0 0 0 0] [0 0 0 0 0]] kernel = [[1] [1] [1]] dilation = [[0 0 0 0 0] [0 1 1 1 0] [0 1 1 1 0] [0 1 1 1 0] [0 0 0 0 0]]
結構元為9x9
1 import cv2 2 import numpy as np 3 o = cv2.imread("/home/miao/img/chap8/dilation.bmp", cv2.IMREAD_UNCHANGED) 4 kernel = np.ones((9,9) , np.uint8) 5 dilation = cv2.dilate(o,kernel) 6 cv2.imshow("original" , o) 7 cv2.imshow("dilation" , dilation) 8 cv2.waitKey() 9 cv2.destroyAllWindows()
原圖


結構元為5x5 迭代了9次
import cv2 import numpy as np o = cv2.imread("/home/miao/img/chap8/dilation.bmp", cv2.IMREAD_UNCHANGED) kernel = np.ones((5,5) , np.uint8) dilation = cv2.dilate(o,kernel , iterations = 9) cv2.imshow("original" , o) cv2.imshow("dilation" , dilation) cv2.waitKey() cv2.destroyAllWindows()

