其实就一个图像特征的提取(一种较简单的方法是将图像分成n*n的区域,统计每块区域中像素点所占的百分比),和SVM中参数的选择(上一篇文章)。不多说,上一波代码(Matlab)。运行有点久,因为参数选择很耗时间(相当于运行了100次),如果不需要参数选择,可以采用默认参数就好。每一次对应参数的分类准确率保存在R_train和R_test中。
clc
clear
%载入数据。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
size_pic = 6;
% 利用uigetfile函数交互式选取训练样本
[FileName,PathName,FilterIndex] = uigetfile( ...
{'*.jpg';'*.bmp'},'请导入训练图片','*.png','MultiSelect','on');
if ~FilterIndex
return;
end
num_train = length(FileName);
TrainData = zeros(num_train,size_pic*size_pic);
TrainLabel = zeros(num_train,1);
for k = 1:num_train
pic = imread([PathName,FileName{k}]);
pic = pick_feature(pic);%提取图像特征
% 将标准化图像按列拉成一个向量并转置,生成6*6的训练样本矩阵
TrainData(k,:) = double(pic(:)');
% 样本标签为样本所对应的数字
TrainLabel(k) = str2double(FileName{k}(1));
end
[FileName,PathName,FilterIndex] = uigetfile( ...
{'*.jpg';'*.bmp'},'请导入测试图片','*.png','MultiSelect','on');
if ~FilterIndex
return;
end
num_train = length(FileName);
TestData = zeros(num_train,size_pic*size_pic);
TestLabel = zeros(num_train,1);
for k = 1:num_train
pic = imread([PathName,FileName{k}]);
pic = pick_feature(pic);
TestData(k,:) = double(pic(:)');
TestLabel(k) = str2double(FileName{k}(1));
end
%%
%SVM识别。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
g = [2^0, 2^-1, 2^-2, 2^-3,2^-4,2^-5,2^-6,2^-7,2^-8,2^-9];%g参数
c = [2^7,2^6,2^5,2^4, 2^3 ,2^2, 2^1, 2^0,2^-1,2^-2];%C参数
R_train = zeros(10,10);%对应参数训练集的分类准确率
R_test = zeros(10,10);%对应参数测试集的分类准确率
for i=1:10
for j=1:10
cmd = ['-c ',num2str(c(i)),' -g ',num2str(g(j))];%模型参数
model = svmtrain(TrainLabel, TrainData, cmd);
% 在训练集上查看识别能力
preTrainLabel = svmpredict(TrainLabel, TrainData, model);%样本集分类情况。。
preTestLabel = svmpredict(TestLabel, TestData, model);%测试集预测情况。。。。
size_train = size(preTrainLabel);
size_test = size(preTestLabel);
corretnum1 = 0;
for m = 1:size_train(1);
if preTrainLabel(m) == TrainLabel(m);
corretnum1 = corretnum1 +1;
end
end
R_train(i,j) = corretnum1/size_train(1);
corretnum2 = 0;
for n = 1:size_test(1)
if preTestLabel(n) == TestLabel(n);
corretnum2 = corretnum2 +1;
end
end
R_test(i,j)=corretnum2/size_test(1);
end
end
function [ A ] = pick_feature( pic )
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
%pic = 255-pic;
% 设定阈值,将反 {MOD}图像转成二值图像
pic = im2bw(pic,0.4);
% 查找数字上所有像素点的行标y和列标x
[y,x] = find(pic == 1);
% 截取包含完整数字的最小区域
pic_preprocess = pic(min(y):max(y), min(x):max(x));
[m, n] = size(pic_preprocess);
b = 6;%将图像等分为10*10的区域;
i = floor(m/b);%行列的等分大小
j = floor(n/b);
s = i*j;
A = zeros(b);%存取每个区域的特征(特征=像素/面积)
T = 0.1;%阀值
for k=1:b
for h=1:b
arry_b = pic_preprocess(1+(k-1)*i:k*i,1+(h-1)*j:h*j);
% if sum(sum(arry_b))/s > T
A(k,h) = sum(sum(arry_b))/s;
% end
end
end