Python openCV检测平行线
Posted
技术标签:
【中文标题】Python openCV检测平行线【英文标题】:Python openCV detect parallel lines 【发布时间】:2013-03-24 16:44:39 【问题描述】:我有一张图片,里面有一些形状。我使用霍夫线检测到线。如何检测哪些线是平行的?
【问题讨论】:
如果这是在 python 中完成的,如标签中所述,您可以使用 scipy 版本的 houghlines,它提供 houghspace 输出图像:参见此处](scikit-image.org/docs/dev/auto_examples/…)。然后,您可以翻转独立轴(theta 或“X”)和从属轴(rho 或“Y”),使 theta 现在是从属轴。在对该霍夫空间图像进行阈值处理后(以获得与最可能的线相对应的 (rho, theta) 的最强烈点),您可以将一条水平线拟合到数据中:theta = constant (y=mx+b with no slope )。 【参考方案1】:笛卡尔坐标系的方程:
y = k * x + b
两条线 y = k1 * x + b1, y = k2 * x + b2 是平行的,如果 k1 = k2。
所以你需要为每条检测到的线计算系数 k。
为了唯一识别一条线的方程,您需要知道属于该线的两个点的坐标。
在找到带有 HoughLines (С++) 的行之后:
vector<Vec2f> lines;
HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );
您有矢量线,它将检测到的线的参数 (r,theta) 存储在极坐标中。您需要在笛卡尔坐标中传输它们:
这里是 C++ 示例:
for( size_t i = 0; i < lines.size(); i++ )
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b)); //the first point
pt1.y = cvRound(y0 + 1000*(a)); //the first point
pt2.x = cvRound(x0 - 1000*(-b)); //the second point
pt2.y = cvRound(y0 - 1000*(a)); //the second point
得到一条直线的这两点后,就可以计算出它的方程了。
【讨论】:
检测线是否平行检查θ值是否足够?我们可以说 theta 值等于线平行吗? 我认为检查 theta 值就足够了。【参考方案2】:HoughLines 以极坐标返回其结果。所以只需检查角度的第二个值。无需转换为 x,y
def findparallel(lines):
lines1 = []
for i in range(len(lines)):
for j in range(len(lines)):
if (i == j):continue
if (abs(lines[i][1] - lines[j][1]) == 0):
#You've found a parallel line!
lines1.append((i,j))
return lines1
【讨论】:
应该是if (abs(lines[i][0][1] - lines[j][0][1]) == 0):
【参考方案3】:
正如约翰所建议的,最简单的方法是检测相似的角度。 OpenCVs HoughLines 函数通过它到原点的距离和角度来表示一条线。
所以你基本上可以做的是用分层聚类算法对不同的角度进行聚类:
from scipy.spatial.distance import pdist
from scipy.cluster.hierarchy import ward, fcluster
img = cv2.imread('images/img01.bmp')
img_canny = cv2.Canny(img, 50, 200, 3)
lines = cv2.HoughLines(img_canny, 1, 5* np.pi / 180, 150)
def find_parallel_lines(lines):
lines_ = lines[:, 0, :]
angle = lines_[:, 1]
# Perform hierarchical clustering
angle_ = angle[..., np.newaxis]
y = pdist(angle_)
Z = ward(y)
cluster = fcluster(Z, 0.5, criterion='distance')
parallel_lines = []
for i in range(cluster.min(), cluster.max() + 1):
temp = lines[np.where(cluster == i)]
parallel_lines.append(temp.copy())
return parallel_lines
【讨论】:
以上是关于Python openCV检测平行线的主要内容,如果未能解决你的问题,请参考以下文章