Leafsnap实现(1)–树叶分类器

文章中第一步首先实现了树叶分类。给出一张图片,判断其是不是一张有效的树叶图片。所谓的有效指的是图片上的东西是树叶,而且背景没有条纹、没有模糊等。

具体实现方法上,文章提到:

We implement this classifier using gist features [1] computed on the image,

which are fed into a Support Vector Machine (SVM) [8] with an RBF kernel

as the classification function.

We use the libsvm [9] implementation of SVMs and the LEAR [10]

implementation of gist. The classifier was trained on 5,972 manually labeled images and takes 1.4 seconds to run per image.

一.特征提取

首先通过LEAR implementation of gist 这个工具来从图像中提取出GIST特征。 具体GIST特征可以参考下面这个博客:GIST特征描述符使用

由于GIST操作的时候必须保证图像大小相同,于是文章提到:

To ensure that the gist values are scale-invariant,we resize the input image to 300  400 (rotating it by 90 degree if it has the wrong aspect ratio)

LEAR implementation of gist的 下载页面,这个包是c实现的,需要用gcc编译。在linux和MAC平台下测试过。。。但是我是在windows平台下,所以又尝试了一下matlab实现的版本

 

二.SVM训练

文章使用的是libSVM,使用了RBF核。由于对SVM还不是很了解,故先学习了一下SVM。

下面两篇文章是OpenCV的ML的SVM教程,分别讲述了线性可分和线性不可分的情况:

线性可分

线性不可分

这篇文章在此基础上翻译得更好一点,还加入了具体数据结构的描述

此外,对于SVM的基本概念,这个链接从原理开始推导,层层深入。

 

在稍微了解了SVM的概念之后,我们就使用一下libSVM的库。这个链接可以下载libSVM。之前有看过coursera上林智仁上的机器学习基石的课,感觉好年轻已经是教授了。

我下载的版本是3.20,下载下来之后我使用的是matlab的版本,需要重新生成能够被matlab直接调用的文件。本来看jennifer的文章以为会很复杂,但是新版本多了一个make.m的文件,只需要进入该目录,然后执行这个make文件就可以生成了。期间会让你选择你的c的编译器版本,我使用了vs2010。编译好之后要测试一下,这里要注意的一个地方就是jennifer提到的,使用heart_scale这个数据集的时候有点问题。具体解决方法就看jennifer的文章好了。

测试成功之后,接下来准备一下正样本图片和负样本图片,对图片进行统一标号,可以使用下面的批处理:

1
2
3

dir /b/s/p/w *.jpg>train_list.txt
@pause

这样就会在图片目录下面自动生成图片路径文件。

接下来需要调整图片大小,全部变成400×300。使用matlab代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

clear;
close all;
%20为训练样本个数,全部变成300 ×400的大小
for i = 1 : 20
filename = sprintf('%s%d%s', 'neg (', i, ').jpg');%这里是获得文件名
img = imread(filename);
[width, length, depth] = size(img); %600 * 800
img_rotate = img;
if width > length %需要旋转
img_rotate = imrotate(img, 90);
end
img_resize = imresize(img_rotate, [300, 400]);
imwrite(img_resize, filename);
end

如果需要翻转,先翻转90度,然后统一resize。

图片都resize了之后,使用SVM训练。

首先获取Gist特征,调用了LEAR with Gist implementation的库,链接中有具体例子。

然后使用libSVM来做训练。关键代码其实只有两行:

训练模型:

model = svmtrain(label, GistFeatures, ‘-s 0 -t 2 -c 1.2 -g 2.8′);

这里label是训练样本的标记,GistFeatures是训练样本特征,第三个参数是SVM参数。

训练完模型之后使用 预测函数 测试一下模型:

[predictlabel,accuracy, c_v] = svmpredict(testdatalabel,double(testdata),model);

第一个参数是测试样本的实际分类,第二个参数是测试样本的特征,第三个参数是刚才训练好的模型。

论文中训练了6000个样本,而且SVM的参数还有待优化。