利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解

为了更好的理解这篇文章,大家可以先看看我写的另一篇博文,链接如下:
https://blog.csdn.net/wenhao_ir/article/details/51774444[0]

OpenCV的霍夫变换线检测函数HoughLines()是利用极坐标下的参数ρ和θ值来表示直线的,我们在实际应用中往往要根据直线的参数ρ和θ值来绘制出直线,那么怎么绘制呢?
在OpenCV中绘制直线的函数为函数line(),它的原型如下:

void cv::line	(	InputOutputArray img,
					Point 	pt1,
					Point 	pt2,
					const Scalar & 	color,
					int 	thickness = 1,
					int 	lineType = LINE_8,
					int 	shift = 0 
				)	

从这个原型中,我们可以看出,如果要使用这个函数绘制线条,那么需要知道线条的两个端点,即参数中的pt1和pt2,所以问题就转化为根据参数ρ和θ值计算要绘制直线的两个端点。
在进行计算前,我们先要搞清楚利用函数HoughLines()得到的θ到底是哪个角的度数。
当直线为水平或垂直时θ的值分别为π/2(即90度)和0(即0度),这个在官方文档中已经说得很清楚了。如下面的截图所示:

至于其他情况,我们就用两张图来测试一下。
案例1的图片如下:
请添加图片描述
第二张图如下:
请添加图片描述
检测图中两条直线的代码如下:

//博主微信/QQ 2487872782
//有问题可以联系博主交流
//有图像处理需求也可联系博主
//图像处理技术交流QQ群 271891601

//OpenCV版本:3.0
//VS版本:2012

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>

using namespace cv;
using namespace std;

#define HOUGH_VOTE 100

int main()
{
	cv::Mat srcImg1 = cv::imread("F:/material/images/P0041-HoughLines-angle-01.bmp", 0);//读取原图像并同时转换为灰度图
	if (!srcImg1.data)   
	{
		cout<<"error load image"<<endl;
		return -1;
	}

	vector<Vec2f> lines;
	float pi180 = (float)CV_PI / 180;

	
	HoughLines(srcImg1, lines, 1, pi180, HOUGH_VOTE, 0, 0);
	int numLines = lines.size();

	for (int l = 0; l<numLines; l++)
	{
		float theta = lines[l][1];
		cout <<"检测到的第"<< l+1<<"条线的角度为"<<":" << theta* 180 / CV_PI<< endl;

	}

	waitKey(0);

	return 0;


}

两幅图像的检测结果如下:

这里解释了为什么检测到多条直线。这是因为我们的直线是有宽度的,所以会检测到多条线。
从这个运行结果我们可以看出在这两种情况下哪个角度是 θ。如下两图所示:

案例二:

知道了哪个角度是θ,我们在图上标出其他已知量、要找的点和一些辅助线,如下图两张:

图中的r就是
由上述几何关系并结合三角函数的和、差公式:

不难得到在两种情况下都有pt1的坐标为:
利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解
利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解
两种情况下都有pt2的坐标为:
利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解
利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解
in
利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解
利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解
有了以上计算公式后,我们便可以根据得到的ρ和θ值计算出pt1和pt2的坐标,进而绘制出直线。
相关代码如下:

	HoughLines(magImg, lines, 1, pi180, HOUGH_VOTE, 0, 0);
	int numLines = lines.size();
	int L = 1000;
	for (int l = 0; l<numLines; l++)
	{
		float rho = lines[l][0], theta = lines[l][1];
		Point pt1, pt2;
		double a = cos(theta), b = sin(theta);
		double x0 = a*rho, y0 = b*rho;
		pt1.x = cvRound(x0 + L * (-b));
		pt1.y = cvRound(y0 + L * (a));
		pt2.x = cvRound(x0 - L * (-b));
		pt2.y = cvRound(y0 - L * (a));
		line(linImg, pt1, pt2, Scalar(255, 0, 0), 3, 8, 0);
	}

很明显,上面的代码中,L值是需要我们根据图像的大小和直线的大小来确定,并不是每一幅图像或每一条直线都取1000。L是什么的长度,博主在上面的手绘图中应该是已经标注得很清楚了。

最后,对这篇博文有不明白的可以加博主的微信/QQ 2487872782交流。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2022年5月7日
下一篇 2022年5月7日