[CV] 霍夫变换直线检测

霍夫变换直线检测

理论#

直线的斜截式 y=mx+b,在正常的图像坐标系(这里可以先把图像空间看作是连续的)中,x,y是变量,m,b是参数,即坐标轴分别为x,y轴。现在,我们可以设定一个直线的参数空间,换一种看法,将坐标轴换为m,b,于是有b=ymxx,y成了参数,这样,在图像空间中的一条直线,就对应了参数空间中的一个点,例如直线是y=x+1,对应参数空间中的点(1,1)如图1所示。

那么如果是在图像空间中的一个点呢?对应到直线的参数空间里是什么呢?

如果在图像空间中只有一个点(例如(1,1)),那这个点在哪条直线上呢?穿过这个点的直线都满足要求。将x,y看作是参数,所以现在有b=ymx>b=1m也就是说图像空间中的一个点对应参数空间中的一条直线。

那么如果在图像空间中,有多个点,那么在参数空间中就有多条直线,如图2所示

参数空间中4条直线,代表着图像空间中,4个点所在的所有可能直线的参数,其中最多有3条直线交在了1点,这表示,若选取交点作为直线参数,那么这条直线可以通过图像空间中的3个点。因此我们选择这条直线作为这4个点的拟合直线。这就是投票机制,选择一个可以让尽可能多的点通过的直线。这样可以避免一些噪声点的影响。

算法

1.离散化参数空间
2.创建一个累加器数组A(m,b),每个元素代表参数空间中的一个点,即图像空间中直线的参数
3.将累加器数组A(m,c)全部置为0
4.for each image edge(x_i,y_i):
    for each element in A(m,c):
        if (m,c)在直线 c = -x_im + yi上:
            A(m,c) = A(m,c)+1 #意味着直线经过这个点
5.在A(m,c)中寻找局部最大值,即局部直线相交最多的点,因为是局部最大值,所以可以找到多条直线

似乎到这里就找到了一个算法,但是仔细想想,累加器应该设置为多大呢?m和b都可以任意取值,那这个累加器可太大了。

我们还有另一种直线的参数表达方式xcosθ+ysinθ=ρ,而0<=θ<=2π,0<=ρ<=ρmax,我们的问题现在变成了给定点(xi,yi)寻找直线(ρ,θ),现在参数范围有限了,我们比较容易设计累加器数组了。

同之前的分析,图像空间中的一个点,变成了参数空间中的一个余弦曲线(不分正弦余弦了),而图像空间中的一条直线变成参数空间中的一个点。那和之前还是一样,拟合多个点,找参数空间中最多余弦曲线相交的点即可。如图3所示

算法#

图4为图像空间的点到参数空间的曲线

python opencv测试代码#

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

img = cv2.imread('board.jpg')#读入图片
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度图像 
gray = cv2.GaussianBlur(gray,(9,9),1.5)#先进行高斯模糊,防止噪点影响 
edges = cv2.Canny(gray,50,150)#边缘检测
plt.subplot(121),plt.imshow(edges,'gray')
plt.xticks([]),plt.yticks([])
#hough transform
lines = cv2.HoughLines(edges,0.5,np.pi/180,80)#霍夫变换检测直线
print(lines)

lines1 = lines[:,0,:]#提取为为二维
for rho,theta in lines1[:]: #将检测到的直线画出来
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a)) 
    cv2.line(img,(x1,y1),(x2,y2),(255,0,0),1)

plt.subplot(122),plt.imshow(img,)
plt.xticks([]),plt.yticks([])
plt.show()

作者:芒果和小猫

出处:https://www.cnblogs.com/WAoyu/p/13070414.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   芒果和小猫  阅读(358)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu