如何使用 opencv 霍夫线算法获取线的交点?
这是我的代码:
import cv2
import numpy as np
import imutils
im = cv2.imread('../data/test1.jpg')
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 60, 150, apertureSize=3)
img = im.copy()
lines = cv2.HoughLines(edges,1,np.pi/180,200)
for line in lines:
for rho,theta in line:
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 3000*(-b))
y1 = int(y0 + 3000*(a))
x2 = int(x0 - 3000*(-b))
y2 = int(y0 - 3000*(a))
cv2.line(img,(x1,y1),(x2,y2),(0,255,0),10)
cv2.imshow('houghlines',imutils.resize(img, height=650))
cv2.waitKey(0)
cv2.destroyAllWindows()
输出:
我想得到所有的交点。
原文由 Nauman Umer 发布,翻译遵循 CC BY-SA 4.0 许可协议
你不想得到平行线的交点;只有垂直线与水平线的交点。此外,由于您有垂直线,计算斜率可能会导致斜率爆炸或 inf 斜率,因此您不应使用
y = mx+b
方程式。你需要做两件事:使用
HoughLines
,您已经得到了rho, theta
的结果,因此您可以轻松地将角度分为两类theta
您可以使用例如cv2.kmeans()
和theta
作为您要拆分的数据。然后,要计算交点,可以使用 给定每条线的两个点计算交点 的公式。您已经从每行计算了两个点:
(x1, y1), (x2, y2)
因此您可以简单地存储并使用它们。编辑:实际上,如下面我的代码所示,有一个公式可用于计算线与rho, theta
形式的交点HoughLines
给出。我之前用一些 python 代码回答 了类似的问题,你可以查看;请注意,这是使用
HoughLinesP
给你线段。代码示例
你没有提供你的原始图像,所以我不能使用它。相反,我将使用 OpenCV 在其霍夫变换和阈值教程中使用的标准数独图像:
首先,我们将读取此图像并使用自适应阈值将其二值化,就像 本 OpenCV 教程 中使用的那样:
然后我们将找到带有
cv2.HoughLines()
的 Hough 线:现在,如果我们想找到交点,实际上我们只想找到垂直线的交点。我们不想要大部分平行线的交点。所以我们需要分割我们的线。在这个特定的例子中,你可以很容易地根据一个简单的测试来检查这条线是水平的还是垂直的;垂直线的
theta
大约为 0 或大约 180;水平线将有一个theta
大约 90。但是,如果你想根据任意数量的角度自动分割它们,而不定义这些角度,我认为最好的主意是使用cv2.kmeans()
。要做好一件棘手的事情。
HoughLines
返回线rho, theta
形式( Hesse范式),和theta
之间0和线18018 (它们都接近水平线),所以我们需要一些方法来获得kmeans
中的这种周期性。如果我们在单位圆上绘制角度,但将角度乘以 2 ,则原来约 180 度的角度将变为接近 360 度,因此单位圆上的值将接近
x, y
角度为 0。因此,我们可以通过绘制2*angle
与单位圆上的坐标来获得一些不错的“接近度”。然后我们可以在这些点上运行cv2.kmeans()
,并自动分割我们想要的任何部分。因此,让我们构建一个函数来进行分割:
现在要使用它,我们可以简单地调用:
这里的好处是我们可以通过指定可选参数
k
来指定任意数量的组(默认情况下,k = 2
所以我没有在这里指定它)。如果我们用不同的颜色绘制每组的线条:
现在剩下的就是找到第一组中每条线与第二组中每条线的交点。由于这些线是 Hesse 范式,因此有一个很好的线性代数公式用于计算这种形式的线的交点。看 这里。让我们在这里创建两个函数;一个只找到两条线的交点,一个函数循环遍历组中的所有线并将该更简单的函数用于两条线:
然后使用它,它很简单:
并绘制所有交叉点,我们得到:
如上所述,此代码也可以将线分割成两组以上的角度。这是它在手绘三角形上运行,并计算检测到的线与
k=3
的交点: