计算 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 的裁剪方式
相关推荐
c2385610 分钟前
把 C++ 内存分配拆透:new 与 malloc 的三层血缘
开发语言·c++·算法
moonsims1 小时前
星闪在跨域无人化系统作用
开发语言·php
Iruoyaoxh2 小时前
栈和队列~
java·开发语言
Hrain-AI2 小时前
2026 企业 AI 编程智能体实战:Codex 与 Claude Code
开发语言·人工智能·kotlin
wdfk_prog2 小时前
嵌入式面试真题第 13 题:单硬件 Timer 下的高精度多路软件定时器架构设计
c语言·开发语言·面试·职场和发展·嵌入式
oort1233 小时前
吃上了自家的细糠,还挺丝滑,用起来手感还行,OortCloud发布新版AI编程平台,下载 OortCodex,Token多,免费薅
大数据·开发语言·人工智能·ai编程
slandarer3 小时前
MATLAB | 泰勒图绘制,支持各种角度范围
开发语言·数学建模·matlab·nature·顶刊·泰勒图
mct1233 小时前
c++ iconv 字符utf-8转换gb2312失败
开发语言·c++
Marst Code4 小时前
Python 3.9 已停止维护!从 3.9 到 3.14 全版本深度对比,生产环境该选哪个?
开发语言·python
ZJH__GO5 小时前
网络编程v2--多客户端互通
java·运维·服务器·开发语言·计算机网络