首页 > 代码库 > 基于Libsvm的图像分类

基于Libsvm的图像分类

基于Libsvm的图像分类

  • 关于Libsvm的废话
  • 基于Libsvm的图像分类实例
  • 说说图像分类的处理结果

1. 关于Libsvm的废话
先来一段废话,大家有心情看看就行,那就是关于支持向量机的问题,支持向量机是在统计学习理论基础上发展起来的一种机器学习方法。基于数据的机器学习是现代智能技术中的一个重要方面,研究的实质是根据给定的训练样本求对某系统输入输出之间依赖关系的估计,使它能对未知输入作出尽可能准确的预测和估计。本文提出了一种利用支持向量机(SupportvectorMachine,简称 SVM)的图像分类方法,关于其他支持向量机(SVM)相关的东西在这里就不多做介绍了。
最初接触支持向量机和Libsvm是上个学期的事情了,学的时间不多,零零碎碎,主要是为了完成导师布置的任务,也就是关于这篇文章第二部分的实例。之所以选择在这个时候写一篇文章,一个方面是所感自学过程中一路的磕磕绊绊,最为无奈的就是在Libsvm相关资料的查找上,虽说有MATLAB中文论坛和MATLAB技术论坛可以提问抑或是查找问题,但说实话一般在论坛提问的方式,效率还是很低下的,关于利用Libsvm图像分类这一块资料更是少之又少;另一方面也是因为自己即将要开始另外一个项目,接手一个项目,免不了要学习新的知识,学习新的知识前,总结一下以前所学,回顾自己做过的东西,算是给过去一个交代,也是对自己所学知识的温习巩固。
关于Libsvm的下载与安装,在这里我就不累赘了,博主用的是林智仁先生的,这个是可以到林智仁先生主页下载的,当然也可以用faruto的,相关基础知识不多说,安装使用大家可以参考MATLAB论坛中faruto学长的“关于SVM的那些破事”一文,虽然其中不少链接已经失效,但相当基础的东西还是有不少,svm算法练习的书网上有不少电子版的下载,再此也不再赘述。

2. 基于Libsvm的图像分类实例
文采不太好,口才也不太好,一向都是我的短板,所以废话不多说,直接说需求:
导师安排的任务很简单,也很好理解,就是给出一副三维的遥感图像,要求我把遥感图像中的事物进行分类,如何分类呢?这个分类如何理解是关键,经过自己思量,我理解导师是让我用rgb颜色可视化不同的事物,通俗点也就是说,把遥感图像中的不同事物用不同的rgb颜色进行分类,遥感图像如下:
技术分享

现在任务大家也都知道了,也就是说我们首先明确了自己要做什么,那么接下来就是确认自己怎么实现目标,在此,我明确了以下几个步骤:
1. 导入图像,即读取图像。
2. 特征提取,选择感兴趣区域,即选取训练集,在这里选取了六块,即在六类事物中选取,之后就是将三维的块–>二维。
3. 在选取的块中选100个点作为训练集。
4. 利用选取的训练样本建立分类模型。
5. 预测分类
6. rgb可视化
根据以上步骤,我们就能很容易的实现我们的编码工作,详细代码如下,供参考:

%% ImageClassifyLibsvm
% a litter test of image classification based on libsvm
% by xiaochou
% last modified 2016.01.26
%% 清空环境变量
close all;
clear;
clc;
format compact;
%% 读取图像
pic = imread(‘1.bmp’);
figure;
imshow(pic);
%% 选定训练集合测试集
TrainData_sea = zeros(100,3,’double’);
TrainData_forest = zeros(100,3,’double’);
TrainData_beach = zeros(100,3,’double’);
TrainData_earth = zeros(100,3,’double’);
TrainData_Smalltree = zeros(100,3,’double’);
TrainData_Road = zeros(100,3,’double’);
% 采样
msgbox(‘Please separate sea samples’,’sea Samples’,’help’);
pause;
[x,y] = ginput(2);
hold on;
plot(x,y,’r*’);
x = uint16(x);
y = uint16(y);
TrainData_seas = pic(y(1):y(2),x(1):x(2),1:3);
[X,Y,P] = size(TrainData_seas);
run = 1;
for i = 1:X
for j = 1:Y
TrainData_sea(run,1) = TrainData_seas(i,j,1);
TrainData_sea(run,2) = TrainData_seas(i,j,2);
TrainData_sea(run,3) = TrainData_seas(i,j,3);
run = run+1;
end
end
randindex = randperm(X*Y);% 这个是1到X*Y的随机组合
TrainData_sea = TrainData_sea(randindex(1:100),:);

