caffe对图片提取特征

浏览: 2398

一、生成lmdb格式文件

实际经常碰到图片大小不一致,如何从原始图片文件转换成caffe中能够运行的db(leveldb/lmdb)文件?

1. 创建图片列表清单,包含类标签,存为txt

如图片目录 example/pic/

创建create_filelist.sh脚本文件,调用linux命令来生成图片清单file_list.txt:

$ sudo vi examples/create_filelist.sh

内容如下:

mkdir examples/_temp
find `pwd`/examples/pic -type f -exec echo {} \; > examples/_temp/temp.txt
sed "s/$/ 0/" examples/_temp/temp.txt > examples/_temp/file_list.txt

然后执行:

$ sudo sh examples/create_filelist.sh


2. 生成lmdb格式文件

命令:

 convert_imageset [FLAGS] ROOTFOLDER/ LISTFILE DB_NAME

使用 build/tools/下的convert_imageset可执行文件,命令行读取图片文件列表,设置打乱次序与否,resize大小与否等参数,生成lmdb格式文件。

sudo vi examples/create_lmdb.sh

内容如下:

#!/usr/bin/en sh
DATA=examples/_temp
rm
-rf $DATA/img_train_lmdb
rm -rf $DATA/features/
build
/tools/convert_imageset --shuffle \
--resize_height=256 --resize_width=256 \
/ $DATA/file_list.txt $DATA/img_train_lmdb

然后执行:

$ sudo sh examples/create_lmdb.sh

生成_temp/img_train_lmdb/下的文件,即为所需lmdb文件。

碰到Premature end of JPEG file错误,可能是jpg文件不正常

二、取所有图片的均值

一般地,图片减去均值后再进行训练和测试,会提高速度和精度。

二进制格式的均值计算:

caffe中使用格式binaryproto,并提供了compute_image_mean.cpp计算均值,放在tools目录下。编译后可执行文件在 build/tools/ 下,可直接调用

sudo build/tools/compute_image_mean examples/_temp/img_train_lmdb data/mb/mb_mean.binaryproto

其中参数,

examples/mnist/mnist_train_lmdb, 格式为lmdb的训练数据,用来计算均值。自己的数据可自行生成lmdb格式文件,并放置相应目录

data/mb/mean.binaryproto, 计算结果

三、提取特征

sudo cp examples/feature_extraction/imagenet_val.prototxt examples/_temp/mb_val.prototxt

修改mb_val.prototxt中mean文件的定义,

sudo vi examples/_temp/mb_val.prototxt

第10行改为:

mean_file: "data/mb/mb_mean.binaryproto"

提取特征前,需下载bvlc_reference_caffenet和几个包,并保证当前用户可以修改/cnn目录sudo chmod -R 777 /cnn

pip install pyyaml
pip install six
scripts/download_model_binary.py models/bvlc_reference_caffenet


提取特征:

./build/tools/extract_features.bin models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel examples/_temp/mb_val.prototxt fc7 examples/_temp/features 10 lmdb

得到的features存在examples/_temp/features。

如果出现错误“Check failed: status.ok() Failed to open leveldb examples/_temp/features”,是上次运行已经生成了目录,用如下命令删除掉:

rm -rf examples/_temp/features/

四、总结

1. 自有图片放在目录 example/pic/

2. create_filelist.sh脚本文件生成图片清单file_list.txt

3. convert_imageset根据file_list.txt,生成图片库img_train_lmdb

4. 用compute_image_mean,对img_train_lmdb取均值,得到mean.binaryproto

5. 修改已有的imagenet_val.prototxt,相应的lmdb,mean,用extract_features.bin提取features


sudo sh examples/create_filelist.sh
sudo sh examples/create_lmdb.sh 
sudo build/tools/compute_image_mean examples/_temp/img_train_lmdb data/mb/mb_mean.binaryproto 
time ./build/tools/extract_features.bin models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel examples/_temp/mb_val.prototxt fc7 examples/_temp/features 666 lmdb GPU --GPU要大写
python lwrite.py


lwrite.py --------------------------

import lmdb
import feat_helper_pb2
import numpy as np
import struct
lmdb_name = './examples/_temp/features'
batch_num = 32256
batch_size = 1
window_num = batch_num*batch_size
dim = 4096
# how many files
count = -1
for index, line in enumerate(open('./examples/_temp/file_list.txt','r')):
   count += 1
# get name of asins from file_list
asin_float = np.zeros((count+1,1))
num = 0
with open('./examples/_temp/file_list.txt') as f:
   for line in f:
      asin_float[num] = line[24:24+8]
      num += 1
# get features from lmdb
f = open('./image_features_mb.b', 'wb')
if 'db' not in locals().keys():
   db = lmdb.open(lmdb_name)
   txn= db.begin()
   cursor = txn.cursor()
   cursor.iternext()
   datum = feat_helper_pb2.Datum()
   keys = []
   values = []
   for key, value in enumerate( cursor.iternext_nodup()):
      keys.append(key)
      values.append(cursor.value())
# transform asins from float to binary
# transform features from google.protobuf to numpy.ndarray to binary
# link asin and featue to af
feat = np.zeros((1,dim))
for im_idx in range(window_num):
   datum.ParseFromString(values[im_idx])
   asin = str(int(asin_float[im_idx]))
   feat[0, 0:dim] = datum.float_data
   features = struct.pack('=%sf' % feat.size, *feat.flatten('F'))
   af = asin+features
   f.write(af)
   if (im_idx == 0 or (im_idx % 1) == 0):
      print im_idx, ': ', asin
f.close()
推荐 1
本文由 safa 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

1 个评论

这个系列不错,多分享。

要回复文章请先登录注册