日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

封装caffe-windows-cpu(支持模型有多个输出)

發布時間:2024/9/21 windows 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 封装caffe-windows-cpu(支持模型有多个输出) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注意:該版本為CPU版本。


用到的caffe-windows來自:https://github.com/happynear/caffe-windows

先下載caffe-windows,解壓;然后下載第三方庫:https://pan.baidu.com/s/1eStyfrc??解壓到caffe-windows-master,看起來是這樣:caffe-windows-master\3rdparty

把3rdparty的bin加入環境變量或者復制里面的dll到build_cpu_only\caffelib下(cudnn的不需要)。

打開caffe-windows-master\src\caffe\proto,雙擊extract_proto.bat,然后用VS2013打開./build_cpu_only/MainBuilder.sln。請確保為Release x64


1.右鍵caffelib項目,重命名為:multi_recognition_cpu(按個人愛好,其他名字也行,不改也可以);再右鍵該項目——>屬性——>配置屬性——>常規:

配置類型修改為動態庫(.dll),目標擴展名修改為.dll


2.C/C++——>常規:

附加包含目錄:

../../3rdparty/include

../../src

../../include

C/C++——>預處理器:

添加?MULTI_RECOGNITION_API_EXPORTS


3.鏈接器——>常規:

附加庫目錄:

../../3rdparty/lib


鏈接器——>輸入:

去掉cuda和cudnn的lib(cu開頭和cudnn開頭的lib)


4.修改net.hpp和net.cpp

為了支持模型多輸出,要知道輸出的順序,所以把輸出blob的名字輸出到控制臺,打開net.hpp,給Net類添加:

