二值圖像連通分量的提取(python+opencv)


算法:

第一步,將圖片轉換為二值圖像A

第二步,創建和A相同大小但是元素都為0的圖像B,並復制A到A_copy中

第三步,A中任選一點值為255的像素,設為p1,並使用計算連通分量算法,當算法收斂時,則檢測出一個連通分量

第四步,將檢測出來的連通分量復制到B中,A_copy中對應的值設為0,記錄連通分量和像素數量

第五步,重復第三步和第四步,直到A_copy中所有的像素值為0,檢測出所有連通分量

 

import cv2
import numpy as np

path = "_cc.png"
img_A = cv2.imread(path)
gray_A = cv2.cvtColor(img_A, cv2.COLOR_BGR2GRAY) #轉換成灰度圖
ret, thresh_A = cv2.threshold(gray_A, 50, 255, cv2.THRESH_BINARY_INV) #灰度圖轉換成二值圖像

thresh_A_copy = thresh_A.copy() #復制thresh_A到thresh_A_copy
thresh_B = np.zeros(gray_A.shape, np.uint8) #thresh_B大小與A相同,像素值為0

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))#3×3結構元

count = [ ] #為了記錄連通分量中的像素個數

#循環,直到thresh_A_copy中的像素值全部為0
while thresh_A_copy.any():

    Xa_copy, Ya_copy = np.where(thresh_A_copy > 0) #thresh_A_copy中值為255的像素的坐標
    thresh_B[Xa_copy[0]][Ya_copy[0]] = 255 #選取第一個點,並將thresh_B中對應像素值改為255

    #連通分量算法,先對thresh_B進行膨脹,再和thresh_A執行and操作(取交集)
    for i in range(200):
        dilation_B = cv2.dilate(thresh_B, kernel, iterations=1)
        thresh_B = cv2.bitwise_and(thresh_A, dilation_B)

    #取thresh_B值為255的像素坐標,並將thresh_A_copy中對應坐標像素值變為0
    Xb, Yb = np.where(thresh_B > 0)
    thresh_A_copy[Xb, Yb] = 0

    #顯示連通分量及其包含像素數量
    count.append(len(Xb))
    if len(count) == 0:
        print("無連通分量")
    if len(count) == 1:
        print("第1個連通分量為{}".format(count[0]))
    if len(count) >= 2:
        print("第{}個連通分量為{}".format(len(count), count[-1] - count[-2]))

cv2.imshow("A", thresh_A)
cv2.imshow("A_copy", thresh_A_copy)
cv2.imshow("B", thresh_B)
cv2.waitKey(0)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM