做网站设计多少钱,即刻搜索收录网站,郑州一建集团工程建设有限公司,深圳市工程交易服务中心基于霍夫变换的目标检测 0. 前言1. 使用圆形霍夫变换统计图像中圆形对象2. 使用渐进概率霍夫变换检测直线2.1 渐进霍夫变换原理2.2 直线检测 3. 使用广义霍夫变换检测任意形状的对象3.1 广义霍夫变换原理3.2 检测自定义形状 小结系列链接 0. 前言
霍夫变换 (Hough Transform,… 基于霍夫变换的目标检测 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, sigma1, low_threshold0.15, high_threshold0.45)(3) 将函数 hog_circle() 应用于边缘图像以搜索半径值在 10 到 20 像素之间的圆并进行投票。选择得票最多的圆我们将 total_num_peaks 参数设置为一个较高值。为了避免多次检测到同一单元我们需要通过使用参数 min_xdistance 和 min_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_peaks400)(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, shapeimage.shape)if len(circles) 1:tree KDTree(np.array(circles), leaf_size2) count tree.query_radius(np.array([[center_y, center_x]]), r10, count_onlyTrue)if count[0] 0: continuecircles.append([center_y, center_x])for j in range(-3,4):image[np.minimum(circyj,h-1), np.minimum(circxj,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, size10)
plt.subplot(132), plt.imshow(edges), plt.axis(off), plt.title(edges with canny, size10)
plt.subplot(133), plt.imshow(image), plt.axis(off), plt.title(circle detected, size10)
plt.suptitle(Counting circles with Circle Hough transform, number of circles{}.format(len(circles)), size12)
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, threshold20, line_length20, line_gap5)最后绘制输入图像、边缘图像和输出图像
fig, axes plt.subplots(1, 3, figsize(30, 20), sharexTrue, shareyTrue)
ax axes.ravel()
plt.gray()
ax[0].imshow(image, cmapplt.cm.gray)
ax[0].set_title(Input image, size10)
ax[1].imshow(edges, cmapplt.cm.gray)
ax[1].set_title(Canny edges, size10)
ax[2].imshow(edges * 0)
for line in lines:p0, p1 lineax[2].plot((p0[0], p1[0]), (p0[1], p1[1]), linewidth5)
ax[2].set_xlim((0, image.shape[1]))
ax[2].set_ylim((image.shape[0], 0))
ax[2].set_title(Probabilistic Hough, size10)
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 测量参考点能否被认为是形状的局部坐标系的原点。 广义霍夫变换解释了如何使用任意非解析形状的边界来构建图像空间和霍夫变换空间之间的映射可以利用这样的映射来检测图像中特定形状的实例。此外形状的变化(例如旋转比例变化或图形逆转)对应于该映射的直接转换。但是最显着的特征是可以组合这些映射从简单形状和组件形状的映射中构建复杂形状的映射。这使得广义霍夫成为一种通用变换可以用来寻找任意复杂的形状。 在本节中我们将学习如何使用 OpenCV 的 createGeneralizedHoughard() 函数来检测任意形状(作为模板图像提供)。
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, size10)
plt.subplot(132), plt.imshow(templ), plt.axis(off), plt.title(template, size10)
plt.subplot(133), plt.imshow(clone), plt.axis(off), plt.title(object detection with generalized Hough, size10)
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】边缘检测详解