Python图像处理【19】基于霍夫变换的目标检测

news2024/10/3 6:35:43

基于霍夫变换的目标检测

    • 0. 前言
    • 1. 使用圆形霍夫变换统计图像中圆形对象
    • 2. 使用渐进概率霍夫变换检测直线
      • 2.1 渐进霍夫变换原理
      • 2.2 直线检测
    • 3. 使用广义霍夫变换检测任意形状的对象
      • 3.1 广义霍夫变换原理
      • 3.2 检测自定义形状
    • 小结
    • 系列链接

0. 前言

霍夫变换 (Hough Transform, HT) 是一种特征提取技术,旨在使用在参数空间中执行的投票过程来查找特定形状的对象实例。经典的霍夫变换可用于检测图像中的直线:

  • 我们可以使用极参数 ( ρ , θ ) (ρ,\theta) (ρ,θ) 表示直线,其中 ρ ρ ρ 是线段的长度, θ θ θ 是线和 x x x 轴之间的夹角
  • 为了探索 ( ρ , θ ) (ρ,θ) (ρ,θ) 参数空间,首先在 ρ − θ ρ-θ ρθ 空间中创建二维直方图
  • 然后,对于 ρ ρ ρ θ θ θ 的每个值,计算输入图像中接近由参数构建的直线的非零像素的数量,并相应地将数组 ( ρ , θ ) (ρ,θ) (ρ,θ) 递增
  • 因此,每个非零像素都可以被认为是对潜在候选线的投票
  • 最可能的线对应于获得最高投票的参数值,即 2D 直方图中的局部最大值。

可以使用类似的投票过程来查找圆的参数空间中的最大值,从而将该方法扩展到检测椭圆或其他曲线,更进一步,可以将该方法推广到其他任何任意形状。曲线的参数越多,使用霍夫变换检测曲线的空间和计算成本就越高。在本节中,我们将学习如何使用不同类型的霍夫变换来检测图像中不同形状的对象。

1. 使用圆形霍夫变换统计图像中圆形对象

在本节中,我们将学习如何使用圆形霍夫变换来统计图像中的圆形对象,并使用 scikit-image.transform 模块实现圆形对象统计。

(1) 首先导入所有必需的库函数:

import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread
from skimage.color import rgb2gray
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte
from sklearn.neighbors import KDTree

(2) 加载输入图像并使用 Canny 边缘检测器检测边缘:

orig = imread('1.png')
h, w = orig.shape[:2]
image = rgb2gray(orig)
edges = canny(image, sigma=1, low_threshold=0.15, high_threshold=0.45)

(3) 将函数 hog_circle() 应用于边缘图像,以搜索半径值在 1020 像素之间的圆,并进行投票。选择得票最多的圆,我们将 total_num_peaks 参数设置为一个较高值。为了避免多次检测到同一单元,我们需要通过使用参数 min_xdistancemin_ydistance 确保检测到的两个相邻峰值之间的最小间隔。

hough_radii = np.arange(10, 20, 1)
hough_res = hough_circle(edges, hough_radii)
 
accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii,
                                           min_xdistance = 10,
                                           min_ydistance = 10,
                                           #num_peaks = 5,
                                           total_num_peaks=400)

(4) 使用 circle_perimeter() 函数绘制图像上检测到的圆,在参数空间和圆形霍夫变换上执行迭代。为了保证最小的间距,使用 KDTree 数据结构查询半径内的所有圆形:

circles = []
image = orig.copy()
for center_y, center_x, radius in zip(cy, cx, radii):
    circy, circx = circle_perimeter(center_y, center_x, radius, shape=image.shape)
    if len(circles) > 1:
        tree = KDTree(np.array(circles), leaf_size=2) 
        count = tree.query_radius(np.array([[center_y, center_x]]), r=10, count_only=True)
        if count[0] > 0: continue
    circles.append([center_y, center_x])
    for j in range(-3,4):
        image[np.minimum(circy+j,h-1), np.minimum(circx+j,w-1)] = (255, 0, 0)

