Python OpenCV學習之圖像形態(tài)學
背景
形態(tài)學處理方法是基于對二進制圖像進行處理的,卷積核決定圖像處理后的效果;形態(tài)學的處理哦本質上相當于對圖像做前處理,提取出有用的特征,以便后續(xù)的目標識別等任務;
一、圖像二值化
定義:將圖像的每個像素變成兩種值,如0和255;
全局二值化的函數原型:
threshold(img,thresh,maxVal,type)
img:最好是灰度圖像thresh:閾值maxVal:超過閾值,替換為maxValtype:有幾種類型,THRESH_BINARY為二值化的類型
案例代碼:
img = cv2.imread('1.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, dst = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

關于type類型,可查看下圖:

二、自適應閾值
解決的問題:由于光照不均勻以及陰影的存在,只有一個閾值會使得在陰影處的白色被二值化成黑色;
若采用全局二值化,在有陰影的圖片中,陰影信息會丟失,如下圖:

當閾值設置較高時,會出現部分陰影信息丟失,如果需要不斷嘗試找到合適閾值是一件耗時的事情,因此就有了自適應閾值的方法;
自適應閾值函數原型:
adaptiveThreshold(img,maxVal,adaptiveMethod,,type,blockSize, C)
adaptiveMethod:計算閾值的方法;blockSize:鄰近區(qū)域的大?。?/li>C:常量,應從計算出的平均值或加權平均值中減去,一般設置為0;
計算閾值主要有兩種兩種方法:
① ADAPTIVE_THRESH_MEAN_C:計算鄰近區(qū)域的平均值;(根據blockSize大小做平均濾波)
② ADAPTIVE_THRESH_GAUSSIAN_C:高斯窗口加權平均值;(根據blockSize大小做高斯濾波)
代碼案例:
img = cv2.imread('new.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 0)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

可以看出,雖然信息成功提取出來,但背景的噪點過多,后續(xù)會加以處理;
三、腐蝕
本質卷積核的值全為1,可通過下圖簡單理解其原理:

函數原型:
erode(img,kernel,iterations=1)
iterations:執(zhí)行的次數;
代碼案例:
img = cv2.imread('./j.png')
kernel = np.ones((3, 3), np.uint8)
dst = cv2.erode(img, kernel, 1)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

上圖為腐蝕后的結果,明顯白色區(qū)域變小了,如果增大卷積核或增加腐蝕次數會使得腐蝕效果更明顯;
四、卷積核獲取
函數原型:
getStructuringElement(type,size)
size一般設置成(3,3)或(5,5)這樣;
type類型:
MORPH_RECT:矩形形狀的卷積核;
MORPH_ELLIPSE:橢圓形狀卷積核;
MORPH_CROSS:十字架形狀卷積核;
腐蝕中的全為1的卷積核可以通過這個函數構造:
kernrl = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
相比于用numpy構造更好;
五、膨脹
膨脹和腐蝕相反,其原理是卷積核中間不為0,則整個卷積核區(qū)域的值都為1,如下圖:

函數原型:
dilate(img,kernel,iterations=1)
代碼案例:
img = cv2.imread('./j.png')
kernel = np.ones((7, 7), np.uint8)
dst = cv2.dilate(img, kernel, 1)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

本次采用7x7的卷積核,所以效果會比較明顯一些;
六、開運算
本質:先腐蝕,后膨脹;
函數原型:
morphologyEx(img,cv2.MORPH_OPEN,kernel)
代碼案例:
img = cv2.imread('./dotj.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
dst = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

從圖中可看出,開運算很好的解決了小的噪點,也就是背景噪點去除;
七、閉運算
本質:先膨脹,后腐蝕;
函數原型等同于開運算,其中的類型進行修改即可;
代碼案例:
img = cv2.imread('./dotinj.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
dst = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

中間還是有一些噪點沒有完全消除,可以調整卷積核大小,將卷積核調大,可以得到更好的效果;
八、形態(tài)學梯度
本質:梯度 = 原圖 - 腐蝕
函數還是morphologyEx,其中類型為MORPH_GRADIENT;
代碼案例:
img = cv2.imread('./j.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dst = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

可以看出來腐蝕的部分,也相當于提取了邊緣;
九、頂帽運算
本質:頂帽 = 原圖 - 開運算
函數還是morphologyEx,其中類型為MORPH_TOPHAT;
代碼案例:
img = cv2.imread('./tophat.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19, 19))
dst = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

十、黑帽運算
本質:黑帽 = 原圖 - 閉運算
函數還是morphologyEx,其中類型為MORPH_BLACKHAT;
代碼案例:
img = cv2.imread('./dotinj.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
dst = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('org', img)
cv2.imshow('dst', dst)
cv2.waitKey(0)

總結
開運算:先腐蝕再膨脹,去除大圖形外的小圖形;
閉運算:先膨脹再腐蝕,去除大圖形內的小圖形;
梯度:求圖形的邊緣;
頂帽:原圖減開運算,得到大圖形外的小圖形;
黑帽:原圖減閉運算,得到大圖形內的小圖形;
以上就是Python OpenCV學習之圖像形態(tài)學的詳細內容,更多關于Python OpenCV圖像形態(tài)學的資料請關注腳本之家其它相關文章!
相關文章
python3 通過 pybind11 使用Eigen加速代碼的步驟詳解
這篇文章主要介紹了python3 通過 pybind11 使用Eigen加速代碼的步驟詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
ubuntu16.04制作vim和python3的開發(fā)環(huán)境
本文給大家介紹的是在ubuntu系統(tǒng)下制作python3開發(fā)環(huán)境的詳細步驟,非常的實用,有需要的小伙伴可以參考下2018-09-09

