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

1.主要内容

  • 霍夫直线变换介绍
  • 相关API学习

2.霍夫直线变换介绍

  • Hough Line Transform用来做直线变换

  • 前提条件——边缘检测以及完成

  • 平面空间到极坐标空间转换

  • 通过霍夫变换我们可以进行一个规则的几何形状的检测,其原理是通过极坐标变化将直角坐标各个点转换到极坐标空间中,形成一条一条的曲线,图像中曲线交点所在的位置,我们认为是同一个直线上的点,然后我们在通过将这些点的极坐标再通过公式反算到直角坐标空间。
    在这里插入图片描述

  • r是距离,在x0,y0不变的情况下,我们每给定一个theta,就得到一个r值,此时我们得到图一中各角度与r’对应关系的曲线。
    在这里插入图片描述

  • 此时,我们把x0,y0向前走一个,再来求函数的极坐标,theta和r,不断的重复该操作,得到图二所示的结果。这些曲线相交于一点,表明我们这些像素点都属于同一条直线。
    在这里插入图片描述

  • 根据我们图二得到曲线交点的角度和极径带入下面的式子来反算到平面空间上,输入不同的x,得到不同的y。
    得到的坐标点在图像上则保留,不在图像上则删除。
    在这里插入图片描述

  • 问题:如何知道这就是图像中相交的点呢?
    解答:将每条曲线所经过的地方数据加1,由于交点处的数据加的最多,那么该点最亮。
    在这里插入图片描述

  • 对于任意一条直线上的所有点来讲,变换到极坐标中,从【0·360】空间,可以得到r的大小。属于同一条直线上点在极坐标空间【r,theta】必然在一个点上有最强的信号出现(那个交点),根据此反算到平面坐标中就可以得到直线上各点的像素坐标。从而得到直线。

  • 从平面坐标变换到霍夫空间(极坐标)
    在这里插入图片描述

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检测效果
在这里插入图片描述

  • 演示代码
//先进行边缘检测
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是默认值

6.课外扩展

size_t 数据类型
OpenCV CV_RGB2GRAY与CV_BGR2GRAY的区别
OpenCV的Image Watch插件安装与使用

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值