1.霍夫直线变换简介
- Hough Line Transform用来做直线检测
- 前提条件 – 边缘检测已经完成
- 平面空间到极坐标空间转换
- 对于任意一条直线上的所有点来说,变换到极坐标中,从[0~360]空间,可以得到r的大小
- 属于同一条直线上点在极坐标空(r, theta)必然在一个点上有最强的信号出现,根据此反算到平面坐标中就可以得到直线上各点的像素坐标。从而得到直线。
2.相关API
2.1 标准的霍夫变换 cv::HoughLines()
- 标准的霍夫变换 cv::HoughLines从平面坐标转换到霍夫空间,最终输出是 表示极坐标空间,需反变换至平面坐标,一般情况是有经验的开发者使用。
cv::HoughLines(
InputArray src, // 输入图像,**必须8-bit的灰度图像**
OutputArray lines, // 输出的极坐标来表示直线
double rho, // 生成极坐标时候的像素扫描步长
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线
double srn=0;// 是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换
double stn=0;//是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换
double min_theta=0; // 表示角度扫描范围 0 ~180之间, 默认即可
double max_theta=CV_PI
)
2.2 霍夫变换直线概率 cv::HoughLinesP()
- 霍夫变换直线概率 cv::HoughLinesP最终输出是直线的两个点的坐标。
cv::HoughLinesP(
InputArray src, // 输入图像,必须8-bit的灰度图像
OutputArray lines, // 输出的极坐标来表示直线,一般为一个vector<Vec4f>变量。
double rho, // 生成极坐标时候的像素扫描步长
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线
double minLineLength=0;// 最小直线长度
double maxLineGap=0;// 最大间隔
)
2.2.1注意:
须将边缘检测后的GRAY图像使用cvtColor(),转变为BGR再进行霍夫变换。
3.例程
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
using namespace std;
int Threshold = 20;
int MinLineLength = 30;
int MaxLineGap = 6;
vector<Vec4f> Plines;
Mat edges, dst;
void HoughLinesP_Demo(int,void*);
int main()
{
Mat src;
src = imread("D:/resource/images/shape.png");
if (src.empty())
printf("the image couldn't' be loading...");
//降噪后边缘处理
Mat GBlur;
GaussianBlur(src, GBlur, Size(3, 3), 0);
Canny(GBlur, edges,0, 255);
//将灰度图像转为BGR,不可少!!!
cvtColor(edges, dst, COLOR_GRAY2BGR);
namedWindow("output");
createTrackbar("Threshold", "output", &Threshold, 40, HoughLinesP_Demo);
createTrackbar("MinLineLength", "output", &MinLineLength, 30, HoughLinesP_Demo);
createTrackbar("MaxLineGap", "output", &MaxLineGap, 30, HoughLinesP_Demo);
//霍夫直线概率变换,并画线
HoughLinesP_Demo(0, 0);
waitKey(0);
return 1;
}
void HoughLinesP_Demo(int,void*)
{
HoughLinesP(edges, Plines, 1, CV_PI / 180.0, Threshold, MinLineLength, MaxLineGap);
Scalar color = Scalar(0, 0, 255);
for (size_t i=0; i < Plines.size(); i++)
{
Vec4f HLines = Plines[i];
line(dst, Point(HLines[0], HLines[1]), Point(HLines[2], HLines[3]), color, 3, LINE_AA);
}
imshow("output", dst);
}