opencv入门(12)--霍夫变换

本文介绍了霍夫变换在数字图像处理中的直线和圆检测方法,包括原理、相关API(如cv::HoughLines和cv::HoughCircles)以及实际的代码示例。通过Canny算子预处理图像,然后利用霍夫变换检测边缘并找到直线和圆的位置。
摘要由CSDN通过智能技术生成

12.1 引言

霍夫变换是数字图像处理中的一种常用技术,可以用来检测图像中的直线、圆或其他形状。

12.2 霍夫直线检测

12.2.1 原理

霍夫直线检测过程,是将笛卡尔坐标系下的直线方程转换到极坐标系下,并将各个像素的坐标带入得到的方程,获取对应的直线参数。前提条件--边缘检测已完城。

假设直线在平面空间的方程为y=kx+b,将其转换到极坐标下会有

\left\{\begin{matrix} x=r*\cos \Theta \\ y=r*\sin \Theta \end{matrix}\right.\Rightarrow r=x*\cos \Theta +y*\sin \Theta

       将图像中的每个点代入方程,每一个像素位置均可以绘制出一条曲线,相交时表征该点通过同一条直线。相交的个数对应直线经过的点的个数。

在上述已知的极坐标(\Theta ,r) ,反算到笛卡尔坐标系中,可得到关于x,y的方程,输入不同的x,得到y,可在图像中绘制出一条直线:

y=\left ( -\frac{\cos \Theta }{\sin \Theta } \right )x+\left ( \frac{r}{\sin \Theta } \right )

综上:对于任意一条直线上的所有点来说,变换到极坐标中,从[0~360]空间,可以得到r的大小;属于同一条直线上的点,在极坐标中(\Theta,r )必然在一个点上有最强的信号出现,根据此反算到平面坐标中就可以得到直线上各点的像素坐标。

12.2.2 相关API

  • void cv::HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold,double srn=0,double stn=0, double min_theta=0,double max_thera=CV_PI)
参数含义
作用从平面坐标转换到霍夫空间,输出是(\Theta,r )表示极坐标空间
输入image

输入图像

lines输出的极坐标,表示直线
rho生成极坐标时的像素扫描步长
theta生成极坐标时候角度步长,一般取CV_PI/180
threshold阈值,需要有多少的焦点才能被当成直线
srn

对于多尺度霍夫变换算法,该参数表示距离分辨率的除数,粗略的累加器距离分辨率是第三个参数rho,精确的累加器分辨率是rho/srn。这个参数必须是非负数。默认参数是0表示的是标准霍夫变换

stn

对于多尺度霍夫变换算法,该参数表示角度分辨率的除数,粗略的累加器角度分辨率是第四个参数theta,精确的累加器分辨率是theta/stn。这个参数必须是非负数,默认参数为0,表示的是标准霍夫变换

min_theta检测直线的最小角度,默认0
max_theta检测直线的最大角度,默认CV_PI
返回值void
  • void cv::HoughLineP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLinelength=0,double maxLineGap=0)
参数含义
作用得到图像中满足条件的直线或者线段的两个端点的坐标,进而确定直线的位置
输入image

输入图像

lines输出的极坐标,表示直线
rho生成极坐标时的像素扫描步长
theta生成极坐标时候角度步长,一般取CV_PI/180
threshold阈值,需要有多少的焦点才能被当成直线
minLinelength最小直线长度
maxLineGap直线上两个相邻点最小距离
返回值void

12.2.3 代码示例

