Caffe-Face extractDeepFeature C++

来源:互联网 发布:淘宝卖家如何隐藏差评 编辑:程序博客网 时间:2024/06/07 18:03

Caffe-Face 特征提取C++版本


说明:

根据extractDeepFeature.m修改的C++版本

extractDeepFeature.cpp:

#include <string>#include <vector>#include <fstream>#include <caffe/caffe.hpp>#include <caffe/layers/memory_data_layer.hpp>#include <opencv2/opencv.hpp>#include "boost/make_shared.hpp"#define NetF float  #define USING_GPU //使用GPU#define IMAGE_WIDTH_STD 96//裁剪的图片大小#define IMAGE_HEIGHT_STD 112#define LANDMARK_SIZE 5//对齐点的个数#define LANDMARK_SIZE_DOUBLE 10//对齐点个数的两倍using namespace caffe;using namespace std;using namespace cv;double src_landmark[LANDMARK_SIZE_DOUBLE] = {    105.8306, 147.9323, 121.3533, 106.1169, 144.3622,    109.8005, 112.5533, 139.1172, 155.6359, 156.3451 };double dst_landmark[LANDMARK_SIZE_DOUBLE] = {    30.2946, 65.5318, 48.0252, 33.5493, 62.7299,    51.6963, 51.5014, 71.7366, 92.3655, 92.2041 };template <typename Dtype>caffe::Net<Dtype>* Net_Init_Load(    std::string param_file, std::string pretrained_param_file, caffe::Phase phase){    caffe::Net<Dtype>* net(new caffe::Net<Dtype>(param_file, phase));    net->CopyTrainedLayersFrom(pretrained_param_file);    return net;}int main(int argc,char **argv){    ::google::InitGoogleLogging(argv[0]);#ifdef USING_GPU    Caffe::set_mode(Caffe::GPU);#else    Caffe::set_mode(Caffe::CPU);#endif       //加载配置和模型文件    caffe::Net<NetF>* _net = Net_Init_Load<NetF>("../model/face_deploy.prototxt",                                                 "../model/face_model.caffemodel", caffe::TEST);      vector<Point2f> facial5points;    vector<Point2f> coord5points;    for (int i = 0; i < LANDMARK_SIZE; i++)    {        facial5points.push_back(Point2f(src_landmark[i], src_landmark[i + LANDMARK_SIZE]));        coord5points.push_back(Point2f(dst_landmark[i], dst_landmark[i + LANDMARK_SIZE]));    }    Mat image, warp_mat, cropImg, cropImg_;    image = imread("../data/1.jpg",1);    imshow("frame", image);//显示原图片    warp_mat = estimateRigidTransform(facial5points, coord5points, false);    if (warp_mat.empty())    {        std::cout << "NULL" << std::endl;        return 0;    }    cropImg = Mat::zeros(IMAGE_HEIGHT_STD, IMAGE_WIDTH_STD, image.type());    warpAffine(image, cropImg, warp_mat, cropImg.size());//裁剪图片    cropImg.convertTo(cropImg, CV_32F);    cropImg = (cropImg - 127.5) / 128;//均值归一化图片    imshow("normalization", cropImg);    /*    transpose(cropImg, cropImg);//转置图片(matlab与C++图片存储方式不同不需要转置)    Mat temp;//matlab与C++彩色三通道的顺序不同,matlab为RGB,C++为BGR。matlab中需要在提特征时调整顺序,C++则不需要。    vector<Mat> channels;    split(cropImg, channels); //通道的拆分       temp = channels.at(0);    channels.at(0) = channels.at(2);    channels.at(2) = temp;    merge(channels, cropImg);//拆分通道的合并      imshow("cropImg", cropImg);    */    flip(cropImg, cropImg_, 0);    imshow("cropImg_", cropImg_);//镜像翻转    cropImg.convertTo(cropImg, CV_8U); //这个地方可以考虑使用Datum类型来传递float类型的图片    cropImg_.convertTo(cropImg_, CV_8U);     std::vector<cv::Mat> dv = { cropImg,cropImg_ };//对齐后图片,这里为两张图片需要修改face_deploy.prototxt中data层batch_size:2    std::vector<int> label = { 0,0 };//图片标签(可随便写)    caffe::MemoryDataLayer<NetF> *m_layer_ = (caffe::MemoryDataLayer<NetF> *)_net->layers()[0].get();//定义数据层指针    m_layer_->AddMatVector(dv, label);//将图片和标签添加到MemoryData层    int end_ind = _net->layers().size();    std::vector<caffe::Blob<NetF>*> input_vec;    clock_t start = clock();    _net->Forward(input_vec);//提特征    clock_t end = clock();    double totaltime;    totaltime = (double)(end - start) / CLOCKS_PER_SEC;    boost::shared_ptr<caffe::Blob<NetF>> fc5 = _net->blob_by_name("fc5");    const NetF* pstart = fc5->cpu_data();//*pstart只代表数组的第一个数    std::vector<double> V1;    for (int i = 0; i < 1024; i++)//循环获取特征数据,1张图片特征为512个    {        std::cout << *pstart << endl;        V1.push_back(*pstart);        pstart++;    }    cout << "\n此程序的运行时间为" << totaltime << "秒!" << endl;    cvWaitKey(0);    return 0;}