print(len(cx))

(5) 最后,绘制原始输入图像,用 Canny 检测到的边缘,以及使用霍夫变换检测到的圆:

plt.figure(figsize=(20, 8))
plt.gray()
plt.subplots_adjust(0,0,1,0.975,0.05,0.05)
plt.subplot(131), plt.imshow(orig), plt.axis('off'), plt.title('original', size=10)
plt.subplot(132), plt.imshow(edges), plt.axis('off'), plt.title('edges with canny', size=10)
plt.subplot(133), plt.imshow(image), plt.axis('off'), plt.title('circle detected', size=10)
plt.suptitle('Counting circles with Circle Hough transform, number of circles={}'.format(len(circles)), size=12)
plt.show()

圆霍夫变换

2. 使用渐进概率霍夫变换检测直线

2.1 渐进霍夫变换原理

霍夫变换是一种流行的提取集合形状的常用方法,变换主要方面是参数化、累加器设计、投票模式和峰值检测。概率霍夫变换 (Probabilistic Hough Transform, PHT) 的目的是最大程度地减少投票中使用的点的比例,同时几乎可以达到标准霍夫变换的水平。
渐进概率霍夫变换 (Progressive Probabilistic Hough Transform, PPHT) 是自适应概率霍夫变换 (Adaptive Probabilistic Hough Transform, APHT) 的一种形式,其目的是通过利用可靠检测具有不同数量支持点的线(特征)所需的投票分数的差异,最大限度地减少检测线(或其他几何特征)所需要的计算量。
PPHT 反映了算法固有的直线检测过程的渐进性,该过程首先找到最长(最显着)的线,然后再检测较短的线。用于投票的分数不需要特别指定或使用先验知识,因为在概率霍夫变换中,它是输入数据固有的复杂函数。该算法非常适合对实时性要求较高的应用,因为投票和直线检测可以并行计算,最显著的特征很可能首先被检测到。实验表明,在许多情况下,PPHT 比标准 HT 更具优势。PPHT 算法描述如下:

  • 循环选择新的随机点进行投票
  • 投票后,检验计数是否可能是由于随机噪声引起
  • 检验过程需要与每个bin更新的阈值进行一次比较
  • 当检测到一条线时,支持点会撤回选票
  • 支持该线的其余点将从尚未投票的点集中删除,然后进行下一次随机选择

PPHT 算法具有以下优势:

  • 只需根据累加器决定是否检测到特征
  • 算法允许被中断,仍然可以输出检测到的显著特征
  • 该算法不需要停止迭代的条件,当所有点被投票或被分配给某个特征时,计算停止

在霍夫变换中,只有一小部分点可以投票,而其余部分作为检测到的特征的支持证据。例如,如果以最小线长度的形式给出约束,则可以在选择投票点之前测试停止条件。在本节中,我们将学习如何使用 transform 模块的 PPHT 实现,在图像中检测直线。

2.2 直线检测

(1) 首先导入所需的库和函数,读取输入图像,然后将其转换为灰度图像:

import matplotlib.pyplot as plt
from skimage.io import imread
from skimage.color import rgb2gray
from skimage.feature import canny
from skimage.color import rgb2gray
from skimage.transform import probabilistic_hough_line

(2) 调用函数 probabilitic_hough_line(),其中:

  • line_length 参数指定的检测线的最小可接受长度
  • line_gap 参数指定的形成直线的像素之间的最大间隙
image = rgb2gray(imread('1.png')) # the image have pixel values in the range [0,1]
edges = canny(image, 2, 30/255, 80/255)
lines = probabilistic_hough_line(edges, threshold=20, line_length=20, line_gap=5)

最后,绘制输入图像、边缘图像和输出图像:

