理解霍夫变换

一、数学理论

我们先从最简单的数学问题出发,给定一些二维坐标点,我们怎么才能求出通过最多点的直线呢?有刷Leetcode的同学可以参考149. 直线上最多的点数这道题去思考。

大家都知道直线方程可以表示为 y = k x + b y = kx + b y=kx+b的形式,所以我们可以枚举所有点之间的组合,计算出来所有组合得到的k和b。(同时还要考虑斜率不存在的情况)
简单分析一下上面做法的时间复杂度。不难理解枚举所有点之间组合的这个步骤需要 C n 2 = n ∗ ( n − 1 ) 1 ∗ 2 C_n^2 = \frac{n * (n -1)}{1*2} Cn2=12n(n1)次计算过程。那么时间复杂度就是 O ( n 2 ) O(n^2) O(n2)的。这个复杂度应用到实际的图像中显然是不合理的。

我们可以从这篇论文中知道,使用霍夫变换我们可以用 O ( n ) O(n) O(n)的时间复杂度去检测出图像中的直线。

其实霍夫变换就是做了一下参数空间映射。对于直线方程我们能不能找到一种可以用有限的参数去表示所有的直线呢?当然可以。
r = x c o s θ + y s i n θ r = x cos\theta + y sin\theta r=xcosθ+ysinθ
简单手写一下推到公式
在这里插入图片描述

显然 θ \theta θ的取值范围是 [ 0 o , 18 0 o ] [0^o, 180^o] [0o,180o],那么 r r r的取值范围呢?
r = x 0 c o s θ + y 0 s i n θ r = x_0cos\theta + y_0sin\theta r=x0cosθ+y0sinθ
r = x 0 2 + y 0 2 ( x 0 x 0 2 + y 0 2 c o s θ + y 0 x 0 2 + y 0 2 s i n θ ) r = \sqrt{x_0^2 + y_0^2} (\frac{x_0}{\sqrt{x_0^2 + y_0^2}}cos\theta + \frac{y_0}{\sqrt{x_0^2 + y_0^2}}sin\theta) r=x02+y02 (x02+y02 x0cosθ+x02+y02 y0sinθ)
令: c o s ϕ = x 0 x 0 2 + y 0 2 cos\phi = \frac{x_0}{\sqrt{x_0^2 + y_0^2}} cosϕ=x02+y02 x0, s i n ϕ = y 0 x 0 2 + y 0 2 sin\phi = \frac{y_0}{\sqrt{x_0^2 + y_0^2}} sinϕ=x02+y02 y0
那么:
r = x 0 2 + y 0 2 c o s ( θ − ϕ ) r =\sqrt{x_0^2 + y_0^2}cos(\theta-\phi) r=x02+y02 cos(θϕ)
(其实就是高一三角函数的课后习题)

由此可知 r r r的取值范围也是确定的。这样我们就可以构造一个叫做累加器(accumulator)的二维矩阵。ok,数学理论部分到这里结束啦,接下来进入代码部分。(talk is cheap, show me the code)

二、代码实践

假设我们有一下几个点,在代码中表示啦。

import matplotlib.pyplot as plt
import math

def points2draw(points):
    x = [pt[0] for pt in points]
    y = [pt[1] for pt in points]
    plt.scatter(x, y)
    plt.show()

points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]

points2draw(points)

在这里插入图片描述
霍夫变换

import matplotlib.pyplot as plt
import math
points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
X = []
Y = []
for pt in points:
    for i in range(0, 181):
        theta = math.pi / 180 * i
        r = math.cos(theta) * pt[0] + math.sin(theta) *pt[1]
        X.append(i)
        Y.append(r)
plt.scatter(X,Y, s = 5 , alpha= 0.8)
plt.show()

在这里插入图片描述

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值