HOG:概述

HOG是什么?

方向梯度直方图,也称为HOG,是一种特征描述符,类似于Canny边缘检测器。它用于计算机视觉和图像处理中的目标检测。

该技术统计图像局部区域中梯度方向的出现次数。该方法类似于边缘方向直方图和尺度不变特征变换(SIFT)。

HOG描述符关注对象的结构或形状。它比任何边缘描述符都好,因为它使用梯度的大小和角度来计算特征。对于图像区域,它使用梯度的大小和方向生成直方图。


计算特征的步骤

1.获取要计算其特征的输入图像。将图像调整为128x64像素(高128像素,宽64像素)的图像。论文中使用了该维度,作者建议将其作为此类检测的主要目标,以在行人检测任务中获得更好的结果。由于本文作者在麻省理工学院行人数据库上获得了异常完美的结果,他们决定制作一个新的、更具挑战性的数据集,称为“INRIA”数据集(http://pascal.inrialpes.fr/data/human/),包含从一组不同的个人照片中剪下的1805(128x64)幅人类图像。

图1:导入的图像。图2:灰度图像。图3:缩放导入图像和灰度图像:

4c4272e47dd57c73a017b7a82ffa6997.png

2.计算图像的梯度。梯度是通过结合图像的大小和角度来获得的。考虑3x3像素的块,首先计算每个像素的Gx和Gy。对于每个像素值,首先使用以下公式计算Gx和Gy。

c5c92930a781407f8bcb25234dda8da9.png

在计算Gx之后,使用下面提到的公式计算每个像素的幅值和角度。

0d4eafd69de65bfc89cc7823dba6dc9d.png

图4:图像幅值的可视化。图5:图像角度的可视化图片

5a93d66a9a463655b70ee5d84dcb67e0.png

3.在获得每个像素的梯度后,梯度矩阵(幅值和角度矩阵)被划分为8x8个单元以形成块。对于每个块,计算9 区间 直方图,每个区间的角度范围为20度。图8表示一个9区间的直方图,其中的值在计算后分配。这些直方图中的各个区间输出该块中梯度的幅值。由于块包含64个不同的值,因此对于所有64个幅值和梯度值,将执行以下计算。由于我们使用9区间直方图,因此:

9cc155d30279c2e25c0fab27e80af4ea.png

第j个区间的边界如下:

fa0529a39782120f14e57ec4ac6e0557.png

每个区间的中心值为:

3c35c62a8c9348b0ff03e11bc85f6b19.png

图6:幅值图像上的8x8块。图7:角度图像上的8x8块图片

b019e1bd70ae7a382a8ebda0984421e5.png

图8:9区间直方图的表示

ab09658224ca4a281b0186b989f676d5.png

  1. 对于块中的每个单元,我们将首先计算第j个区间,然后计算将分别提供给第j个和(j+1)个区间的值。该值由以下公式给出:

86c69a420c6f689654829dfc84cccfa0.png

  1. 将数组列作为区间的单元,并将Vj和Vj+1的值附加到数组中,索引为每个像素计算的第j个和第(j+1)个单元。

  2. 上述计算后的合成矩阵形状为16x8x9。

  3. 完成所有区间的直方图计算后,将9区间直方图矩阵中的4个区间组合在一起,形成一个新区间(2x2)。以重叠的方式移动,步幅为8像素。对于区间中的所有4个单元,我们将每个组成单元的所有9区间直方图连接起来,形成36个特征向量。

上图说明了9区间直方图的计算方法

b3729d815370122ab700cb75495735c2.png

在图像周围遍历2x2网格框,以便从4个bin生成组合fbi

40856a794438aaa23a660a5b40ecb5b2.gif

  1. 每个bin的fbi值通过L2范数标准化:

式中,ε是一个小值,加在fb的平方上,以避免零除法误差。在代码中,取的值为1e-05。

2f831ac3b66d4970be35c829f9cb1679.png

  1. 为了规范化,首先通过以下公式计算k值:

ca9b535aaebce529872a44d28978b62e.png

  1. 进行此标准化是为了减少相同对象的图像之间对比度变化的影响。从每个block中,采集了一个36点的特征向量。在水平方向上有7个区间,在垂直方向上有15个区间。因此,HOG特征的总长度为:7 x 15 x 36=3780。获得所选图像的HOG特征。

使用skimage库对同一图像上的HOG特征进行可视化

59fcedbd72303bfedefb74e835888498.png


Python计算HOG特征

导入库和所需的映像

import matplotlib.pyplot as plt
from skimage import io
from skimage import color
from skimage.transform import resize
import math
from skimage.feature import hog
import numpy as np
img = resize(color.rgb2gray(io.imread("B.jpg")), (128, 64))

所使用图像的可视化

plt.figure(figsize=(15, 8))
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.show()

9c20b1c56c44d0bfe80baa5fcd6a5de0.png

img = np.array(img)

计算图像的梯度和角度

mag = []
theta = []
for i in range(128):
  magnitudeArray = []
  angleArray = []
  for j in range(64):
    # 轴0的条件
    if j-1 <= 0 or j+1 >= 64:
      if j-1 <= 0:
        # 第一个元素
        Gx = img[i][j+1] - 0
      elif j + 1 >= len(img[0]):
        Gx = 0 - img[i][j-1]
    #  第一个元素
    else:
      Gx = img[i][j+1] - img[i][j-1]
    
    # 轴1的条件
    if i-1 <= 0 or i+1 >= 128:
      if i-1 <= 0:
        Gy = 0 - img[i+1][j]
      elif i +1 >= 128:
        Gy = img[i-1][j] - 0
    else:
      Gy = img[i-1][j] - img[i+1][j]

    # 计算幅度
    magnitude = math.sqrt(pow(Gx, 2) + pow(Gy, 2))
    magnitudeArray.append(round(magnitude, 9))

    # 计算角度
    if Gx == 0:
      angle = math.degrees(0.0)
    else:
      angle = math.degrees(abs(math.atan(Gy / Gx)))
    angleArray.append(round(angle, 9))
  mag.append(magnitudeArray)
  theta.append(angleArray)
mag = np.array(mag)
theta = np.array(theta)

图像幅度的可视化

plt.figure(figsize=(15, 8))
plt.imshow(mag, cmap="gray")
plt.axis("off")
plt.show()

9932d2b7160ea95552fefcdc82efff86.png

图像角度的可视化

plt.figure(figsize=(15, 8))
plt.imshow(theta, cmap="gray")
plt.axis("off")
plt.show()

3b17f8b3ad6dcf12d79760b97b75cb1b.png

number_of_bins = 9
step_size = 180 / number_of_bins

计算第j个区间的函数

def calculate_j(angle):
  temp = (angle / step_size) - 0.5
  j = math.floor(temp)
  return j

计算第j个区间的中心值的函数

def calculate_Cj(j):
  Cj = step_size * (j + 0.5)
  return round(Cj, 9)

计算第j个区间的值的函数

def calculate_value_j(magnitude, angle, j):
  Cj = calculate_Cj(j+1)
  Vj = magnitude * ((Cj - angle) / step_size)
  return round(Vj, 9)

为8x8单元格提供9区间直方图

histogram_points_nine = []
for i in range(0, 128, 8):
  temp = []
  for j in range(0, 64, 8):
    magnitude_values = [[mag[i][x] for x in range(j, j+8)] for i in range(i,i+8)]
    angle_values = [[theta[i][x] for x in range(j, j+8)] for i in range(i, i+8)]
    for k in range(len(magnitude_values)):
      for l in range(len(magnitude_values[0])):
        bins = [0.0 for _ in range(number_of_bins)]
        value_j = calculate_j(angle_values[k][l])
        Vj = calculate_value_j(magnitude_values[k][l], angle_values[k][l], value_j)
        Vj_1 = magnitude_values[k][l] - Vj
        bins[value_j]+=Vj
        bins[value_j+1]+=Vj_1
        bins = [round(x, 9) for x in bins]
    temp.append(bins)
  histogram_points_nine.append(temp)
print(len(histogram_points_nine))
print(len(histogram_points_nine[0]))
print(len(histogram_points_nine[0][0]))
16
8
9

为由2x2的块提供HOG特征向量

(1个块由8x8个单元组成)

epsilon = 1e-05
feature_vectors = []
for i in range(0, len(histogram_points_nine) - 1, 1):
  temp = []
  for j in range(0, len(histogram_points_nine[0]) - 1, 1):
    values = [[histogram_points_nine[i][x] for x in range(j, j+2)] for i in range(i, i+2)]
    final_vector = []
    for k in values:
      for l in k:
        for m in l:
          final_vector.append(m)
    k = round(math.sqrt(sum([pow(x, 2) for x in final_vector])), 9)
    final_vector = [round(x/(k + epsilon), 9) for x in final_vector]
    temp.append(final_vector)
  feature_vectors.append(temp)
print(len(feature_vectors))
print(len(feature_vectors[0]))
print(len(feature_vectors[0][0]))
15
7
36

获得的HOG特征数量

print(f'Number of HOG features = {len(feature_vectors) * len(feature_vectors[0]) * len(feature_vectors[0][0])}')
Number of HOG features = 3780

在Python中使用skimage库的HOG特征

导入库

from skimage.io import imread
from skimage.transform import resize
from skimage.feature import hog
from skimage import exposure
import matplotlib.pyplot as plt

读取图像

img = imread('B.jpg')
plt.axis("off")
plt.imshow(img)
print(img.shape)
(781, 794, 3)

66193300ed4179c5017124a860770a0b.png

缩放

resized_img = resize(img, (128*4, 64*4))
plt.axis("off")
plt.imshow(resized_img)
print(resized_img.shape)
(512, 256, 3)

9839917a1160939a805726452d8cbff1.png

创建和可视化HOG特征

fd, hog_image = hog(resized_img, orientations=9, pixels_per_cell=(8, 8),
                 cells_per_block=(2, 2), visualize=True, multichannel=True)
plt.axis("off")
plt.imshow(hog_image, cmap="gray")
plt.show()

bbc2a4ca1ecf737c09c99dee39d4523b.png

Colab链接:https://colab.research.google.com/drive/1_yDbX68uCxejK448Y0ByOACQUUZw5hWR?usp=sharing

参考引用

  1. Histograms of Oriented Gradients for Human Detection : http://lear.inrialpes.fr/people/triggs/pubs/Dalal-cvpr05.pdf

  2. SkImage Documentation : https://scikit-image.org/docs/dev/api/skimage.feature.html?highlight=hog#skimage.feature.hog

  3. HOG (Histogram of Oriented Gradients) Features (Theory and Implementation using MATLAB and Python) : https://www.youtube.com/watch?v=QmYJCxJWdEs

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

0b9b0534e70d1899ee1a682a6c6ea73d.png

  • 2
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工业摄像头与OpenCV结合使用可以实现强大的图像处理和计算机视觉应用。下面是简单的概述: 1. 工业摄像头选择:选择适合工业应用的摄像头,例如USB摄像头、IP摄像头或工业相机。确保摄像头具有足够的分辨率、帧率和图像质量,以满足应用需求。 2. 数据采集:使用OpenCV的VideoCapture函数或相关库函数,从摄像头中采集图像数据。可以指定摄像头的设备索引或文件路径。 3. 图像处理:利用OpenCV提供的丰富函数库,进行各种图像处理操作。例如,可以进行图像滤波、边缘检测、颜色空间转换、形态学操作等。 4. 特征提取:使用OpenCV的特征提取算法,例如SIFT、SURF或ORB等,提取图像中的关键点和描述子。这些特征可以用于图像匹配、目标跟踪和目标识别等任务。 5. 目标检测和跟踪:使用OpenCV的目标检测和跟踪算法,例如Haar级联分类器、HOG+SVM或深度学习模型,实现目标的实时检测和跟踪。 6. 机器视觉应用:将图像处理和分析的结果应用于工业自动化、质量控制、机器人视觉等领域。例如,可以实现产品缺陷检测、物体定位和姿态估计等功能。 7. 图像显示和保存:使用OpenCV的imshow函数将处理后的图像显示在屏幕上,使用imwrite函数将图像保存到本地文件中。 需要注意的是,在工业环境中,可能需要考虑实时性、稳定性和可靠性等方面的要求。此外,还可以结合其他工具和库,如ROS(机器人操作系统)和PCL(点云库),以实现更复杂的工业视觉应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值