算法:
第一步,將圖片轉換為二值圖像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)