在骨架图像OpenCV python中查找线 [英] Find Line in skeleton Images OpenCV python

查看:382
本文介绍了在骨架图像OpenCV python中查找线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下图片:





我希望找到行进行一些计算,平均长度等...
我试图用 HoughLinesP ,但它找不到行。我该怎么办?



这是我的代码:

  sk =骨架(掩模); 
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的参数我只能获得线段,不是一条实线。

解决方案

虽然霍夫线算法仅适用于线条(并且你明确地处理曲线) ),通过大大增加 rho theta 参数。



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






编辑
您有一点问题:OpenCV的定义 cv2.HoughLinesP 。来自
显示太多行。降低参数



为什么要进行骨架化?



您的输入图像(如给定的)看起来边缘已经存在。 skeletonize 的输出只是边缘的中心线,这听起来像是一件好事,但对于Hough Lines来说,这意味着减少线段投票的像素数量。

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

具体情况并没有太大变化,但我认为这不会影响手头的任务。



为什么不贴标签?



您要获得的是单个线段。为什么不标记图像?

 来自matplotlib import pyplot as plt 
from scipy import ndimage

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



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



现在你可以单独选择行

  line = labels == 2#选择标签为2的像素仅为

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



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


I have the following picture:

and I want to find the lines to do some calculations, average length etc ... I tried to use HoughLinesP, but it doesn't find the lines. How can I do?

This is my code:

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)

Output:

If i change the parameters of HoughLinesP I only get fragments of line, not a solid line.

解决方案

Although the Hough lines algorithm is meant for lines only (and you're clearly dealing with curves), there might be a way to salvage your attempt, by greatly augmenting the rho and theta parameters.

This should make the curved sides point to the same bin rather than be split in different bins.


EDIT : You have a bit of a problem : OpenCV's definition of cv2.HoughLinesP. From the documentation :

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

As you might see, the 5th parameter is lines, the output variable. Your call is

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

So your given minLineLength parameter has no effect (it becomes an output variable), and maxLineGap has wrong interpretation too.

I suggest to explicitly write parameter names (without parameter tweaks yet)

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

a bit long to write, but at least OpenCV doesn't mix the parameters anymore

Visualizing the lines

I changed the line color for each line for an easier time visualizing which segment is where :

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

Changing parameters

By having less bins for rho and theta (achieved by increasing the parameters) you will have more chances of having the edges of a curve vote for the same line-bin.

Here are some attempts (full code below)

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

Too many lines shown. Lowering the parameters

Why skeletonize ?

Your input image (as given) looks like edges are already there. The output of skeletonize is only the central line of edges, which sounds like a positive thing, but for Hough Lines, it means reducing the number of pixels "voting" for line segments.

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

This didn't change much in specifics, but I thought it couldn't hurt the task at hand.

Why not label ?

What you're trying to get is individual line segments. Why not just label the image ?

from matplotlib import pyplot as plt
from scipy import ndimage 

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

By applying a little morphological operators you will get individual lines or in the worst case, line branchings.

Now you can select the lines individually by doing

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

Applying Hough lines to these might be overkill to untangle them, but you'd have significantly broken down your problems already.

Calculation of metrics is now super easy (see ndimage.measurement documentation) and iteration over arrays is super simple.

这篇关于在骨架图像OpenCV python中查找线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