如何从 OpenCV C++ 中的 HoughLines 函数输出中绘制所需的线?

Posted

技术标签:

【中文标题】如何从 OpenCV C++ 中的 HoughLines 函数输出中绘制所需的线?【英文标题】:How to draw a desired line from HoughLines function output in OpenCV C++? 【发布时间】:2018-08-11 04:40:13 【问题描述】:

上下文:

lecture 中的第 8 页说 OpenCV HoughLines 函数返回一个 N x 2 行参数数组 rhotheta 存储在名为 lines 的数组。

然后为了从这些角度实际创建线,我们有一些公式,后来我们使用 line 函数。公式在下面的代码中解释。

代码:

    //Assuming we start our program with the Input Image as shown below.
    //This array will be used for storing rho and theta as N x 2 array

    vector<Vec2f> lines; 

    //The input bw_roi is a canny image with detected edges
    HoughLines(bw_roi, lines, 1, CV_PI/180, 70, 0, 0); '

    //These formulae below do the line estimation based on rho and theta

    for( size_t i = 0; i < lines.size(); i++ )
    
        float rho = lines[i][0], theta = lines[i][1];
        Point2d pt1, pt2;
        double m;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;

        //When we use 1000 below we get Observation 1 output. 
        //But if we use 200, we get Observation 2 output.

        pt1.x = cvRound(x0 + 1000*(-b)); 
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));

        //This line function is independent of HoughLines function    
        //and is used for drawing any type of line in OpenCV

        line(frame, pt1, pt2, Scalar(0,0,255), 3, LINE_AA);
     

输入图像:

观察 1:

观察 2:

问题:

在上面显示的代码中,如果我们将数字与 a、-a、b 和 -b 相乘,我们会得到不同长度的行。当我乘以 200 而不是 1000(导致观察 1)时,得到了观察 2。

更多信息请参考上图代码第18行和第19行的cmets。

问题:

当我们从 HoughLines 输出中绘制线条时,我们如何控制线条的起点和终点?

例如,我希望观察 2 中的右侧车道(从左上角指向右下角的红线)从屏幕的右下角开始并指向屏幕的左上角(就像左车道)。

【问题讨论】:

【参考方案1】:

给定

a = cos(theta)
b = sin(theta)

x0 = a * rho
y0 = b * rho

你可以为(rho, theta)定义的线上的所有点写公式

x = x0 - c * b
y = y0 + c * a

其中c 是到参考点的距离(与通过原点的垂线相交)。

在您的情况下,您已经使用 c = 1000c = -1000 对其进行了评估,以得到两个点来画一条线。

您可以将它们重写为

c = (x0 - x) / b
c = (y - y0) / a

然后用代入法计算水平和垂直截距:

x = x0 - ((y - y0) / a) * b

y = y0 + ((x0 - x) / b) * a

注意:注意正确处理ab为0的情况。


假设您有一张 800x600 的图片(为了保持数字简单)。我们可以将图像的底部边缘定义为线y = 599。使用上面的公式计算你的线截取x 的值。

如果截取点在图像中 (0 &lt;= x &lt; 800),那就是您的起点。 如果它在左边 (x &lt; 0),找到与线 x = 0 的截距作为起点。 如果它在右边 (x &gt;= 800),找到与线 x = 799 的截距作为起点。

然后使用类似的技术找到第二个点,以便能够画一条线。

【讨论】:

@谢谢丹。我一直在寻找这样的解释。 OpenCV 函数并没有像你那样很好地解释事情。有时它假设所有用户都会知道某些对每个人来说并不明显的事情。因此,我们不得不偶尔在 *** 上提出这样的问题 :)

以上是关于如何从 OpenCV C++ 中的 HoughLines 函数输出中绘制所需的线?的主要内容,如果未能解决你的问题,请参考以下文章

C# 窗口中的 C++ opencv 应用程序

从 OpenCV(C++)中的目录读取多个图像

如何在 OpenCV c++ 中从图像中裁剪特定的矩形部分(ROI)

从 Android 中的本机 c++ 文件调用本机 opencv

OpenCV 中的轮廓比较(从 C 到 C++ 的转换)

如何使用 OpenCV 从 C++ 程序制作 Android 应用程序