实验环境
(1) Windows7,MatlabR 2016b;
(2) LIBSVM工具箱;
遇到的问题及解决方法:
起初安装的MATLABr2014b,配置libsvm工具包的过程中,遇到make不成功等问题,后来在网上看了各种帖子后,把Matlab2014换成matlab2016,最后成功解决了问题,当然期间安装了编译器,尝试了很多种办法,最后才成功使用libsvm工具包。
案例背景
数据集获取:《Matlab神经网络43个案例分析》,MATLAB技术论坛网址为http://www.matlabsky.com/
图像预处理
训练样本的部分截图
对图像标准化处理的子函数pic_preprocess代码如下所示。
%% sub function of pre-processing pic
function pic_preprocess = pic_preprocess(pic)
% 图片预处理子函数
% 图像反色处理
pic = 255-pic;
%设定阈值,将反色图像转成二值图像
pic = im2bw(pic,0.4) ;
%查找数字上所有像素点的行标y和列标x
[y,x] = find(pic == 1);
%截取包含完整数字的最小区域
pic_preprocess = pic (min(y):max(y),min(x):max(x));
%将截取的包含完整数字的最小区域图像转成16*16的标准化图像
pic_preprocess = imresize(pic_preprocess, [16, 16]);
导入训练样本
%%载入训练数据,利用uigetfile函数交互式选取训练样本
[FileName,PathName,FilterIndex]=uigetfile(...
{'*.png';'*bpm'},'请导入训练图片','*.png','MultiSelect','on');
if ~FilterIndex %如果用户取消,则返回上一步
return;
end
num_train=length(FileName);%filename是一个字符串数组
TrainData=zeros(num_train,16*16);
TrainLabel=zeros(num_train,1);
for k=1:num_train
pic=imread([PathName,FileName{k}]);%逐个读图
pic=pic_preprocess(pic); %将一幅图转为16*16个二进制数
TrainData(k,:)=double(pic(:)');%单引号是将pic转一维数组,存放在第K行
TrainLabel(k)=str2double(FileName{k}(6));%文件名中第4个字符是该图片的数字
end
建立SVM模型
% 创建/训练SVM模型
model = svmtrain(TrainLabel,TrainData);
[predict_label_1,accuracy_1] = svmpredict(TrainLabel,TrainData,model);
对测试样本进行与训练样本同样的图像预处理
%%载入测试样本
[FileName,PathName,FilterIndex]=uigetfile(...
{'*.png';'*bpm'},'请导入测试图片','*.bmp','MultiSelect','on');
if ~FilterIndex %如果用户取消,则返回上一步
return;
end
num_train=length(FileName);%filename是一个字符串数组
TrainData=zeros(num_train,16*16);
TrainLabel=zeros(num_train,1);
for k=1:num_train
pic=imread([PathName,FileName{k}]);%逐个读图
pic=pic_preprocess(pic); %将一幅图转为16*16个二进制数
TrainData(k,:)=double(pic(:)');%单引号是将pic转一维数组,存放在第K行
TrainLabel(k)=str2double((FileName{k}(6))-1);%文件名中第4个字符是图片的数字
end
对测试样本进行识别
%%对测试样本进行分类
preTestLabel=svmpredict(TestLabel,TestData,Model);
TestLabel'
PreTestLabel'
测试样本的实际分类与预测分类对比效果图
%% 绘图
figure
plot(1:length(TestLabel),TestLabel,'r-*')
hold on
plot(1:length(TestLabel),predict_label_2,'b:o')
grid on
legend('真实类别','预测类别')
xlabel('测试集样本编号')
ylabel('类别标签')
string = {'测试集的实际分类和预测分类对比图';
['accuracy = ' num2str(accuracy_2(1)) '%']};
title(string)