Python - OpenCV 之影象形態學(膨脹與腐蝕)
Python - OpenCV 之影象形態學(膨脹與腐蝕)
基於 OpenCV 的影象形態學處理 - 膨脹,腐蝕,開運算,閉運算. 涉及到的 OpenCV 函式 -cv2.erode()
,cv2.dilate()
,cv2.morphologyEx()
膨脹和腐蝕是影象形態學的兩個基本操作. 典型應用是在二值影象中的使用,是很多識別技術中重要的中間處理步驟.
在灰度影象中根據閾值同樣可以完成膨脹與腐蝕操作.
1. 原理
二值影象f(x,y) 的膨脹操作,類似於對影象的卷積操作.
需要有個 kernel 操作矩陣,類似於卷積核(filters, kernel),常見的是 3X3 的矩陣. 這是形態學處理的核心.
但與卷積不同的是,如果矩陣中的畫素點有任意一個點的值是前景色,則設定中心畫素點為前景色;否則不變.
影象形態學運算中腐蝕,膨脹,開運算和閉運算:
[1] - 腐蝕是一種消除邊界點,使邊界向內部收縮的過程
可以用來消除小且無意義的物體.
腐蝕演算法:
用 3x3 的 kernel,掃描影象的每一個畫素;
用 kernel 與其覆蓋的二值影象做 “與” 操作;
如果都為1,結果影象的該畫素為1;否則為0.
結果:使二值影象減小一圈.
[2] - 膨脹是將與物體接觸的所有背景點合併到該物體中,使邊界向外部擴張的過程
可以用來填補物體中的空洞.
膨脹演算法:
用 3x3 的 kernel,掃描影象的每一個畫素;
用 kernel 與其覆蓋的二值影象做 “與” 操作;
如果都為0,結果影象的該畫素為0;否則為1.
結果:使二值影象擴大一圈.
[3] - 先腐蝕後膨脹的過程稱為開運算
用來消除小物體、在纖細點處分離物體、平滑較大物體的邊界的同時並不明顯改變其面積.
[4] - 先膨脹後腐蝕的過程稱為閉運算
用來填充物體內細小空洞、連線鄰近物體、平滑其邊界的同時並不明顯改變其面積
2. OpenCV 實現
2.1. 定義 kernel 矩陣
首先定義 kernel 矩陣 - 兩種方式:
[1] - 利用 cv2.getStructuringElement 函式
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) # 橢圓結構 kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) # 十字結構 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # 矩形結構
kernel = np.uint8(np.zeros((3, 3))) for i in range(3): kernel[2, i] = 1 kernel[i, 2] = 1
2.2. 腐蝕和膨脹
cv2.erode() 和 cv2.dilate() 函式
import cv2 import numpy as np import matplot.pyplot as plt png = cv2.imread('test.png', 0) plt.figure() plt.subplot(1, 3, 1) plt.imshow(png) plt.axis('off') # 定義 kernel kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(10, 10)) # 影象腐蝕 eroded = cv2.erode(png, kernel) plt.subplot(1, 3, 2) plt.imshow(eroded) # Eroded Image plt.axis('off') # 影象膨脹 dilated = cv2.dilate(png, kernel) plt.subplot(1, 3, 3) plt.imshow(dilated) # Dilated Image plt.axis('off') plt.show()
2.3. 開運算和閉運算
cv2.morphologyEx() 函式
[1] - 先腐蝕後膨脹叫開運算
常用於去除噪聲
cv2.morphologyEx() 函式:
open_ = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
[2] - 先膨脹後腐蝕叫閉運算
常用於填充前景物體中的小洞,或者前景物體上的小黑點.
lose_ = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
開運算和閉運算不是可逆的.
# --*-- coding:utf-8 --*-- import cv2 import numpy as np import matplot.pyplot as plt png = cv2.imread('test.png', 0) plt.figure() plt.subplot(1, 3, 1) plt.imshow(png) plt.axis('off') # 定義 kernel kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # 閉運算 closed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) plt.subplot(1, 3, 2) plt.imshow(closed) # Closed Image plt.axis('off') #開運算 opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) plt.subplot(1, 3, 3) plt.imshow(opened) # Opened Image plt.axis('off') plt.show()