如何训练libsvm格式的图像(像素)数据用于Java识别

我想让一个Java应用程序通过使用libsvm来识别字符,但是当进入这个时,我不明白如何训练图像数据与libsvm一起使用?

最近要学习它,我用现有数据进行了测试:

我还通过将每个像素转换为0来创建基于32x32的训练图像数据,但我不知道它是否可以用于创建libsvm训练数据格式? 还有libsvm测试数据是如何创建的?

转换图像像素(0,1)示例:

 00000000000001111000000000000000 00000000000011111110000000000000 00000000001111111111000000000000 00000001111111111111100000000000 00000001111111011111100000000000 00000011111110000011110000000000 00000011111110000000111000000000 00000011111110000000111100000000 00000011111110000000011100000000 00000011111110000000011100000000 00000011111100000000011110000000 00000011111100000000001110000000 00000011111100000000001110000000 00000001111110000000000111000000 00000001111110000000000111000000 00000001111110000000000111000000 00000001111110000000000111000000 00000011111110000000001111000000 00000011110110000000001111000000 00000011110000000000011110000000 00000001111000000000001111000000 00000001111000000000011111000000 00000001111000000000111110000000 00000001111000000001111100000000 00000000111000000111111000000000 00000000111100011111110000000000 00000000111111111111110000000000 00000000011111111111110000000000 00000000011111111111100000000000 00000000001111111110000000000000 00000000000111110000000000000000 00000000000011000000000000000000 0 00000000000001111111110000000000 00000000001111111111111000000000 00000000011111111111111100000000 00000000011111111111111100000000 00000000011111111111111110000000 00000001111111111111111100000000 00000000111110000011111100000000 00000000000000000001111100000000 00000000000000000001111100000000 00000000000000000001111100000000 00000000000000000011111000000000 00000000000000000111111000000000 00000000000000000111111000000000 00000000000000000111111000000000 00000000000000001111110000000000 00000000011111111111111111000000 00000000111111111111111111100000 00000000111111111111111111100000 00000000111111111111111111100000 00000001111111111111111110000000 00000001111111111110000000000000 00000001111111111110000000000000 00000000111111111110000000000000 00000000000011111000000000000000 00000000000011111000000000000000 00000000000011111000000000000000 00000000000111111000000000000000 00000000000111111000000000000000 00000000001111110000000000000000 00000000011111110000000000000000 00000000001111100000000000000000 00000000001111100000000000000000 7 

如何获取libsvm (training, testing data)

libsvm有一个特定的数据格式,每一行都是一个训练/测试向量的forms

LABEL INDEX0:VALUE0 INDEX1:VALUE1 … INDEXN:VALUEN

因此,在最“天真”的方法中,您只需通过连接连续的行将矩阵表示转换为行表示,因此图像就像

 010 011 000 

会成为

 010011000 

并以libsvm格式(假设我们用“5”标记):

 5 0:0 1:1 2:0 3:0 4:1 5:1 6:0 7:0 8:0 9:0 

由于libsvm支持“稀疏”表示,您可以使用“0”来省略值

 5 1:1 4:1 5:1 

这是一种手动方式,样本数据位于: http : //www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/binary/a1a

最简单的“自动”方式是将您的数据表示为.csv格式(再次 – 将数据转换为行状格式,然后转换为.csv),这是非常标准的方法:

LABEL,PIXEL_0,PIXEL_1,…,PIXEL_N

然后使用此程序进行转换

 /* convert cvs data to libsvm/svm-light format */ #include  #include  #include  char buf[10000000]; float feature[100000]; int main(int argc, char **argv) { FILE *fp; if(argc!=2) { fprintf(stderr,"Usage %s filename\n",argv[0]); } if((fp=fopen(argv[1],"r"))==NULL) { fprintf(stderr,"Can't open input file %s\n",argv[1]); } while(fscanf(fp,"%[^\n]\n",buf)==1) { int i=0,j; char *p=strtok(buf,","); feature[i++]=atof(p); while((p=strtok(NULL,","))) feature[i++]=atof(p); // --i; /* if ((int) feature[i]==1) printf("-1 "); else printf("+1 "); */ // printf("%f ", feature[1]); printf("%d ", (int) feature[0]); for(j=1;j 

训练和测试文件都具有完全相同的结构,只需将您的数据以一定比例(3:1或9:1)随机分成文件trainingtesting ,但请记住为每个文件中的每个类包含平衡数量的训练向量。

特别是 - 您的数据看起来有点像MNIST数据集,如果是这种情况,这已经为libsvm准备了:

http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass.html

MNIST培训: http : //www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/mnist.scale.bz2

MNIST测试: http : //www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/mnist.scale.t.bz2

如果可以使用您的数据,将图像转换为[0,1]区间中的实值图像将比二进制数据(丢失大量信息)更有价值。

编辑

例如,如果您的图像是8位灰度图像,那么每个像素实际上是0到255之间的数字v 。您现在正在做的是一些阈值处理,为v > T设置1,为v <= T设置0 ,将这些值映射到实际值会为模型提供更多信息。 它可以通过简单压缩v / 255来完成。 结果,所有值都在[0,1]区间内,但也有“介于两者之间”的值,如0.25等。