fig, axes = plt.subplots(1, 3, figsize=(30, 20), sharex=True, sharey=True)
ax = axes.ravel()
plt.gray()
ax[0].imshow(image, cmap=plt.cm.gray)
ax[0].set_title('Input image', size=10)
ax[1].imshow(edges, cmap=plt.cm.gray)
ax[1].set_title('Canny edges', size=10)
ax[2].imshow(edges * 0)
for line in lines:
    p0, p1 = line
    ax[2].plot((p0[0], p1[0]), (p0[1], p1[1]), linewidth=5)
ax[2].set_xlim((0, image.shape[1]))
ax[2].set_ylim((image.shape[0], 0))
ax[2].set_title('Probabilistic Hough', size=10)
for a in ax:
 a.set_axis_off()
plt.axis('off')
plt.tight_layout()
plt.show()

直线检测

3. 使用广义霍夫变换检测任意形状的对象

3.1 广义霍夫变换原理

广义霍夫变换 (Generalized Hough Transform, GHT) 是指使用模板匹配的原理对霍夫变换的变体;这种修改使霍夫变换可用于检测其模型所描述的任意对象。GHT 的原始实现使用边缘信息来定义从边缘点的方向到形状的参考点映射。参考点是其形状的局部坐标系的原点,GHT 测量参考点能否被认为是形状的局部坐标系的原点。
广义霍夫变换解释了如何使用任意非解析形状的边界来构建图像空间和霍夫变换空间之间的映射,可以利用这样的映射来检测图像中特定形状的实例。此外,形状的变化(例如旋转,比例变化或图形逆转)对应于该映射的直接转换。但是,最显着的特征是,可以组合这些映射,从简单形状和组件形状的映射中构建复杂形状的映射。这使得广义霍夫成为一种通用变换,可以用来寻找任意复杂的形状。
在本节中,我们将学习如何使用 OpenCVcreateGeneralizedHoughard() 函数来检测任意形状(作为模板图像提供)。

3.2 检测自定义形状

(1) 我们首先导入所需的库和函数:

from matplotlib.pylab import imshow, title, show
from skimage.filters import threshold_otsu
import cv2
import numpy as np
import matplotlib,pylab as plt

(2) 读取输入和模板图像,将它们转换为灰度图像,并使用 Canny 进行边缘检测:

orig = cv2.imread('match_shapes.png')
img = 255-cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
templ = 255-cv2.imread('shape2.png', 0)
edges = cv2.Canny(img, 130,150)

(3) 使用 cv2 中的 createGeneralizedHoughBallard() 函数检测源图像内部的模板形状,并检索图像内部形状的位置以及对形状的相应投票:

alg = cv2.createGeneralizedHoughBallard()
alg.setTemplate(templ)
[positions,votes] = alg.detect(edges)

(4) 在检测到的包含形状的区域周围绘制边界框,在图像内部找到的可能位置的坐标表示形状的中心坐标:

