霍夫变换直线检测
前提条件:边缘检测已经完成(单通道8位灰度图像,经过二值化变为黑白图像)
平面空间转到极坐标空间

通过上式子可以把像素点转化成极坐标,如下图所示。

上面的曲线相交与一点,说明了什么信息呢?说明这些像素都在一条直线。
比如一个图像有200个像素,通过坐标变换。那么就可以得到200条曲线。相交点的对应横坐标角度就是直线在空间坐标的角度。这就是霍夫变换的原理。
霍夫直线变换介绍:
变换到极坐标中,从[0,360]空间,可以得到r的大小
属于同一条直线上点在极坐标空间(r,θ)必然在一个点上有强的信号出现,根据此反算到平面坐标中可以得到直线上各点的像素坐标,从而得到直线。

相关API学习:
标准的霍夫变换 HoughLines从平面坐标转换到霍夫空间,最终输出(θ,r)表示极坐标空间。
霍夫变换直线斜率概率 HoughLinesP最终输出直线的两个点空间坐标。
HoughLines(
src,
dst,
double rho, //生成极坐标时候的像素扫描步长
double theta, 生成极坐标时候的角度步长,一般取值CV_P/180
int threshold, 阈值,只有获得足够交点的极坐标点才被看成是直线
double srn=0, 是否应用多尺度的霍夫变换,设置为0表示经典变换
double stn=0,
double min_theta=0,
double max_theta=CV_PI
);
HoughLines(
src,
dst,
double rho, //生成极坐标时候的像素扫描步长
double theta, 生成极坐标时候的角度步长,一般取值CV_P/180
int threshold, 阈值,只有获得足够交点的极坐标点才被看成是直线
double minLineLength = 0, 最小直线长度
double maxLineGap = 0 最大间隔像素
);
代码:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
void help()
{
 cout << "\nThis program demonstrates line finding with the Hough transform.\n"
         "Usage:\n"
         "./houghlines <image_name>, Default is pic1.jpg\n" << endl;
}
int main(int argc, char** argv)
{
 const char* filename = argc >= 2 ? argv[1] : "1.jpg";
 Mat src = imread(filename, 0);
 imshow("source", src);
 if(src.empty())
 {
     help();
     cout << "can not open " << filename << endl;
     return -1;
 }
 Mat dst, cdst;
 Canny(src, dst, 50, 200, 3);
 cvtColor(dst, cdst, CV_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, 90, 0,2 );
  for( size_t i = 0; i < lines.size(); i++ )
  {
    Vec4i l = lines[i];
    line( src, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA);
  }
 #endif
 imshow("detected lines", src);
 waitKey();
 return 0;
}效果:

————————————————
版权声明:本文为CSDN博主「南山二毛」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:
https://blog.csdn.net/qq_16481211/article/details/79607896

 少有人走的路
少有人走的路




















