caffe 提取特徵C++介面__C++

來源:互聯網
上載者:User

一、前言

     以下為使用caffe的C++介面提取某層的特徵向量,作下記錄,一下兩種方式耗時基本相同。

二、方式一

//CaffeExFeat.h#ifndef CAFFEEXFEAT_H #define CAFFEEXFEAT_H#include "caffe/caffe.hpp"#include <string>#include <vector>#include "opencv2/opencv.hpp"using namespace caffe;class CaffeExFeat{public: explicit CaffeExFeat(std::string proto,std::string model,char* nameLayer,std::string meanFile,float scale=-1); explicit CaffeExFeat(std::string proto,std::string model,char* nameLayer,float v1=0.0,float v2=0.0,float v3=0.0,float scale=-1); ~CaffeExFeat();double*extractFeat(const cv::Mat& img);double calSimilarity(const cv::Mat& img1 ,const cv::Mat& img2);private:unsigned int blob_id_;boost::shared_ptr< Net<float> > net_;cv::Size input_geometry_;int num_channels_;cv::Mat mean_;Blob<float>* input_blobs_;unsigned int featNum_;float scale_;void init(std::string proto,std::string model,float scale);    void getMeanData(std::string mean_file);    void getMeanData(float v1,float v2,float v3 );unsigned int get_blob_index( char *query_blob_name);void wrapInputLayer(std::vector<cv::Mat>* input_channels);void preprocess(const cv::Mat& img,std::vector<cv::Mat>* input_channels);};#endif
//CaffeExFeat.cpp#include "CaffeExFeat.h"CaffeExFeat::CaffeExFeat(std::string proto,std::string model, char* nLayer,std::string meanFile,float scale){init(proto,model,scale);getMeanData(meanFile);    blob_id_ = get_blob_index(nLayer);}CaffeExFeat::CaffeExFeat(std::string proto,std::string model, char* nLayer,float v1,float v2,float v3,float scale){init(proto,model,scale);getMeanData(v1,v2,v3);    blob_id_ = get_blob_index(nLayer);}void CaffeExFeat::init(std::string proto,std::string model,float scale){scale_=scale;Phase phase = TEST;Caffe::set_mode(Caffe::CPU);net_ = boost::shared_ptr< Net<float> >(new caffe::Net<float>(proto, phase));net_->CopyTrainedLayersFrom(model);input_blobs_ = net_->input_blobs()[0];num_channels_ = input_blobs_->channels();input_geometry_ = cv::Size(input_blobs_->width(),input_blobs_->height());input_blobs_->Reshape(1, num_channels_,input_geometry_.height, input_geometry_.width); //難道可輸入多張圖net_->Reshape();  //維度改變}CaffeExFeat::~CaffeExFeat(){}double* CaffeExFeat::extractFeat(const cv::Mat& img){std::vector<cv::Mat> input_channels;wrapInputLayer(&input_channels);preprocess(img, &input_channels);    net_->ForwardPrefilled();boost::shared_ptr<Blob<float> > featBlob = net_->blobs()[blob_id_];featNum_ = featBlob->count();    const float *featData = (const float *) featBlob->cpu_data();        double* out = new double[featNum_];    for(int k=0;k<featNum_;++k) out[k]=featData[k];return out;}double CaffeExFeat::calSimilarity(const cv::Mat& img1 ,const cv::Mat& img2){double* feat_1 = extractFeat(img1);double* feat_2 = extractFeat(img2);double sim = cblas_ddot(featNum_,feat_1,1,feat_2,1)/(std::sqrt(cblas_ddot(featNum_,feat_1,1,feat_1,1))*std::sqrt(cblas_ddot(featNum_,feat_2,1,feat_2,1)));    delete []feat_1;delete []feat_2;return sim;}void CaffeExFeat::getMeanData(std::string mean_file){  BlobProto blob_proto;    ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);      /* Convert from BlobProto to Blob<float> */    Blob<float> mean_blob;    mean_blob.FromProto(blob_proto);      /* The format of the mean file is planar 32-bit float BGR or grayscale. */    std::vector<cv::Mat> channels;    float* data = mean_blob.mutable_cpu_data();    for (int i = 0; i < num_channels_; ++i) {      /* Extract an individual channel. */      cv::Mat channel(mean_blob.height(), mean_blob.width(), CV_32FC1, data);      channels.push_back(channel);      data += mean_blob.height() * mean_blob.width();    }      /* Merge the separate channels into a single image. */    cv::Mat mean;    cv::merge(channels, mean);      /* Compute the global mean pixel value and create a mean image    * filled with this value. */    cv::Scalar channel_mean = cv::mean(mean);    mean_ = cv::Mat(input_geometry_, mean.type(), channel_mean);  }void CaffeExFeat::getMeanData(float v1,float v2, float v3){cv::Scalar channel_mean(v1,v2,v3);mean_ = cv::Mat(input_geometry_,CV_32FC3,channel_mean );}unsigned int CaffeExFeat::get_blob_index( char *query_blob_name){    std::string str_query(query_blob_name);        vector< string > const & blob_names = net_->blob_names();    for( unsigned int i = 0; i != blob_names.size(); ++i )     {         if( str_query == blob_names[i] )         {             return i;        }     }    LOG(FATAL) << "Unknown blob name: " << str_query;}void CaffeExFeat::wrapInputLayer(std::vector<cv::Mat>* input_channels) {    Blob<float>* input_layer = net_->input_blobs()[0];      int width = input_layer->width();    int height = input_layer->height();    float* input_data = input_layer->mutable_cpu_data();    for (int i = 0; i < input_layer->channels(); ++i) {      cv::Mat channel(height, width, CV_32FC1, input_data);      input_channels->push_back(channel);      input_data += width * height;    }  }void CaffeExFeat::preprocess(const cv::Mat& img,std::vector<cv::Mat>* input_channels){  cv::Mat sample;    if (img.channels() == 3 && num_channels_ == 1)      cv::cvtColor(img, sample, CV_BGR2GRAY);    else if (img.channels() == 4 && num_channels_ == 1)      cv::cvtColor(img, sample, CV_BGRA2GRAY);    else if (img.channels() == 4 && num_channels_ == 3)      cv::cvtColor(img, sample, CV_BGRA2BGR);    else if (img.channels() == 1 && num_channels_ == 3)      cv::cvtColor(img, sample, CV_GRAY2BGR);    else      sample = img;   cv::Mat sample_resized;  if (sample.size() != input_geometry_)      cv::resize(sample, sample_resized, input_geometry_);    else      sample_resized = sample;  cv::Mat sample_float;  if (num_channels_ == 3)      sample_resized.convertTo(sample_float, CV_32FC3);    else      sample_resized.convertTo(sample_float, CV_32FC1);  cv::Mat sample_normalized;    cv::subtract(sample_float, mean_, sample_normalized);    if(scale_!=-1){  cv::multiply(scale_ ,sample_normalized,sample_normalized);    }    cv::split(sample_normalized, *input_channels);}

