clc; clear; close all;
%% 阶段1:数据预处理强化
dataPath = ‘D:\cxdownload\ORL人脸识别数据集’;
targetSize = [112, 92]; % ORL标准尺寸
% 使用更健壮的图像读取方式
try
personFolders = dir(fullfile(dataPath, ‘s*’)); % 匹配标准ORL子目录命名
numPersons = length(personFolders);
catch ME
error(‘路径访问错误: %s\n原始错误信息: %s’, dataPath, ME.message);
end
% 预分配矩阵优化
imgPerPerson = 10;
allImages = zeros(prod(targetSize), numPersons * imgPerPerson, ‘single’);
labels = zeros(numPersons * imgPerPerson, 1);
count = 1;
for i = 1:numPersons
imgDir = fullfile(dataPath, personFolders(i).name);
pgmFiles = dir(fullfile(imgDir, ‘*.pgm’));
% 添加图像顺序校验
[~, idx] = sort_nat({pgmFiles.name}); % 需要natsort文件交换
pgmFiles = pgmFiles(idx);
for j = 1:imgPerPerson
imgPath = fullfile(imgDir, pgmFiles(j).name);
try
% 添加对比度受限直方图均衡化
img = adapthisteq(imread(imgPath));
img = im2single(imresize(img, targetSize));
allImages(:, count) = img(:);
labels(count) = i;
count = count + 1;
catch ME
error('图像处理失败: %s\n错误信息: %s', imgPath, ME.message);
end
end
end
% 数据完整性检查
assert(count-1 == numPersons*imgPerPerson, ‘数据加载不完整’);
disp(['成功加载 ‘, num2str(count-1), ’ 张图像’]);
%% 阶段2:特征工程升级
X = allImages’; % 转换为样本×特征矩阵
y = labels(:);
% 改进的标准化流程
meanFace = mean(X, 1);
X = bsxfun(@minus, X, meanFace); % 只中心化不缩放
% 注意:此处保留中心化供PCA使用,不进行缩放避免信息损失
% 优化PCA实施
k = 150; % 通过累积方差确定
[coeff, ~, latent] = pca(X, ‘Centered’, false); % 已手动中心化
explainedVar = cumsum(latent)./sum(latent);
k = find(explainedVar >= 0.95, 1); % 保留95%方差
X_pca = X * coeff(:, 1:k);
%% 阶段3:模型训练升级
rng(42);
cv = cvpartition(y, ‘HoldOut’, 0.2, ‘Stratify’, true);
% 数据集划分
X_train = X_pca(cv.training, :);
y_train = y(cv.training);
X_test = X_pca(cv.test, :);
y_test = y(cv.test);
% 网格搜索优化
[C_values, gamma_values] = meshgrid(logspace(-3, 3, 5), logspace(-5, 2, 5));
best_accuracy = 0;
disp(‘开始网格搜索…’);
for i = 1:numel(C_values)
svmTemplate = templateSVM(…
‘KernelFunction’, ‘rbf’,…
‘BoxConstraint’, C_values(i),…
‘KernelScale’, gamma_values(i));
model = fitcecoc(X_train, y_train,...
'Coding', 'onevsone',...
'Learners', svmTemplate);
% 使用加速交叉验证
cv_model = crossval(model, 'KFold', 5, 'Verbose', 0);
cv_accuracy = 1 - kfoldLoss(cv_model);
fprintf('C=%.2e γ=%.2e → 准确率=%.2f%%\n',...
C_values(i), gamma_values(i), cv_accuracy*100);
if cv_accuracy > best_accuracy
best_params = [C_values(i), gamma_values(i)];
best_accuracy = cv_accuracy;
end
end
%% 阶段4:最终模型训练与评估
final_template = templateSVM(…
‘KernelFunction’, ‘rbf’,…
‘BoxConstraint’, best_params(1),…
‘KernelScale’, best_params(2));
final_model = fitcecoc(X_train, y_train,…
‘Coding’, ‘onevsone’,…
‘Learners’, final_template,…
‘Verbose’, 1);
% 综合评估
y_pred = predict(final_model, X_test);
accuracy = sum(y_pred == y_test)/numel(y_test);
fprintf(‘\n===== 最终性能 =====\n’);
fprintf(‘测试集准确率: %.2f%%\n’, accuracy*100);
disp(confusionmat(y_test, y_pred));
disp(‘=====================’);未定义函数或变量 ‘sort_nat’。
出错 Untitled8 (line 26)
[~, idx] = sort_nat({pgmFiles.name}); % 需要natsort文件交换,matlab版本为2016a