Use cv2.connectedComponents y elimine elementos con un pequeño número de píxeles

Quiero usar la función cv2.connectedComponents para conectar componentes en una imagen binaria, como la siguiente …

introduzca la descripción de la imagen aquí

He añadido la característica a cv2. ConectadoComponentes para eliminar elementos con una pequeña cantidad de píxeles.

Desafortunadamente, el algoritmo es extremadamente lento para imágenes grandes debido a la extensión. ¿Hay una manera de volver a escribir la extensión para acelerar el algoritmo?

import cv2 import numpy as np def zerolistmaker(n): listofzeros = [0] * n return listofzeros img = cv2.imread('files/motorway/gabor/eGaIy.jpg', 0) img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1] # ensure binary retval, labels = cv2.connectedComponents(img) ################################################## # ENLARGEMENT ################################################## sorted_labels = labels.ravel() sorted_labels = np.sort(sorted_labels) maxPixel = 50 # eliminate elements with less than maxPixel # detect how often an element occurs i=0 counter=0 counterlist = zerolistmaker(retval) while i < len(sorted_labels): if sorted_labels[i] == counter: counterlist[counter] = counterlist[counter] + 1 else: counter = counter + 1 i = i - 1 i = i + 1 # delete small pixel values i=0 while i < len(counterlist): if counterlist[i] < maxPixel: counterlist[i] = 0 i = i + 1 i=0 counterlisthelper = [] while i < len(counterlist): if counterlist[i] == 0: counterlisthelper.append(i) i = i + 1 i=0 j=0 k=0 while k < len(counterlisthelper): while i < labels.shape[0]: while j < labels.shape[1]: if labels[i,j] == counterlisthelper[k]: labels[i,j] = 0 else: labels[i,j] = labels[i,j] j = j + 1 j = 0 i = i + 1 i = 0 j = 0 k = k + 1 ################################################## ################################################## # Map component labels to hue val label_hue = np.uint8(179*labels/np.max(labels)) blank_ch = 255*np.ones_like(label_hue) labeled_img = cv2.merge([label_hue, blank_ch, blank_ch]) # cvt to BGR for display labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR) # set bg label to black labeled_img[label_hue==0] = 0 cv2.imshow('labeled.png', labeled_img) cv2.waitKey() 

En python, debes evitar bucles profundos. Prefiero usar numpy no sea python-loop .

Imporved

 ################################################## ts = time.time() num = labels.max() N = 50 ## If the count of pixels less than a threshold, then set pixels to `0`. for i in range(1, num+1): pts = np.where(labels == i) if len(pts[0]) < N: labels[pts] = 0 print("Time passed: {:.3f} ms".format(1000*(time.time()-ts))) # Time passed: 4.607 ms ################################################## 

Resultado:

introduzca la descripción de la imagen aquí introduzca la descripción de la imagen aquí


Todo el código:

 #!/usr/bin/python3 # 2018.01.17 22:36:20 CST import cv2 import numpy as np import time img = cv2.imread('test.jpg', 0) img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1] # ensure binary retval, labels = cv2.connectedComponents(img) ################################################## ts = time.time() num = labels.max() N = 50 for i in range(1, num+1): pts = np.where(labels == i) if len(pts[0]) < N: labels[pts] = 0 print("Time passed: {:.3f} ms".format(1000*(time.time()-ts))) # Time passed: 4.607 ms ################################################## # Map component labels to hue val label_hue = np.uint8(179*labels/np.max(labels)) blank_ch = 255*np.ones_like(label_hue) labeled_img = cv2.merge([label_hue, blank_ch, blank_ch]) # cvt to BGR for display labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR) # set bg label to black labeled_img[label_hue==0] = 0 cv2.imshow('labeled.png', labeled_img) cv2.imwrite("labeled.png", labeled_img) cv2.waitKey()