基于libsvm的图像分割
——30cases与40cases&25cases“联谊”第一弹
By faruto
2010/6/2
很早就想用libsvm来做图像相关的一些东西,因为libsvm我自认为还算熟悉,图像基本的一些东西也都零散的学过,但用libsvm来做图像相关的,还未曾“染指”。正好rocwoods的25cases有这个相关的,所以详细研究学习了一下~
“联谊”案例:30cases第12、13章(libsvm分类相关),25cases案例18——9.3.4(用matlab自带的svm实现图像分割),40cases案例37——A.2.2(用kmeans实现图像分割)
现用libsvm来实现图像分割,测试图片用的亦是25cases和40cases中的那个littleduck测试图片。主体程序思想为25cases中的代码过程,改进之处为可以让用户利用ginput来提取背景的样本点和前景(待分割出来的目标)的样本点作为训练样本,而不需实现指定背景和前景的样本点,也不用额外的小软件来查看某点的RGB值,ginput即可。O(∩_∩)O~
测试代码:
[code]
%% ImSegmentLibsvm
% a litter test of image segment based on libsvm
% by faruto
% Email:patrick.lee@foxmail.com
% QQ:516667408
% http://blog.sina.com.cn/faruto
% last modified 2010.06.01
% Super Moderator @ www.ilovematlab.cn
%%
tic;
close all;
% clear;
clc;
format compact;
%%
pic = imread('littleduck.jpg');
figure;
imshow(pic);
%% 确定训练集
TrainData_background = zeros(10,3,'double');
TrainData_foreground = zeros(10,3,'double');
% 背景采样
msgbox('Please get 20 background samples','Background Samples','help');
pause;
for run = 1:20
[x,y] = ginput(1);
hold on;
plot(x,y,'r*');
x = uint8(x);
y = uint8(y);
TrainData_background(run,1) = pic(x,y,1);
TrainData_background(run,2) = pic(x,y,2);
TrainData_background(run,3) = pic(x,y,3);
end
% 待分割出来的前景采样
msgbox('Please get 20 foreground samples which is the part to be segmented', 'Foreground Samples','help');
pause;
for run = 1:20
[x,y] = ginput(1);
hold on;
plot(x,y,'ro');
x = uint8(x);
y = uint8(y);
TrainData_foreground(run,1) = pic(x,y,1);
TrainData_foreground(run,2) = pic(x,y,2);
TrainData_foreground(run,3) = pic(x,y,3);
end
% % 背景训练样本 10*3
% TrainData_background = ...
% [52 74 87;
% 76 117 150;
% 19 48 62;
% 35 64 82;
% 46 58 36;
% 50 57 23;
% 110 127 135;
% 156 173 189;
% 246 242 232;
% 166 174 151];
% % 前景训练样本 8*3
% TrainData_foreground = ...
% [211 192 107;
% 202 193 164;
% 32 25 0;
% 213 201 151;
% 115 75 16;
% 101 70 0;
% 169 131 22;
% 150 133 87];
% let background be 0 & foreground 1
TrainLabel = [zeros(length(TrainData_background),1); ...
ones(length(TrainData_foreground),1)];
%% 建立支持向量机 基于libsvm
TrainData = [TrainData_background;TrainData_foreground];
model = svmtrain(TrainLabel, TrainData, '-t 1 -d 1');
%% 进行预测 i.e.进行图像分割 基于libsvm
preTrainLabel = svmpredict(TrainLabel, TrainData, model);
[m,n,k] = size(pic);
TestData = double(reshape(pic,m*n,k));
TestLabal = svmpredict(zeros(length(TestData),1), TestData, model);
%%
ind = reshape([TestLabal,TestLabal,TestLabal],m,n,k);
ind = logical(ind);
pic_seg = pic;
pic_seg(~ind) = 0;
figure;
imshow(pic_seg);
figure;
subplot(1,2,1);
imshow(pic);
subplot(1,2,2);
imshow(pic_seg);
%%
toc;
[/code]
测试图片结果:
![基于libsvm的图像分割 基于libsvm的图像分割](http://s11.sinaimg.cn/middle/4cf8aad348807b1927cba&690)
![基于libsvm的图像分割 基于libsvm的图像分割](http://s3.sinaimg.cn/middle/4cf8aad348807b19a0642&690)
![基于libsvm的图像分割 基于libsvm的图像分割](http://s15.sinaimg.cn/middle/4cf8aad348807b19c509e&690)