热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

opencv——HoughLines、HoughLinesP霍夫线变换(标准霍夫线变换、多尺度霍夫线变换、累积概率霍夫线变换)

霍夫线变换的原理一条直线在图像二维空间可由两个变量表示,有以下两种情况:①在笛卡尔坐标系中:可由参数斜率和截距(k,b)表示。②在极坐标系中:可由参数极经和极角(r,θ)表示。对于

霍夫线变换的原理



  • 一条直线在图像二维空间可由两个变量表示,有以下两种情况:

① 在笛卡尔坐标系中:可由参数斜率和截距(k,b)表示。

② 在极坐标系中:可由参数极经和极角(r,θ)表示。

对于霍夫线变换,我们将采用第二种方式极坐标系来表示直线,因此直线的表达式可为:

化简便可得到:



  • 对于(x0,y0),我们可以将通过这一点的所有直线统一定义为:

 

这就意味着每一对 (r_{\theta},\theta) 代表一条通过点 (x_{0}, y_{0}) 的直线。 

 



  • 对于一个给定点  (x_{0}, y_{0}) ,我们可以在直角坐标系中,绘出所有通过它的直线(θ 为 x 轴,r 为 y 轴)。最终我们将得到一条正弦曲线。


    Polar plot of a the family of lines of a point

    注意:只绘出满足下列条件的点 r > 0  and  0<\theta <2 \pi





  • 我们可以对图像中所有的点进行上述操作.。如果两个不同点进行上述操作后得到的曲线在平面 \theta - r 相交, 这就意味着它们有一个公共的(θ,rθ),即过一条公共的直线。下图中,若曲线每点权重均为 1 ,则交点处权重为 3。

Polar plot of the family of lines for three points



  • 越多曲线交于一点,也就意味着这个交点表示的直线由更多的点组成,权重和越大。我们可以设置一个阈值,来决定多少条曲线交于一点(权重多大)我们才认为检测到了一条直线。



  • 这就是霍夫线变换要做的.。它追踪图像中每个点对应曲线间的交点.。如果交于一点的曲线的数量超过了阈值, 那么可以认为这个交点所代表的参数对  (\theta, r_{\theta})  在原图像中为一条直线。




 

OpenCV 实现了以下三种霍夫线变换:



  1. 标准霍夫变换(StandardHough Transform,SHT)

    • 原理在上面的部分已经说明了. 它能给我们提供一组参数对 (\theta, r_{\theta}) 的集合来表示检测到的直线。

    • 在 OpenCV 中通过函数 HoughLines 来实现。



  2. 多尺度霍夫变换(Multi-ScaleHough Transform,MSHT)

    • 和标准霍夫变换类似。



  3. 累计概率霍夫变换(ProgressiveProbabilistic Hough Transform,PPHT),由HoughLinesP函数调用。

    • 这是执行起来效率更高的霍夫线变换. 它输出检测到的直线的端点 (x_{0}, y_{0}, x_{1}, y_{1})

    • 在 OpenCV 中它通过函数 HoughLinesP 来实现。



 
标准 & 多尺度 霍夫线变换:HoughLines 函数

void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn = 0, double stn = 0);




  • image,输入图像,即源图像。需要为 8 位的单通道二值图像。

  • lines,存放直线的矢量信息的数组。每条直线由具有 2 个元素的矢量(ρ,Θ)表示,其中,ρ 是离坐标原点(0,0)也就是图像左上角的距离,Θ 是弧度线条旋转角度(0 表示垂直直线,∏/2 表示水平直线,注意,不是 0 度和 90 度)

  • rho,以像素为单位的距离精度。另一种表述是平面 \theta - r 中 r 轴的单位长度。

  • theta,以弧度为单位的角度精度。另一种表示是平面 \theta - r 中 θ 轴的单位长度。

  • threshold,权重累加平面的阈值参数。大于阈值 threshold 的线段才可以被确认为直线。

  • srn,默认值为 0。多尺度霍夫线变换才会用到的参数。对于多尺度霍夫线变换,平面 \theta - r 中 r 轴的单位长度 = rho / srn。

  • stn,默认值为 0。也是多尺度霍夫线变换才会用到的参数。对于多尺度霍夫线变换,平面 \theta - r 中 θ 轴的单位长度 = theta / stn。如果 srn、stn 同时为 0,就表示使用经典霍夫变换,否则两个参数都应该为正数。

 

代码示例:

#include
#include
using namespace std;
using namespace cv;
int hough_value = 70;
Mat src, canny_img;
void hough_change(int, void*) {
vectorlines;
HoughLines(canny_img, lines, 1, CV_PI / 180.0, hough_value);
RNG rngs = { 12345 };
Mat show = src.clone();
for (int i = 0; i float rho = lines[i][0], theta = lines[i][1];
double sin_theta = sin(theta), cos_theta = cos(theta);
double x = rho * cos_theta, y = rho * sin_theta;
//以垂点为基础,将直线延长
Point pt1, pt2;
pt1.x = cvRound(x + 1000 * (-sin_theta));
pt1.y = cvRound(y + 1000 * (cos_theta));
pt2.x = cvRound(x - 1000 * (-sin_theta));
pt2.y = cvRound(y - 1000 * (cos_theta));
Scalar colors = Scalar(rngs.uniform(0, 255), rngs.uniform(0, 255), rngs.uniform(0, 255));
line(show, pt1, pt2, colors, 2);
}
imshow("show", show);
}
int main() {
src = imread("C:/Users/齐明洋/Desktop/1.jpg");
GaussianBlur(src, src, Size(3, 3), 0, 0);
imshow("src", src);
Canny(src, canny_img, 55, 110, 3);
imshow("canny_img", canny_img);
namedWindow("show");
createTrackbar("threshold", "show", &hough_value, 200, hough_change);
hough_change(0, 0);
waitKey(0);
}

效果演示:

 

 

 

累计概率霍夫变换:HoughLinesP 函数


void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength = 0, double maxLineGap= 0);




  • lines,存放直线信息矢量的数组。每条直线由具有 4 个元素的矢量(x_1,y_1,x_2,y_2)表示,其中,(x_1,y_1)和(x_2,y_2)是每条检测到的直线的两端端点。

  • minLineLength ,默认值为 0。最低线段的长度,比这个设定参数短的线段就不能被显现出来。

  • maxLineGap,默认值为 0。允许将同一行点与点之间连接起来的最大距离。

  • 其余参数,类比 HoughLines 函数的参数。

 

代码示例:

 

效果演示:

 

借鉴博客:https://www.cnblogs.com/xmu-rcs-jty/p/7531814.html

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html

 



推荐阅读
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • MongoDB用户验证auth的权限设置及角色说明
    本文介绍了MongoDB用户验证auth的权限设置,包括readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase、cluster相关的权限以及root权限等角色的说明和使用方法。 ... [详细]
author-avatar
狠毒的水瓶_617_223_489_321
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有