霍夫变换直线检测算法实现OpenCV(C++)

这篇具有很好参考价值的文章主要介绍了霍夫变换直线检测算法实现OpenCV(C++)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、原理
对于霍夫变换的原理这里就不进行描述啦,感兴趣的可以自行搜索。也可以看知乎上面的这篇贴文通俗易懂理解——霍夫变换原理。
二、算法代码

/*
*参数说明:
*src:待检测的原图像
*rho:以像素为单位的距离分辨率,即距离r离散时的单位长度
*theat:以角度为单位的距离分辨率,即角度Θ离散时的单位长度
*Threshold:累加器阈值,参数空间中离散化后每个方格被通过的
           累计次数大于该阈值,则该方格代表的直线被视为在
		   原图像中存在
*lines:检测到的直线极坐标描述的系数数组,每条直线由两个参
       数表示,分别为直线到原点的距离r和原点到直线的垂线与
	   x轴的夹角Θ 
*/
void myHoughLines(Mat &src,double rho,double theat,int Threshold,vector<Vec2f> &lines)
{
	if (src.empty()|| rho<0.1 || theat>360|| theat<0)
		return ;

	int row = src.rows;
	int col = src.cols;
	Mat gray;
	if (src.channels() > 1)
	{//灰度化
		cvtColor(src, gray, COLOR_BGR2GRAY);
	}
	else
		src.copyTo(gray);

	int maxDistance = sqrt(src.cols*src.cols + src.rows*src.rows);
	int houghMat_cols = 360 / theat;//霍夫变换后距离夹角坐标下对应的Mat的宽
	int houghMat_rows = maxDistance / rho;//霍夫坐标距离夹角下对应的Mat的高
	Mat houghMat = Mat::zeros(houghMat_rows, houghMat_cols, CV_32FC1);

	//边缘检测
	Canny(gray, gray, 100, 200, 3);

	//二值化
	threshold(gray, gray, 160, 255, THRESH_BINARY);

	//遍历二值化后的图像
	for (int i = 0;i < row;i++)
	{
		for (int j = 0;j < col;j++)
		{
			if (gray.ptr<uchar>(i)[j] != 0)
			{
				/*从0到360度遍历角度,得到一组关于距离夹角的离散点,即得到
				一组关于经过当前点(i,j)按单位角度theat旋转得到的直线*/
				for (int k = 0;k < 360/ theat;k += theat)
				{
					double r = i*sin(k*CV_PI / 180) + j*cos(k*CV_PI / 180);
					if (r >= 0)
					{//直线到原点的距离必须大于0
						//获得在霍夫变换距离夹角坐标系下对应的Mat的行的下标
						int r_subscript = r / rho;
						
						//经过该直线的点数加1
						houghMat.at<float>(r_subscript,k)= houghMat.at<float>(r_subscript, k)+1;
					}
					
				}
			}
		}
	}
	
	//经过直线的点数大于阈值,则视为在原图中存在该直线
	for (int i = 0;i < houghMat_rows;i++)
	{
		for (int j = 0;j < houghMat_cols;j++)
		{
			if (houghMat.ptr<float>(i)[j] > Threshold)
			{
				//line保存直线到原点的距离和直线到坐标原点的垂线和x轴的夹角
				Vec2f line(i*rho,j*theat*CV_PI/180);
				lines.push_back(line);
			}
		}
	}
	
}

三、效果测试
测试代码

void drawLine(Mat &img, vector<Vec2f> lines, double rows, double cols, Scalar scalar, int n)
{
	Point pt1, pt2;
	for (int i = 0;i < lines.size();i++)
	{
		float rho = lines[i][0];//直线到坐标原点的距离
		float theat = lines[i][1];//直线到坐标原点的垂线和x轴的夹角
		double a = cos(theat);
		double b = sin(theat);
		double x0 = a*rho, y0 = b*rho;//直线与过坐标原点的垂线的交点
		double length = max(rows, cols);//突出高宽的最大值
		
		//计算直线上的一点
		pt1.x = cvRound(x0 + length*(-b));
		pt1.y = cvRound(y0 + length*(a));
		//计算直线上的另一点
		pt2.x = cvRound(x0 - length*(-b));
		pt2.y = cvRound(y0 - length*(a));
		while (pt1.x == pt2.x&&pt1.y == pt2.y)
		{
			//计算直线上的另一点
			pt2.x = cvRound(x0 + length*(-b));
			pt2.y = cvRound(y0 + length*(a));
		}
		//两点绘制直线
		line(img, pt1, pt2, scalar, n);
	}
}

int main()
{
	//Mat test = imread("../d.png");
    Mat test = imread("../HoughLines.jpg");
	vector<Vec2f> lines;
	myHoughLines(test,1,1,100,lines);
	for (int i = 0;i < lines.size();i++)
	{
		cout << "直线为:" << endl << lines[i] << endl;
	}
	Mat testResult = Mat::zeros(test.size(),CV_8U);//在全黑的图像中画出直线
	//test.copyTo(testResult);//在原图上画出直线

	drawLine(testResult, lines, test.rows, test.cols, Scalar(255),1);
	imshow("原图:", test);
	imshow("变换后的直线:", testResult);
	waitKey(0);
	return 0;
}

