opencv-霍夫变换

霍夫变换就是一个可以让计算机学会自己找图形的算法。是图形处理领域内从图像中检测几何形状的基本方法之一。经典霍夫变换用来检测图像中的直线,后来霍夫变换经过扩展可以进行任意型状物体的识别,例如圆和椭圆。

霍夫变换运用两个坐标空间之间的变换,将在一个空间具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测形状的问题转化成统计峰值问题

一,霍夫直线变换原理

如下图,将xy坐标系转换为kb的坐标系。由于一条直线的kb值是确定的,所以在kb坐标系下,一条直线就可以表示为一个点

在kb坐标系下,kb相当于变量,而xy相当于常量,所以,xy坐标系下的AB两点相当于霍夫空间的两条直线。在xy坐标系下,过A点有无数多条直线,对应霍夫空间中就是A点坐标对应直线上的无数多个点

读到这就可以发现,笛卡尔坐标系(xy坐标系)下的点 就代表了霍夫空间的一条直线,多个点就代表多条直线,如果这几个点共线,就代表这几个点对应在霍夫空间下的直线均交于一点,利用这个特点我们就可以检测图片中的直线

(错误更正:下图第一句多条曲线改为多条直线)在笛卡尔坐标系下,出现多个点,并且这多个点可以连成多条直线。将这些点均对应到霍夫空间中,可以看到交出了ABCD四个点,而AC点由三条直线交出,相比于BD更多,我们会选择尽可能多直线交出的点

将笛卡尔坐标系用极坐标表示出来。接下来将其转换到霍夫空间中,由于极坐标系变量为ρ和θ,所以霍夫空间的xy轴就是ρ和θ。如下图,根据上式xcosθ+ysinθ=ρ将笛卡尔坐标系中的点转换到霍夫空间中即可,可以发现最终也交于一点,这个点就代表了笛卡尔坐标系下的直线

再举一个例子

二,霍夫圆变换原理

霍夫圆变换有a,b,r三个参数,构成三维空间

以上霍夫圆变换仅为简单介绍,在OpenCV中是有优化的,这里不做介绍

三,霍夫变化在OpenCV中的应用

1,霍夫直线变换函数

OpenCV已经给我们封装好了函数,我们可以调用 cv2.HoughLines函数来使用霍夫直线变换检测图片中的直线。

rho就是上文提到的,如下蓝圈所示垂直距离。theta角度步长就是在选定一个θ值范围进行遍历代入时每次加几度,一般为1°。阈值可以简单的理解为直线的长度。返回值lines为极坐标表示的直线,如果我们需要利用这条直线,要把它转换为笛卡尔坐标下的直线

以下为将极坐标转换为笛卡尔坐标并画出直线的代码

python 复制代码
lines = cv2.HoughLines(edges, 1, np.pi/180, 180)#通过调阈值来改变图像中找到直线的数量
#调完阈值还不行就调第二个参数1
for line in lines:
    rho, theta = line[0]
    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 *a)
    y2 = int(y0 - 1000 *a)
    cv2.line(picture, (x1, y1), (x2, y2), (0, 0, 255), 2)

检测直线代码实例

python 复制代码
def line_detect(picture):
    gray = cv2.cvtColor(picture, cv2.COLOR_BGR2GRAY)
    gaussion = cv2.GaussianBlur(gray, (9, 9), 0)
    edges = cv2.Canny(gaussion, 50, 150)
    lines = cv2.HoughLines(edges, 1, np.pi/180, 180)
    for line in lines:
        rho, theta = line[0]
        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 *a)
        y2 = int(y0 - 1000 *a)
        cv2.line(picture, (x1, y1), (x2, y2), (0, 0, 255), 2)

2,霍夫直线变换优化函数-概率霍夫检测

概率霍夫检测核心点是采取概率挑选机制,选取某些点进行检测,而不是像cv2.HoughLines一样选取所有点,这样可以减少计算压力

3,霍夫圆变换函数

circles为返回值,返回(圆横坐标。圆纵坐标,半径)

python 复制代码
def circle_detect(picture):
    gray = cv2.cvtColor(picture, cv2.COLOR_BGR2GRAY)
    gaussion = cv2.GaussianBlur(gray, (9, 9), 0)
    edges = cv2.Canny(gaussion, 50, 150)
    #通过修改阈值param1和param2来调整检测的圆。从20向后都是比较重要的要调整的参数
    circles = cv2.HoughCircles(edges,HOUGH_GRADIENT,1,20,param1=30,param2=20,minRadius=10,maxRadius=35)
    circles = np.uint16(np.around(circles))
    for circle in circles[0, :]:
        cv2.circle(picture, (circle[0],circle[1]), circle[2], (0, 0, 255), 2)    
        cv2.circle(picture, (circle[0],circle[1]), 2, (0, 0, 255), 2)
相关推荐
说私域21 分钟前
基于定制开发开源 AI 智能名片 S2B2C 商城小程序的热点与人工下发策略研究
人工智能·小程序
GoGeekBaird1 小时前
GoHumanLoopHub开源上线,开启Agent人际协作新方式
人工智能·后端·github
Jinkxs1 小时前
测试工程师的AI转型指南:从工具使用到测试策略重构
人工智能·重构
别惹CC2 小时前
Spring AI 进阶之路01:三步将 AI 整合进 Spring Boot
人工智能·spring boot·spring
stbomei4 小时前
当 AI 开始 “理解” 情感:情感计算技术正在改写人机交互规则
人工智能·人机交互
Moshow郑锴9 小时前
人工智能中的(特征选择)数据过滤方法和包裹方法
人工智能
TY-20259 小时前
【CV 目标检测】Fast RCNN模型①——与R-CNN区别
人工智能·目标检测·目标跟踪·cnn
CareyWYR10 小时前
苹果芯片Mac使用Docker部署MinerU api服务
人工智能
失散1310 小时前
自然语言处理——02 文本预处理(下)
人工智能·自然语言处理
mit6.82411 小时前
[1Prompt1Story] 滑动窗口机制 | 图像生成管线 | VAE变分自编码器 | UNet去噪神经网络
人工智能·python