欢迎光临
我们一直在努力

霍夫变换:几何特征检测与量化验证【计算机视觉】

霍夫变换:几何特征检测与量化验证【计算机视觉】

  • 霍夫变换(Hough Transform)
    • Ⅰ、引言
    • Ⅱ、霍夫变换核心原理
      • 一、霍夫直线变换:二维参数空间的峰值检测
        • (1)核心映射逻辑(3步拆解)
        • (2)数学例子
      • 二、霍夫圆变换:三维参数空间的优化求解
        • (1)数学例子
        • (2)核心优势
      • 三、核心差异:霍夫变换 vs 直接拟合
    • Ⅲ、代码实现
      • 一、霍夫直线检测
      • 二、霍夫圆变换
    • Ⅳ、总结
      • 上一章

霍夫变换(Hough Transform)

        霍夫变换是计算机视觉领域中经典的几何特征检测算法,核心解决了“从含噪声、遮挡、模糊的图像中精准提取直线/圆等规则几何形状”的问题,通过“图像空间→参数空间”的映射转换,实现对几何特征的鲁棒检测,是车道线检测、工业零件质检、文档边框矫正、相机标定等场景的核心技术支撑。

注意:本文所有代码均可导入Jupyter Notebook 完整代码仓库地址:🔗 GitHub:https://github.com/KnifeWen007/CV—StudyNotebook


Ⅰ、引言

        在计算机视觉任务中,边缘检测仅能提取图像中离散的边缘像素,却无法将这些像素整合为完整的几何形状(如直线、圆)—— 而实际场景中,车道线、零件孔洞、文档边框等核心目标均以规则几何形态存在,离散的边缘像素无法直接支撑后续的识别与分析。

        霍夫变换为解决这一痛点提供了核心思路:它放弃在图像空间中直接拟合几何形状,转而将每个边缘像素映射到参数空间,通过检测参数空间的峰值来定位几何特征的参数,从而实现“从离散像素到完整形状”的提取。这一方法具备极强的抗噪声、抗遮挡能力,衍生出霍夫直线变换、霍夫圆变换两大核心分支,分别适配不同几何特征的检测需求,是几何特征提取领域的“基石算法”。


Ⅱ、霍夫变换核心原理

        霍夫变换的本质是**“空间转换”**:将图像空间中难以拟合的几何特征,转换为参数空间中易于检测的峰值特征。其中,霍夫直线变换是最基础、应用最广的分支,霍夫圆变换是其扩展形式,二者核心逻辑一致,仅参数空间维度不同。

一、霍夫直线变换:二维参数空间的峰值检测

        在图像空间中,直线的描述方式决定了霍夫变换的实现逻辑—— 若采用笛卡尔坐标系

y

=

k

x

+

b

y=kx+b

y=kx+b,垂直直线的斜率

k

k

k 会趋于无穷大,无法有效映射;因此霍夫变换采用极坐标方程描述直线:

ρ

=

x

cos

θ

+

y

sin

θ

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

ρ=xcosθ+ysinθ

  • ρ

    \\rho

    ρ:坐标原点到直线的垂直距离(单位:像素),范围为

    [

    D

    ,

    D

    ]

    [-D, D]

    [D,D]

    D

    D

    D 为图像对角线长度);

  • θ

    \\theta

    θ:垂线与x轴正方向的夹角(单位:弧度),范围为

    [

    0

    ,

    π

    )

    [0, \\pi)

    [0,π)(覆盖所有直线方向)。

