文章目录
概要
HOG(Histogram of Oriented Gradients,方向梯度直方图)是一种在计算机视觉和图像处理中用于目标检测的特征描述子。本文将详细介绍如何使用MATLAB实现一个简单的HOG特征提取函数HOG_features
,该函数接收灰度图像作为输入,并输出表示图像HOG特征的可视化图像。
整体架构流程
- 伽马校正:首先对输入的灰度图像进行伽马校正以增强图像对比度。
- 计算边缘:接着计算图像的水平和垂直方向上的梯度来获得每个像素点的梯度幅度和方向。
- 构建梯度直方图:然后,将图像划分为多个小的连通区域(cell),对于每个cell,根据其中所有像素点的梯度信息构建一个梯度方向直方图。
- 归一化:为了减少光照变化和阴影的影响,通常会对相邻的一组cell(block)进行对比度归一化。
- 可视化:最后,构造一个可视化的HOG特征图像,用线段的长度和方向来表示每个cell中的梯度信息。
技术名词解释
- HOG(Histogram of Oriented Gradients):一种特征描述方法,通过统计局部区域内梯度的方向分布来表征物体的形状。
- 伽马校正:对图像亮度进行非线性调整的一种方法,目的是补偿显示设备的伽马值。
- 梯度:数学概念,指多变量函数在某一点处的最大变化率及其方向。
- Cell:HOG算法中定义的小的图像区域,用来统计局部的梯度方向直方图。
- Block:由一个或多个相邻的cell组成的更大的区域,用于归一化过程。
- 归一化:对数据进行线性变换,使结果落在特定范围内,如[0,1]之间。
技术细节
代码解析
- 伽马校正:代码中通过
sqrt(img)
对原始灰度图像进行了伽马校正,这有助于增强图像的对比度。 - 计算边缘:利用了两个一维滤波器
fx
和fy
分别沿X轴和Y轴方向计算图像梯度,随后计算梯度幅值Ied
和方向Iphase
。 - 构建梯度直方图:采用8x8像素的步长划分图像为cells,并且为每个cell构建了一个包含9个bin的方向直方图。
- 归一化:代码中尝试对每个cell的直方图进行归一化,但实际代码中并未实现块归一化。
- 可视化:创建了一个
image_hog
矩阵用于保存可视化的HOG特征,但此部分代码存在一些逻辑错误,比如intensity
的计算方式不正确,以及block
填充逻辑的问题。 - 高斯平滑:定义了一个5x5的高斯核
G
,但是conv2(G, image_hog);
这一行没有赋值给任何变量,因此高斯平滑操作实际上并没有应用到image_hog
上。
注意事项
- 代码中存在一些潜在的问题,例如
image_hog
的转置操作可能是不必要的,以及高斯平滑的操作未被正确应用。 Cell
的初始化应该与循环结构相匹配,即应根据预期的cell数量初始化其大小。- 在计算
Hist
时,代码直接对tmped
进行了归一化,这可能不是最合适的归一化方法。 - 可视化部分的代码逻辑较为复杂,且有误,需要重新考虑如何有效地将HOG特征映射到可视化图像中。
小结
HOG特征是计算机视觉领域中非常重要的工具,尤其适用于人体检测等任务。上述提供的MATLAB代码实现了HOG特征的基本构建过程,但在某些方面还需要改进和优化。正确的实现应该包括准确的细胞单元和块的归一化、无误的可视化逻辑以及高效的性能。此外,代码还应该考虑到边界条件和其他可能影响算法效果的因素。
完整代码
function hog_image = HOG_features(grayImg)
% 伽马校正
img = double(grayImg);
img = sqrt(img);
% 计算边缘
fy = [-1 0 1];
fx = fy';
Iy = imfilter(img, fy, 'replicate');
Ix = imfilter(img, fx, 'replicate');
Ied = sqrt(Ix.^2 + Iy.^2);
Iphase = Iy ./ Ix;
% 计算 cell 的梯度直方图
step = 8;
orient = 9;
jiao = 360 / orient;
Cell = cell(1, 1);
cell_row = 1;
cell_col = 1;
[m, n] = size(img);
for i = 1:step:m-step
cell_row = 1;
for j = 1:step:n-step
tmpx = Ix(i:i+step-1, j:j+step-1);
tmped = Ied(i:i+step-1, j:j+step-1);
tmped = tmped / sum(sum(tmped));
tmpphase = Iphase(i:i+step-1, j:j+step-1);
Hist = zeros(1, orient);
for p = 1:step
for q = 1:step
if isnan(tmpphase(p, q))
tmpphase(p, q) = 0;
end
ang = atan(tmpphase(p, q));
ang = mod(ang * 180 / pi, 360);
if tmpx(p, q) < 0
if ang < 90
ang = ang + 180;
end
if ang > 270
ang = ang - 180;
end
end
ang = ang + 0.0000001;
Hist(ceil(ang / jiao)) = Hist(ceil(ang / jiao)) + tmped(p, q);
end
end
Hist = Hist / sum(Hist);
Cell{cell_row, cell_col} = Hist;
cell_row = cell_row + 1;
end
cell_col = cell_col + 1;
end
% 显示准备工作
angle = [40, 80, 120, 160, 200, 240, 280, 320, 360];
rad = angle * pi / 180;
k = tan(rad);
[m, n] = size(Cell);
image_hog = zeros(m * 17, n * 17);
for x = 1:m-1
for y = 1:n-1
intensity = (Cell{x, y} + Cell{x, y + 1} + Cell{x + 1, y} + Cell{x + 1, y + 1}) * 64;
X = -8:1:8;
[a, b] = size(k);
for i = 1:b
Y(i, :) = ceil(X * k(i));
end
% 标记 block 画线
block = zeros(17, 17);
for i = 1:17
X(i) = X(i) + 9;
for j = 1:9
Y(j, i) = Y(j, i) + 9;
if Y(j, i) > 17
Y(j, i) = 17;
end
if Y(j, i) < 1
Y(j, i) = 1;
end
end
end
% 标记
for i = 1:17
for j = 1:9
block(X(i), Y(j, i)) = intensity(j);
end
end
% 填充 HOG 图像
image_hog((x-1)*17+1:(x-1)*17+17 , (y-1)*17+1:(y-1)*17+17) = block(:,:);
end
end
image_hog = image_hog';
% 高斯平滑
G = [1 2 3 2 1;
2 5 6 5 2;
3 6 8 6 3;
2 5 6 5 2;
1 2 3 2 1;]
conv2(G, image_hog);
% 返回 HOG 特征图像
hog_image = image_hog;
end
标签:HOG,ang,end,17,cell,step,matlab,特征提取
From: https://blog.csdn.net/qq_40407694/article/details/144868442