1.主要内容
  • 霍夫直线变换介绍
  • 相关API学习
2.霍夫直线变换介绍
  • Hough Line Transform用来做直线变换
  • 前提条件——边缘检测以及完成
  • 平面空间到极坐标空间转换
  • 通过霍夫变换我们可以进行一个规则的几何形状的检测,其原理是通过极坐标变化将直角坐标各个点转换到极坐标空间中,形成一条一条的曲线,图像中曲线交点所在的位置,我们认为是同一个直线上的点,然后我们在通过将这些点的极坐标再通过公式反算到直角坐标空间。
    21.霍夫变换——直线检测_scala
  • r是距离,在x0,y0不变的情况下,我们每给定一个theta,就得到一个r值,此时我们得到图一中各角度与r’对应关系的曲线。
    21.霍夫变换——直线检测_scala_02
  • 此时,我们把x0,y0向前走一个,再来求函数的极坐标,theta和r,不断的重复该操作,得到图二所示的结果。这些曲线相交于一点,表明我们这些像素点都属于同一条直线。
    21.霍夫变换——直线检测_计算机视觉_03
  • 根据我们图二得到曲线交点的角度和极径带入下面的式子来反算到平面空间上,输入不同的x,得到不同的y。
    得到的坐标点在图像上则保留,不在图像上则删除。
    21.霍夫变换——直线检测_scala_04
  • 问题:如何知道这就是图像中相交的点呢?
    解答:将每条曲线所经过的地方数据加1,由于交点处的数据加的最多,那么该点最亮。
    21.霍夫变换——直线检测_霍夫变换_05
  • 对于任意一条直线上的所有点来讲,变换到极坐标中,从【0·360】空间,可以得到r的大小。属于同一条直线上点在极坐标空间【r,theta】必然在一个点上有最强的信号出现(那个交点),根据此反算到平面坐标中就可以得到直线上各点的像素坐标。从而得到直线。
  • 从平面坐标变换到霍夫空间(极坐标)
    21.霍夫变换——直线检测_取值_06
3.相关API学习
  • 标准的霍夫变换cv::HoughLines从平面坐标转换到霍夫空间,最终输出是(threta,r)表示极坐标空间。
  • 霍夫变换直线概率cv;;HoughLinesP最终输出是直线的两个点(x0,y0,x1,y1)
4.相关API学习
  • cv;;HonghLines
cv::HoughLine(
InputArray src, //输入图像,必须8—bit的灰度图像
OutputArray lines,//输出的极坐标来表示直线
double rho, //生成极坐标的时候像素扫描步长(极坐标空间中r的最大值),一般取值1
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
)//一般是有经验的开发者使用,需要自己反变换到平面空间

  • cv::HonghLinesP
cv::HoughLineP(
InputArray src, //输入图像,必须8—bit的灰度图像
OutputArray lines,//输出的极坐标来表示直线
double rho, //生成极坐标的时候像素扫描步长
double theta,//生成极坐标的时候的角度扫描步长,一般取值CV_PI/180
int threshold,//阈值,只有获得足够交点的极坐标点才被看成是直线
double minlineLength = 0,//最小直线长度
double maxLineGap = 0,//最大间隔,比较重要的一个参数
)//自动反算到平面空间

HonghLinesP检测效果

21.霍夫变换——直线检测_scala_07

  • 演示代码
//先进行边缘检测
imshow("原图像",src);
Canny(src,src_gray,150,200,3);
cvtColor(src_gray,dst,CV_GRAY2BGR);
//霍夫直线检测
vector<Vec4f>plines;//将我们霍夫变换得到的结果存放到这个数据中
HonghLinesP(src_gray,plines,1,CV_PI/180,10,0,10);
for(size_t i = 0;i < plines.size();i++){
Vec4f h1 = plines[i];
line(dst,Point(h1[0],h1[1]),Point(h1[2],h1[3]),Scalar(0,0,255),3,LINE_AA);
}
imshow("输出图像",dst);

5.line函数

void  line(
Mat& img, //要绘制线段的图像
Point pt1,//线段的起点
Point pt2,//线段的终点
const Scalar& color,//线段的颜色,通过一个Scalar对象定义
int thickness = 1,//线条的宽度
int linetType = 8,
//线条的类型。可以取值8,4,和CV_AA,
//分别代表8邻接连接线、4邻接连接线和反锯齿连接线
// 默认值为8邻接连接线,为了获得更好的效果可以选用CV_AA(采用了高斯滤波)
int shift = 0 //坐标点小数点位数
)

示例:

line(frame,beginPoint,endPoint,Scalar(0,0,255),2)
//画一条直线,起点为beginPoint,终点为endPoint,颜色是红色,线宽为2,shift是默认值