解释霍夫变换。

48
我只是想大胆尝试,向计算机视觉迈出第一步。我尝试自己实现霍夫变换,但是我无法完全理解它的整个过程。我阅读了维基百科条目,甚至看了Richard Duda和Peter Hart的原始著作“使用霍夫变换检测图片中的直线和曲线”,但都没有帮助我更好地理解。有人可以用更友好的语言来解释一下吗?
4个回答

137

以下是关于如何使用霍夫变换在图像中检测直线的非常基础和直观的解释:

图片描述


1
很好的例子!可能需要稍微说明一下,你提到了沿着边缘画线,并将这些边缘显示为点,这很好,但实际上这些线只是该边缘的切线。 - SIslam
1
@mlai,这张图片是你创建的吗?如果是,我可以在我的硕士论文中使用它吗?如果不是,能否告诉我你从哪里得到它,我很喜欢它!谢谢。 - Scott Alistair
3
谢谢!是的,这是我自己创作的。请随意在您的论文中使用它。 - mlai
这对于初学者来说是改变生活的。 - shivam thakur
我认为这是最友好且解释清晰的方式。 - user11717481
显示剩余3条评论

41

通常更常用直角坐标系中的y = mx + b来表示一条直线。正如维基百科文章所述,一条直线也可以用极坐标形式表示。霍夫变换利用这种表示方式(对于直线而言,至少是这样的。讨论也可以适用于圆,椭圆等)。

霍夫变换的第一步是将图像缩减为一组边缘。Canny算子是一个常见的选择。得到的边缘图像被用作霍夫过程的输入。

总结一下,边缘图像中的“亮点”被转换为极坐标形式,即使用方向theta和距离r来表示它们的位置,而不是xy。(通常使用图像中心点作为坐标系变换的参考点。)

霍夫变换本质上是一个直方图。映射到相同thetar的边缘像素被假定为定义了图像中的一条直线。为了计算出现的频率,thetar被离散化(分成若干个箱)。一旦所有的边缘像素都被转换为极坐标形式,就可以分析这些箱来确定原始图像中的直线。

通常查找N个最常见的参数,或阈值化参数,使计数小于某个n的值被忽略。

我不确定这个答案是否比你最初提供的来源更好 - 你卡在哪个具体点了吗?


你的回答很好。它让我对其他地方读到的东西更有信心了。Ray H在下面提供的答案也告诉了我一些我难以想象的东西:所有可能的参数组合都被计算了。所以,通过不同的方式听到这个问题,我的头脑变得更加清晰了。 - Haoest
3
有一个很酷的 JavaScript 工具,可以在 http://gmarty.github.io/hough-transform-js/ 上查看投票空间。 - dooderson

16

Hough变换是一种寻找最有可能表示一条直线(或圆、或其他形状)的值的方法。

将一张包含线条和背景两种像素的图片作为输入给Hough变换。在该图片中,线条上的像素与背景的像素是不同的。

对于每个属于线条的像素,都会计算出所有可能的参数组合。例如,如果坐标为(1,100)的像素是线条的一部分,则它可以构成斜率(m)=0,截距(c)=100的一条直线;也可以构成m=1,c=99的直线,或者m=2,c=98,或m=3,c=97等等。可以通过解决直线方程y=mx+c来找到所有可能的组合。

每个像素都会向能够解释它的参数(m和c)投一票。因此,如果您的线条由1000个像素组成,那么正确的m和c组合将获得1000票。

拥有最多票数的m和c组合将被返回作为直线的参数。


3
这里有另一个角度(在电视节目数字的试播集中使用):想象一下,草坪上有一个像喷泉一样的洒水器,早些时候它在草坪上某个地方,向周围喷出水滴。现在洒水器不见了,但水滴仍然存在。想象将每个水滴变成自己的洒水器,向周围喷出水滴 - 在所有方向都是如此,因为水滴不知道它来自哪个方向。这将在地面上分散大量的水,除了一个地方会有很多水同时落下。那个地方就是原来洒水器所在的位置。
例如,应用于线检测的方法类似。图像中的每个点都是原始水滴之一;当它作为洒水器时,它会发送自己的水滴标记通过该点可能经过的所有线条。许多次附加水滴着陆的地方代表通过许多图像点的线的参数 - 哇!线被检测到了!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接