51Halcon机器视觉

 找回密码
 会员注册

QQ登录

只需一步,快速开始

扫一扫,微信登录

查看: 4420|回复: 7
收起左侧

[OpenCV] 霍夫变换直线检测及原理理解

[复制链接]
  • TA的每日心情
    点赞
    昨天 14:39
  • 签到天数: 992 天

    连续签到: 4 天

    [LV.10]以坛为家III

    386

    主题

    1564

    帖子

    7492

    积分

    Rank: 9

    积分
    7492

    突出贡献优秀版主荣誉管理论坛元老切换助手验证会员最佳新人

    发表于 2017-11-16 22:07:06 | 显示全部楼层 |阅读模式

    51Halcon诚邀您的加入,专注于机器视觉开发与应用技术,我们一直都在努力!

    您需要 登录 才可以下载或查看,没有帐号?会员注册

    x
    霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体。该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果。霍夫变换于1962年由Paul Hough 首次提出[53],后于1972年由Richard Duda和Peter Hart推广使用[54],经典霍夫变换用来检测图像中的直线,后来霍夫变换扩展到任意形状物体的识别,多为圆和椭圆.
    经过几天的学习,发现各位大牛的理解方式之前都是有一些区别的,但是核心的思想没有变化,因此记录一下自己对霍夫变换直线检测的认识。
    一、原理介绍:
    1、对于直角坐标系中的任意一点A(x0,y0),经过点A的直线满足Y0=k*X0+b.(k是斜率,b是截距)
    2、那么在X-Y平面过点A(x0,y0)的直线簇可以用Y0=k*X0+b表示,但对于垂直于X轴的直线斜率是无穷大的则无法表示。因此将直角坐标系转换到极坐标系就能解决该特殊情况。
    3、在极坐标系中表示直线的方程为ρ=xCosθ+ySinθ(ρ为原点到直线的距离),如图所示:
    4、如上图,假定在一个8*8的平面像素中有一条直线,并且从左上角(1,8)像素点开始分别计算θ为0°、45°、90°、135°、180°时的ρ,图中可以看出ρ分别为1、(9√2)/2、8、(7√2)/2、-1,并给这5个值分别记一票,同理计算像素点(3,6)点θ为0°、45°、90°、135°、180°时的ρ,再给计算出来的5个ρ值分别记一票,此时就会发现ρ = (9√2)/2的这个值已经记了两票了,以此类推,遍历完整个8*8的像素空间的时候ρ = (9√2)/2就记了5票, 别的ρ值的票数均小于5票,所以得到该直线在这个8*8的像素坐标中的极坐标方程为 (9√2)/2=x*Cos45°+y*Sin45°,到此该直线方程就求出来了。(PS:但实际中θ的取值不会跨度这么大,一般是PI/180)。
    二、Opencv实现直线检测:
    1、Opencv1.0版本:

    1. #include<cv.h>
    2. #include<highgui.h>

    3. int main()
    4. {
    5.         IplImage* pImgSrc = NULL;    //源图像
    6.         IplImage* pImg8u = NULL;     //灰度图
    7.         IplImage* pImgCanny = NULL;  //边缘检测后的图
    8.         IplImage* pImgDst = NULL;    //在图像上画上检测到的直线后的图像
    9.         CvSeq* lines = NULL;
    10.         CvMemStorage* storage = NULL;

    11.         /*边缘检测*/
    12.         pImgSrc = cvLoadImage(".\\res\\street.jpg", 1);
    13.         pImg8u = cvCreateImage(cvGetSize(pImgSrc), IPL_DEPTH_8U, 1);
    14.         pImgCanny = cvCreateImage(cvGetSize(pImgSrc), IPL_DEPTH_8U, 1);
    15.         pImgDst = cvCreateImage(cvGetSize(pImgSrc), IPL_DEPTH_8U, 1);
    16.         cvCvtColor(pImgSrc, pImg8u, CV_BGR2GRAY);
    17.         cvCanny(pImg8u, pImgCanny, 20, 200, 3);

    18.         /*检测直线*/
    19.         storage = cvCreateMemStorage(0);
    20.         lines = cvHoughLines2(pImgCanny, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 80, 200, 10);
    21.         pImgDst = cvCreateImage(cvGetSize(pImgSrc), IPL_DEPTH_8U, 3);
    22.         cvCvtColor(pImg8u, pImgDst, CV_GRAY2BGR);

    23.         /*在pImgDst上画出检测到的直线*/
    24.         for (int i = 0; i < lines->total; i++)
    25.         {
    26.                 CvPoint* line = (CvPoint*)cvGetSeqElem(lines, i);
    27.                 cvLine(pImgDst, line[0], line[1], CV_RGB(255, 0, 0), 3, 8);
    28.         }

    29.         cvNamedWindow("src", 1);
    30.         cvNamedWindow("canny", 1);
    31.         cvNamedWindow("hough", 1);
    32.         cvShowImage("src", pImgSrc);
    33.         cvShowImage("canny", pImgCanny);
    34.         cvShowImage("hough", pImgDst);

    35.         cvWaitKey(0);

    36.         cvReleaseImage(&pImgSrc);
    37.         cvReleaseImage(&pImg8u);
    38.         cvReleaseImage(&pImgCanny);
    39.         cvReleaseImage(&pImgDst);
    40.         cvReleaseMemStorage(&storage);

    41.         return 0;
    42. }
    复制代码
    2、Opencv2.4.9版本:

    1. #include<opencv2\imgproc\imgproc.hpp>
    2. #include<opencv2\opencv.hpp>
    3. #include<opencv2\highgui\highgui.hpp>
    4. using namespace std;
    5. using namespace cv;

    6. int main()
    7. {
    8.         Mat Image = imread(".//res//street.jpg", 0);
    9.         Mat CannyImg;
    10.         Canny(Image, CannyImg, 140, 250, 3);
    11.         imshow("CannyImg", CannyImg);

    12.         Mat DstImg;
    13.         cvtColor(Image, DstImg, CV_GRAY2BGR);

    14.         vector<Vec4i> Lines;
    15.         HoughLinesP(CannyImg, Lines, 1, CV_PI / 360, 170,30,15);
    16.         for (size_t i = 0; i < Lines.size(); i++)
    17.         {
    18.                 line(DstImg, Point(Lines[i][0], Lines[i][1]), Point(Lines[i][2], Lines[i][3]), Scalar(0, 0, 255), 2, 8);
    19.         }
    20.         imshow("HoughLines_Detect", DstImg);
    21.         imwrite(".//res//HoughLines_Detect.jpg", DstImg);
    22.         waitKey(0);
    23.         return 0;
    24. }
    复制代码
    3、效果图:


    三、推荐一个国外公路直线检测的大神的个人主页(有很多资源和源码):
    他研究了公路上的直线(斑马线)等的检测。

    转载自:http://blog.csdn.net/ycj9090900/article/details/52944708
    无效附件更新 权限提升操作 删帖申请 举报以及其他需要帮助请加入QQ群:214663141 广告位招商 有意者联系
  • TA的每日心情
    开心
    2020-3-3 13:18
  • 签到天数: 101 天

    连续签到: 1 天

    [LV.6]常住居民II

    1

    主题

    44

    帖子

    501

    积分

    Rank: 6Rank: 6

    积分
    501
    发表于 2017-11-17 09:38:28 | 显示全部楼层
    好牛!!!已经看懵逼了。。。管理员V5!

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    害羞
    2018-6-3 08:32
  • 签到天数: 199 天

    连续签到: 1 天

    [LV.7]常住居民III

    0

    主题

    17

    帖子

    841

    积分

    Rank: 6Rank: 6

    积分
    841

    活跃会员

    发表于 2017-11-27 10:24:06 | 显示全部楼层
    楼主太牛了。谢谢分享。

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    害羞
    2018-1-10 08:58
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    0

    主题

    8

    帖子

    47

    积分

    Rank: 1

    积分
    47
    发表于 2017-12-13 10:57:14 | 显示全部楼层

    楼主太牛了。谢谢分享。

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    害羞
    2018-7-20 21:54
  • 签到天数: 27 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    2

    主题

    43

    帖子

    119

    积分

    Rank: 1

    积分
    119

    活跃会员切换助手验证会员

    发表于 2018-3-11 22:33:08 | 显示全部楼层
    楼主太牛了。谢谢分享。

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    害羞
    2018-7-20 21:54
  • 签到天数: 27 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    2

    主题

    43

    帖子

    119

    积分

    Rank: 1

    积分
    119

    活跃会员切换助手验证会员

    发表于 2018-3-11 22:40:37 | 显示全部楼层
    其实也还好吧,但是想想到用投票来确定直线,并且计算出偏转角也是不容易的

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    开心
    2020-11-17 14:21
  • 签到天数: 95 天

    连续签到: 1 天

    [LV.6]常住居民II

    1

    主题

    100

    帖子

    881

    积分

    Rank: 3

    积分
    881
    发表于 2018-4-20 07:37:09 | 显示全部楼层
    牛人,支持一下

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

  • TA的每日心情
    叹气
    2020-9-28 08:46
  • 签到天数: 59 天

    连续签到: 1 天

    [LV.5]常住居民I

    13

    主题

    77

    帖子

    209

    积分

    Rank: 2Rank: 2

    积分
    209
    发表于 2020-4-16 15:02:09 | 显示全部楼层
    看懂了,但是一般还是每隔1度取个ρ

    1.发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    2.提问请组织好自己的逻辑,标题注明大概是什么问题,问题内容写详细,需提供问题症状、错误代码、截图、位置等等信息,不要让别人去猜你想问啥;

    3.如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    4.回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

    您需要登录后才可以回帖 会员登录 | 会员注册

    本版积分规则

    建议您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流浏览器浏览本网站

    51Halcon会员技术交流会员技术交流 | 51Halcon官方客服咨询官方客服咨询 | Halcon切换助手使用反馈切换助手使用

    申请友链| 小黑屋| 手机版| Archiver| 有问题需要咨询站长?|  

    CopyRight © 2015-2020 51Halcon机器视觉. Version X3.4.

    粤ICP备15095995号-2 粤公网安备44030602000670号

    快速回复 返回顶部 返回列表