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

基于霍夫变换的目标检测

    • 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: continuecircles.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 = lineax[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 1cv2.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.mzph.cn/news/639118.shtml

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

相关文章

H5112C PWM调光 无频闪 高性价比 支持12V 24V 36V 48V 60V 72V 内置MOS

PWM调光芯片是一种常用于LED调光控制的芯片,其工作原理如下: 脉冲宽度调制(PWM):PWM是一种调制技术,通过改变信号的脉冲宽度来控制输出信号的平均功率。在PWM调光中,芯片会以一定的频率产生一系…

SpringCloud Alibaba 深入源码 - Nacos 和 Eureka 的区别(健康检测、服务的拉取和订阅)

目录 一、Nacos 和 Eureka 的区别 1.1、以 Nacos 注册流程来解析区别 一、Nacos 和 Eureka 的区别 1.1、以 Nacos 注册流程来解析区别 a)首先,我们的服务启动时。都会把自己的信息提交给注册中心,然后注册中心就会把信息保存下来. 注册的…

ELK日志分析

目录 一、ELK概述 (一)ELK的定义 (二)ELK工具 1.ElasticSearch 2.Kiabana 3.Logstash (1)定义 (2)插件 ① input ② filter ③ output (三)可以添…

快速排序(三)——hoare法

目录 ​一.前言 二.快速排序 hoare排法​ 三.结语 一.前言 本文给大家带来的是快速排序,快速排序是一种很强大的排序方法,相信大家在学习完后一定会有所收获。 码字不易,希望大家多多支持我呀!(三连+关…

Spring Boot3整合Druid(监控功能)

目录 1.前置条件 2.导依赖 错误依赖: 正确依赖: 3.配置 1.前置条件 已经初始化好一个spring boot项目且版本为3X,项目可正常启动。 作者版本为3.2.2最新版 2.导依赖 错误依赖: 这个依赖对于spring boot 3的支持不够&#…

H5嵌入小程序适配方案

时间过去了两个多月,2024已经到来,又老了一岁。头发也掉了好多。在这两个月时间里都忙着写页面,感觉时间过去得很快。没有以前那么轻松了。也不是遇到了什么难点技术,而是接手了一个很烂得项目。能有多烂,一个页面发起…

开源无代码应用程序生成器Saltcorn

什么是 Saltcorn ? Saltcorn 是一个无需编写任何代码即可构建数据库 Web 应用程序的平台。它配备了一个吸睛的仪表板,丰富的生态系统、视图生成器以及支持主题的界面,使用直观的点击、拖放用户界面来构建整个应用程序。 软件的特点&#xff1…

智慧文旅运营综合平台:重塑文化旅游产业的新引擎

目录 一、建设意义 二、包含内容 三、功能架构 四、典型案例 五、智慧文旅全套解决方案 - 210份下载 在数字化浪潮席卷全球的今天,智慧文旅运营综合平台作为文化旅游产业与信息技术深度融合的产物,正逐渐显现出其强大的生命力和广阔的发展前景。 该…

海外抖音TikTok、正在内测 AI 生成歌曲功能,依靠大语言模型 Bloom 进行文本生成歌曲

近日,据外媒The Verge报道,TikTok正在测试一项新功能,利用大语言模型Bloom的AI能力,允许用户上传歌词文本,并使用AI为其添加声音。这一创新旨在为用户提供更多创作音乐的工具和选项。 Bloom 是由AI初创公司Hugging Fac…

C语言——内存函数介绍和模拟实现(memcpy、memmove、memset、memcmp)

之前我们讲过一些字符串函数(http://t.csdnimg.cn/ZcvCo),今天我们来讲一讲几个内存函数,那么可能有人要问了,都有字符串函数了,怎么又来个内存函数,这不是一样的么? 我们要知道之前…

第十二站(20天):C++泛型编程

模板 C提供了模板(template)编程的概念。所谓模板,实际上是建立一个通用函数或类, 其 类内部的类型和函数的形参类型不具体指定 ,用一个虚拟的类型来代表。这种通用的方式称 为模板。 模板是泛型编程的基础, 泛型编程即以一种独立于任何特定…

C++面试:跳表

目录 跳表介绍 跳表的特点: 跳表的应用场景: C 代码示例: 跳表的特性 跳表示例 总结 跳表(Skip List)是一种支持快速搜索、插入和删除的数据结构,具有相对简单的实现和较高的查询性能。下面是跳表…

职业规划,软件开发工程师的岗位任职资格

软件工程师是指从事软件开发的人,主要的工作涉及到项目培训和项目设计两个方面。在实际工作中,软件工程师是一个广义的概念,包括了很多与软件相关的人员。除开最基础的编程语言,还有数据库语言等等。从事这份工作,需要…

记录一下uniapp 集成腾讯im特别卡(已解决)

uniapp的项目运行在微信小程序 , 安卓 , ios手机三端 , 之前这个项目集成过im,不过版本太老了,0.x的版本, 现在需要添加客服功能,所以就升级了 由于是二开 , 也为了方便 , 沿用之前的webview嵌套腾讯IM的方案 , 选用uniapp集成ui ,升级之后所有安卓用户反馈点击进去特别卡,几…

HR人才测评,如何做技术研发人员基本素质测评?

技术研发人员的基本素质测评,可以从以下几个方面考虑: 1. 技术能力:首要的因素是技术能力,包括编程能力、算法能力、架构设计能力、代码调试和优化能力等。在测评中可以通过技术测试、编程练习、项目经验等方式来考察。 2. 学习…

Java - 深入理解加密解密和签名算法

文章目录 应用的接口安全性问题可能来源加密解密Why保护数据隐私防止未经授权的访问防止数据泄露 对称加密 VS 单向加密 VS 非对称加密一、对称加密二、单向加密(哈希加密)三、非对称加密 常用的对称加密算法1. AES(高级加密标准)…

Django从入门到精通(二)

目录 三、视图 3.1、文件or文件夹 3.2、相对和绝对导入urls 3.3、视图参数requests 3.4、返回值 3.5、响应头 3.6、FBV和CBV FBV 四、静态资源 4.1、静态文件 4.2、媒体文件 五、模板 5.1、寻找html模板 5.2、模板处理的本质 5.3、常见模板语法 5.4、内置模板函…

对称密码算法有什么优点

对称密码算法是一种加密和解密数据的方法,其中加密和解密使用相同的密钥。这种方法的一个关键特点是加密和解密的速度非常快,因此它在许多需要高速加密的应用中非常有用。 对称密码算法的优点主要在于其效率和安全性。由于加密和解密使用相同的密钥&…

自定义注解与拦截器实现不规范sql拦截(拦截器实现篇)

最近考虑myBatis中sql语句使用规范的问题,如果漏下条件或者写一些不规范语句会对程序性能造成很大影响。最好的方法就是利用代码进行限制,通过拦截器进行sql格式的判断在自测环节就能找到问题。写了个简单情景下的demo,并通过idea插件来将myB…

UE5 Windows打包时报错“SDK Not Found”解决方案

在Unreal Engine 5.0.3 Windows平台下打包时报错:“Windows的SDK未正常安装,而其是生成数据的必需项。请检查主工具栏中“启动“菜单SDK部分来更新SDK。” 解决方案: 1、打开 Visual Studio Installer,点击“修改”按钮&#xf…