Python OpenCV 霍夫(Hough Transform)直线变换检测原理,图像处理第 33 篇博客丨【百变AI秀】

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 33 篇。

基础知识铺垫

霍夫变换(Hough Transform)是图像处理领域中,从图像中识别几何形状的基本方法之一。主要识别具有某些相同特征的几何形状,例如直线,圆形,本篇博客的目标就是从黑白图像中识别出直线。

翻阅霍夫直线变换的原理时候,橡皮擦觉得原理部分需要先略过,否则很容易在这个地方陷进去,但是问题来了,这个原理略过了,直接应用函数,里面有些参数竟然看不懂。例如极坐标,角度扫描范围,这种函数就属于绕不过去的知识点了,所以本文转移方向,死磕原理,下面的博文将语无伦次的为你展示如何学习原理知识。

霍夫变换直线检测的基本原理

因为数学知识的贫乏,所以在学习阶段会涉及到很多基础概念的学习,一起来吧。

首先找到相对官方的资料,打开该 地址

下面是一个数学小白对原理的学习经验。

教材说:众所周知,一条直线在图像二维空间可由两个变量表示。

  • 在笛卡尔坐标系:可由参数: (m,b) 斜率和截距表示;
  • 在极坐标系: 可由参数: (r,θ) 极径和极角表示。

抱歉,小白还真不知道……即使学习过,这些年也早已经还给老师了。

一开始难道要学习笛卡尔坐标系,不,你低估小白的能力了,我第一个查询的是 θ 读作 西塔,是一个希腊字母。

什么是笛卡尔坐标系?

这个比较简单,直角坐标系。

斜率和截距

斜率,亦称“角系数”,表示一条直线相对于横坐标轴的倾斜程度。

一条直线与某平面直角坐标系横坐标轴正半轴方向的夹角的正切值即该直线相对于该坐标系的斜率。

如果直线与 x 轴互相垂直,直角的正切直无穷大,故此直线不存在斜率。
对于一次函数 y=kx+bk 就是该函数图像的斜率。

在学习的时候,也学到如下内容:

截距:对 x 的截距就是 y=0 时,x 的值,对 y 的截距就是 x=0 时,y 的值,
截距就是直线与坐标轴的交点的横(纵)坐标。x 截距为 ay 截距 b,截距式就是:x/a+y/b=1(a≠0且b≠0)

斜率:对于任意函数上任意一点,其斜率等于其切线与 x 轴正方向所成的角,即 k=tanαax+by+c=0中,k=-a/b

需要注意的是:斜率不能不存在或等于 0,因为当斜率不存在时,直线垂直于 X 轴,没有纵截距,当斜率等于 0 时,直线平行于 X 轴,没有横截距。

什么是极坐标系?

关于极坐标系,打开 百度百科 学习一下即可。

重点学到下面这个结论就行:

有序数对(θ,ρ)就称为 P 点的极坐标,记为 P(θ,ρ);p 称为 P 点的极径,θ 称为 P 点的极角。

找资料的时候,发现一个解释的比较清楚的 博客,后续可以继续学习使用。

继续阅读资料,看到如下所示的图,这个图也出现在了很多解释原理的博客里面,但是图下面写了一句话

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




y


=



(








cos





θ




sin





θ





)



x


+



(




r



sin





θ





)




y = \left ( -\dfrac{\cos \theta}{\sin \theta} \right ) x + \left ( \dfrac{r}{\sin \theta} \right )


在这里直接蒙掉了,怎么就表示成极坐标系了?上面这个公式依旧是笛卡尔坐标系表示直线的方式呀,只是把 kb 的值给替换掉了。




y


=





k


x


+


b



y = -kx + b



其中







k


=



(








cos





θ




sin





θ





)




-k=\left(-\dfrac{\cos \theta}{\sin \theta} \right)





b


=



(




r



sin





θ





)




b=\left ( \dfrac{r}{\sin \theta} \right )



这还是笛卡尔坐标系呀,不是极坐标系。

为何是这样的,具体原因可以参照下图。


chou 图

霍夫空间

继续寻找关于霍夫变换的资料,找到一个新的概念霍夫空间

在笛卡尔坐标系中,一条直线可以用公式




y


=


k


x


+


q



y = kx+q


表示,其中 kb 是参数,表示的是斜率和截距。

接下来将方程改写为




b


=





k






x


0



+



y


0




b=-k*x_0+y_0


,这时就建立了一个基于 k - b 的笛卡尔坐标系。

此时这个新的方程在 k - b 坐标系也有一个新的直线。

你可以在纸上画出这两个方程对应的线和点,如下图所示即可。


chou 图

新的 k - b 坐标系就叫做霍夫空间,这时得到一个结论,图像空间 x - y 中的点




A


(



x


0



,



y


0



)



A(x_0,y_0)


对应了霍夫空间 k – b 中的一条直线




b


=





k






x


0



+



y


0




b = -k*x_0+y_0


,即图像空间的点与霍夫空间的直线发生了对应关系。

如果在图像空间 x - y 中在增加一个点




B


(



x


0



,



y


0



)



B(x_0,y_0)


,那相应的该点在霍夫空间也会产生相同的点与线的对应关系,并且 A 点与 B 点产生的直线会在霍夫空间相交于一个点。而这个点的坐标值




(



k


0



,



b


0



)



(k_0,b_0)


就是直线 AB 的参数。

如果到这里你掌握了,这个性质就为我们解决直线检测提供了方法,只需要把图像空间的直线对应到霍夫空间的点,然后统计交点就可以达到目的,例如图像空间中有 3 条直线,那对应到霍夫空间就会有 3 个峰值点。