clone = orig.copy() #np.dstack([edges, edges, edges])
for i in range(len(positions[0])):
    pos, scale, angle = positions[0][i][:2], positions[0][i][2], positions[0][i][3]
    print(pos, scale, angle)
    # need to write code here to rotate the bounding rect if angle is not zero and scale is not 1
    cv2.rectangle(clone, (int(pos[0]) - templ.shape[1]//2, int(pos[1]) - templ.shape[0]//2), 
                         (int(pos[0] + templ.shape[1]//2), int(pos[1] + templ.shape[0]//2)), 
                         (0,0,255), 2)

(5) 最后,绘制输入和模板图像以及边界框,在图像中可以看出,虽然模板图像与源图像中对象略有不同,但该算法仍可以正确找到图像内部的形状:

plt.figure(figsize=(20, 8))
plt.gray()
plt.subplots_adjust(0,0,1,0.975,0.05,0.05)
plt.subplot(131), plt.imshow(img), plt.axis('off'), plt.title('input', size=10)
plt.subplot(132), plt.imshow(templ), plt.axis('off'), plt.title('template', size=10)
plt.subplot(133), plt.imshow(clone), plt.axis('off'), plt.title('object detection with generalized Hough', size=10)
plt.show()

任意形状检测

小结

霍夫变换是一种特征提取 (feature extraction) 技术,在图像分析、计算机视觉等领域应用广泛,利用霍夫变换可以辨别并提取图像中的目标特征。本节中,我们学习了霍夫变换的基本原理,进一步将广义霍夫变换将其扩展到检测任意形状对象,并学习了如何利用霍夫变换检测图像中的目标对象。

系列链接

Python图像处理【1】图像与视频处理基础
Python图像处理【2】探索Python图像处理库
Python图像处理【3】Python图像处理库应用
Python图像处理【4】图像线性变换
Python图像处理【5】图像扭曲/逆扭曲
Python图像处理【6】通过哈希查找重复和类似的图像
Python图像处理【7】采样、卷积与离散傅里叶变换
Python图像处理【8】使用低通滤波器模糊图像
Python图像处理【9】使用高通滤波器执行边缘检测
Python图像处理【10】基于离散余弦变换的图像压缩
Python图像处理【11】利用反卷积执行图像去模糊
Python图像处理【12】基于小波变换执行图像去噪
Python图像处理【13】使用PIL执行图像降噪
Python图像处理【14】基于非线性滤波器的图像去噪
Python图像处理【15】基于非锐化掩码锐化图像
Python图像处理【16】OpenCV直方图均衡化
Python图像处理【17】指纹增强和细节提取
Python图像处理【18】边缘检测详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1402008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024最新:optee系统开发精讲 - 课程介绍

(本课程中如有涉及代码或硬件架构,则对应的版本号:TF-A 2.80,optee 3.20, Linux Kernel 6.3,armv8.79.0的aarch64) (注意: 该课程没有PPT,该课程是对照代码讲解的&#x…

回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于ABC-SVR人工蜂群算法优化支持…

矩阵重叠问题判断

创作背景 看到一道题目有感而发想写一篇题解,涉及的是一种逆向思维 桌面窗体重叠 - 洛谷https://www.luogu.com.cn/problem/U399827题目来源于《信息学奥赛课课通》 大致就是给一个长方形的左上顶点坐标(x1,y1)和右下顶点坐标(x…

面试题:SpringBoot项目怎么设计业务操作日志功能?

文章目录 前言需求描述与分析系统日志操作日志 设计思路Spring AOPFilter和HandlerInterceptorSpringAOP、过滤器、拦截器对比 实现方案环境配置依赖配置表结构设计代码实现 测试调试方法验证结果 总结 前言 很久以前都想写这篇文章,一直没有空,但直到现…

【QT+QGIS跨平台编译】之一:【sqlite+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、sqlite3介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、sqlite3介绍 SQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的&…

MSVS C# Matlab的混合编程系列2 - 构建一个复杂(含多个M文件)的动态库:

前言: 本节我们尝试将一个有很多函数和文件的Matlab算法文件集成到C#的项目里面。 本文缩语: MT = Matlab 问题提出: 1 我们有一个比较复杂的Matlab文件: 这个MATLAB的算法,写了很多的算法函数在其他的M文件里面,这样,前面博客的方法就不够用了。会报错: 解决办法如下…

[学习笔记]刘知远团队大模型技术与交叉应用L3-Transformer_and_PLMs

RNN存在信息瓶颈的问题。 注意力机制的核心就是在decoder的每一步,都把encoder的所有向量提供给decoder模型。 具体的例子 先获得encoder隐向量的一个注意力分数。 注意力机制的各种变体 一:直接点积 二:中间乘以一个矩阵 三:…

Opncv模板匹配 单模板匹配 多模板匹配

目录 问题引入 单模板匹配 ①模板匹配函数: ②查找最值和极值的坐标和值: 整体流程原理介绍 实例代码介绍: 多模板匹配 ①定义阈值 ②zip函数 整体流程原理介绍 实例代码: 问题引入 下面有请我们的陶大郎登场 这张图片是我们的陶大郎,我们接下来将利用陶大郎来介绍…

恒悦sunsite博客2023年总结及2024年展望

一、2023年总结 一年如一日的坚持做好一件事并不是容易的事情,但是只要我们坚持下去,乘风破浪会有时,直挂云帆济沧海。   2023年是意义非凡的一年,年初的时候自己定下了两个目标:第一个是完成博客专家认证&#xff1…

HarmonyOS鸿蒙应用开发 (一、环境搭建及第一个Hello World)

万事开头难。难在迈出第一步。心无旁骛,万事可破。没有人一开始就能想清楚,只有做起来,目标才会越来越清晰。--马克.扎克伯格 前言 2024年1月16日,华为目前开启已HarmonyOS NEXT开发者预览版Beta招募,报名周期为1月15…

做好销售人员激励的3个要诀

企业合并是企业发展的重要战略手段之一。许多成长中的企业在经过一段时间的积累后,为了获得快速成长,实现规模效应,通常会采用合并的手段实现目标,同时企业会制定新型政策规范企业管理。但是在制定政策之前,企业通常会…

到店商详架构变迁

一、项目背景 到店商详是平台为京东到店业务提供的专属商详页面,将传统电商购物路径打造成以LBS门店属性的本地生活服务交易链路。 二、架构变迁 1、 主站商详扩展点 **优点:**到店侧仅关注业务,无需过度关注服务部署、性能优化等。 **缺…

Java实现大学计算机课程管理平台 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 实验课程档案模块2.2 实验资源模块2.3 学生实验模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 实验课程档案表3.2.2 实验资源表3.2.3 学生实验表 四、系统展示五、核心代码5.1 一键生成实验5.2 提交实验5.3 批阅实…

数字IC笔试题——门控时钟与控制信号电平、与门门控、或门门控、上升沿门控、下降沿门控

门控时钟问题。 (华为-2019-芯片-数字-34) 从后端设计考虑,在必须使用门控时钟的时候,需要遵循一个原则:门控时钟的输出只能跟着时钟信号进行跳变,而不能跟着控制信号进行跳变,也就是说对于用N…

【订单领域】如果订单要分库分表,如何确认最佳库表数量?

🎉欢迎来系统设计专栏:如果订单要分库分表,如何确认最佳库表数量? 📜其他专栏:java面试 数据结构 源码解读 故障分析 🎬作者简介:大家好,我是小徐🥇☁️博客首页&#x…

python-分享篇-draw heart

文章目录 heart代码效果 draw-heart代码效果 heart-shape-chart代码效果 heart-stitching-by-string代码效果 love-you代码效果 heart 代码 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3Ddef heart_3d(x,y,z):return (x**2(9…

用友NC portal/file 任意文件读取漏洞复现

0x01 产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具,用友NC提供了一系列业务管理模块,包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等,帮助企业实现数字化转型和高效管理。 0x02 漏洞概述 用友NC 系统 /portal/file等接口存在任意…

文心一言4.0参数配置

链接:百度智能云千帆大模型平台 文心一言API使用教程(python版)_python_蓝桉155-百度飞桨星河社区 检查代码的逻辑错误:# 定义一个后台进程类,继承自subprocess.Popen class BackgroundProcess(subprocess.Popen): d…

2023年12月青少年机器人技术等级考试(四级)理论综合试卷

2023年12月青少年机器人技术等级考试(四级)理论综合试卷 单选题 第 1 题 单选题 Arduino UNO/Nano主控板,当数字引脚输出信号为高电平时,对应的电压是 ?( ) A.0V B.5V C.-0.5 ~ 1.5V D.3…