配置文件数据层:

layer{  name: "data"  type: "MemoryData"  top: "data"  top: "label"  memory_data_param{    batch_size:2    channels:3    height:112    width:96  }}

参考:http://blog.csdn.net/sunshine_in_moon/article/details/50126307
Demo:点击下载

代码更新:

//mat转Datum类型bool CvMatToDatumSignalChannel(const cv::Mat& cv_mat, Datum* datum){  if (cv_mat.empty())    return false;  int channels = cv_mat.channels();  datum->set_channels(cv_mat.channels());  datum->set_height(cv_mat.rows);  datum->set_width(cv_mat.cols);  datum->set_label(0);  datum->clear_data();  datum->clear_float_data();  datum->set_encoded(false);  int datum_height = datum->height();  int datum_width  = datum->width();  if(channels == 3){    for(int c = 0;c < channels;c++){      for (int h = 0; h < datum_height; ++h){        for (int w = 0; w < datum_width; ++w){          const float* ptr = cv_mat.ptr<float>(h);          datum->add_float_data(ptr[w*channels+c]);        }      }    }  }  return true;}//提特征Mat getFeature(Mat image,vector<Point2f> points){    Mat warp_mat, cropImg, cropImg_;    cropImg = matlabtransform(image,points);//crop图片,可使用其他方法。    cropImg.convertTo(cropImg, CV_32FC3);    cropImg = (cropImg - 127.5) / 128;//均值归一化图片    flip(cropImg, cropImg_, 1);//镜像翻转    boost::shared_ptr<MemoryDataLayer<float> > mem_data_layer;    mem_data_layer = boost::static_pointer_cast<MemoryDataLayer<float> >(_net->layers()[0]);    Datum datum,datum_;    CvMatToDatumSignalChannel(cropImg,&datum);      CvMatToDatumSignalChannel(cropImg_,&datum_);    std::vector<Datum> datum_vector;    datum_vector.push_back(datum);     datum_vector.push_back(datum_);     mem_data_layer->set_batch_size(2);    mem_data_layer->AddDatumVector(datum_vector);    _net->Forward();    boost::shared_ptr<caffe::Blob<NetF> > fc5 = _net->blob_by_name("fc5");    const NetF* pstart = fc5->cpu_data();//*pstart只代表数组的第一个数    cv::Mat tmp(1024, 1, CV_32FC1);//获取特征值    for(int i=0;i<1024;i++){        for(int j=0;j<1;j++){            tmp.at<float>(i,j) = (float)*pstart;            pstart++;               }       }    return tmp;}

mTransform.m

function [R,G,B] = mTransform(B_image,G_image,R_image,facial5points)image(:,:,1) = R_image;image(:,:,2) = G_image;image(:,:,3) = B_image;image = permute(image, [2,1,3]);imgSize = [112, 96];coord5points = [30.2946, 65.5318, 48.0252, 33.5493, 62.7299; ...        51.6963, 51.5014, 71.7366, 92.3655, 92.2041];Tfm = cp2tform(facial5points', coord5points', 'similarity');cropImg = imtransform(image, Tfm, 'XData', [1 imgSize(2)],...        'YData', [1 imgSize(1)], 'Size', imgSize);R = cropImg(:,:,1);G = cropImg(:,:,2);B = cropImg(:,:,3);end
0 0
原创粉丝点击