Caffe图片特征提取(Python/C++)

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,将次参数提取并保存即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值