Hough变换

1、霍夫变换直线检测(还有圆检测,统一几何形状检测);
2、相关API;
3、代码演示;

霍夫直线变换

1、Hough Line Transform用来做直线检测;
2、前提条件-边缘检测已经完成(Canny运算);
3、将平面直角坐标转换到极坐标系中,霍夫空间–极坐标空间,平面直角坐标–空域,将图像从空域转换到霍夫域;

4、霍夫直线变换的原理:通过将图像上的像素点全部变换到极坐标空间形成很多曲线,如果其中有曲线相交于1点,则这些像素点属于同一条直线,其中交点的θ表示直线的角度,再根据交点的r、θ值反算出平面坐标中对应的像素点,即可得到对应的直线;

注:平面像素点到极坐标下曲线转换公式:

极坐标下交点到平面像素坐标转换公式:

5、直线相交点的确定方法:转换后的曲线经过的点都对应+1,则曲线经过次数最多的点值最大,亮度最大;(信号越强,点越白)

相关API

1、标准霍夫变换 : cv::HoughLines(),从平面坐标转换到霍夫空间,最终输出(theta,r)表示极坐标空间;只是输出找到的霍夫空间中的交点,反算需要自己完成;
2、霍夫变换直线概率cv::HoughLinesP(),最终输出直线的平面坐标中两个点坐标(x0,y0,x1,y1);


参数说明:
rho --扫描步长,一般取1,最大取值是图像宽度高度平方的开根号;
theta–角度步长,一般取 CV_PI/180; 最大值是π;
threshold–阈值,只有获得足够交点的极坐标点才被看成直线,可以设10(10个像素长)
srn --是否设置多尺度霍夫变换(图像金字塔),不需要设置0;


注:
minLineLength: 最小直线长度,直线多少像素才认为是直线;
maxLineGap : 间隔多少像素以内仍然认为是直线;

Code

说明:
1、Canny运算后图像为二值图像,不能画彩色线,需要调用cvtColor(edge_image, dst, CV_GRAY2BGR);转换到单通道彩色颜色空间,后面才能画彩色线;
2、创建vector<Vec4f> pline存储任意数量的Hough计算结果;
3、HoughLinesP()中调整 --最小直线长度,最大间隔可以有效改进图像显示结果;

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
   
	Mat src,dst;
	src = imread("C:\\Users\\hello\\Desktop\\22.jpg");
	if (!src.data)
	{
   
		cout << "could not load the image..." << endl;
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	Mat gaus,edge_image;
	GaussianBlur(src, gaus, Size(3, 3), 0, 0);
	//extract image 提取的彩色图像
	Canny(gaus, edge_image, 50, 100, 3, false); //边缘检测
	
	cvtColor(edge_image, dst, CV_GRAY2BGR);//转换为彩色图像
	
	imshow("edge_image", edge_image);

	//创建一个包含4个float元素的数组
	vector<Vec4f> plines;
	//Hough直变换
	HoughLinesP(edge_image, plines,1, CV_PI / 180, 20, 0, 20); //一般不用舍弃,大于0的保留
	//将检测到的直线画出来
	Scalar color = Scalar(0, 0, 255);
	for (size_t i = 0; i < plines.size(); i++)
	{
   
		Vec4f hline = plines[i];
		line(dst, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 3, LINE_AA);//画线
	}
	imshow("Hough line Detection", dst);

	waitKey(0);
	return 0;
}

效果