im2rec的使用及那些坑


#1

学完目标检测之后一直想要用自己的数据跑一下模型看看,结果被im2rec坑了好久,看了网上的一些帖子,又回头看了一下源码,终于算是搞懂了。在这里写一下自己遇到的那些坑=-=

im2rec.py可以实现两种功能,一是制作相应的lst,而是制作rec文件。
不管对于图片分类还是目标识别问题,均可以通过lst(通过ImageDetIter()中的path_imglist读取)和rec(通过ImageDetIter()中的path_reclist和path_idxlist读取)读取文件。

1.使用im2rec制作lst文件
调用make_list()方法获得的,其中涉及四个参数:
recursive:是否递归访问子目录,如果存在多个目录可以设置该参数
list::脚本默认为False,所以制作lst时应设置为True
prefix:需要生成的lst文件的前缀
root:指定数据集的根目录,其子目录为图片或进一步的子目录

示例: python im2rec.py --recursive=True --list=True test data/images

坑: 不管是相对路径还是绝对路径,路径的格式错误后都会导致生成的lst文件为空。

2.使用im2rec制作rec文件
此时一般需要将–list设置为False(此时使用已经创建好的list进行rec制作),使用已经生成的lst文件生成rec文件。

涉及参数:
–list 是否创建list文件,默认为False
–exts 所能接受的图片后缀,默认为jpg和jpeg
–chunks 分块数量,默认为1
–train-ratio 训练集所占的比例,默认为1.0
–test-ratio 测试集所占的比例,默认为0
–recursive 是否递归的对root下的文件夹进行遍历
–shuffle 是否打乱list中的图片顺序,默认为True
–pass-through 是否跳过transform,默认为False
–resize 是否将短边缩放至设定尺寸,默认为0
–center-crop 是否进行中心剪裁,默认为False
–quality 图片解码质量(0-100),默认为95
–num-thread 编码的线程数,默认为1
–color 色彩解码模式[-1,0,1],-1为彩色模式,0为灰度模式,1为alpha模式,默认为1
–encoding 解码模式(jpeg,png),默认为jpeg
–pack-label 是否读入多维度标签数据,默认为False (重要,如果进行多标签数据制作或者目标检测的数据制作,那么就必须将其设置为True)

示例: python im2rec.py --recursive=True --pack-label=True test data/images

坑: 一开始的时候以为要在前头加入lst文件的名称,即写成了python im2rec.py test.lst --recursive=True --pack-label=True test data/images
结果程序就报错提示unrecognized arguments

坑: 更正上述错误后,再次尝试,生成了rec文件,但是报错:lst should at least has three parts, but only has 1 parts for [’’]
回头去看了一下自己的lst文件和im2rec的代码,发现生成的lst文件在尾部多了一个空白行,所以最后报错,去除后报错消失。

附录:目标识别相关lst的格式说明
0 4 5 640 480
1 0.1 0.2 0.8 0.9
2 0.5 0.3 0.6 0.8
data/xxx.jpg
(以上为一行中的数据,数据间使用 /t 分割)
index A B [extra header]
(object0),
(object1) …
image_path

index:图片序号
A:头字段宽度(minimum2,大小为2+extra header的宽度
extra header:附加字段部分,可选,多为输入图片的width&height
B:label字段的宽度,通常情况下为5(一个label+四个坐标数值)
object:标记字段,由一个label+四个坐标数值组成

折腾了大半天的教训==遇到错误不要慌,对着错误去找代码看一般都能找得到原因。


#2

另外看了下ImageDetIter()的功能说明,因为只有在训练集中需要idx文件,所以里面的数字是用来定位每张图片的开头的位置吗?
@szha


#3

@yulangwx @mli 请问如何生成自己的多目标检测数据集 这部分能不能写个demo


#4

多目标的文件和单目标的文件差别其实并不大,最重要的工作其实就是把lst文件做出来。其他的就可以对照着论坛里面的各种帖子把问题解决掉就好了。


#5

请问一下,label的宽度是不是多长都可以?


#6

@zhreshold

是这样,但需要定好最长的长度,不足的补上就行了


#7

idx文件不是必要的,但是能帮助shuffle,否则会用块shuffle,可能导致随机性不太好


#8

了解了,谢谢。


#9

@yulangwx 你好,请问对于多类别的任务,label应该怎样存放,才可以用im2rec生成lst


#10

那个我没有尝试,是自己写了个脚本生成的lst文件。


#11

@yulangwx
我按照你提供的格式自己写了个脚本生成lst,已经成功生成rec了。非常感谢分享


#12

请问一下,目标识别中 A 头字段宽度具体是指什么?


#13

就是object之外的字段信息.
如果是2,就是头字段 + 目标长度描述字段;
如果是4,就是头字段 + 目标长度描述字段 + 图片宽度字段 + 图片高度字段.


#14

哦,明白了,谢谢了!:grinning:


#15

再请教一下,我将数据写成你说的目标识别的格式了,但是我发现Im2rec.py并不能读取这样的.lst
目标识别数据集的rec具体是怎样制作的呢?


#16

报错的提示是什么呢?


#17

lst中第一张图片:

0 4 5 1280 720
0 0.399609375 0.124305555556 0.14765625 0.229166666667
/path_to_gluon/chapter_computer-vision/data/image/tortoise/000000.JPEG

报错如下:

Creating .rec file from /path_to_gluon/chapter_computer-vision/data/train.lst in /path_to_gluon/chapter_computer-vision/data
multiprocessing not available, fall back to single threaded encoding
imread read blank (None) image for file: /path_to_gluon/chapter_computer-vision/data/image/tortoise/720
Traceback (most recent call last):
File “im2rec.py”, line 316, in
record.write_idx(item[0], s)
File “path_to_anaconda2/lib/python2.7/site-packages/mxnet-1.0.0-py2.7.egg/mxnet/recordio.py”, line 285, in write_idx
self.write(buf)
File “path_to_anaconda2/lib/python2.7/site-packages/mxnet-1.0.0-py2.7.egg/mxnet/recordio.py”, line 135, in write
ctypes.c_size_t(len(buf))))
TypeError: object of type ‘NoneType’ has no len()


#18

应该是路径的问题,你试试使用绝对路径?


#19

可是,我使用的已经是绝对路径了。
我觉得问题是不是出在这里:

imread read blank (None) image for file: /path_to_gluon/chapter_computer-vision/data/image/tortoise/720

它读取的是720,他把图片高度当做图片名了,并没有读取第三行的图片路径。


#20

哦,我搞明白了。:joy:
数据之间都是‘\t’, 我以为每张图片信息分了三行。