直线检测:霍夫变换 HoughLines 和 HoughLinesP

第一部分:函数介绍

1、标准霍夫线变换
void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )
参数:
image:边缘检测的输出图像. 它应该是个灰度图 (但事实上是个二值化图)

lines:储存着检测到的直线的参数对 的容器

rho:参数极径 以像素值为单位的分辨率. 我们使用 1 像素.

theta:参数极角 以弧度为单位的分辨率. 我们使用 1度 (即CV_PI/180)

theta:要”检测” 一条直线所需最少的的曲线交点

srn and stn: 参数默认为0.

2、统计概率霍夫线变换
void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold,double minLineLength=0, double maxLineGap=0 )
参数:

image: 边缘检测的输出图像. 它应该是个灰度图 (但事实上是个二值化图) *

lines: 储存着检测到的直线的参数对 的容器,也就是线段两个端点的坐标

rho :  参数极径 以像素值为单位的分辨率. 我们使用 1 像素.

theta: 参数极角 以弧度为单位的分辨率. 我们使用 1度 (即CV_PI/180)

threshold: 要”检测” 一条直线所需最少的的曲线交点

minLinLength: 能组成一条直线的最少点的数量. 点数量不足的直线将被抛弃.线段的最小长度

maxLineGap:线段上最近两点之间的阈值

备注:
(1)霍夫线变换是一种用来寻找直线的方法.
(2)霍夫线变换之前, 首先要对图像进行边缘检测的处理,即霍夫线变换的直接输入只能是边缘二值图像.

第二部分:原理
直线检测:霍夫变换 HoughLines 和 HoughLinesP_第1张图片
直线检测:霍夫变换 HoughLines 和 HoughLinesP_第2张图片
直线检测:霍夫变换 HoughLines 和 HoughLinesP_第3张图片
上面的5和6是重点,笛卡尔坐标系中,同一条直线上的点,转到极坐标系下,会相交于一个点。

第三部分:代码实现

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 
 
using namespace cv;
using namespace std;
 
int main(int argc, char** argv)
{
 const char* filename = argc >= 2 ? argv[1] : "1.jpg";
 
 Mat src = imread(filename,0);//1表示读取原图像,0表示将原图像转化为灰度图
 printf("src.channels: %d\n",src.channels());
 if(src.empty())
 {
     cout << "can not open " << filename << endl;
     return -1;
 }
 
 Mat dst, cdst;
 Canny(src, dst, 50, 200, 3);//用Canny算子对图像进行边缘检测
 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;//储存着检测到的直线的参数对 (X1, Y1, X2, Y2) 的容器,也就是线段的两个端点
  HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
  //dst:边缘检测的输出图像. 它应该是个灰度图,作为我们的输入图像
  //1:参数极径 r 以像素值为单位的分辨率. 我们使用 1 像素.
  //CV_PI/180:参数极角 \theta 以弧度为单位的分辨率. 我们使用 1度 (即CV_PI/180)
  //50:要”检测” 一条直线所需最少的的曲线交点
  //50:能组成一条直线的最少点的数量. 点数量不足的直线将被抛弃.
  //10:线段上最近两点之间的阈值,也就是能被认为在一条直线上的亮点的最大距离.
 
  //通过画出检测到的直线来显示结果.
  for( size_t i = 0; i < lines.size(); i++ )
  {
    Vec4i l = lines[i];//Vec4i 就是Vec,里面存放4个int
    line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA);
    //要划的线所在的图像:cdst, 起点:Point(l[0], l[1]), 终点:Point(l[2], l[3]), 颜色:Scalar(0,0,255),
  }
 #endif
 imshow("source", src);
 imshow("detected lines", cdst);
 
 waitKey();
 
 return 0;//等待用户按键推出程序
}

第四部分:结果
输入输出图像:
直线检测:霍夫变换 HoughLines 和 HoughLinesP_第4张图片
直线检测:霍夫变换 HoughLines 和 HoughLinesP_第5张图片

你可能感兴趣的:(图像处理,Opencv,直线检测)