在骨架图像OpenCV python中查找线

时间:2015-10-15 10:38:03

标签: python opencv image-processing

我有以下图片:

我想找到做一些计算的线,平均长度等...... 我试图使用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的参数,我只会获得行的片段,而不是实线。

1 个答案:

答案 0 :(得分:5)

虽然霍夫线算法仅用于线条(并且您明确处理曲线),但可以通过大大增加rho和{{1}来挽救您的尝试。参数。

这应该使弯曲的边指向相同的仓,而不是分成不同的仓。

编辑: 您有一点问题:OpenCV对theta的定义。来自documentation

  

cv2.HoughLinesP(image,rho,theta,threshold [,lines [,minLineLength [,maxLineGap]]])

正如您所看到的,第五个参数是cv2.HoughLinesP,即输出变量。 你的电话是

lines

因此,您的给定cv2.HoughLinesP(sk,1,np.pi/180,100,minLineLength,maxLineGap) ^^^^^^^^^^^^^ lines 参数无效(它变为输出变量),minLineLength也有错误的解释。

我建议显式写参数名称(尚未调整参数)

maxLineGap

写一点,但至少OpenCV不再混合参数

可视化线

我更改了每一行的线条颜色,以便更容易地查看哪个线段在哪里:

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

更改参数

通过为 color = np.random.uniform(0,255,3) cv2.line(imgOut,(x1,y1),(x2,y2),color,2) rho设置较少的分档(通过增加参数来实现),您将有更多机会让曲线的边缘为同一个分档投票。

以下是一些尝试(下面的完整代码)

theta

Too many lines 显示的线太多。降低参数

为什么要骨化?

您的输入图像(如给定的)看起来边缘已经存在。 rho=5,theta=np.deg2rad(10),threshold=10,minLineLength=5,maxLineGap=2 的输出只是边缘的中心线,这听起来像是一件好事,但对于Hough Lines来说,它意味着减少像素的数量"投票"对于细分市场。

skeletonize

这在具体细节上没有太大变化,但我认为它不会伤害手头的任务。

为什么不标签?

您尝试获得的是各个细分市场。为什么不标记图像?

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

Labelled image

通过应用一些形态学运算符,您将获得单独的行或在最坏的情况下,行分支。

现在您可以通过

单独选择行
from matplotlib import pyplot as plt
from scipy import ndimage 

labels,nblabels = ndimage.label(sk)
plt.imshow(labels,'jet')
plt.show()

将Hough线应用于这些可能是过度的解开它们,但你已经明显地解决了你的问题。

指标的计算现在非常简单(参见ndimage.measurement文档),对数组的迭代非常简单。