霍夫变换(Hough Line Transform)-直线检测

OpenCV官网
参考1

原理

  • 直角坐标表示
  1. y = m x + b y=mx+b y=mx+b 描述一条直线, m是斜率, b是截距,m和b是参数。
  2. 如果将上面 的式子改写: b = − m x + y b=-mx+y b=mx+y ,x和y 是参数。

根据以上两个式子得出结论:给定一个点(x,y),对应到 2 上就是一条直线,x 相当于斜率,y相当于截距。如果给定一系列的点(x1,y1)、(x2,y2)、(x3,y3)…都在一条直线上,也就是满足 y = m x + b y=mx+b y=mx+b,那么对应到 2 中,每个点对应的线将交于一点。 但是由于 参数 m 和 b可能比较大,所以采用极坐标比较合适。

霍夫变换(Hough Line Transform)-直线检测_第1张图片

  • 极坐标系表示
  1. 极坐标系,一条直线的表示,知道 r r r θ \theta θ ,确定一条直线(红色):
霍夫变换(Hough Line Transform)-直线检测_第2张图片
  1. 整理后:

Image Space中每一个点对应到 Parameter Space 中就是一条曲线(三角函数曲线)。在Image Space中的一条直线上,对应到Parameter Space 中 也是相交于一点(只看 r > 0 r>0 r>0 0 < θ < 2 π 0<\theta < 2\pi 0<θ<2π):

霍夫变换(Hough Line Transform)-直线检测_第3张图片
  • 检测方法
  1. 对于图像的每个像素点(x,y),对应到参数空间中,找到交点,交于此点的曲线个数就是图像空间的直线上的像素点数。
  2. 设置一个阈值,交于一点曲线个数超过这个值,图像中才算一条直线;在图像空间中意味着参数为( r , θ r,\theta r,θ)的直线。

代码

#include 
#include 


using namespace cv;
using namespace std;



int main(void)
{
	Mat dst,cdst,cdstP;

	const char* image = "../res/lines.png";

	Mat src = imread(image, cv::IMREAD_GRAYSCALE);
	if(src.empty())
	{
		cout << " Oops, failed load image" << endl;
	}


	Canny(src,dst,50,200,3);
	
	cvtColor(dst,cdst,cv::COLOR_GRAY2BGR);


	cdstP = cdst.clone();

//第一种API
	vector<Vec2f> lines;
	HoughLines(dst,lines,1,CV_PI/180,120,0,0);

	for(int i=0; i< lines.size(); i++)
	{
		float rho= lines[i][0], theta = lines[i][1];
		Point pt1,pt2;

		double a = cos(theta), b = sin(theta);
		double x0 = a*rho, y0 = b*rho;


		pt1.x = cvRound(x0+1000*(-b));  //见底下图的解释
		pt1.y = cvRound(y0+1000*(a));
		pt2.x = cvRound(x0- 1000*(-b));
		pt2.y = cvRound(y0 - 1000*(a));
		line(cdst,pt1,pt2,Scalar(0,0,255),3,LINE_AA);

	}
	
//第二种API
	vector<Vec4i> linesP;
	HoughLinesP(dst,linesP,1,CV_PI/180,50,50,10);  
	for(int i=0;i<linesP.size();i++)
	{
		Vec4i l = linesP[i];
		line(cdstP,Point(l[0],l[1]),Point(l[2],l[3]),Scalar(0,0,255),3,LINE_AA);
	}

//显示
	imshow("HoughLines Demo", cdst);
	imshow("HoughLinesP Demo" ,cdstP);
	waitKey(0);

	return 0;
};

霍夫变换(Hough Line Transform)-直线检测_第4张图片

结果:

霍夫变换(Hough Line Transform)-直线检测_第5张图片
霍夫变换(Hough Line Transform)-直线检测_第6张图片
霍夫变换(Hough Line Transform)-直线检测_第7张图片

OpenCV API

不建议使用
void cv::HoughLines
(
InputArray image,     // 8bits 单通道灰度 图像
OutputArray lines,    // vector (ρ,θ) ,ρ和θ是极坐标,θ弧度制,范围 0- π 2 \frac{\pi}{2} 2π, 横轴为0,纵轴为 π 2 \frac{\pi}{2} 2π
double rho,    // r 的步长(没明白),一般设1
double theta,    //θ部长(没明白),一般设置CV_PI/180
int threshold,    // votes 的阈值,只有大于这个的点数的线,才会被检测
double srn = 0,    // 处理多尺度图像,一般默认即可
double stn = 0,    //处理多尺度图像,一般默认即可
double min_theta = 0,    // 默认即可
double max_theta = CV_PI     //默认即可
)



建议使用

void cv::HoughLinesP
(
InputArray image,          // 8bits 单通道灰度图像
OutputArray lines,          // 4-element vector (x1,y1,x2,y2) (x1,y1)和(x2,y2)是直线的端点
double rho,          // r 的步长(没明白),一般设1
double theta,          // θ部长(没明白),一般设置CV_PI/180
int threshold,          //直线点数的阈值,>threshold才会被检测
double minLineLength = 0,     //小于此点数的直线将会被删除
double maxLineGap = 0     //同一条直线上两点的最小Gap
)

你可能感兴趣的:(opencv)