霍夫变换
- 在许多应用场合中需要快速准确地检测出直线或者圆。其中一种非常有效的解决问题的方法是霍夫(Hough)变换,其为图像处理中从图像中识别几何形状的基本方法之一
- 霍夫变换是图像处理中的一种特征提取的技术.
- 最基本的霍夫变换是从黑白图像中检测直线(线段)
- 霍夫变换在OpenCV中分为
霍夫线变换
和霍夫圆变换
两种
霍夫线变换
- 霍夫线变换是一种用来寻找直线的方法.
- 在使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像.
- OpenCV支持三种不同的霍夫线变换. 分别是:
标准霍夫变换(Standard Hough Transform,SHT)
多尺度霍夫变换(Multi-Scale Hough Transform,MSHT)
累计概率霍夫变换(Progressive Probabilistic Hough Transform ,PPHT)
相关函数学习
-
HoughLines
/*
OpenCV中的霍夫直线检测的函数为HoughLines
改进版本的HoughLinesP函数(统计概论霍夫直线检测)
*/
void HoughLines(
InputArray image, //输入8-比特、单通道 (二值) 图像
OutputArray lines, //输出的角度和r长度: lines为输出直线向量,两个元素的向量(ρ,θ)代表一条直线,ρ是从原点(图像的左上角)的距离,θ是直线的角度(单位是弧度),0表示垂直线,π/2表示水平线
double rho, //与像素相关单位的距离精度
double theta, //弧度测量的角度精度
int threshold, //阈值参数。如果相应的累计值大于 threshold, 则函数返回的这个线段.
double srn=0, double stn=0 //多尺度变换,距离精度 rho 的分母,角度精度 theta 的分母。
);
-
HoughLinesP
// 通过统计概率的霍夫线变换找到线段
void HoughLinesP(
InputArray image, //输入 8-比特、单通道 (二值) 图像
OutputArray lines, //输出线段的两个端点,保存为(x_1, y_1, x_2, y_2)
double rho, //与象素相关单位的距离精度,((width + height) * 2 + 1) / rho 表示r的空间范围,一般取1
double theta, //弧度测量的角度精度,(CV_PI/theta)表示霍夫空间角度方向的大小
int threshold, //阈值参数。如果相应的累计值大于 threshold, 则函数返回的这个线段.
double minLineLength=0, //最小的线段长度
double maxLineGap=0 //这个参数表示在同一条直线上进行碎线段连接的最大间隔值(gap), 即当同一条直线上的两条碎线段之间的间隔小于maxLineGap时,将其合二为一
);
demo学习
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
static void help()
{
cout << "\nThis program demonstrates line finding with the Hough transform.\n"
"Usage:\n"
"./houghlines <image_name>, Default is ./pic1.png\n" << endl;
}
int main(int argc, char** argv)
{
cv::CommandLineParser parser(argc, argv,
"{help h||}{@image|./pic1.png|}"
);
if (parser.has("help"))
{
help();
return 0;
}
string filename = parser.get<string>("@image");
if (filename.empty())
{
help();
cout << "no image_name provided" << endl;
return -1;
}
Mat src = imread(filename, 0);
if(src.empty())
{
help();
cout << "can not open " << filename << endl;
return -1;
}
Mat dst, cdst;
Canny(src, dst, 50, 200, 3);
cvtColor(dst, cdst, COLOR_GRAY2BGR);
#if 0
vector<Vec2f> lines;
HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );
for( size_t 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, CV_AA);
}
#else
vector<Vec4i> lines;
HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
for( size_t i = 0; i < lines.size(); i++ )
{
Vec4i l = lines[i];
line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
}
#endif
imshow("source", src);
imshow("detected lines", cdst);
waitKey();
return 0;
}