1. 项目概述
在计算机视觉和模式识别领域,特征提取与分类是核心任务之一。本文将详细介绍如何利用MATLAB实现HOG(梯度方向直方图)和GLCM(灰度共生矩阵)特征提取,并结合支持向量机(SVM)进行图像分类的完整流程。
这个方案特别适合处理需要同时考虑纹理和形状特征的分类问题。我在多个工业质检项目中实际应用过这种组合方法,相比单一特征方法,准确率平均提升了15-20%。下面我将从数据准备到模型评估,逐步拆解每个环节的实现细节和优化技巧。
2. 核心流程设计
2.1 整体架构设计
整个项目采用经典的机器学习pipeline,包含以下关键环节:
- 数据准备与预处理
- 双特征提取(HOG+GLCM)
- 特征融合与降维
- SVM模型训练与调优
- 性能评估与可视化
这种架构的优势在于:
- HOG捕捉图像的边缘和形状信息
- GLCM提取纹理特征
- 两者的互补性可以显著提升分类性能
2.2 技术选型考量
选择MATLAB实现主要基于以下考虑:
- 内置完善的图像处理和机器学习工具箱
- 矩阵运算效率高,适合特征处理
- 可视化工具丰富,便于调试
- 代码可读性强,易于工程化
提示:虽然Python的scikit-learn也很流行,但在处理小规模图像数据(<10,000张)时,MATLAB的开发效率往往更高,特别是需要快速原型验证的场景。
3. 数据准备与预处理
3.1 数据集组织规范
推荐采用以下目录结构:
code复制Project/
├── data/
│ ├── train_data/
│ │ ├── class1/
│ │ ├── class2/
│ │ └── ...
│ └── test_data/
│ ├── class1/
│ ├── class2/
│ └── ...
这种结构的好处是:
- 与MATLAB的imageSet函数天然兼容
- 便于按类别统计样本量
- 支持递归读取子目录
3.2 图像预处理细节
预处理环节包含三个关键步骤:
- 灰度化处理:
matlab复制grayImg = rgb2gray(img);
即使原始图像已经是灰度图,这个操作也能确保数据格式统一。
- 尺寸归一化:
matlab复制resizedImg = imresize(grayImg, [64 64]);
选择64x64尺寸的考虑:
- 计算效率与特征维度的平衡
- 足够保留主要形状和纹理信息
- 适合大多数工业应用场景
- 直方图均衡化(可选):
matlab复制eqImg = histeq(resizedImg);
在光照条件差异大的场景特别有用。
4. 特征提取实现
4.1 HOG特征提取
HOG参数设置建议:
matlab复制cellSize = [8 8]; % 每个cell的像素大小
blockSize = [2 2]; % 每个block包含的cell数
numBins = 9; % 方向bin的数量
这些参数的经验值:
- cellSize:通常为图像尺寸的1/8到1/10
- blockSize:2x2或3x3效果较好
- numBins:9个方向在大多数情况下足够
提取HOG特征的完整代码:
matlab复制hogFeat = extractHOGFeatures(img, ...
'CellSize', cellSize, ...
'BlockSize', blockSize, ...
'NumBins', numBins, ...
'UseSignedOrientation', true);
4.2 GLCM特征提取
GLCM需要设置的关键参数:
matlab复制distances = [1]; % 像素对距离
angles = [0, 45, 90, 135]; % 计算方向(度)
特征选择建议提取以下统计量:
- 对比度(Contrast)
- 相关性(Correlation)
- 能量(Energy)
- 同质性(Homogeneity)
实现代码:
matlab复制glcm = graycomatrix(img, ...
'Offset', [0 1; -1 1; -1 0; -1 -1], ...
'NumLevels', 8, ...
'GrayLimits', []);
stats = graycoprops(glcm, {'contrast','correlation','energy','homogeneity'});
4.3 特征融合策略
将两种特征简单串联:
matlab复制combinedFeat = [hogFeat, glcmFeat];
更优的做法是先分别归一化:
matlab复制normHOG = (hogFeat - mean(hogFeat)) / std(hogFeat);
normGLCM = (glcmFeat - mean(glcmFeat)) / std(glcmFeat);
combinedFeat = [normHOG, normGLCM];
注意:特征融合后维度可能很高,建议进行PCA降维保留95%的方差:
matlab复制[coeff,score,~] = pca(combinedFeat);
cumVar = cumsum(var(score))/sum(var(score));
keepIdx = find(cumVar <= 0.95);
finalFeat = score(:, keepIdx);
5. SVM分类实现
5.1 模型训练基础
MATLAB中使用fitcecoc实现多类SVM:
matlab复制template = templateSVM(...
'KernelFunction', 'rbf', ...
'BoxConstraint', 1, ...
'KernelScale', 'auto');
model = fitcecoc(...
trainingFeatures, ...
trainingLabels, ...
'Learners', template, ...
'Coding', 'onevsone');
关键参数说明:
- KernelFunction:RBF核适合非线性问题
- BoxConstraint:正则化参数,控制过拟合
- KernelScale:自动选择通常效果不错
5.2 参数调优技巧
推荐使用超参数优化:
matlab复制params = hyperparameters('fitcecoc', trainingFeatures, trainingLabels);
params(1).Range = [1e-3, 1e3]; % BoxConstraint范围
params(2).Range = [1e-3, 1e3]; % KernelScale范围
optimizedModel = fitcecoc(...
trainingFeatures, ...
trainingLabels, ...
'OptimizeHyperparameters', params, ...
'HyperparameterOptimizationOptions', ...
struct('AcquisitionFunctionName','expected-improvement-plus'));
5.3 类别不平衡处理
三种常用方法:
- 类别权重:
matlab复制classWeights = numel(trainingLabels)./(numClasses*countcats(trainingLabels));
- 过采样/欠采样:
matlab复制% 使用ADASYN算法过采样
[newFeatures, newLabels] = ADASYN(trainingFeatures, trainingLabels);
- 代价敏感学习:
matlab复制costMatrix = [0 1; 2 0]; % 错误分类惩罚
model = fitcecoc(..., 'Cost', costMatrix);
6. 性能评估与优化
6.1 评估指标实现
基础评估代码:
matlab复制predictedLabels = predict(model, testFeatures);
% 混淆矩阵
confMat = confusionmat(testLabels, predictedLabels);
% 准确率
accuracy = sum(diag(confMat))/sum(confMat(:));
% 分类报告
precision = diag(confMat)./sum(confMat,1)';
recall = diag(confMat)./sum(confMat,2);
f1 = 2*(precision.*recall)./(precision+recall);
6.2 ROC曲线绘制
二分类场景下的ROC绘制:
matlab复制[~,scores] = predict(model, testFeatures);
[X,Y,T,AUC] = perfcurve(testLabels, scores(:,2), 'positiveClass');
figure;
plot(X,Y);
xlabel('False Positive Rate');
ylabel('True Positive Rate');
title(['ROC Curve (AUC = ', num2str(AUC), ')']);
grid on;
6.3 特征可视化技巧
使用t-SNE可视化特征分布:
matlab复制rng default; % 可重复性
Y = tsne(features, 'NumDimensions', 2);
gscatter(Y(:,1), Y(:,2), labels);
title('t-SNE Visualization of Features');
7. 工程实践建议
7.1 性能优化技巧
- 并行计算加速:
matlab复制parfor i = 1:numImages
features(i,:) = extractFeatures(images{i});
end
- 特征提取缓存:
matlab复制if exist('features_cache.mat', 'file')
load('features_cache.mat');
else
features = extractAllFeatures(images);
save('features_cache.mat', 'features');
end
- 内存优化:
matlab复制% 预分配数组
features = zeros(numImages, featLength);
7.2 常见问题排查
- 准确率低:
- 检查特征是否归一化
- 尝试不同的特征组合
- 调整SVM核参数
- 训练速度慢:
- 减少特征维度
- 使用线性核代替RBF
- 尝试子采样
- 过拟合:
- 增加正则化参数
- 添加更多训练数据
- 使用交叉验证
8. 应用案例扩展
8.1 工业质检应用
金属表面缺陷检测优化方案:
- 多尺度HOG提取(64x64和128x128)
- 添加Gabor滤波增强纹理
- 集成多个SVM模型的投票机制
8.2 医学影像分析
X光片分类改进:
- 病灶区域ROI提取
- 3D GLCM分析(针对CT/MRI)
- 结合临床meta数据
8.3 交通标志识别
针对不同光照条件的优化:
- 色彩空间转换(HSV/Lab)
- 基于偏振特性的特征增强
- 多视角特征融合
在实际项目中,我发现HOG+GLCM组合特别适合处理以下场景:
- 需要同时考虑形状和纹理的分类问题
- 中小规模数据集(几百到几千样本)
- 对实时性要求不苛刻的应用
最后分享一个实用技巧:在部署到生产环境时,可以将训练好的模型导出为C代码,大幅提升执行效率。MATLAB的Coder工具箱可以自动完成这个转换过程。