SVM对手写数字的识别

2019-04-15 13:18发布

其实就一个图像特征的提取(一种较简单的方法是将图像分成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 endfunction [ 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