遍历图像空间中的所有点,将点转换到霍夫空间,形成大量直线,然后统计出直线交会的点,每个点的坐标都是图像空间直线方程参数,这时就能得到图像空间的直线了。

上述的内容没有问题,但是存在一种情况是,当直线趋近于垂直时,斜率 k 会趋近于无穷大,这时就没有办法转换了,解决办法是使用法线来表示直线。

完善霍夫空间

上文提及的斜截式如下:




y


=





k


x


+


b



y = -kx + b



其中







k


=



(








cos





θ




sin





θ





)




-k=\left(-\dfrac{\cos \theta}{\sin \theta} \right)





b


=



(




r



sin





θ





)




b=\left ( \dfrac{r}{\sin \theta} \right )


通过第二个公式,可以得到下述公式:




ρ


=


x





cos





θ


+


y





sin





θ



ρ = x \cdot \cos \theta + y \cdot \sin \theta


此时,我们可以带入一些数值进行转换。

图像空间有如下的几个点:





  • (


    1


    ,


    0


    )



    (1,0)


    ,通过




    p


    =


    x


    cos





    θ


    +


    y


    sin





    θ



    p = x \cos \theta + y \sin \theta


    转换为




    p


    =


    cos





    θ



    p=\cos \theta






  • (


    2


    ,


    2


    )



    (2,2)


    ,通过




    p


    =


    x


    cos





    θ


    +


    y


    sin





    θ



    p = x \cos \theta + y \sin \theta


    转换为




    p


    =


    2


    cos





    θ


    +


    2


    sin





    θ



    p=2\cos \theta +2\sin\theta






  • (


    3


    ,


    2


    )



    (3,2)


    ,通过




    p


    =


    x


    cos





    θ


    +


    y


    sin





    θ



    p = x \cos \theta + y \sin \theta


    转换为




    p


    =


    3


    cos





    θ


    +


    2


    sin





    θ



    p=3\cos \theta +2\sin\theta


转换后的函数,都可以在霍夫空间 θ - ρ(横坐标是 θ,纵坐标是 ρ)进行表示。

原理这时就比较清晰了:

一条直线能够通过在平面 θ - rr 就是本文中的 ρ) 寻找交于一点的曲线数量来检测。
越多曲线交于一点也就意味着这个交点表示的直线由更多的点组成。
一般来说我们可以通过设置直线上点的阈值来定义多少条曲线交于一点我们才认为检测到了一条直线。

相关数学知识挖坑

除了一些数学知识以外,经典的博客我们也有必要记录一下,方便后面学习的时候,进行复盘。

本部分用于记录本文中提及的相关数学原理,后续还要逐步埋坑。

  • 直线方程,点斜式、截距式、斜截式、两点式、法线式等内容;
  • 正弦曲线。

橡皮擦的小节

今天涉及了一点点数学知识,能力限制,大家一起学习,有错误的地方,可以在评论区指出,不胜感激。

希望今天的 1 个小时(今天内容有点多,不一定可以看完),你有所收获,我们下篇博客见~

今天是持续写作的第 74 / 100 天。
如果你有想要交流的想法、技术,欢迎在评论区留言。


博主 ID:梦想橡皮擦,希望大家点赞评论收藏

【百变AI秀】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/296704

免责声明:务必仔细阅读

  • 本站为个人博客,博客所转载的一切破解、path、补丁、注册机和注册信息及软件等资源文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。

  • 本站为非盈利性站点,打赏作为用户喜欢本站捐赠打赏功能,本站不贩卖软件等资源,所有内容不作为商业行为。

  • 本博客的文章中涉及的任何解锁和解密分析脚本,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断.

  • 本博客的任何内容,未经许可禁止任何公众号、自媒体进行任何形式的转载、发布。

  • 博客对任何脚本资源教程问题概不负责,包括但不限于由任何脚本资源教程错误导致的任何损失或损害.

  • 间接使用相关资源或者参照文章的任何用户,包括但不限于建立VPS或在某些行为违反国家/地区法律或相关法规的情况下进行传播, 博客对于由此引起的任何隐私泄漏或其他后果概不负责.

  • 请勿将博客的任何内容用于商业或非法目的,否则后果自负.

  • 如果任何单位或个人认为该博客的任何内容可能涉嫌侵犯其权利,则应及时通知并提供身份证明,所有权证明至admin@proyy.com.我们将在收到认证文件后删除相关内容.

  • 任何以任何方式查看此博客的任何内容的人或直接或间接使用该博客的任何内容的使用者都应仔细阅读此声明。博客保留随时更改或补充此免责声明的权利。一旦使用并复制了博客的任何内容,则视为您已接受此免责声明.

您必须在下载后的24小时内从计算机或手机中完全删除以上内容.

您使用或者复制了本博客的任何内容,则视为已接受此声明,请仔细阅读


更多福利请关注一一网络微信公众号或者小程序

一一网络微信公众号
打个小广告,宝塔服务器面板,我用的也是,很方便,重点是免费的也能用,没钱太难了,穷鬼一个,一键全能部署及管理,送你3188元礼包,点我领取https://www.bt.cn/?invite_code=MV9kY3ZwbXo=


一一网络 » Python OpenCV 霍夫(Hough Transform)直线变换检测原理,图像处理第 33 篇博客丨【百变AI秀】

发表评论

发表评论

一一网络-提供最优质的文章集合

立即查看 了解详情