(1)核心映射逻辑(3步拆解)
  • 单点映射:图像空间中一个边缘点

    (

    x

    ,

    y

    )

    (x,y)

    (x,y),对应参数空间(

    ρ

    \\rho

    ρ

    θ

    \\theta

    θ)中一条连续的正弦曲线—— 这条曲线代表“所有经过该点的直线的参数组合”;

  • 多点交汇:图像空间中同一条直线上的

    N

    N

    N 个边缘点,在参数空间中的

    N

    N

    N 条正弦曲线会交于同一个

    (

    ρ

    ,

    θ

    )

    (\\rho, \\theta)

    (ρ,θ) 点,交汇次数等于直线上的边缘点数;

  • 峰值检测:统计参数空间中每个

    (

    ρ

    ,

    θ

    )

    (\\rho, \\theta)

    (ρ,θ) 点的交汇次数,超过设定阈值的点即为“有效直线”—— 阈值越高,检测到的直线越“完整”,抗噪声能力越强。


  • (2)数学例子

            假设图像中有一条水平直线

    y

    =

    50

    y=50

    y=50,取其上3个点

    P

    1

    (

    10

    ,

    50

    )

    P_1(10,50)

    P1(10,50)

    P

    2

    (

    20

    ,

    50

    )

    P_2(20,50)

    P2(20,50)

    P

    3

    (

    30

    ,

    50

    )

    P_3(30,50)

    P3(30,50),我们通过霍夫映射逻辑,清晰说明这3个点共线的核心原因,贴合极坐标方程与映射规则:

    • 第一步:将3个点分别代入霍夫极坐标方程

      ρ

      =

      x

      cos

      θ

      +

      y

      sin

      θ

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

      ρ=xcosθ+ysinθ,得到3条对应曲线的表达式:

    • P

      1

      (

      10

      ,

      50

      )

      P_1(10,50)

      P1(10,50)

      ρ

      1

      =

      10

      cos

      θ

      +

      50

      sin

      θ

      \\rho_1 = 10\\cos\\theta + 50\\sin\\theta

      ρ1=10cosθ+50sinθ

    • P

      2

      (

      20

      ,

      50

      )

      P_2(20,50)

      P2(20,50)

      ρ

      2

      =

      20

      cos

      θ

      +

      50

      sin

      θ

      \\rho_2 = 20\\cos\\theta + 50\\sin\\theta

      ρ2=20cosθ+50sinθ

    • P

      3

      (

      30

      ,

      50

      )

      P_3(30,50)

      P3(30,50)

      ρ

      3

      =

      30

      cos

      θ

      +

      50

      sin

      θ

      \\rho_3 = 30\\cos\\theta + 50\\sin\\theta

      ρ3=30cosθ+50sinθ

    • 第二步:分析3条曲线的交汇点—— 我们知道,这条水平直线

      y

      =

      50

      y=50

      y=50 的本质特征是“与x轴平行,到原点的垂直距离为50”,对应霍夫参数空间中唯一一组有效参数:

      θ

      =

      π

      /

      2

      \\theta=\\pi/2

      θ=π/2(90°)、

      ρ

      =

      50

      \\rho=50

      ρ=50。 当

      θ

      =

      π

      /

      2

      \\theta=\\pi/2

      θ=π/2 时,根据三角函数性质:

      cos

      θ

      =

      0

      \\cos\\theta=0

      cosθ=0

      sin

      θ

      =

      1

      \\sin\\theta=1

      sinθ=1,将其分别代入3条曲线表达式:

    • ρ

      1

      =

      10

      ×

      0

      +

      50

      ×

      1

      =

      50

      \\rho_1 = 10\\times0 + 50\\times1 = 50

      ρ1=10×0+50×1=50

    • ρ

      2

      =

      20

      ×

      0

      +

      50

      ×

      1

      =

      50

      \\rho_2 = 20\\times0 + 50\\times1 = 50

      ρ2=20×0+50×1=50

    • ρ

      3

      =

      30

      ×

      0

      +

      50

      ×

      1

      =

      50

      \\rho_3 = 30\\times0 + 50\\times1 = 50

      ρ3=30×0+50×1=50

    • 第三步:得出结论—— 此时3个点对应的3条正弦曲线,均精准交汇于参数空间的

      (

      ρ

      =

      50

      ,

      θ

      =

      π

      /

      2

      )

      (\\rho=50, \\theta=\\pi/2)

      (ρ=50,θ=π/2) 点,交汇次数为3(等于直线上的边缘点数)。

    • 第四步:结合峰值检测规则—— 若我们设定的检测阈值≤3,则该交汇点会被判定为“有效峰值”,对应图像空间中一条完整的直线,即3个点所在的水平直线

      y

      =

      50

      y=50

      y=50,这也从霍夫变换的角度,严格证明了这3个点共线。

            反之,若3个点不在同一条直线上,它们在参数空间中的3条正弦曲线不会交于同一个

    (

    ρ

    ,

    θ

    )

    (\\rho, \\theta)

    (ρ,θ) 点,只会各自出现独立的低频次交点,无法达到检测阈值,因此不会被判定为有效直线—— 这也是霍夫变换区分“共线点”与“非共线点”的核心逻辑。


    二、霍夫圆变换:三维参数空间的优化求解

            圆的参数方程为

    (

    x

    a

    )

    2

    +

    (

    y

    b

    )

    2

    =

    r

    2

    (x-a)^2 + (y-b)^2 = r^2

    (xa)2+(yb)2=r2,其中

    (

    a

    ,

    b

    )

    (a,b)

    (a,b) 为圆心坐标,

    r

    r

    r 为半径—— 对应的参数空间是三维的

    (

    a

    ,

    b

    ,

    r

    )

    (a,b,r)

    (a,b,r),直接遍历所有可能的

    (

    a

    ,

    b

    ,

    r

    )

    (a,b,r)

    (a,b,r) 组合计算量极大(时间复杂度呈指数级增长):假设图像尺寸为

    W

    ×

    H

    W\\times H

    W×H,半径范围为

    [

    0

    ,

    R

    ]

    [0, R]

    [0,R],则需遍历

    W

    ×

    H

    ×

    R

    W\\times H\\times R

    W×H×R 次,对分辨率稍高的图像(如

    1000

    ×

    1000

    1000\\times1000

    1000×1000),仅半径遍历100次就需10亿次计算,完全不具备工程实用性。

            工程中普遍采用霍夫梯度法(也叫“两步法”)优化,核心是“降维求解”,具体拆解为3个核心步骤:

  • 第一步:边缘检测与梯度计算:对图像做Canny边缘检测得到边缘点,再计算每个边缘点的梯度方向(梯度是像素值变化的最快方向,垂直于边缘切线,因此梯度方向必然指向圆心—— 这是梯度法的核心几何依据);
  • 第二步:二维投票找圆心:以每个边缘点为起点,沿梯度方向绘制一条短线(或射线),统计图像中所有射线的交汇点,交汇频次最高的点即为圆心

    (

    a

    ,

    b

    )

    (a,b)

    (a,b)—— 这一步仅在二维

    (

    a

    ,

    b

    )

    (a,b)

    (a,b) 空间投票,计算量从三维降至二维;

  • 第三步:一维统计找半径:确定圆心

    (

    a

    ,

    b

    )

    (a,b)

    (a,b) 后,计算该圆心到所有边缘点的欧式距离

    d

    =

    (

    x

    a

    )

    2

    +

    (

    y

    b

    )

    2

    d=\\sqrt{(x-a)^2 + (y-b)^2}

    d=(xa)2+(yb)2

    ,统计距离的出现频次,频次最高的距离值即为圆的半径

    r

    r

    r—— 这一步仅需一维遍历,计算量进一步降低。


  • (1)数学例子

            假设图像中有一个圆心为

    (

    100

    ,

    100

    )

    (100,100)

    (100,100)、半径为50的圆,取圆上3个边缘点

    P

    1

    (

    100

    ,

    50

    )

    P_1(100,50)

    P1(100,50)

    P

    2

    (

    150

    ,

    100

    )

    P_2(150,100)

    P2(150,100)

    P

    3

    (

    100

    ,

    150

    )

    P_3(100,150)

    P3(100,150)

    • 第一步:计算3个点的梯度方向:
    • P

      1

      (

      100

      ,

      50

      )

      P_1(100,50)

      P1(100,50) 在圆的正下方,边缘切线为水平方向,梯度方向垂直向上,指向

      (

      100

      ,

      100

      )

      (100,100)

      (100,100)

    • P

      2

      (

      150

      ,

      100

      )

      P_2(150,100)

      P2(150,100) 在圆的正右方,边缘切线为垂直方向,梯度方向水平向左,指向

      (

      100

      ,

      100

      )

      (100,100)

      (100,100)

    • P

      3

      (

      100

      ,

      150

      )

      P_3(100,150)

      P3(100,150) 在圆的正上方,边缘切线为水平方向,梯度方向垂直向下,指向

      (

      100

      ,

      100

      )

      (100,100)

      (100,100)

    • 第二步:沿3个点的梯度方向绘制射线,所有射线均交汇于

      (

      100

      ,

      100

      )

      (100,100)

      (100,100),该点投票频次最高,判定为圆心;

    • 第三步:计算圆心

      (

      100

      ,

      100

      )

      (100,100)

      (100,100) 到3个点的距离:

    • P

      1

      P_1

      P1

      (

      100

      100

      )

      2

      +

      (

      50

      100

      )

      2

      =

      50

      \\sqrt{(100-100)^2 + (50-100)^2}=50

      (100100)2+(50100)2

      =50

    • P

      2

      P_2

      P2

      (

      150

      100

      )

      2

      +

      (

      100

      100

      )

      2

      =

      50

      \\sqrt{(150-100)^2 + (100-100)^2}=50

      (150100)2+(100100)2

      =50

    • P

      3

      P_3

      P3

      (

      100

      100

      )

      2

      +

      (

      150

      100

      )

      2

      =

      50

      \\sqrt{(100-100)^2 + (150-100)^2}=50

      (100100)2+(150100)2

      =50; 距离的峰值为50,因此判定圆的半径为50。


    (2)核心优势
  • 计算量大幅降低:将三维

    (

    a

    ,

    b

    ,

    r

    )

    (a,b,r)

    (a,b,r) 空间的遍历拆解为“二维找圆心 + 一维找半径”,计算复杂度从

    O

    (

    W

    ×

    H

    ×

    R

    )

    O(W\\times H\\times R)

    O(W×H×R) 降至

    O

    (

    W

    ×

    H

    +

    W

    ×

    H

    )

    O(W\\times H + W\\times H)

    O(W×H+W×H),工程可执行性显著提升;

  • 鲁棒性更强:梯度方向天然指向圆心,即使圆存在部分遮挡(如仅保留1/4圆弧),剩余边缘点的梯度射线仍能交汇到正确圆心,抗遮挡、抗噪声能力远优于直接三维遍历;
  • 参数约束更精准:通过梯度方向约束,避免了无关边缘点对圆心检测的干扰,相比无约束的三维投票,误检率大幅降低。
  • 三、核心差异:霍夫变换 vs 直接拟合

    对比维度霍夫变换直接几何拟合
    抗噪声能力 强(阈值筛选峰值) 弱(单个噪声点影响拟合)
    抗遮挡能力 强(部分边缘即可检测) 弱(需完整边缘)
    计算复杂度 中(参数空间遍历) 低(仅拟合公式求解)
    适用场景 噪声/遮挡/模糊图像 无噪声、完整边缘图像

    Ⅲ、代码实现

    一、霍夫直线检测

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt

    # Notebook配置:图片内嵌显示、支持中文
    %matplotlib inline
    plt.rcParams['font.sans-serif'] = ['DejaVu Sans']
    plt.rcParams['axes.unicode_minus'] = False

    # 1. 读取图像
    img = cv2.imread('road.png')
    if img is None:
    raise FileNotFoundError("未找到road.png!检查文件名/路径")

    # 2. 图像预处理:灰度+高斯模糊+Canny边缘检测
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转灰度图
    blur = cv2.GaussianBlur(gray, (5, 5), 0) # 高斯模糊降噪
    edges = cv2.Canny(blur, 50, 150) # 提取边缘

    # 3. 霍夫直线检测(概率霍夫变换)
    lines = cv2.HoughLinesP(
    edges,
    rho=1, # 距离精度1像素
    theta=np.pi/180, # 角度精度1度
    threshold=50, # 投票阈值
    minLineLength=50, # 最短直线长度
    maxLineGap=10 # 直线断点最大间距
    )

    # 4. 绘制检测到的直线
    img_lines = img.copy()
    if lines is not None:
    for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(img_lines, (x1, y1), (x2, y2), (0, 0, 255), 2) # 红色直线,线宽2
    else:
    print("未检测到有效直线!可降低threshold参数")

    # 5. 可视化结果
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))

    # 显示边缘检测结果
    ax1.imshow(edges, cmap='gray')
    ax1.set_title('Canny Edge Detection', fontsize=12)
    ax1.axis('off')

    # 显示直线检测结果
    ax2.imshow(cv2.cvtColor(img_lines, cv2.COLOR_BGR2RGB))
    ax2.set_title('Hough Line Detection', fontsize=12)
    ax2.axis('off')

    plt.tight_layout()
    plt.show()

    在这里插入图片描述

    核心函数:cv2.HoughLinesP()

    参数说明:

    lines = cv2.HoughLinesP(
    edges, # 输入:Canny边缘检测后的边缘图
    rho=1, # 距离精度:1像素(参数空间ρ的步长)
    theta=np.pi/180, # 角度精度:π/180弧度(即1度,参数空间θ的步长)
    threshold=50, # 投票阈值:只有投票数≥50的直线才会被检测出
    minLineLength=50, # 最短直线长度:过滤短于50像素的噪声线
    maxLineGap=10 # 直线断点最大间距:10像素内的断点可合并为一条直线
    )

    cv2.HoughLinesP() 是概率霍夫变换的核心实现

    本质是:

  • 将图像空间的边缘点映射到ρ-θ参数空间;
  • 统计参数空间中各(ρ,θ)点的交汇次数(投票数);
  • 保留投票数≥阈值的(ρ,θ),还原为图像空间的直线坐标(x1,y1,x2,y2)。

  • 二、霍夫圆变换

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt

    # 配置图片显示
    %matplotlib inline
    plt.rcParams['font.sans-serif'] = ['DejaVu Sans']
    plt.rcParams['axes.unicode_minus'] = False

    # 读取本地图片
    img = cv2.imread('circle.png')
    if img is None:
    raise FileNotFoundError("未找到circle.png!请确认图片在代码同级目录")

    # 图像预处理
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (5, 5), 0)

    # 霍夫圆检测
    circles = cv2.HoughCircles(
    blur,
    cv2.HOUGH_GRADIENT,
    dp=1,
    minDist=30,
    param1=50,
    param2=25,
    minRadius=5,
    maxRadius=0
    )

    # 绘制检测到的圆
    img_circles = img.copy()
    if circles is not None:
    circles = np.uint16(np.around(circles))
    for circle in circles[0, :]:
    x, y, r = circle[0], circle[1], circle[2]
    cv2.circle(img_circles, (x, y), 3, (0, 255, 0), 4)
    cv2.circle(img_circles, (x, y), r, (0, 0, 255), 3)
    print(f"共检测到 {len(circles[0, :])} 个圆,已全部绘制")
    else:
    print("未检测到任何圆!可尝试降低param2至20或减小minDist至20")

    # 显示结果
    plt.figure(figsize=(10, 8))
    plt.imshow(cv2.cvtColor(img_circles, cv2.COLOR_BGR2RGB))
    plt.title('Hough Circle Detection')
    plt.axis('off')
    plt.show()

    在这里插入图片描述

    核心函数:cv2.HoughCircles()

    参数说明:

    circles = cv2.HoughCircles(
    blur, # 输入:高斯模糊后的灰度图(降噪后检测更准确)
    method=cv2.HOUGH_GRADIENT,# 检测方法:霍夫梯度法(唯一实用的圆检测方法)
    dp=1, # 分辨率因子:1表示参数空间与图像空间分辨率一致
    minDist=20, # 圆心最小距离:避免检测到重复的同心圆/邻近圆
    param1=50, # Canny边缘检测高阈值:低阈值自动为其1/2,提取圆边缘
    param2=30, # 圆心投票阈值:值越小检测圆越多,值越大检测越精准
    minRadius=0, # 最小检测半径:0表示无下限
    maxRadius=0 # 最大检测半径:0表示无上限
    )

    cv2.HoughCircles() 基于霍夫梯度法实现

    核心是“降维求解”:

  • 先通过Canny边缘检测提取圆边缘,计算每个边缘点的梯度方向(指向圆心);
  • 在二维空间统计梯度方向的交汇点,投票数≥param2的点判定为圆心;
  • 计算圆心到边缘点的距离,统计峰值作为圆的半径;
  • 最终输出格式为(x, y, r)(圆心坐标+半径),完成圆检测。

  • Ⅳ、总结

    综上,霍夫变换凭借「图像空间与参数空间对偶映射+累加投票」的核心逻辑,成为直线、圆这类规则几何形状检测的经典技术,也是本次分享的核心内容。

    直线检测核心: 通过极坐标方程(

    ρ

    =

    x

    cos

    θ

    +

    y

    sin

    θ

    ρ=x\\cosθ+y\\sinθ

    ρ=xcosθ+ysinθ)规避了直角坐标下垂直线斜率无穷大的缺陷,经「边缘预处理→空间映射→累加投票→峰值检测」四步,即可鲁棒提取图像中的直线;

    圆检测核心: 拓展至三维参数空间(圆心x、圆心y、半径r),通过对圆心和半径的投票统计,实现圆形目标的定位与识别。

    二者均能有效应对图像噪声、局部遮挡、形状不完整等问题,是计算机视觉中几何特征提取的基础方法。

    实战选型技巧:

    • 直线检测:追求精度选「标准霍夫变换」,需实时性则用「概率霍夫变换」;
    • 圆检测:依赖霍夫圆变换(CHT),可通过优化参数空间量化精度、调整投票阈值,平衡检测效果与计算效率。

    霍夫变换无需精准匹配目标完整轮廓,对复杂场景适应性强,也是入门计算机视觉几何检测的核心知识点。


    上一章

    图像去雾:从直方图增强到暗通道先验【计算机视觉】https://blog.csdn.net/R_Feynman_/article/details/158807328?spm=1001.2014.3001.5501

    赞(0)
    未经允许不得转载:171主机测评 » 霍夫变换:几何特征检测与量化验证【计算机视觉】
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址