三、方式二

#ifndef CAFFEEXFEAT_H #define CAFFEEXFEAT_H#include "caffe/caffe.hpp"#include <string>#include <vector>#include "opencv2/opencv.hpp"using namespace caffe;class CaffeExFeat{public: explicit CaffeExFeat(std::string proto,std::string model,char* nameLayer,std::string meanFile,float scale=1.); explicit CaffeExFeat(std::string proto,std::string model,char* nameLayer,float v1=0.0,float v2=0.0,float v3=0.0,float scale=1.); ~CaffeExFeat();double*extractFeat(const cv::Mat& img);double calSimilarity(const cv::Mat& img1 ,const cv::Mat& img2);private:unsigned int blob_id;boost::shared_ptr< Net<float> > net;Blob<float>* input_blobs;int channel,width,height;unsigned int featNum;float *meanData;float scale_;void init(std::string proto,std::string model,float scale);    void getMeanData(std::string meanFile);    void getMeanData(float v1,float v2,float v3 );unsigned int get_blob_index( char *query_blob_name);};#endif
#include "CaffeExFeat.h"CaffeExFeat::CaffeExFeat(std::string proto,std::string model, char* nLayer,std::string meanFile,float scale){init(proto,model,scale);getMeanData(meanFile);    blob_id = get_blob_index(nLayer);}CaffeExFeat::CaffeExFeat(std::string proto,std::string model, char* nLayer,float v1,float v2,float v3,float scale){init(proto,model,scale);getMeanData(v1,v2,v3);    blob_id = get_blob_index(nLayer);}void CaffeExFeat::init(std::string proto,std::string model,float scale){scale_=scale;Phase phase = TEST;Caffe::set_mode(Caffe::CPU);net = boost::shared_ptr< Net<float> >(new caffe::Net<float>(proto, phase));net->CopyTrainedLayersFrom(model);input_blobs = net->input_blobs()[0];channel = input_blobs->channels();width = input_blobs->width();height = input_blobs->height();}CaffeExFeat::~CaffeExFeat(){delete meanData;} double* CaffeExFeat::extractFeat(const cv::Mat& img){cv::Mat resizedImg;cv::resize(img , resizedImg, cv::Size(height,width)); //縮放和去均值float *input_data = input_blobs->mutable_cpu_data();for(int h=0;h<height; ++h){const uchar* ptr = img.ptr<uchar>(h);int img_index = 0;for(int w=0; w<width ;++w){for(int c=0;c<channel ;++c){int blob_index = (c*height+h)*width +w ;input_data[blob_index] =(static_cast<float>(ptr[img_index++])-meanData[blob_index])*scale_;}}}  net->ForwardPrefilled();boost::shared_ptr<Blob<float> > featBlob = net->blobs()[blob_id];featNum = featBlob->count(); const float *featData = (const float *) featBlob->cpu_data();double* out = new double[featNum];for(int k=0;k<featNum;++k) out[k]=featData[k];return out;}double CaffeExFeat::calSimilarity(const cv::Mat& img1 ,const cv::Mat& img2){double* feat_1 = extractFeat(img1);double* feat_2 = extractFeat(img2);double sim = cblas_ddot(featNum,feat_1,1,feat_2,1)/(std::sqrt(cblas_ddot(featNum,feat_1,1,feat_1,1))*std::sqrt(cblas_ddot(featNum,feat_2,1,feat_2,1)));    delete []feat_1;delete []feat_2;return sim;}void CaffeExFeat::getMeanData(std::string meanFile){Blob<float> image_mean;  BlobProto blob_proto;  const float *mean_ptr;  unsigned int num_pixel;    bool succeed = ReadProtoFromBinaryFile(meanFile, &blob_proto);  if (succeed)  {      image_mean.FromProto(blob_proto);      num_pixel = image_mean.count(); /* NCHW=1x3x256x256=196608 */      mean_ptr = (const float *) image_mean.cpu_data();  meanData = new float[num_pixel];memcpy(meanData,mean_ptr,num_pixel*sizeof(float));}}void CaffeExFeat::getMeanData(float v1,float v2, float v3){int wh = width*height;    meanData = new float[channel*wh];std::vector<float> vec;vec.push_back(v1);vec.push_back(v2);vec.push_back(v3);for(int c=0; c<channel ; ++c){for(int k=0;k<wh ;++k){meanData[k+c*wh] = vec[c];}}}unsigned int CaffeExFeat::get_blob_index( char *query_blob_name){    std::string str_query(query_blob_name);        vector< string > const & blob_names = net->blob_names();    for( unsigned int i = 0; i != blob_names.size(); ++i )     {         if( str_query == blob_names[i] )         {             return i;        }     }    LOG(FATAL) << "Unknown blob name: " << str_query;}
//main.cpp#include "CaffeExFeat.h"#include <iostream>int main(int argc,char**argv){    caffe::GlobalInit(&argc,&argv);  //關掉Log    std::string proto = "***.prototxt";    std::string model = "***.caffemodel";    CaffeExFeat exFeater(proto,model,(char*)"fc5", 127.5,127.5,127.5 ,1./128);     cv::Mat img_1 = cv::imread(path);    double* feat = extractFeat(img_1);   delete[] feat;   return 0;}

四、編譯下

g++ CaffeExFeat.cpp main.cpp -o main -D CPU_ONLY -I /home/trainer/Jyang/caffe-intel/include -L /home/trainer/Jyang/caffe-intel/build/lib -lcblas -lpthread  -lcaffe -lboost_system -lglog `pkg-config opencv --libs --cflags`


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.