caffe:Linux C++提取图片特征

网络上很多基于python的提取图片特征的程序,相对来说使用C++的比较少,本文主要介绍基于Linux C++环境下的对图片特征的提取。

首先,需要将第一层更改为MemoryData类型,具体如下:

layer {
name: “data”
type: “MemoryData”
top: “data”
top: “label”

transform_param {
scale: 0.00390625
mean_file: “cnbc/cnbc.train.mean.binaryproto”
}

memory_data_param{
batch_size:1
channels:3
height:250
width:250
}
}
layer {
bottom: “data”
top: “conv1_1”

将训练用的网络的最后面的分类及loss层删除,更改成如下:
tail -20 vgg_deploy.prototxt
type: “Dropout”
dropout_param {
dropout_ratio: 0.5
}
}
layer {
bottom: “fc7”
top: “fc8”
name: “fc8”
type: “InnerProduct”
inner_product_param {
num_output: 53
}
}
layer {
name: “prob”
type: “Softmax”
bottom: “fc8”
top: “prob”
}

Linux C++代码如下:
hpp文件:
/***** we have to define USE_OPENCV before include opencv.hpp,
or else, we can not use the function AddMatVector *****/

#ifndef USE_OPENCV
#define USE_OPENCV
#endif

#include “caffe/caffe.hpp”
#include “caffe/common.hpp”
#include “opencv2/opencv.hpp”

#include “caffe/layers/memory_data_layer.hpp”
//#include “boost/shared_ptr.hpp”
//#include “opencv2/imgproc/imgproc.hpp”
#include
#include <opencv/highgui.h>
//#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;
using namespace caffe;
using namespace boost;

void copy(const float* data_src, Mat& img_dst)
{
for (int i=0; i<img_dst.rows; i++)
for (int j=0; j<img_dst.cols; j++)
img_dst.at(i, j) = (data_src + iimg_dst.rows + j);
}

void copy(const Mat& img_src, float* data_dst)
{
for (int i=0; i < img_src.rows; i++)
for (int j=0; j < img_src.cols; j++)
(data_dst + iimg_src.rows + j) = img_src.at(i, j);
}

void copy(const uchar* data_src, Mat& img_dst)
{
for (int i=0; i<img_dst.rows; i++)
for (int j=0; j<img_dst.cols; j++)
img_dst.at(i, j) = (data_src + iimg_dst.rows + j);
}
void copy(const Mat& img_src, uchar* data_dst)
{
for (int i=0; i < img_src.rows; i++)
for (int j=0; j < img_src.cols; j++)
(data_dst + iimg_src.rows + j) = img_src.at(i, j);
}

double CosineSimilarity(Mat mVec1, Mat mVec2)
{
return (mVec1.dot(mVec2)) / (sqrt(mVec1.dot(mVec1))*sqrt(mVec2.dot(mVec2)));
}

SRC文件如下:
#include “My.hpp”

#define NetF float
#define DWORD unsigned long //DWORD is used in Windows, we should use unsigned long or double here
int main(int argc, char* argv[])
{
Mat f1(1, 1024, CV_32F);
Mat f2(1, 1024, CV_32F);
Mat f3(1, 1024, CV_32F);

    if( argc != 5)
    {
            cout << "Parameter error" << endl;
            cout << "should like: atr deployNet caffeModel labeCount imageName" << endl;
            return -1;
    }

    //string basePath("/home/bruce/local_install/caffe/examples/");
    string basePath("");
    string deployNet = basePath + argv[1];
    string caffeModel = basePath + argv[2];

    Caffe::set_mode(Caffe::CPU);
    caffe::Net<float>* net(new caffe::Net<float>(deployNet.c_str(), caffe::TEST));
    net->CopyTrainedLayersFrom(caffeModel.c_str());


    vector<int> labels;
    for(int n = 0; n < atoi(argv[3]); n++)
    {
            labels.push_back(n);
    }
    vector<Mat> batches1;
    vector<Mat> batches2;
    vector<Mat> batches3;

    Mat src1, src2, src3;

    string imageName = basePath + argv[4];
    src1 = cv::imread(imageName.c_str(), IMREAD_COLOR);
    cv::resize(src1, src1, cv::Size(250,250));
    batches1.push_back(src1);
    MemoryDataLayer<float>* memory_data_layer;
    memory_data_layer = (MemoryDataLayer<float>*)net->layers()[0].get();

    cout << "attach to net done" << endl;

    boost::shared_ptr<caffe::Blob<float> > fc7 = net->blob_by_name("fc7");
    const float* fc7data = NULL;
    fc7data = fc7->cpu_data();

    cout << "get fc7 cpu data" << endl;

    boost::shared_ptr<caffe::Blob<float> > prob = net->blob_by_name("prob");
    const float* probdata = NULL;
    probdata = prob->cpu_data();

    cout << "get prob layer cpu data" << endl;

    DWORD start = getTickCount();

    memory_data_layer->AddMatVector(batches1, labels);
    net->Forward();
    cout << "batches1 forward done" << endl;

    DWORD end = getTickCount();
    cout << "time length for forward: " << end - start << endl;

    copy(fc7data, f1);
    
    for (int X=0; X<atoi(argv[3]); X++)
            cout << "label " << X << ": " << probdata[X] << endl;

return 0;
}

编译就比较简单了,用g++编,缺少什么库就直接加路径,根据不同的安装目录进行修改,以下可供参考(直接使用命令行,如果用makefile也是差不多的,懒的去写…):
[bruce@Atrinet caffe]$ cat make.sh
#export ROOT_PATH=/home/bruce/local_install
#g++ -o app blob_demo.cpp -I /usr/local/include/ -I $ROOT_PATH/include/ -I $ROOT_PATH/caffe/include -I $ROOT_PATH/blas/include -I $ROOT_PATH/include/google/protobuf/ -D CPU_ONLY -I ./.build_release/src/ -L ./build/lib/ -L $ROOT_PATH/lib/ -lcaffe -lglog -lprotobuf -lboost_system

g++ -o atr atrinet.cpp -I /usr/local/include/ -I $ROOT_PATH/include/ -I $ROOT_PATH/caffe/include -I $ROOT_PATH/blas/include -I $ROOT_PATH/include/google/protobuf/ -D CPU_ONLY -I ./.build_release/src/ -L ./build/lib/ -L $ROOT_PATH/lib/ -lcaffe -lglog -lprotobuf -lboost_system -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lstdc++ -lopencv_core

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值