我有下面的图片:
我想找到线来做一些计算,平均长度等......
我尝试使用 HoughLinesP
,但没有找到线条。我该怎么办?
这是我的代码:
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)
输出:
如果我更改 HoughLinesP
的参数,我只会得到线段,而不是实线。
最佳答案
尽管 Hough 线算法仅适用于线(并且您显然是在处理曲线),但可能有一种方法可以挽救您的尝试,方法是大大增加 rho
和 theta
参数。
这应该使弯曲的边指向同一个 bin,而不是分成不同的 bin。
编辑:
你有一点问题:OpenCV 对 cv2.HoughLinesP
的定义。来自documentation :
cv2.HoughLinesP(image, rho, theta, threshold[, lines[, minLineLength[, maxLineGap]]])
如您所见,第 5 个参数是输出变量 lines
。
你的电话是
cv2.HoughLinesP(sk,1,np.pi/180,100,minLineLength,maxLineGap)
^^^^^^^^^^^^^
lines
所以你给定的 minLineLength
参数没有效果(它变成了一个输出变量),而且 maxLineGap
也有错误的解释。
我建议明确地写参数名称(还没有参数调整)
cv2.HoughLinesP(sk.astype(np.uint8),rho=1,theta=np.pi/180,threshold=100,
minLineLength=minLineLength,maxLineGap=maxLineGap)
写的有点长,但至少OpenCV不会再混参数了
可视化线条
我更改了每行的线条颜色,以便更轻松地可视化哪个段在哪里:
color = np.random.uniform(0,255,3)
cv2.line(imgOut,(x1,y1),(x2,y2),color,2)
改变参数
通过减少 rho
和 theta
的 bin(通过增加参数实现),您将有更多机会让曲线的边缘投票给同一条线 -垃圾箱。
这里有一些尝试(下面是完整的代码)
rho=5,theta=np.deg2rad(10),threshold=10,minLineLength=5,maxLineGap=2
为什么骨架化?
您的输入图像(如给定的)看起来边缘已经存在。 skeletonize
的输出只是边缘的中心线,这听起来像是一件积极的事情,但对于 Hough Lines 来说,这意味着减少为线段“投票”的像素数。
# sk = skeletonize(mask==255)
sk = mask==255
这在细节上没有太大变化,但我认为这不会影响手头的任务。
为什么不加标签?
您要获取的是单独的线段。为什么不直接标记图像?
from matplotlib import pyplot as plt
from scipy import ndimage
labels,nblabels = ndimage.label(sk)
plt.imshow(labels,'jet')
plt.show()
通过应用一些形态学运算符,您将获得单独的线条,或者在最坏的情况下,获得线条分支。
现在你可以单独选择行了
line = labels == 2 # select the pixels with label 2 only
将霍夫线应用于这些问题可能无法理清它们,但您已经大大分解了您的问题。
度量的计算现在非常容易(参见 ndimage.measurement 文档)并且数组迭代非常简单。
关于python - 在骨架图像OpenCV python中查找线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33146296/