《数字图像处理-OpenCV/Python》第16章:图像的特征描述
本书京东 优惠购书链接 https://item.jd.com/14098452.html
本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html
第16章:图像的特征描述
特征通常是针对图像中的目标或关键点而言的。目标的边界(轮廓)通常是一条简单的闭合曲线。针对目标边界的特征描述符,称为边界描述符(Boundary Descriptors)。针对目标所在区域的特征描述符,称为区域描述符(Region Descriptors)。针对关键点的描述符,称为关键点描述符(Keypoints Descriptors)。
本章内容概要
- 介绍边界描述符,如弗里曼链码、傅里叶描述符和傅里叶频谱分析。
- 介绍区域特征描述符,如紧致度、圆度、偏心率。
- 介绍灰度共生矩阵。
- 学习和使用方向梯度直方图,构造方向梯度直方图(HOG)关键点描述符。
- 学习和使用二进制描述符,如LBP描述符、BRIEF描述符和FREAK描述符。
16.7 特征描述之HOG描述符
方向梯度直方图(Histogram of Oriented Gradient,HOG)使用方向梯度的分布作为特征来构造描述符,应用非常广泛。
梯度的幅值是边缘和角点检测的基础,梯度的方向包含丰富的图像特征。HOG的基本思想:图像的局部特征可以用梯度幅值和方向的分布描述。HOG的基本方法是将图像划分成多个单元格,计算每个单元格的HOG,把每个单元格的HOG连接起来构造为HOG特征向量。
HOG描述符的向量维数不是固定不变的,取决于检测图像的大小和单元格的大小。HOG描述符不具有尺度和旋转不变性,但具有良好的几何和光学不变性,特别适合人体检测。
OpenCV中的函数cv::HOGDescriptor类用于实现HOG描述符。在Python语言中,OpenCV提供了HOG类的接口函数cv.HOGDescriptor。
函数原型
cv.HOGDescriptor(_winSize, _blockSize, _blockStride, _cellSize, _nbins) → retval
hog.compute(img[, _winStride, _padding]) → descriptors
参数说明
◎ winSize:检测窗口大小,是形为(w,h)的元组,默认值为(64,128)。
◎ blockSize:子块大小,是形为(w,h)的元组,默认值为(16,16)。
◎ blockStride:子块的滑动步长,是形为(w,h)的元组,默认值为(8,8)。
◎ cellSize:单元格大小,是形为(w,h)的元组,默认值为(8,8)。
◎ nbins:直方图的条数,是整型数据,默认值为9。
◎ img:输入图像,允许为单通道图像,数据类型为CV_8U。
◎ winStride:窗口大小,可选项,必须是blockStride的整数倍。
◎ descriptors:HOG描述符,是形为(lenHOG,)的Numpy 数组,数据类型为CV_32F。
函数说明
(1) 计算每个单元格cell的HOG:方向梯度的取值范围为0~180度,等分为nbins个区间,将单元格像素的方向梯度分配到nbins个扇形区间,累加每个区间内的像素数,得到nbins位的HOG向量。
(2) 构造子块block的HOG:多个单元格cell组合为子块block,子块的HOG描述符就是多个单元格HOG向量的串联,长度为nbins×blockSize/cellSize。
(3) 整个检测窗口的HOG:子块block以步长blockStride在检测窗口内滑动,遍历检测窗口,检测窗口的HOG就是每个子块block的HOG串联。
注意问题
(1) 函数cv.HOGDescriptor能实例化HOGDescriptor类,定义一个HOGDescriptor类对象。成员函数hog.compute能计算给定图像的HOG描述符。
(2) 推荐设置检测窗口大小winSize为子块大小blockSize的整数倍,子块大小blockSize为单元格大小cellSize的整数倍,子块大小blockSize为滑动步长blockStride的整数倍。
(3) 函数中方向梯度的取值范围是0~180度,而不是0~360度。
(4) 函数cv::HOGDescriptor类的功能丰富,参数和成员函数很多,可以实现尺度不变性的检测。更多使用方法可以参见OpenCV官方文档。
【例程1609】特征描述之HOG描述符
本例程介绍基于距离变换的分水岭算法的实现方法,通过每个像素到最近的零像素点生成标注图像。
基于距离变换的分水岭算法的主要步骤如下。
(1) 通过阈值分割将灰度图像转换为二值图像,使用开运算消除噪点。
(2) 通过形态学的膨胀运算,生成确定背景区域sureBG。
(3) 通过距离变换,由阈值分割得到高亮区域,生成确定前景区域sureFG。
(4) 对确定前景区域进行连通性分析,即对多个分割目标编号。
(5) 确定前景区域与确定背景区域重合的部分,作为待定区域unknown。
(6) 从连通域标记图像中去除确定背景区域,作为标注图像。
(7) 基于标记图像使用分水岭算法进行分割,得到分割的目标轮廓,标注为-1。
# 【1609】特征描述之 HOG 描述符
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
def drawHOG(image, descriptors, cx, cy, rad):
angles = np.arange(0, 180, 22.5).astype(np.float32) # start, stop, step
normGrad = descriptors/np.max(descriptors).astype(np.float32)
gx, gy = cv.polarToCart(normGrad*rad, angles, angleInDegrees=True)
for i in range(angles.shape[0]):
px, py = int(cx+gx[i]), int(cy+gy[i])
cv.arrowedLine(image, (cx,cy), (px, py), 0, tipLength=0.1) # 黑色
return image
if __name__ == '__main__':
# (1) 读取样本图像,构造样本图像集合
img = cv.imread("../images/Fig1101.png", flags=0) # 灰度图像
height, width, wCell, d = 200, 200, 20, 10
img = cv.resize(img, (width, height)) # 调整为统一尺寸
# (2) 构造 HOG 检测器
winSize = (20, 20)
blockSize = (20, 20)
blockStride = (20, 20)
cellSize = (20, 20)
nbins = 8
hog = cv.HOGDescriptor(winSize, blockSize, blockStride, cellSize, nbins)
lenHOG = nbins * (blockSize[0]/cellSize[0]) * (blockSize[1]/cellSize[1]) \
* ((winSize[0]-blockSize[0])/blockStride[0] + 1) \
* ((winSize[1]-blockSize[1])/blockStride[1] + 1)
print("length of descriptors:", lenHOG)
# (3) 计算检测区域的 HOG 描述符
xt, yt = 80, 80 # 检测区域位置
cell = img[xt:xt+wCell, yt:yt+wCell]
cellDes = hog.compute(cell) # HOG 描述符,(8,)
normGrad = cellDes/np.max(cellDes).astype(np.float32)
print("shape of descriptors:{}".format(cellDes.shape))
print(cellDes)
# (4) 绘制方向梯度示意图
imgGrad = cv.resize(cell, (wCell*10, wCell*10), interpolation=cv.INTER_AREA)
Gx = cv.Sobel(img, cv.CV_32F, 1, 0, ksize=5) # X 轴梯度 Gx
Gy = cv.Sobel(img, cv.CV_32F, 0, 1, ksize=5) # Y 轴梯度 Gy
magG, angG = cv.cartToPolar(Gx, Gy, angleInDegrees=True) # 用极坐标求幅值与方向 (0~360度)
print(magG.min(), magG.max(), angG.min(), angG.max())7
angCell = angG[xt:xt+wCell, yt:yt+wCell]
box = np.zeros((4, 2), np.int32) # 计算旋转矩形的顶点, (4, 2)
for i in range(wCell):
for j in range(wCell):
cx, cy = i*10+d, j*10+d
rect = ((cx,cy), (8,1), angCell[i,j]) # 旋转矩形类
box = np.int32(cv.boxPoints(rect)) # 计算旋转矩形的顶点,(4, 2)
cv.drawContours(imgGrad, [box], 0, (0,0,0), -1)
# (5) 绘制检测区域的HOG
cellHOG = np.ones((201,201), np.uint8) # 白色
cellHOG = drawHOG(cellHOG, cellDes, xt+d, yt+d, 40)
# (6) 绘制图像的HOG
imgHOG = np.ones(img.shape, np.uint8)*255 # 白色
for i in range(10):
for j in range(10):
xc, yc = 20*i, 20*j
cell = img[xc:xc+wCell, yc:yc+wCell]
descriptors = hog.compute(cell) # HOG 描述符,(8,)
imgHOG = drawHOG(imgHOG, descriptors, xc+d, yc+d, 8)
imgWeight = cv.addWeighted(img, 0.5, imgHOG, 0.5, 0)
plt.figure(figsize=(9, 6.2))
plt.subplot(231), plt.title("1. Original")
cv.rectangle(img, (xt,yt), (xt+wCell,yt+wCell), (0,0,0), 2) # 绘制 block
plt.axis('off'), plt.imshow(img, cmap='gray')
plt.subplot(232), plt.title("2. Oriented gradient")
angNorm = np.uint8(cv.normalize(angG, None, 0, 255, cv.NORM_MINMAX))
plt.axis('off'), plt.imshow(angNorm, cmap='gray')
plt.subplot(233), plt.title("3. Image with HOG")
cv.rectangle(imgWeight, (xt,yt), (xt+wCell,yt+wCell), (0,0,0), 2) # 绘制 block
plt.axis('off'), plt.imshow(imgWeight, cmap='gray')
plt.subplot(234), plt.title("4. Grad angle of cell")
plt.axis('off'), plt.imshow(imgGrad, cmap='gray')
plt.subplot(235), plt.title("5. HOG of cell")
strAng = ("0", "22", "45", "67", "90", "112", "135", "157")
plt.bar(strAng, cellDes*wCell*wCell)
plt.subplot(236), plt.title("6. HOG diagram of cell")
plt.axis('off'), plt.imshow(cellHOG, cmap='gray')
plt.tight_layout()
plt.show()
图16-9 可视化的HOG描述符
程序说明:
运行结果,可视化的HOG描述符如图16-9所示。
(1) 图16-9(1)所示为原始图像,图中黑色方框是一个单元格cell。图16-9(2)所示为原始图像的方向梯度图,像素值的大小反映了方向梯度的角度。
(2) 图16-9(4)所示为图16-9(1)中方框位置单元格cell的方向梯度图,图中的线段表示像素点的方向梯度,注意例程中方向梯度的范围是0~180度。
(3) 图16-9(5)所示为对图16-9(4)单元格中的所有像素点,按8个方向区间绘制的HOG。图16-9(6)所示为图16-9(5)的单元格HOG的空间矢量。
(4) 图16-9(3)所示为整个图像的可视化HOG。将图像划分为10×10个单元格,计算每个单元格的HOG,表示为图16-9(6)所示的空间矢量形式。
(5) 例程介绍了HOG处理过程和结果的各种图像,是为了便于理解HOG的思路和计算步骤。在实际应用中,检测图像的HOG是维数为lenHOG的特征向量,而不是二维图像。
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/139766654)
Copyright 2024 youcans, XUPT
Crated:2024-06-18
《数字图像处理-OpenCV/Python》 独家连载专栏 : https://blog.csdn.net/youcans/category_12418787.html