计算 HOG算子的典型 MATLAB 程序

计算 HOG(Histogram of Oriented Gradients,方向梯度直方图)算子的典型 MATLAB 程序。这个实现遵循 Dalal & Triggs 2005 的经典 CVPR 论文 流程,结构清晰、参数可调


一、HOG 计算流程

  1. 灰度化
  2. Gamma 校正(可选)
  3. 计算梯度(x/y 方向)
  4. 构建 Cell(如 8×8 像素)内的方向直方图(9 bins,0°~180°)
  5. Block 归一化(如 2×2 Cells,L2-norm)
  6. 拼接所有 Block 的特征 → 最终 HOG 特征向量

二、MATLAB 程序

主程序:hog_demo.m

matlab 复制代码
%% HOG (Histogram of Oriented Gradients) Demo
% 参考: Dalal & Triggs, CVPR 2005
clear; clc; close all;

%% ========== 1. 读入图像 ==========
img = imread('test_image.jpg');   % 建议用行人图片测试
% img = imresize(img, [128 64]);   % INRIA 行人标准尺寸

if size(img,3)==3
    gray = rgb2gray(img);
else
    gray = img;
end

%% ========== 2. Gamma 校正(可选) ==========
gray = imadjust(gray, [], [], 0.5);  % 压缩动态范围

%% ========== 3. 计算梯度 ==========
[Gx, Gy] = imgradientxy(gray, 'sobel');
[mag, ori] = imgradient(Gx, Gy);     % mag: 梯度幅值, ori: 方向[-180,180]

% 转为 [0,180](无符号梯度,亮度不变性)
ori = mod(ori, 180);

%% ========== 4. HOG 参数 ==========
cellSize = 8;        % 每个 cell 8×8 像素
numBins  = 9;        % 方向 bin 数
anglePerBin = 180 / numBins;

blockSize = 2;       % 2×2 cells per block
stride   = 1;        % block 滑动步长(cell 数)

[h, w] = size(gray);
cellsX = floor(w / cellSize);
cellsY = floor(h / cellSize);

%% ========== 5. 构建 Cell 直方图 ==========
cellHist = zeros(cellsY, cellsX, numBins);

for cy = 1:cellsY
    for cx = 1:cellsX
        % Cell 区域
        yrange = (cy-1)*cellSize+1 : cy*cellSize;
        xrange = (cx-1)*cellSize+1 : cx*cellSize;
        
        magCell = mag(yrange, xrange);
        oriCell = ori(yrange, xrange);
        
        % 投票到 9 个方向 bin
        for b = 1:numBins
            binLow  = (b-1)*anglePerBin;
            binHigh = b*anglePerBin;
            
            % 方向落在当前 bin 内
            idx = (oriCell >= binLow) & (oriCell < binHigh);
            cellHist(cy, cx, b) = sum(magCell(idx));
        end
    end
end

%% ========== 6. Block 归一化 ==========
blocksY = cellsY - blockSize + 1;
blocksX = cellsX - blockSize + 1;

hogFeat = [];

for by = 1:blocksY
    for bx = 1:blocksX
        % 取出 2×2 cell 的直方图
        block = cellHist(by:by+blockSize-1, bx:bx+blockSize-1, :);
        blockVec = block(:);
        
        % L2 归一化
        epsVal = 1e-6;
        blockNorm = blockVec / sqrt(norm(blockVec)^2 + epsVal);
        
        hogFeat = [hogFeat; blockNorm];
    end
end

%% ========== 7. 可视化 ==========
figure('Color','white','Position',[100 100 900 400])

subplot(1,2,1)
imshow(gray)
title('Input Image')

subplot(1,2,2)
visualizeHOG(gray, hogFeat, cellSize, blockSize, numBins)
title('HOG Visualization')

fprintf('HOG 特征维度: %d\n', length(hogFeat));

HOG 可视化函数:visualizeHOG.m

matlab 复制代码
function visualizeHOG(img, hogFeat, cellSize, blockSize, numBins)
% 绘制 HOG 箭头图
    [h, w] = size(img);
    imshow(img); hold on;
    
    anglePerBin = 180 / numBins;
    featIdx = 1;
    
    for by = 1:(h/cellSize - blockSize + 1)
        for bx = 1:(w/cellSize - blockSize + 1)
            for cy = 0:blockSize-1
                for cx = 0:blockSize-1
                    % Cell 中心
                    centerY = (by+cy-1)*cellSize + cellSize/2;
                    centerX = (bx+cx-1)*cellSize + cellSize/2;
                    
                    % 该 Cell 的 9 维直方图
                    histVec = hogFeat(featIdx:featIdx+numBins-1);
                    featIdx = featIdx + numBins;
                    
                    % 画 9 个方向的箭头
                    for b = 1:numBins
                        angle = (b-0.5)*anglePerBin;
                        len = histVec(b) * 10;  % 缩放因子
                        
                        dx = len * cosd(angle);
                        dy = len * sind(angle);
                        
                        quiver(centerX, centerY, dx, dy, ...
                               'Color','r','LineWidth',1.2,'MaxHeadSize',0.5);
                    end
                end
            end
        end
    end
    hold off;
end

三、运行效果说明

  • 红色箭头:表示梯度方向强度

  • 箭头长度:正比于该方向的梯度幅值

  • 特征维度示例(128×64 图像):

    复制代码
    Cell: 16×8
    Block: 15×7
    每 Block: 2×2×9 = 36 维
    总维度: 15×7×36 = 3780

    这正是 INRIA 行人检测 的标准 HOG 维度。

参考代码 计算HOG算子的典型程序 www.youwenfan.com/contentcsw/82584.html

四、关键参数含义

参数 典型值 作用
cellSize 8×8 统计梯度的局部区域
numBins 9 0°~180°,每 20° 一个 bin
blockSize 2×2 对比度归一化,抗光照
L2-norm 防止单一强梯度主导
无符号梯度 0°~180° 忽略边缘方向正反

五、与 OpenCV / VLFeat 的差异

实现 特点
本程序 教学友好、完全透明
VLFeat (vl_hog) 速度快、支持浮点 Cell
OpenCV (HOGDescriptor) 工业级、支持 SVM 训练
MATLAB 自带 extractHOGFeatures 封装好,但不可控

如果你想完全对齐 OpenCV 结果,需要:

  • [0,360) 有符号梯度
  • 改用 三线性插值投票
  • 增加 重叠 Block 的裁剪方式
相关推荐
楷哥爱开发1 小时前
降低网络爬虫成本:基础设施优化指南
服务器·开发语言·php
bubiyoushang8881 小时前
ADMM(交替方向乘子法)算例
matlab
feifeigo1232 小时前
matlab电力系统重构实现
开发语言·matlab·重构
小c君tt2 小时前
QT笔记记录
开发语言·笔记·qt
布朗克1682 小时前
Go 入门到精通-08-复合类型之数组与切片
开发语言·后端·golang·数组与切片
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题 第151题】【06_Spring篇】第11题:说一下 Spring Bean 的生命周期?
java·开发语言·后端·spring·面试
广州浮点FLOATLIC3 小时前
Creo 许可证利用率怎么优化:制造企业该先看共享规则,还是先看模块占用结构
java·开发语言
wuyk5553 小时前
21. 嵌入式面试避坑指南:sizeof 是关键字,不是函数!
c语言·开发语言·stm32·单片机·嵌入式硬件
2601_962440843 小时前
计算机毕业设计之jsp教室管理系统
java·开发语言·笔记·分布式·算法·课程设计·推荐算法