msgbox(‘Please separate forest samples’,’forest Samples’,’help’);
pause;
[x,y] = ginput(2);
hold on;
plot(x,y,’bo’)
x = uint16(x);
y = uint16(y);
TrainData_forests = pic(y(1):y(2),x(1):x(2),1:3);
[X,Y,P] = size(TrainData_forests);
run = 1;
for i = 1:X
for j = 1:Y
TrainData_forest(run,1) = TrainData_forests(i,j,1);
TrainData_forest(run,2) = TrainData_forests(i,j,2);
TrainData_forest(run,3) = TrainData_forests(i,j,3);
run = run+1;
end
end
randindex = randperm(X*Y);% 这个是1到X*Y的随机组合
TrainData_forest = TrainData_forest(randindex(1:100),:);

msgbox(‘Please separate beach samples’,’beach Samples’,’help’);
pause;
[x,y] = ginput(2);
hold on;
plot(x,y,’g.’)
x = uint16(x);
y = uint16(y);
TrainData_beachs = pic(y(1):y(2),x(1):x(2),1:3);
[X,Y,P] = size(TrainData_beachs);
run = 1;
for i = 1:X
for j = 1:Y
TrainData_beach(run,1) = TrainData_beachs(i,j,1);
TrainData_beach(run,2) = TrainData_beachs(i,j,2);
TrainData_beach(run,3) = TrainData_beachs(i,j,3);
run = run+1;
end
end
randindex = randperm(X*Y);% 这个是1到X*Y的随机组合
TrainData_beach = TrainData_beach(randindex(1:100),:);

msgbox(‘Please separate earth samples’,’earth Samples’,’help’);
pause;
[x,y] = ginput(2);
hold on;
plot(x,y,’b*’)
x = uint16(x);
y = uint16(y);
TrainData_earths = pic(y(1):y(2),x(1):x(2),1:3);
[X,Y,P] = size(TrainData_earths);
run = 1;
for i = 1:X
for j = 1:Y
TrainData_earth(run,1) = TrainData_earths(i,j,1);
TrainData_earth(run,2) = TrainData_earths(i,j,2);
TrainData_earth(run,3) = TrainData_earths(i,j,3);
run = run+1;
end
end
randindex = randperm(X*Y);% 这个是1到X*Y的随机组合
TrainData_earth = TrainData_earth(randindex(1:100),:);

msgbox(‘Please separate Smalltrees samples’,’Smalltrees Samples’,’help’);
pause;
[x,y] = ginput(2);
hold on;
plot(x,y,’r*’)
x = uint16(x);
y = uint16(y);
TrainData_Smalltrees = pic(y(1):y(2),x(1):x(2),1:3);
[X,Y,P] = size(TrainData_Smalltrees);
run = 1;
for i = 1:X
for j = 1:Y
TrainData_Smalltree(run,1) = TrainData_Smalltrees(i,j,1);
TrainData_Smalltree(run,2) = TrainData_Smalltrees(i,j,2);
TrainData_Smalltree(run,3) = TrainData_Smalltrees(i,j,3);
run = run+1;
end
end
randindex = randperm(X*Y);% 这个是1到X*Y的随机组合
TrainData_Smalltree = TrainData_Smalltree(randindex(1:100),:);

msgbox(‘Please separate Roads samples’,’Roads Samples’,’help’);
pause;
[x,y] = ginput(2);
hold on;
plot(x,y,’r*’)
x = uint16(x);
y = uint16(y);
TrainData_Roads = pic(y(1):y(2),x(1):x(2),1:3);
[X,Y,P] = size(TrainData_Roads);
run = 1;
for i = 1:X
for j = 1:Y
TrainData_Road(run,1) = TrainData_Roads(i,j,1);
TrainData_Road(run,2) = TrainData_Roads(i,j,2);
TrainData_Road(run,3) = TrainData_Roads(i,j,3);
run = run+1;
end
end
randindex = randperm(X*Y);% 这个是1到X*Y的随机组合
TrainData_Road = TrainData_Road(randindex(1:100),:);

