MATLAB实现HOG特征提取与SVM行人检测

一、HOG特征提取实现

1. 核心算法流程
matlab 复制代码
function hog_feat = compute_hog(img)
    % 输入:灰度图像(单通道)
    % 输出:归一化后的HOG特征向量
    
    % 参数设置
    cell_size = 8;    % cell尺寸(像素)
    block_size = 2;   % block包含的cell数
    num_bins = 9;     % 方向直方图分箱数
    
    [rows, cols] = size(img);
    
    % 1. 计算梯度
    [Gx, Gy] = imgradientxy(img, 'sobel');
    grad_mag = sqrt(Gx.^2 + Gy.^2);
    grad_dir = atan2(Gy, Gx) * 180/pi;  % 转换为角度
    
    % 2. 构建梯度直方图
    num_cells_x = floor(cols/cell_size);
    num_cells_y = floor(rows/cell_size);
    hog_cell = zeros(num_cells_y, num_cells_x, num_bins);
    
    for i = 1:num_cells_y
        for j = 1:num_cells_x
            % 提取当前cell区域
            cell_img = grad_mag((i-1)*cell_size+1:i*cell_size, ...
                               (j-1)*cell_size+1:j*cell_size);
            cell_dir = grad_dir((i-1)*cell_size+1:i*cell_size, ...
                               (j-1)*cell_size+1:j*cell_size);
            
            % 计算方向直方图
            hist = zeros(1, num_bins);
            for k = 1:numel(cell_dir)
                angle = cell_dir(k);
                if angle < 0, angle = angle + 180; end
                bin = round(angle / (180/num_bins)) + 1;
                hist(bin) = hist(bin) + cell_mag(k);
            end
            hog_cell(i,j,:) = hist / sum(hist);  % 归一化
        end
    end
    
    % 3. Block归一化
    hog_feat = [];
    for i = 1:block_size:num_cells_y-block_size+1
        for j = 1:block_size:num_cells_x-block_size+1
            block = hog_cell(i:i+block_size-1, j:j+block_size-1, :);
            block = block(:);  % 展平
            block = block / norm(block + eps);  % L2归一化
            hog_feat = [hog_feat; block];
        end
    end
end
2. 关键优化点
  • Gamma校正:预处理阶段进行对比度归一化

    matlab 复制代码
    img = sqrt(img);  % Gamma=0.5的近似实现
  • 方向插值:采用双线性插值提升方向估计精度

  • 重叠Block:设置50%重叠区域提升特征连续性


二、SVM分类器训练

1. 数据准备
matlab 复制代码
% 加载INRIA数据集
pos_dir = 'INRIAPerson/pos/';
neg_dir = 'INRIAPerson/neg/';

% 提取正样本特征
pos_feat = [];
for i = 1:numel(dir(pos_dir))
    img = imread(fullfile(pos_dir, dir(pos_dir){i}));
    img = imresize(img, [64, 128]);
    pos_feat = [pos_feat; compute_hog(img)];
end
labels_pos = ones(size(pos_feat,1),1);

% 提取负样本特征
neg_feat = [];
for i = 1:numel(dir(neg_dir))
    img = imread(fullfile(neg_dir, dir(neg_dir){i}));
    img = imresize(img, [64, 128]);
    neg_feat = [neg_feat; compute_hog(img)];
end
labels_neg = -ones(size(neg_feat,1),1);

% 合并数据集
features = [pos_feat; neg_feat];
labels = [labels_pos; labels_neg];
2. 训练流程
matlab 复制代码
% 划分训练集和测试集
cv = cvpartition(size(features,1),'HoldOut',0.3);
train_feat = features(cv.training,:);
train_labels = labels(cv.training,:);
test_feat = features(cv.test,:);
test_labels = labels(cv.test,:);

% 训练SVM模型
model = fitcsvm(train_feat, train_labels, ...
    'KernelFunction','linear', ...
    'BoxConstraint',1, ...
    'Standardize',true);

