Encontrar Línea en esqueleto Imágenes OpenCV python

Tengo la siguiente imagen:

y quiero encontrar las líneas para hacer algunos cálculos, longitud media, etc. Intenté usar HoughLinesP , pero no encuentra las líneas. ¿Como lo puedo hacer?

Este es mi código:

 sk=skeleton(mask); rows, cols = sk.shape imgOut=np.zeros((rows,cols,3),np.uint8) imgOut[:,:,0]=0 imgOut[:,:,1]=0 imgOut[:,:,2]=0 minLineLength = 0 maxLineGap = 0 lines = cv2.HoughLinesP(sk,1,np.pi/180,100,minLineLength,maxLineGap) for x1,y1,x2,y2 in lines[0]: cv2.line(imgOut,(x1,y1),(x2,y2),(0,255,0),2) print len(lines[0]) cv2.imshow('skel',sk) cv2.imshow('Line',imgOut) cv2.imwrite('Out.bmp',imgOut) 

Salida:

Si cambio los parámetros de HoughLinesP solo obtengo fragmentos de línea, no una línea continua.

Aunque el algoritmo de líneas de Hough está destinado solo a líneas (y claramente se trata de curvas), podría haber una manera de salvar su bash, aumentando considerablemente los parámetros rho y theta .

Esto debería hacer que los lados curvos apunten al mismo recipiente en lugar de dividirse en diferentes contenedores.


EDIT : Tiene un pequeño problema: la definición de OpenCV de cv2.HoughLinesP . De la documentación :

cv2.HoughLinesP (imagen, rho, theta, umbral [, líneas [, minLineLength [, maxLineGap]]])

Como puede ver, el quinto parámetro es lines , la variable de salida. Tu llamada es

 cv2.HoughLinesP(sk,1,np.pi/180,100,minLineLength,maxLineGap) ^^^^^^^^^^^^^ lines 

Por lo tanto, su parámetro minLineLength no tiene ningún efecto (se convierte en una variable de salida), y maxLineGap tiene una interpretación incorrecta.

Sugiero escribir explícitamente nombres de parámetros (sin ajustes de parámetros todavía)

 cv2.HoughLinesP(sk.astype(np.uint8),rho=1,theta=np.pi/180,threshold=100, minLineLength=minLineLength,maxLineGap=maxLineGap) 

un poco largo para escribir, pero al menos OpenCV ya no mezcla los parámetros

Visualizando las lineas

Cambié el color de la línea para cada línea para que sea más fácil visualizar qué segmento es donde:

  color = np.random.uniform(0,255,3) cv2.line(imgOut,(x1,y1),(x2,y2),color,2) 

Cambiando parametros

Al tener menos intervalos para rho y theta (que se logra al boost los parámetros), tendrá más posibilidades de que los bordes de una curva voten por el mismo intervalo de líneas.

Aquí hay algunos bashs (código completo a continuación)

 rho=5,theta=np.deg2rad(10),threshold=10,minLineLength=5,maxLineGap=2 

Demasiadas lineas Se muestran demasiadas líneas. Bajando los parametros

¿Por qué esqueletizar?

Su imagen de entrada (como se indica) parece que los bordes ya están allí. La salida de skeletonize es solo la línea central de bordes, que suena como algo positivo, pero para Hough Lines, significa reducir la cantidad de píxeles que “votan” para los segmentos de línea.

 # sk = skeletonize(mask==255) sk = mask==255 

Esto no cambió mucho en los detalles, pero pensé que no podía dañar la tarea en cuestión.

¿Por qué no etiquetar?

Lo que estás tratando de obtener es segmentos de línea individuales. ¿Por qué no solo etiquetar la imagen?

 from matplotlib import pyplot as plt from scipy import ndimage labels,nblabels = ndimage.label(sk) plt.imshow(labels,'jet') plt.show() 

Imagen etiquetada

Al aplicar un poco de operadores morfológicos obtendrá líneas individuales o, en el peor de los casos, ramificaciones de líneas.

Ahora puedes seleccionar las líneas individualmente haciendo

 line = labels == 2 # select the pixels with label 2 only 

Aplicar líneas de Hough a estos podría ser excesivo para desenredarlos, pero ya habrías desglosado significativamente tus problemas.

El cálculo de las métricas ahora es súper fácil (consulte la documentación de ndimage.measurement ) y la iteración sobre matrices es muy simple.