目录

2024-08-15-opencv-python-霍夫变换直线检测

opencv-python 霍夫变换直线检测

文章目录

原理

霍夫变换(Hough Transform)是一种在图像处理中用来识别图像中直线、圆和其他形状的数学变换,是Hough在1962年提出的。其核心思想是将图像中的点映射到一个参数空间,这个空间中涵盖了某个几何形状的所有参数。通过这种变换,可以将图像中的点对应到参数空间中的线或圆上,从而实现对直线和圆的检测。

霍夫变换的基本步骤通常包括:

  1. 边缘检测:首先,使用Canny边缘检测器或其他边缘检测算法来检测图像中的边缘点。

  2. 参数空间初始化:创建一个参数空间,对于直线检测,参数空间通常是一个角度

    θ \theta

    θ 和距离

    θ \theta

    θ 的笛卡尔网格;对于圆检测,参数空间通常是一个半径

    r r

    r 和圆心角度

    θ \theta

    θ 的极坐标网格。

  3. 投票过程:对于检测到的每个边缘点,计算它在参数空间中对应的所有可能的线或圆的参数。这些参数代表了图像空间中所有可能的几何形状。对于每个参数,进行累加投票,即在参数空间中对应的线或圆的位置增加一个计数。

  4. 阈值化:设定一个阈值,只保留投票数超过阈值的参数。这样可以排除噪声和边缘点引起的干扰。

  5. 参数解码:最后,将参数空间中投票最多的点解码回图像空间,这些点就是检测到的直线或圆的参数。

霍夫变换的直线检测结果由

( ρ , θ ) (\rho, \theta)

(

ρ

,

θ

) 来表示,其中

ρ \rho

ρ 表示直线与坐标原点

( 0 , 0 ) (0,0)

(

0

,

0

) 的距离,

θ \theta

θ 是直线的垂线与

x x

x 轴的夹角。从而直线方程可表示为点法式

x cos ⁡ θ + y sin ⁡ θ − ρ

0 x\cos\theta+y\sin\theta-\rho=0

x

cos

θ

y

sin

θ

ρ

=

0

对于尺寸为

m m

m 行

n n

n 列的图像来说,四个边框分别是

x

0 , x

n , y

0 , y

m x=0, x=n, y=0, y=m

x

=

0

,

x

=

n

,

y

=

0

,

y

=

m ,记

c

cos ⁡ θ , s

sin ⁡ θ c=\cos\theta, s=\sin\theta

c

=

cos

θ

,

s

=

sin

θ ,则直线与四个边框的交点分别为

( 0 , ρ s ) ( n , ρ − n c s ) ( ρ c , 0 ) ( ρ − m s c , m ) \begin{matrix} (0, \frac{\rho}{s})&(n, \frac{\rho-nc}{s})\ (\frac{\rho}{c}, 0)&(\frac{\rho-ms}{c}, m)\ \end{matrix}

(

0

,

s

ρ

)

(

c

ρ

,

0

)

(

n

,

s

ρ

n

c

)

(

c

ρ

m

s

,

m

)

实战

通过opencv中的直线检测函数,可得到如下检测结果。

https://i-blog.csdnimg.cn/blog_migrate/37b2280559eaa409e2686e72b1fd6ef7.png#pic_center

代码如下。

from scipy.misc import ascent
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = ascent().astype(np.uint8)
m, n = img.shape

edges = cv.Canny(img, 50, 150, apertureSize = 3)
lines = cv.HoughLines(edges,1.5,np.pi/180,200)

fig, ax = plt.subplots(1,2)

ax[0].imshow(img, cmap='gray')
for line in lines:
    rho,theta = line[0]
    c = np.cos(theta)
    s = np.sin(theta)
    xs = [0, n, rho/c, (rho-m*s)/c]
    print(xs)
    ys = [rho/s, (rho-n*c)/s, 0, m]
    i1, i2 = np.argsort(xs)[1:3]
    ax[0].plot([xs[i1], xs[i2]], [ys[i1], ys[i2]], ls='--')
    ax[1].plot([xs[i1], xs[i2]], [ys[i1], ys[i2]], ls='--')

plt.grid()
plt.show()

【HoughLines】就是opencv中的基于霍夫变换的直线检测函数,其输入的四个参数分别是待检测图像、以像素为单位的距离精度

p r p_r

p

r

、以弧度为单位的角度精度 KaTeX parse error: Undefined control sequence: \tehta at position 3: p_\̲t̲e̲h̲t̲a̲ 以及累加平面的阈值参数。

p r , p θ p_r, p_\theta

p

r

,

p

θ

这两个值设得越大,则会检查出越多的直线。

68747470733a2f2f62:6c6f672e6373646e2e6e65742f6d305f33373831363932322f:61727469636c652f64657461696c732f313336353738353333