python-opencv 形态学
五、形態學運算 檢測邊和 角點
?形態學算子檢測圖像中的邊緣和拐角(實際用:Canny或Harris等算法)
5.1 檢測邊緣
?形態學檢測邊緣的原理:在膨脹時,圖像中的物體會想周圍“擴張”;腐蝕時,圖像中的物體會“收縮”。由于這兩幅圖像其變化的區域只發生在邊緣。所以這時將兩幅圖像相減,得到的就是圖像中物體的邊緣。
import cv2
original_img = cv2.imread('image/1.jpg',0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
dilate_img = cv2.dilate(original_img, kernel)
erode_img = cv2.erode(original_img, kernel)
"""
我選了一張較好的圖片,有的圖片要去噪(高斯模糊)
將兩幅圖像相減獲得邊;cv2.absdiff參數:(膨脹后的圖像,腐蝕后的圖像)
上面得到的結果是灰度圖,將其二值化以便觀察結果
反色,對二值圖每個像素取反
"""
absdiff_img = cv2.absdiff(dilate_img,erode_img);
retval, threshold_img = cv2.threshold(absdiff_img, 40, 255, cv2.THRESH_BINARY);
result = cv2.bitwise_not(threshold_img);
cv2.imshow("rlufei",original_img)
cv2.imshow("dilate_img",dilate_img)
cv2.imshow("erode_img",erode_img)
cv2.imshow("absdiff_img",absdiff_img)
cv2.imshow("threshold_img",threshold_img)
cv2.imshow("result",result)
cv2.waitKey(0)
cv2.destroyAllWindows()
?
5.2檢測拐角
拐角的檢測的原理:先用十字形的結構元素膨脹像素,這種情況下只會在邊緣處“擴張”,角點不發生變化。接著用菱形的結構元素腐蝕原圖像,導致只有在拐角處才會“收縮”,而直線邊緣都未發生變化。第二步是用X形膨脹原圖像,角點膨脹的比邊要多。這樣第二次用方塊腐蝕時,角點恢復原狀,而邊要腐蝕的更多。所以當兩幅圖像相減時,只保留了拐角處。
?
import cv2
image = cv2.imread('image/1.jpg',0)
original_image = image.copy()
#構造5×5的結構元素,分別為十字形、菱形、方形和X型
cross = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
diamond = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
diamond[0, 0] = 0
diamond[0, 1] = 0
diamond[1, 0] = 0
diamond[4, 4] = 0
diamond[4, 3] = 0
diamond[3, 4] = 0
diamond[4, 0] = 0
diamond[4, 1] = 0
diamond[3, 0] = 0
diamond[0, 3] = 0
diamond[0, 4] = 0
diamond[1, 4] = 0
square = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5)) #構造方形結構元素
x = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
dilate_cross_img = cv2.dilate(image,cross) #使用cross膨脹圖像
erode_diamond_img = cv2.erode(dilate_cross_img, diamond) #使用菱形腐蝕圖像
dilate_x_img = cv2.dilate(image, x) #使用X膨脹原圖像
erode_square_img = cv2.erode(dilate_x_img,square) #使用方形腐蝕圖像
result = cv2.absdiff(erode_square_img, erode_diamond_img) #將兩幅閉運算的圖像相減獲得角
retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY) #使用閾值獲得二值圖#在原圖上用半徑為5的圓圈將點標出。
for j in range(result.size):y = int(j / result.shape[0])x = int(j % result.shape[0])if result[x, y] == 255: #result[] 只能傳入整型cv2.circle(image,(y,x),5,(255,0,0))
cv2.imshow("original_image", original_image)
cv2.imshow("Result", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、禮帽/頂帽,黑帽 算法
該算法可以圖像識別的預處理,用于圖像二值化后去除孤立點,如下圖所示?
import cv2
original_img = cv2.imread('image/1.jpg',0)
gray_img = cv2.resize(original_img,None,fx=0.8, fy=0.8, interpolation = cv2.INTER_CUBIC) #圖形太大了縮小一點
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) #定義矩形結構元素(核大小為3效果好)
TOPHAT_img = cv2.morphologyEx(gray_img, cv2.MORPH_TOPHAT, kernel) #頂帽運算
BLACKHAT_img = cv2.morphologyEx(gray_img, cv2.MORPH_BLACKHAT, kernel) #黒帽運算
bitwiseXor_gray = cv2.bitwise_xor(gray_img,TOPHAT_img)
#顯示如下腐蝕后的圖像
cv2.imshow("gray_img", gray_img)
cv2.imshow("TOPHAT_img", TOPHAT_img)
cv2.imshow("BLACKHAT_img", BLACKHAT_img)
cv2.imshow("bitwiseXor_gray",bitwiseXor_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
?
三、開運算和閉運算
開運算和閉運算就是將腐蝕和膨脹按照一定的次序進行處理。? 運算不可逆,即先開后閉并不能得到原先的圖像。
為了獲取圖像中的主要對象:對一副二值圖連續使用閉運算和開運算,或者消除圖像中的噪聲,也可以對圖像先用開運算后用閉運算,不過這樣也會消除一些破碎的對象。
開運算:先腐蝕后膨脹,用于移除由圖像噪音形成的斑點。
閉運算:先膨脹后腐蝕,用來連接被誤分為許多小塊的對象;
"""
cv2.morphologyEx(src, # 輸入圖片op, # 需要處理類型的函數:(cv2.MORPH_OPEN,cv2.MORPH_CLOSE,cv2.MORPH_GRADIENT)kernel, # 卷積核大小dst=None, anchor=None, iterations=None, #迭代次數,默認1次borderType=None, borderValue=None)
"""
import cv2
import numpy as np
original_img = cv2.imread('original_img.png',0)
gray_res = cv2.resize(original_img,None,fx=0.8,fy=0.8,interpolation = cv2.INTER_CUBIC) #圖形太大了縮小一點
# B, G, img = cv2.split(res)
# _,RedThresh = cv2.threshold(img,160,255,cv2.THRESH_BINARY) #設定紅色通道閾值160(閾值影響開閉運算效果)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) #定義矩形結構元素closed1 = cv2.morphologyEx(gray_res, cv2.MORPH_CLOSE, kernel,iterations=1) #閉運算1
closed2 = cv2.morphologyEx(gray_res, cv2.MORPH_CLOSE, kernel,iterations=3) #閉運算2
opened1 = cv2.morphologyEx(gray_res, cv2.MORPH_OPEN, kernel,iterations=1) #開運算1
opened2 = cv2.morphologyEx(gray_res, cv2.MORPH_OPEN, kernel,iterations=3) #開運算2
gradient = cv2.morphologyEx(gray_res, cv2.MORPH_GRADIENT, kernel) #梯度#顯示如下腐蝕后的圖像
cv2.imshow("gray_res", gray_res)
cv2.imshow("Close1",closed1)
cv2.imshow("Close2",closed2)
cv2.imshow("Open1", opened1)
cv2.imshow("Open2", opened2)
cv2.imshow("gradient", gradient)cv2.waitKey(0)
cv2.destroyAllWindows()
?
二、腐蝕和膨脹
腐蝕:腐蝕會把物體的邊界腐蝕掉,卷積核沿著圖象滑動,如果卷積核對應的原圖的所有像素值為1,那么中心元素就保持原來的值,其余部分變為零。主要應用在去除白噪聲,也可以斷開連在一起的物體。
膨脹:卷積核所對應的原圖像的像素值只要有一個是1,中心像素值就是1。一般在除噪是,先腐蝕再膨脹開運算,因為腐蝕在去除白噪聲的時候也會使圖像縮小,所以我們之后要進行膨脹。當然也可以用來將兩者物體連通。
import cv2
import numpy as np
import math
import matplotlib.pyplot as plttargetImg = cv2.imread('image/1.jpg')
kernel_4 = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
HSV = cv2.cvtColor(targetImg, cv2.COLOR_BGR2HSV) # 把BGR圖像轉換為HSV格式
Lower = np.array([0, 3, 5]) # 要識別顏色-紅色的下限 ## 0 5 5 10 255 255
Upper = np.array([10, 255, 255]) # 要識別的顏色-紅色的上限# mask是把HSV圖片中在顏色范圍內的區域變成白色,其他區域變成黑色
mask = cv2.inRange(HSV, Lower, Upper)
erosion = cv2.erode(mask, kernel_4, iterations=1)
erosion = cv2.erode(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(erosion, kernel_4, iterations=1)
dilation = cv2.dilate(dilation, kernel_4, iterations=1)cv2.imshow("img", targetImg)
cv2.imshow("mask", mask)
cv2.imshow("target", target)
cv2.imshow("erosion", erosion)
cv2.imshow("dilation", dilation)
cv2.waitKey()
# cv2.imshow("cv_cut_img_circle", cv_cut_img_circle)
# return cropped
一、定義結構元素
形態學處理的核心就是定義結構元素,在OpenCV-Python中,可以使用其自帶的getStructuringElement函數,也可以直接使用NumPy的ndarray來定義一個結構元素。
(形象圖如下:)
如下代碼:為上圖的十字形結構
當然還可以定義橢圓/矩形等:
橢圓:cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
矩形:cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
print("elemrnt":element )
------------------------------------------------
import numpy as np
NpKernel = np.uint8(np.zeros((5,5)))
for i in range(5):NpKernel[2, i] = 1NpKernel[i, 2] = 1
print("NpKernel ",NpKernel )上述結果輸出(相同):
array([[0, 0, 1, 0, 0],[0, 0, 1, 0, 0],[1, 1, 1, 1, 1],[0, 0, 1, 0, 0],[0, 0, 1, 0, 0]], dtype=uint8)
參考書籍:
《opencv基礎開發教程?》
參考blog:
https://blog.csdn.net/sunny2038/article/details/9137759
https://blog.csdn.net/on2way/article/details/46850813
https://blog.csdn.net/wsp_1138886114/article/details/82917661
?
?
總結
以上是生活随笔為你收集整理的python-opencv 形态学的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求从前慢歌词
- 下一篇: python-opencv 轮廓检测