[plain]?view plaincopy
  • protected:??
  • ?????std::vector<std::string>?outputblobnames;??

  • 以及:

    [plain]?view plaincopy
  • public:??
  • ??inline?std::vector<std::string>?output_blobs_names()?const??
  • ??{??
  • ??????return?outputblobnames;??
  • ??}??

  • net.cpp修改:(最后一行,把輸出blob名字保存到vector中)

    [plain]?view plaincopy
  • for?(set<string>::iterator?it?=?available_blobs.begin();??
  • ??????it?!=?available_blobs.end();?++it)?{??
  • ????LOG_IF(INFO,?Caffe::root_solver())??
  • ????????<<?"This?network?produces?output?"?<<?*it;??
  • ????net_output_blobs_.push_back(blobs_[blob_name_to_idx[*it]].get());??
  • ????net_output_blob_indices_.push_back(blob_name_to_idx[*it]);??
  • ????outputblobnames.push_back(*it);??
  • ??}??

  • 這樣,屬性就配置好了代碼也修改完了,再右鍵該項目,添加新建項,有四個:

    classification.h

    classification.cpp

    multi_recognition_cpu.h

    multi_recognition_cpu.cpp


    classification.h:

    [plain]?view plaincopy
  • #ifndef?CLASSIFICATION_H_??
  • #define?CLASSIFICATION_H_??
  • ??
  • #include?<caffe/caffe.hpp>??
  • #include?<opencv2/core/core.hpp>??
  • #include?<opencv2/highgui/highgui.hpp>??
  • #include?<opencv2/imgproc/imgproc.hpp>??
  • #include?<iosfwd>??
  • #include?<memory>??
  • #include?<utility>??
  • #include?<vector>??
  • #include?<iostream>??
  • #include?<string>??
  • #include?<time.h>??
  • ??
  • using?namespace?caffe;??
  • using?std::string;??
  • typedef?std::pair<int,?float>?Prediction;??
  • ??
  • class??ClassifierImpl?{??
  • public:??
  • ????ClassifierImpl(const?string&?model_file,??
  • ????????const?string&?trained_file,??
  • ????????const?string&?mean_file??
  • ????????);??
  • ??
  • ????std::vector<std::vector<Prediction>?>?Classify(const?cv::Mat&?img,?int?N?=?2);??
  • private:??
  • ????void?SetMean(const?string&?mean_file);??
  • ??
  • ????std::vector<std::vector<float>?>?Predict(const?cv::Mat&?img);??
  • ??
  • ????void?WrapInputLayer(std::vector<cv::Mat>*?input_channels);??
  • ??
  • ????void?Preprocess(const?cv::Mat&?img,??
  • ????????std::vector<cv::Mat>*?input_channels);??
  • ??
  • private:??
  • ????shared_ptr<Net<float>?>?net_;??
  • ????cv::Size?input_geometry_;??
  • ????int?num_channels_;??
  • ????cv::Mat?mean_;??
  • };??
  • #endif??

  • classification.cpp:

    [plain]?view plaincopy
  • #include?"classification.h"??
  • ??
  • ClassifierImpl::ClassifierImpl(const?string&?model_file,??
  • ????const?string&?trained_file,??
  • ????const?string&?mean_file)?{??
  • #ifdef?CPU_ONLY??
  • ????Caffe::set_mode(Caffe::CPU);??
  • #else??
  • ????Caffe::set_mode(Caffe::GPU);??
  • #endif??
  • ??
  • ????/*?Load?the?network.?*/??
  • ????net_.reset(new?Net<float>(model_file,?TEST));??
  • ????net_->CopyTrainedLayersFrom(trained_file);??
  • ??
  • ????CHECK_EQ(net_->num_inputs(),?1)?<<?"Network?should?have?exactly?one?input.";??
  • ????std::cout?<<?"Network?have?"?<<?net_->num_outputs()?<<?"?outputs.\n";??
  • ????vector<string>?names?=?net_->output_blobs_names();??
  • ??
  • ????for?(int?n?=?0;?n?<?net_->num_outputs();?++n)??
  • ????{??
  • ????????std::cout?<<?"Output?"?<<?n?+?1?<<?":"?<<?names[n]?<<?";?have?"?<<?net_->output_blobs()[n]->channels()?<<?"?outputs.\n";??
  • ????}??
  • ??
  • ??
  • ????Blob<float>*?input_layer?=?net_->input_blobs()[0];??
  • ????std::cout?<<?"Input?width:"?<<?input_layer->width()?<<?";"?<<?"Input?height:"?<<?input_layer->height()?<<?"\n";??
  • ????num_channels_?=?input_layer->channels();??
  • ????CHECK(num_channels_?==?3?||?num_channels_?==?1)??
  • ????????<<?"Input?layer?should?have?1?or?3?channels.";??
  • ????input_geometry_?=?cv::Size(input_layer->width(),?input_layer->height());??
  • ??
  • ??
  • ????/*?Load?the?binaryproto?mean?file.?*/??
  • ????SetMean(mean_file);??
  • ??
  • }??
  • ??
  • static?bool?PairCompare(const?std::pair<float,?int>&?lhs,??
  • ????const?std::pair<float,?int>&?rhs)?{??
  • ????return?lhs.first?>?rhs.first;??
  • }??
  • ??
  • /*?Return?the?indices?of?the?top?N?values?of?vector?v.?*/??
  • static?std::vector<int>?Argmax(const?std::vector<float>&?v,?int?N)?{??
  • ????std::vector<std::pair<float,?int>?>?pairs;??
  • ????for?(size_t?i?=?0;?i?<?v.size();?++i)??
  • ????????pairs.push_back(std::make_pair(v[i],?i));??
  • ????std::partial_sort(pairs.begin(),?pairs.begin()?+?N,?pairs.end(),?PairCompare);??
  • ??
  • ????std::vector<int>?result;??
  • ????for?(int?i?=?0;?i?<?N;?++i)??
  • ????????result.push_back(pairs[i].second);??
  • ????return?result;??
  • }??
  • ??
  • /*?Return?the?top?N?predictions.?*/??
  • std::vector<std::vector<Prediction>?>?ClassifierImpl::Classify(const?cv::Mat&?img,?int?N)?{??
  • ????std::vector<std::vector<Prediction>?>?outputPredict;??
  • ????std::vector<std::vector<float>?>?output?=?Predict(img);??
  • ??
  • ????for?(auto?bg?=?output.begin();?bg?!=?output.end();?++bg)??
  • ????{??
  • ????????std::vector<int>?maxN?=?Argmax(*bg,?N);??
  • ????????std::vector<Prediction>?predictions;??
  • ????????for?(int?i?=?0;?i?<?N;?++i)?{??
  • ????????????int?idx?=?maxN[i];??
  • ????????????predictions.push_back(std::make_pair(idx,?(*bg)[idx]));??
  • ????????}??
  • ????????outputPredict.push_back(predictions);??
  • ????????predictions.clear();??
  • ????????maxN.clear();??
  • ????}??
  • ??
  • ????return?outputPredict;??
  • }??
  • ??
  • /*?Load?the?mean?file?in?binaryproto?format.?*/??
  • void?ClassifierImpl::SetMean(const?string&?mean_file)?{??
  • ????BlobProto?blob_proto;??
  • ????ReadProtoFromBinaryFileOrDie(mean_file.c_str(),?&blob_proto);??
  • ????Blob<float>?mean_blob;??
  • ????mean_blob.FromProto(blob_proto);??
  • ????CHECK_EQ(mean_blob.channels(),?num_channels_)??
  • ????????<<?"Number?of?channels?of?mean?file?doesn't?match?input?layer.";??
  • ????std::vector<cv::Mat>?channels;??
  • ????float*?data?=?mean_blob.mutable_cpu_data();??
  • ????for?(int?i?=?0;?i?<?num_channels_;?++i)?{??
  • ????????cv::Mat?channel(mean_blob.height(),?mean_blob.width(),?CV_32FC1,?data);??
  • ????????channels.push_back(channel);??
  • ????????data?+=?mean_blob.height()?*?mean_blob.width();??
  • ????}??
  • ??
  • ????cv::Mat?mean;??
  • ????cv::merge(channels,?mean);??
  • ????cv::Scalar?channel_mean?=?cv::mean(mean);??
  • ????mean_?=?cv::Mat(input_geometry_,?mean.type(),?channel_mean);??
  • }??
  • std::vector<std::vector<float>?>?ClassifierImpl::Predict(const?cv::Mat&?img)?{??
  • ????Blob<float>*?input_layer?=?net_->input_blobs()[0];??
  • ????input_layer->Reshape(1,?num_channels_,??
  • ????????input_geometry_.height,?input_geometry_.width);??
  • ????net_->Reshape();??
  • ????std::vector<cv::Mat>?input_channels;??
  • ????WrapInputLayer(&input_channels);??
  • ????Preprocess(img,?&input_channels);??
  • ????net_->ForwardPrefilled();??
  • ??
  • ????std::vector<std::vector<float>?>?outPredict;??
  • ????for?(int?i?=?0;?i?<?net_->output_blobs().size();?++i)??
  • ????{??
  • ????????Blob<float>*?output_layer?=?net_->output_blobs()[i];??
  • ????????const?float*?begin?=?output_layer->cpu_data();??
  • ????????const?float*?end?=?begin?+?output_layer->channels();??
  • ????????std::vector<float>?temp(begin,?end);??
  • ????????outPredict.push_back(temp);??
  • ????????temp.clear();??
  • ????}??
  • ??
  • ????return?outPredict;??
  • }??
  • ??
  • void?ClassifierImpl::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?ClassifierImpl::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);??
  • ????cv::split(sample_normalized,?*input_channels);??
  • ??
  • ????CHECK(reinterpret_cast<float*>(input_channels->at(0).data)??
  • ????????==?net_->input_blobs()[0]->cpu_data())??
  • ????????<<?"Input?channels?are?not?wrapping?the?input?layer?of?the?network.";??
  • }??

  • 導出類:

    multi_recognition_cpu.h:

    [plain]?view plaincopy
  • #ifndef?MULTI_RECOGNITION_CPU_H_??
  • #define?MULTI_RECOGNITION_CPU_H_??
  • ??
  • #ifdef?MULTI_RECOGNITION_API_EXPORTS??
  • #define?MULTI_RECOGNITION_API?__declspec(dllexport)??
  • #else??
  • #define?MULTI_RECOGNITION_API?__declspec(dllimport)??
  • #endif??
  • #include?<opencv2/core/core.hpp>??
  • #include?<opencv2/highgui/highgui.hpp>??
  • #include?<opencv2/imgproc/imgproc.hpp>??
  • #include?<string>??
  • #include?<vector>??
  • #include?<iostream>??
  • #include?<io.h>??
  • class?ClassifierImpl;??
  • using?std::string;??
  • using?std::vector;??
  • typedef?std::pair<int,?float>?Prediction;??
  • ??
  • class?MULTI_RECOGNITION_API?MultiClassifier??
  • {??
  • public:??
  • ????MultiClassifier(const?string&?model_file,??
  • ????????const?string&?trained_file,??
  • ????????const?string&?mean_file);??
  • ??
  • ????~MultiClassifier();??
  • ????std::vector<std::vector<Prediction>?>Classify(const?cv::Mat&?img,?int?N?=?2);??
  • ????void?getFiles(std::string?path,?std::vector<std::string>&?files);??
  • private:??
  • ????ClassifierImpl?*Impl;??
  • };??
  • ??
  • #endif??

  • multi_recognition_cpu.cpp:

    [plain]?view plaincopy
  • #include?"multi_recognition_cpu.h"??
  • #include?"classification.h"??
  • ??
  • MultiClassifier::MultiClassifier(const?string&?model_file,?const?string&?trained_file,?const?string&?mean_file)??
  • {??
  • ????Impl?=?new?ClassifierImpl(model_file,?trained_file,?mean_file);??
  • }??
  • MultiClassifier::~MultiClassifier()??
  • {??
  • ????delete?Impl;??
  • }??
  • std::vector<std::vector<Prediction>?>?MultiClassifier::Classify(const?cv::Mat&?img,?int?N?/*?=?2?*/)??
  • {??
  • ????return?Impl->Classify(img,?N);??
  • }??
  • void?MultiClassifier::getFiles(string?path,?vector<string>&?files)??
  • {??
  • ????//文件句柄??
  • ????long???hFile?=?0;??
  • ????//文件信息??
  • ????struct?_finddata_t?fileinfo;??
  • ????string?p;??
  • ????if?((hFile?=?_findfirst(p.assign(path).append("\\*").c_str(),?&fileinfo))?!=?-1)??
  • ????{??
  • ????????do??
  • ????????{??
  • ????????????if?((fileinfo.attrib?&??_A_SUBDIR))??
  • ????????????{??
  • ????????????????if?(strcmp(fileinfo.name,?".")?!=?0?&&?strcmp(fileinfo.name,?"..")?!=?0)??
  • ????????????????????getFiles(p.assign(path).append("\\").append(fileinfo.name),?files);??
  • ????????????}??
  • ????????????else??
  • ????????????{??
  • ????????????????files.push_back(p.assign(path).append("\\").append(fileinfo.name));??
  • ????????????}??
  • ????????}?while?(_findnext(hFile,?&fileinfo)?==?0);??
  • ????????_findclose(hFile);??
  • ????}??
  • }??

  • 右鍵項目,生成就可以了。

    最后得到:


    模型可以有多個輸出:



    封裝的代碼下載地址:caffe-windows-cpu

    總結

    以上是生活随笔為你收集整理的封装caffe-windows-cpu(支持模型有多个输出)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。