% 确定训练集和训练标签
pic1(1:100,1) = 1;
pic2(1:100,1) = 2;
pic3(1:100,1) = 3;
pic4(1:100,1) = 4;
pic5(1:100,1) = 5;
pic6(1:100,1) = 6;
Train_label = [pic1;pic2;pic3;pic4;pic5;pic6];
Train_data = http://www.mamicode.com/[TrainData_sea;TrainData_forest;TrainData_beach;TrainData_earth;TrainData_Smalltree;TrainData_Road];
% 确定测试集和测试标签
[X,Y,P] = size(pic);
TestData = http://www.mamicode.com/zeros(X*Y,3,’double’);
k = 1;
for i = 1:X
for j = 1:Y
TestData(k,1) = pic(i,j,1);
TestData(k,2) = pic(i,j,2);
TestData(k,3) = pic(i,j,3);
k = k+1;
end
end
Test_data =http://www.mamicode.com/TestData;
Test_label = [ones(length(TestData)/6,1);2*ones(length(TestData)/6,1);3*ones(length(TestData)/6,1);4*ones(length(TestData)/6,1);5*ones(length(TestData)/6,1);6*ones(length(TestData)/6,1)];
%% 建模预测
% 利用训练集合建立分类模型
model = svmtrain(Train_label,Train_data,’-c 1 -g 0.2 b 1’);
[predict_label,accuracy,decision_values] = svmpredict(Test_label,Test_data,model);
%% 分类可视化
result=zeros(X,Y,3); % RGB彩图
for k=1:X*Y % R分量 G分量 B分量
if (predict_label(k,1)==1) Test_data(k,1)=0;Test_data(k,2)=0;Test_data(k,3)=255; % 蓝色
elseif(predict_label(k,1)==2) Test_data(k,1)=0;Test_data(k,2)=255; Test_data(k,3)=0; % 绿色
elseif(predict_label(k,1)==3) Test_data(k,1)=255;Test_data(k,2)=255; Test_data(k,3)=255; % 白色
elseif(predict_label(k,1)==4) Test_data(k,1)=0; Test_data(k,2)=0; Test_data(k,3)=0; % 黑色
elseif(predict_label(k,1)==5) Test_data(k,1)=204; Test_data(k,2)=0; Test_data(k,3)=153; % 紫色
elseif(predict_label(k,1)==5) Test_data(k,1)=255; Test_data(k,2)=255; Test_data(k,3)=0; % 紫色
end
end
k=1;
for i = 1:X
for j=1:Y
result(i,j,1)=Test_data(k,1);
result(i,j,2)=Test_data(k,2);
result(i,j,3)=Test_data(k,3);
k=k+1;
end
end
result=uint8(result);
figure;imshow(result);

3. 说说图像分类的处理结果
运行程序后,我们首先要进行点的选取,通过选择不同的区域,组成样本集,进行训练,选取如下:
技术分享
选取样本集后,我们将这些块组成训练样本,丢进SVM里面进行训练,最后对图像进行测试分类预测,得到的分类结果图如下:
技术分享
从实验结果中分析可知,这里将遥感图中的6类事物用不同的颜色进行表征,其中蓝色代表海洋,黑色代表土地,黄色代表小路,白色代表海滩,绿色代表森林,紫色代表灌木丛,我们可以看到,图像中选取的样本集不同,分类器参数不同,对于事物分类有很大的影响。该程序可以正确的完成分类任务。得出结论:在一定条件下,Libsvm分类能够很好的对图像实现分类。


最后稍微写个小总结和几句题外话,这里主要是深入研究了对图像事物提取特征的方法,并利用Libsvm完成了对图像中不同事物的分类。分类其实相对而言并不难,难就在于入门,接触一项新东西,我们往往会不知道从何处着手,这才是最可怕的地方,前面就已经说过,Libsvm方面的资料虽然多,但在图像分类这一块上,可参考的资料寥寥无几,博主也是在相关文本分类的参考下写完这些代码的,写完之后有过反复修改,查出了不少缺陷,如今虽说尚可但其中还有很多不足之处,希望大家能够一起多多交流,指正,最后,感谢大家的拜读。

结束语:宝剑锋从磨砺出,梅花香自苦寒来。
最后补充一下,本文为作者原创,转载请注明出处,最近才发现博客的图片功能恢复正常,所以在今天把实验数据图片补充完整了!
补充于11.6号下午,小仇哥

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    基于Libsvm的图像分类