上述代码中的drawLine()函数是《OpenCV4快速入门》一书的代码清单 7-2中的原函数,只用于画线。
测试原图
霍夫直线检测c++实现,OpenCV,算法,算法,c++,计算机视觉
测试效果
霍夫直线检测c++实现,OpenCV,算法,算法,c++,计算机视觉
该算法代码的解析在代码的注释中已经写明,对函数参数也进行了说明。我使用了多张图片进行了测试,以及多次调整参数进行测试,发现在rho=1,theat=1,Threshold=100时的检测效果可以达到最佳。文章来源地址https://www.toymoban.com/news/detail-745083.html

到了这里,关于霍夫变换直线检测算法实现OpenCV(C++)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【OpenCV】cv2.HoughLines()霍夫直线检测

    霍夫直线检测(Hough Line Transform)是一种在图像中检测直线的经典算法。它通过将二维图像空间中的点映射到极坐标空间中,将直线检测问题转化为在参数空间中找到交点的问题。 原理: 对于图像空间中的每个边缘点,计算其对应在极坐标空间中可能的直线。 极坐标空间中

    2024年02月05日
    浏览(43)
  • OpenCV——霍夫变换圆检测

        HoughCircles 该函数使用霍夫变换在灰度图像中查找圆。 image :输入图像,需要为 8 位的灰度单通道图像。 circle :找到的圆的输出向量。每个向量被编码为3或4个元素的浮点型向量 ( x , y , r a d i u s ) (x, y, radius) ( x , y , r a d i u s ) 或 ( x , y , r a d i u s , v o t e s ) (x, y, radius,

    2024年02月13日
    浏览(27)
  • OpenCV | 霍夫变换:以车道线检测为例

    霍夫变换 霍夫变换只能灰度图,彩色图会报错 lines = cv2.HoughLinesP(edge_img,1,np.pi/180,15,minLineLength=40,maxLineGap=20) 参数1:要检测的图片矩阵 参数2:距离r的精度,值越大,考虑越多的线 参数3:距离theta的精度,值越大,考虑越多的线 参数4:累加数阈值,值越小,考虑越多的线

    2024年02月04日
    浏览(27)
  • OpenCV26HoughCircles 霍夫圆变换原理及圆检测

    霍夫圆变换的基本原理与霍夫线变换大体类似 对直线来说,一条直线能由极径极角(r,θ)表示,而对于圆来说,我们需要三个参数:圆心(a,b),半径 r 笛卡尔坐标系中圆的方程为: (x-a)2 + (y-b)2 = r2 化简便可得到: a = x - r·cosθ b = y - r·sinθ 对于(x0,y0),我们可以将通

    2024年02月03日
    浏览(29)
  • OpenCV中的图像处理 —— 霍夫线 / 圈变换 + 图像分割(分水岭算法) + 交互式前景提取(GrabCut算法)

    🌎上一节我们介绍了OpenCV中傅里叶变换和模板匹配,这一部分我们来聊一聊霍夫线/圈变换的原理和应用、使用分水岭算法实现图像分割和使用GrabCut算法实现交互式前景提取 🏠哈喽大家好,这里是ErrorError!,一枚某高校大二本科在读的♂同学,希望未来在机器视觉领域能够有

    2023年04月08日
    浏览(34)
  • OPENCV C++(七)霍夫线检测+找出轮廓和外接矩形+改进旋转

    霍夫线检测  定义存放输出线的向量 此向量输出有距离,角度 因为检测的原理就是在变换霍夫空间里面去检测的,这里可以理解为极坐标 第3个参数是距离精度 第四个参数是角度精度,第五个是阈值,只有点超过90个才算一条线 在图中画线操作: 这里是画线操作  概率霍夫

    2024年02月13日
    浏览(31)
  • OpenCV如何实现直线检测

    本文主要介绍OpenCV自带的直线检测函数HoughLines()的用法,这个函数的第一个参数是一个二值化图像,所以在进行霍夫变换之前要首先进行二值化,或者进行Canny 边缘检测。第二和第三个值分别代表beta; 和 theta; 的精确度。第四个参数是阈值,只有累加其中的值高于阈值时才被

    2024年02月14日
    浏览(29)
  • 【矩阵检测】Hough霍夫变换矩阵检测【含Matlab源码 3563期】

    获取代码方式1: 完整代码已上传我的资源:【矩阵检测】基于matlab Hough霍夫变换矩阵检测【含Matlab源码 3563期】 点击上面蓝色字体,直接付费下载,即可。 获取代码方式2: 付费专栏Matlab图像处理(初级版) 备注: 点击上面蓝色字体 付费专栏Matlab图像处理(初级版) ,扫

    2024年02月04日
    浏览(29)
  • 【计算机图形学】图形变换(以任意直线为对称轴的对称变换)

    模块3-2 图形变换 一 实验目的 编写图形各种变换的算法 二 实验内容 1 :任意直线的对称变换。要求将变换矩阵写在实验报告中,并与代码匹配。求对任意直线Ax+By+C=0的对称变换矩阵。 实验结果如下图所示: 1:预设图形初始化 2:鼠标左键点击直线起点 3:鼠标右键点击直线

    2024年02月01日
    浏览(45)
  • Python-OpenCV中的图像处理-霍夫变换

    霍夫(Hough)变换在检测各种形状的技术中非常流行,如果要检测的形状可以用数学表达式描述,就可以是使用霍夫变换检测它。即使要检测的形状存在一点破坏或者扭曲也是可以使用。 Hough直线变换,可以检测一张图像中的直线 cv2.HoughLines(image, rho, theta, threshold) return:返回值

    2024年02月13日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包