OpenCV官网
参考1
根据以上两个式子得出结论:给定一个点(x,y),对应到 2 上就是一条直线,x 相当于斜率,y相当于截距。如果给定一系列的点(x1,y1)、(x2,y2)、(x3,y3)…都在一条直线上,也就是满足 y = m x + b y=mx+b y=mx+b,那么对应到 2 中,每个点对应的线将交于一点。 但是由于 参数 m 和 b可能比较大,所以采用极坐标比较合适。
Image Space中每一个点对应到 Parameter Space 中就是一条曲线(三角函数曲线)。在Image Space中的一条直线上,对应到Parameter Space 中 也是相交于一点(只看 r > 0 r>0 r>0 和 0 < θ < 2 π 0<\theta < 2\pi 0<θ<2π):
#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;
};
结果:
(不建议使用)
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
)