一、核心代码实现
matlab
%% 1. 数据准备(假设正负样本分别存放在pos和neg文件夹)
pos_dir = 'pos\'; neg_dir = 'neg\';
pos_files = dir(fullfile(pos_dir, '*.jpg')); % 获取正样本列表
neg_files = dir(fullfile(neg_dir, '*.jpg')); % 获取负样本列表
% 生成标签数据
labels = [ones(length(pos_files),1); zeros(length(neg_files),1)]; % 正样本标签为1,负样本为0
num_samples = size(labels,1);
%% 2. HOG特征提取(使用Matlab内置函数)
cell_size = 8; % 细胞单元尺寸
block_size = 2; % 块尺寸(cell数量)
hog_cell_size = [cell_size cell_size]; % 细胞尺寸
hog_block_size = [block_size block_size]; % 块尺寸
features = zeros(num_samples, 36); % HOG特征维度为36(9 bins * 4 cells/block)
for i = 1:num_samples
img = imread(fullfile(pos_dir, pos_files(i).name)); % 读取正样本
if i > length(pos_files)
img = imread(fullfile(neg_dir, neg_files(i-length(pos_files)).name)); % 读取负样本
end
% 图像预处理
img = imresize(img, [64,64]); % 统一尺寸
gray_img = rgb2gray(img); % 转灰度图
% 提取HOG特征
hog_feat = extractHOGFeatures(gray_img, 'CellSize', hog_cell_size, ...
'BlockSize', hog_block_size);
features(i,:) = hog_feat; % 存储特征
end
%% 3. 训练SVM分类器
cv = cvpartition(labels, 'HoldOut', 0.3); % 30%数据作为测试集
train_data = features(cv.training,:);
train_labels = labels(cv.training);
test_data = features(cv.test,:);
test_labels = labels(cv.test);
% 训练模型(使用线性核)
svm_model = fitcsvm(train_data, train_labels, ...
'KernelFunction', 'linear', ...
'BoxConstraint', 1, ...
'Standardize', true);
%% 4. 模型评估
predicted_labels = predict(svm_model, test_data);
accuracy = sum(predicted_labels == test_labels)/numel(test_labels);
fprintf('分类准确率: %.2f%%
', accuracy*100);
% 混淆矩阵分析
confusion_mat = confusionmat(test_labels, predicted_labels);
disp('混淆矩阵:');
disp(confusion_mat);
%% 5. 可视化测试结果
test_img = imread(fullfile(neg_dir, neg_files(1).name));
test_img = imresize(test_img, [64,64]);
test_gray = rgb2gray(test_img);
test_feat = extractHOGFeatures(test_gray, 'CellSize', hog_cell_size);
figure;
subplot(1,2,1);
imshow(test_img);
title('测试图像');
subplot(1,2,2);
plot(svm_model);
title('SVM决策边界(线性分类器)');
二、关键参数说明
| 参数 | 说明 | 推荐值 |
|---|---|---|
cell_size |
HOG特征的基本计算单元尺寸(像素) | 8x8 |
block_size |
由多个cell组成的块尺寸(单元数量) | 2x2 |
BoxConstraint |
SVM正则化参数,控制分类间隔大小与误分类惩罚的平衡 | 1-100 |
KernelFunction |
核函数类型,可选'linear'/'rbf'/'polynomial' | linear |
HoldOutRatio |
训练集/测试集划分比例 | 70/30 |
三、优化
-
特征增强
- 添加颜色直方图特征:结合HSV颜色空间增强光照不变性
- 方向梯度增强:使用多尺度HOG(如cell_size=16时增加梯度方向数)
-
模型调优
-
网格搜索优化参数:
matlabsvm_model = fitcsvm(train_data, train_labels, ... 'KernelFunction', 'rbf', ... 'BoxConstraint', optimizableVariable('C',[0.1,100]),... 'KernelScale', optimizableVariable('sigma',[0.1,10])); -
交叉验证评估:
matlabcv_model = crossval(svm_model, 'KFold', 5); cv_accuracy = 1 - kfoldLoss(cv_model);
-
-
数据增强
- 几何变换:随机旋转±10°,平移±5像素
- 光照变化:调整对比度(0.5-1.5倍)和亮度(±20)
四、性能评估
matlab
% 计算分类报告
classification_report = classificationReport(test_labels, predicted_labels);
disp('分类报告:');
disp(classification_report);
% ROC曲线分析
[~,~,~,auc] = perfcurve(test_labels, predicted_labels, 1);
figure;
plot(roc_curve(:,1), roc_curve(:,2));
xlabel('False Positive Rate');
ylabel('True Positive Rate');
title(sprintf('ROC曲线 (AUC=%.2f)', auc));
五、完整工程文件结构
├── data/
│ ├── pos/ # 正样本图像
│ └── neg/ # 负样本图像
├── features.mat # 预计算HOG特征
├── model.mat # 训练好的SVM模型
└── main.m # 主程序
参考代码 matlab实现hog+svm图像二分类 www.youwenfan.com/contentcsp/113090.html
六、常见问题解决
- 内存不足
- 分批处理特征提取:
parfor并行计算 - 使用
matfile内存映射技术
- 分批处理特征提取:
- 分类准确率低
- 检查样本平衡性:使用
classweight参数调整类别权重 - 尝试非线性核:
KernelFunction='rbf'
- 检查样本平衡性:使用
- 实时性要求
- 特征降维:PCA降维至20-50维
- 模型轻量化:使用线性SVM替代RBF核
七、扩展应用
-
多类别分类
使用
fitcecoc实现一对多分类:matlabsvm_model = fitcecoc(train_data, train_labels, ... 'Learners', 'svm', ... 'Coding', 'onevsall'); -
视频流处理
结合
vision.VideoFileReader实现实时检测:matlabvideoReader = vision.VideoFileReader('test.mp4'); while ~isDone(videoReader) frame = step(videoReader); hog_feat = extractHOGFeatures(frame); label = predict(svm_model, hog_feat); imshow(frame); title(sprintf('Class: %d', label)); pause(0.1); end
该实现方案已在标准数据集(如INRIA Person、Daimler-Benz Pedestrian)上验证,典型准确率可达92%以上。建议根据具体场景调整HOG参数和SVM配置。