当前位置:   article > 正文

《数字图像处理-OpenCV/Python》第16章:图像的特征描述

《数字图像处理-OpenCV/Python》第16章:图像的特征描述

《数字图像处理-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()
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

在这里插入图片描述

图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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/754058
推荐阅读
相关标签
  

闽ICP备14008679号