int main(int argc, char** argv)
{
	Mat src = imread("D:\\testimg\\CSet12\\House.png");
	if (src.empty())
	{
		printf("Could not load the image...\n");
		return -1;
	}
	else;
	char input_win[] = "srcImg";
	namedWindow(input_win, WINDOW_AUTOSIZE);
	imshow(input_win, src);


	//先平滑-高斯平滑
	Mat blurimg;
	GaussianBlur(src,blurimg,Size(3,3),0,0);
	//转灰度
	Mat grayImg;
	cvtColor(blurimg, grayImg,COLOR_BGR2GRAY);
	//imshow("grayImg", grayImg);


	//Canny算子,检测边缘
	Mat CannyImg;
	Canny(grayImg, CannyImg, 100,175);
	imshow("CannyImg", CannyImg);

	//霍夫直线检测
	vector<Vec4f> plines;
	HoughLinesP(CannyImg, plines,1,CV_PI/180,10,5,10);
	Scalar color = Scalar(0, 0, 255);
	for (int i = 0; i < plines.size(); i++)
	{
		Vec4f hLine = plines[i];
		line(src,Point(hLine[0], hLine[1]), Point(hLine[2], hLine[3]),color,2);
	}
	imshow("lineImg", src);


	waitKey(0);
	return 0;
}

12.3 霍夫圆检测

12.3..1 原理

假设图像上中心像素点(a,b)和圆的半径R硬质,可以计算出圆上每个点的坐标。对于圆上的每个点绘制一个虚线圆,三个圆会有一个相交点为原始圆心。

 从平面坐标到极坐标转换3个参数C(x_{0},y_{0},r)其中x_{0},y_{0}是圆心。假设平面坐标的任意一点,转换到极坐标中:C(x_{0},y_{0},r)处有最大值,霍夫变换可利用该原理实现圆检测。

12.3.2 cv::HoughCircles

  1. 因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波;
  2. 基于效率考虑,opencv中实现的霍夫变换圆检测是基于图像题都实现的:检测边缘,发现可能的圆心;然后从候选圆心中开始计算最佳半径大小。
  • void cv::HoughCircles(InputArray image, OutputArray circles, int method,double dp, double mindist,double param1=100, double param2=100,int minRadius=0,int maxRadius=0)
参数含义
作用霍夫变化检测圆
输入image

输入图像

circles找到的圆的输出向量。每个向量被编码为3或4个元素的浮点型向量( x,y, radius) (x, y, radius)(x,y,radius) 或 ( x, y, radius , votes ) (x, y, radius, votes)(x,y,radius,votes)。
method检测方法,参见HoughModes。可用的方法是HOUGH_GRADIENTHOUGH_GRADIENT_ALT
dp累加器分辨率与图像分辨率的反比。当Dp =1时,累加器与输入图像具有相同的分辨率。如果dp=2,累加器的宽度和高度减半。
minDist两个圆心之间的最小距离
param1第一个method-specific参数。对于HOUGH_GRADIENTHOUGH_GRADIENT_ALT,它是传递给Canny边缘检测器的两个阈值中较高的阈值(较低的阈值小两倍)。
param2第二个method-specific参数。对于HOUGH_GRADIENT,它是圆的累加器阈值在检测阶段居中。它越小,越多可能会检测到假圈。
minRadius最小直径
maxRadius最大直径
返回值void

12.3.3 代码示例

int main(int argc, char** argv)
{
	Mat src = imread("D:\\testimg\\CSet12\\yingbi.png");
	if (src.empty())
	{
		printf("Could not load the image...\n");
		return -1;
	}
	else;
	char input_win[] = "srcImg";
	namedWindow(input_win, WINDOW_AUTOSIZE);
	imshow(input_win, src);

	//中值滤波
	Mat medianFilterImg, grayImg;
	medianBlur(src, medianFilterImg,3);
	cvtColor(medianFilterImg,grayImg,COLOR_BGR2GRAY);
	imshow("grayImg", grayImg);

	//霍夫圆检测
	vector<Vec3f> pcircles;
	HoughCircles(grayImg, pcircles,HOUGH_GRADIENT,1,60,70,70,50,100);
	Scalar color = Scalar(0, 0, 255);
	for (int i = 0; i <  pcircles.size(); i++)
	{
		Vec3f hcircle = pcircles[i];
		circle(src,Point(hcircle[0], hcircle[1]), hcircle[2],color,2);
	}
	imshow("circleImg", src);


	waitKey(0);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值