尽管霍夫线算法仅适用于直线(并且您显然正在处理曲线),但可能有一种方法可以通过大大增强rho
and theta
参数。
这应该使弯曲的边指向同一个垃圾箱,而不是分成不同的垃圾箱。
EDIT:
你有一个问题:OpenCV 的定义cv2.HoughLinesP
。来自文档 http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=cv2.houghlinesp#cv2.HoughLinesP :
cv2.HoughLinesP(图像, rho, theta, 阈值[ 线[ 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
and theta
(通过增加参数来实现)您将有更多机会让曲线的边缘投票给相同的行箱。
这是一些尝试(下面是完整代码)
rho=5,theta=np.deg2rad(10),threshold=10,minLineLength=5,maxLineGap=2
Too many lines shown. Lowering the parameters
为什么要骨骼化?
您的输入图像(如给定的)看起来边缘已经存在。的输出skeletonize
只是边缘的中心线,这听起来像是一件积极的事情,但对于霍夫线来说,这意味着减少对线段“投票”的像素数量。
# 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.测量 http://docs.scipy.org/doc/scipy/reference/ndimage.html#module-scipy.ndimage.measurements文档)并且数组上的迭代非常简单。