本文着重讲解代码,支持向量机(svm)的原理这里就不再赘述了。
上代码!
零、图像预处理函数
function pic_preprocess = pic_preprocess(pic)
% 图片预处理子函数
pic = 255-pic;
% 图像反色处理
pic = im2bw(pic,0.4);
% 设定阈值,将反色图像转成二值图像
[y,x] = find(pic == 1);
% 查找数字(识别目标)的所有像素点的行标y和列标x
pic_preprocess = pic(min(y):max(y), min(x):max(x));
% 截取包含完整数字的最小区域
pic_preprocess = imresize(pic_preprocess,[16,16]);
% 将截取的包含完整数字的最小区域图像转成16*16的标准化图像
一、训练集数据处理
1、读入训练集图像
[FileName,PathName,FilterIndex] = uigetfile( ...
{'*.jpg';'*.bmp'},'请导入训练图片','*.jpg','MultiSelect','on');
%FileName:读入图像的文件名
%PathName:图像文件的路径
%FilterIndex:可选项的索引 例如{'*.jpg';'*.bmp'}中 前者索引为1 后者索引为2
%{'*.jpg';'*.bmp'}:可选项类型
%'请导入训练图片':文本对话框
%'MultiSelect','on':多选功能打开,可以一次选择多个图像
if ~FilterIndex %如果FilterIndex为0 则返回上一步再次导入图像
return;
end
2、为读入的图像留存储空间
num_train = length(FileName);
%训练集中图像的数目
TrainData = zeros(num_train,16*16);
%训练数据集 该矩阵维度50*256
TrainLabel = zeros(num_train,1);
%训练标签集 50*1 列向量
3、对图像预处理、收纳、贴标签
for k = 1:num_train
pic = imread([PathName,FileName{k}]); %读入图像
pic = pic_preprocess(pic);%进行图像预处理 预处理后pic维度为16*16
TrainData(k,:) = double(pic(:)');
%将预处理后的图像按列拉成一个列向量,然后转置成行向量 放入训练数据集第k行中
%训练数据集的每一行 存放一张图片(即转换成行向量的图片像素数据)
TrainLabel(k) = str2double(FileName{k}(4));
%为每张图像贴上对应的标签
%FlieName{1} 细胞体中第1个元素:'num0_1.jpg',FlieName{1}(4)为字符'0'
end
这一模块可以理解成对原始图像进行标准化,然后将二维图像展平成一维数组,收入数据集矩阵中,并贴上对应的标签。就像把一堆衣服,一件件叠好,然后收纳进柜子,并贴上标签(T恤or卫衣or其它)衣服——原始图像,叠好——预处理,收纳——放入数据集矩阵,贴标签——建立标签集 。
二、建立支持向量机
1、参数寻优,需要下载作者自建的工具包
ga_option.maxgen = 100;
ga_option.sizepop = 20;
ga_option.cbound = [0,100];
ga_option.gbound = [0,100];
ga_option.v = 10;
ga_option.ggap = 0.9;
[bestCVaccuracy,bestc,bestg] = ...
gaSVMcgForClass(TrainLabel,TrainData,ga_option)
%找到最优参数 bestc、bestg
2、训练支持向量机
cmd = ['-c ',num2str(bestc),' -g ',num2str(bestg)];
%最优参数
model = libsvmtrain(TrainLabel, TrainData, cmd);
%构建支持向量机模型
preTrainLabel = libsvmpredict(TrainLabel, TrainData, model);
%通过训练集检验模型的识别率
三、测试集数据导入
详细解析同第一部分训练集数据处理,不再赘述
[FileName,PathName,FilterIndex] = uigetfile( ...
{'*.jpg';'*.bmp'},'请导入测试图片','*.bmp','MultiSelect','on');
if ~FilterIndex
return;
end
num_test = length(FileName);
TestData = zeros(num_test,16*16);
TestLabel = zeros(num_test,1);
for k = 1:num_test
pic = imread([PathName,FileName{k}]);
pic = pic_preprocess(pic);
TestData(k,:) = double(pic(:)');
TestLabel(k) = str2double(FileName{k}(4));
end
四、功能实现
用训练好的模型对测试集进行验证,看识别准确率
preTestLabel = libsvmpredict(TestLabel, TestData, model);
TestLabel' %显示测试集原来的标签
preTestLabel' %显示模型预测的标签
五、总结
整体而言,这一案例较为简单,可以仔细阅读本文、并进行上机实验加深对代码理解。这是我的第一篇博客,还显得十分生涩。此外没对支持向量机进行理论分析,仅为代码的解读,有不妥之处还望各位指正。
PS:
代码中的训练集和测试集均为《MATLAB神经网络43个案例分析》一书中的资源。可在此下载:https://service.buaapress.com.cn/mzs/file/index/c/d/keyword/MATLAB