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;
}