Caffe图片特征提取(Python/C++)
1.Caffe特征提取(C++实现)
Caffe框架提供了相应的Tools(build/tools/extract_features.bin)工具extract features,官方教程,使用方法如下:
extract_features.bin xxx.caffemodel xxxx.prototxt layer-name output-path mini-batches db-style
xxx.caffemodel:已训练好的模型参数
xxxx.prototxt :模型定义(包括要提取的图片的路径,mean-file等)
layer_name:要提取的特征的名字(eg. fc6 fc7),中间以空格隔开
output-path:提取的feature保存路径
mini-batches: 每次batch_size的大小
db_-style: feature保存的格式(leveldb/lmdb)
详细内容请参考官方教程,写的很详细。
- 优点:简单,直接可用
- 不足:灵活性不高,需要自己写代码解析相应的feature
2.Caffe特征提取(Python实现)
本文参考了Caffe官方教程feature visualization 的部分代码,利用Python实现了,计算图片均值(mean-file),特征提取及保存,具体过程如下。
1)计算输入图片的均值保存为npy格式。
#**input**
#work_path:working path containing the input file
#list_name:every line containing ‘image_path label‘
#save_name:where to save the mean file
#image_size: the mean_file‘s size
#channel: the mean_file‘s channnel
#**output**
#mean_file value(3*227*227)
def compute_image_mean(work_path,list_name = ‘train.txt‘, save_name = ‘227_227_mean.npy‘, image_size = (227,227), channnel = 3):
mean = np.zeros((channnel,) + image_size, dtype=np.float64)
list = os.path.join(work_path,list_name)
with open(list, ‘r‘) as f:
lines = f.readlines()
sample_size = len(lines)
count = 0
for i, line in enumerate(lines):
if(count%1000 == 0):
print (‘Finish:%d\r\n‘%count)
image_name, label = line[:-1].split()
img = cv2.imread(image_name).astype(np.float32)
res = cv2.resize(img, image_size)
res = res.transpose(2, 0, 1)
mean += res
count += 1
mean = mean / sample_size
save_file = os.path.join(work_path,save_name)
np.save(save_file, mean)
return mean
2)通过前向传播提取Feature,并保存为npy格式
#**input**
#net:Caffe net
#mean_file:image mean file(c*h*w)
#input_file:input image file(image_path label)
#output_prefix_file(output_path),every image has a output_path
#layer_name:eg. ‘fc6 fc7‘
def computer_features(net,mean_file,input_file,output_prefix_file,
layer_names = ‘fc6 fc7‘):
# load the mean image for subtraction
mu = np.load(mean_file)
# create transformer for the input called ‘data‘
transformer = caffe.io.Transformer({‘data‘: net.blobs[‘data‘].data.shape})
transformer.set_transpose(‘data‘, (2, 0, 1)) # move image channels to outermost dimension
transformer.set_mean(‘data‘, mu) # subtract the dataset-mean value in each channel
transformer.set_raw_scale(‘data‘, 255) # rescale from [0, 1] to [0, 255]
transformer.set_channel_swap(‘data‘, (2, 1, 0)) # swap channels from RGB to BGR
# set the size of the input (we can skip this if we‘re happy
# with the default; we can also change it later, e.g., for different batch sizes)
net.blobs[‘data‘].reshape(batch_size, # batch size
3, # 3-channel (BGR) images
227, 227) # image size is 227x227
features = layer_names.split()
inputlines = []
outputlines = []
with open(input_file, ‘r‘) as f:
for line in f:
inputlines.append(line)
with open(output_prefix_file, ‘r‘) as f:
for line in f:
outputlines.append(line)
assert len(inputlines) == len(outputlines)
i = 0
for input,output in zip(inputlines,outputlines):
input = input.strip(‘\n\t‘)
output = output.strip(‘\n\t‘)
image_path,label = input.split()
# print image_path
input_image = caffe.io.load_image(image_path)
transformed_image = transformer.preprocess(‘data‘, input_image)
net.blobs[‘data‘].data[...] = transformed_image
net.forward()
if not os.path.isdir(output):
os.makedirs(output)
for feature in features:
output_file = os.path.join(output,feature+‘.npy‘)
np.save(output_file, net.blobs[feature].data[0])
if (i%1000 == 0):
print (‘Finish:%d\r\n‘ % i)
i += 1
model_def = ‘models/bvlc_reference_caffenet/deploy.prototxt‘
model_weights = ‘models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel‘
net = caffe.Net(model_def, # defines the structure of the model
model_weights, # contains the trained weights
caffe.TEST) # use test mode (e.g., don‘t perform dropout)
mean_file = args.root + args.mean
input_file = args.root + args.inputs
output_file = args.root + args.outputs
caffe.set_mode_cpu()
computer_features(net,mean_file,input_file,output_file)
以上代码每次只处理1张图片,如果数据量较大,会比较慢,建议采用批量的模式来计算,发挥GPU的优势,改动也比较简单,如果需要Batch-size版的,可私下交流。
利用python提取caffe特征最关键的就是:net.blobs[‘fc6’].data,将次参数提取并保存即可
时间: 2024-10-28 11:12:38