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
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)
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
Se muestran demasiadas líneas. Bajando los parametros
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.
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()
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.