% 性能评估
predicted = predict(model, test_feat);
accuracy = sum(predicted == test_labels)/numel(test_labels);
disp(['测试集准确率: ', num2str(accuracy*100, '%.2f'), '%']);

三、行人检测实现

1. 滑动窗口检测
matlab 复制代码
function detections = sliding_window_detection(img, model, step=8)
    [rows, cols] = size(img);
    detections = [];
    
    for y = 1:step:rows-64
        for x = 1:step:cols-128
            window = imcrop(img, [x, y, 128, 64]);
            hog_feat = compute_hog(window);
            if predict(model, hog_feat) == 1
                detections = [detections; x, y, 128, 64];
            end
        end
    end
end
2. 非极大值抑制(NMS)
matlab 复制代码
function keep = nms(boxes, overlap)
    if isempty(boxes), return; end
    
    % 转换为x1,y1,x2,y2格式
    x1 = boxes(:,1);
    y1 = boxes(:,2);
    x2 = x1 + boxes(:,3)-1;
    y2 = y1 + boxes(:,4)-1;
    
    % 计算面积
    area = (x2 - x1 + 1) .* (y2 - y1 + 1);
    
    % 按置信度排序
    [~, idx] = sort(predictions, 'descend');
    x1 = x1(idx);
    y1 = y1(idx);
    x2 = x2(idx);
    y2 = y2(idx);
    area = area(idx);
    
    pick = [];
    while ~isempty(idx)
        last = length(idx);
        i = idx(last);
        pick = [pick; i];
        
        % 计算重叠区域
        xx1 = max(x1(i), x1(idx(1:last-1)));
        yy1 = max(y1(i), y1(idx(1:last-1)));
        xx2 = min(x2(i), x2(idx(1:last-1)));
        yy2 = min(y2(i), y2(idx(1:last-1)));
        
        w = max(0, xx2 - xx1 + 1);
        h = max(0, yy2 - yy1 + 1);
        overlap_ratio = (w .* h) ./ (area(idx(1:last-1)) + area(i) - w .* h);
        
        % 删除重叠过高的框
        idx(idx(1:last-1) & overlap_ratio > overlap) = [];
    end
end

四、完整检测流程

matlab 复制代码
% 加载测试图像
img = imread('test.jpg');
img_gray = rgb2gray(img);

% 检测
detections = sliding_window_detection(img_gray);

% 非极大值抑制
keep = nms(detections, 0.3);
final_detections = detections(keep,:);

% 可视化结果
figure;
imshow(img);
hold on;
for i = 1:size(final_detections,1)
    rectangle('Position', final_detections(i,:), ...
              'EdgeColor','r', 'LineWidth',2);
end
hold off;

参考代码 HOG特征提取在进行SVM行人检测 www.youwenfan.com/contentcsn/81104.html

五、扩展应用

  1. 实时检测:结合YOLOv3实现混合检测框架
  2. 多目标跟踪:集成卡尔曼滤波器进行轨迹预测
  3. 异常检测:分析时序行人行为特征
相关推荐
JIngJaneIL2 小时前
基于Java酒店管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot
机器学习之心2 小时前
MATLAB基于LOO-PSO-KELM的微电阻点焊质量预测与工艺优化
matlab·工艺优化
ZC·Shou3 小时前
Rust 之二 各组件工具的源码、构建、配置、使用(二)
开发语言·ide·rust·工具·命令·clippy·rustfmt
沐知全栈开发3 小时前
SQLite Limit 子句详解
开发语言
资深web全栈开发3 小时前
Go语言从1.18到1.25版本功能更新详解
开发语言·后端·golang
YouEmbedded3 小时前
函数模板与类模板——泛型编程
开发语言·c++·函数模板·类模板
听风吟丶3 小时前
微服务性能压测与容量规划实战:从高并发稳定性到精准资源配置
java·开发语言
小此方3 小时前
Re:从零开始学C++(一)基础精讲·上篇:命名空间、输入输出、缺省参数、函数重载
开发语言·c++
玦尘、3 小时前
《统计学习方法》第7章——支持向量机SVM(上)【学习笔记】
学习·支持向量机·学习方法