怎么用C++提取任意一張圖片的特征(從內(nèi)存讀取數(shù)據(jù))
關(guān)于使用C++接口來提取特征,caffe官方提供了一個(gè)extract_features.cpp的例程,但是這個(gè)文件的輸入是blob數(shù)據(jù),即使輸入層使用的是ImageData,也需要在deploy.prototxt中指定圖片的位置,很不方便。
如果想要使用opencv來讀取一個(gè)圖片,然后用caffe訓(xùn)練好的model提取特征,就需要對(duì)輸入層進(jìn)行改寫。另外官方例程默認(rèn)的輸出是leveldb格式,我們也可以獲取float類型的多維特征(數(shù)組),這樣集成到我們的項(xiàng)目中更靈活。
01
首先我們需要改寫deploy.prototxt的輸入層為"MemoryData":
layer { name: "data" type: "MemoryData" top: "data" top: "label" memory_data_param{ batch_size:1 channels:3 height:100 width:100 } }
在之前的訓(xùn)練中可能使用的是"ImageData"、"Data"之類的,現(xiàn)在改成MemoryData不影響。
02
我準(zhǔn)備提取的層的名字是"res5_6",就是"InnerProduct"的前一層,當(dāng)我想提取"InnerProduct"全連接層的輸出時(shí),總是報(bào)錯(cuò),提示原始參數(shù)和網(wǎng)絡(luò)參數(shù)不匹配(就是訓(xùn)練好的model和現(xiàn)在deploy的網(wǎng)絡(luò)維度不一樣),所以只好提取前一層了,并且要把全連接層屏蔽掉,屏蔽的方法是把prototxt里相應(yīng)層的名字改掉就好(相對(duì)于caffemodel里面的名字)。[以上問題暫時(shí)還沒解決,留坑]
03
下面是更改之后的 extract_features.cpp的代碼:
#include <stdio.h> #include <string> #include <vector> #include <iostream> #include <opencv2/opencv.hpp> #include "boost/algorithm/string.hpp" #include "google/protobuf/text_format.h" #include "caffe/blob.hpp" #include "caffe/common.hpp" #include "caffe/net.hpp" #include "caffe/proto/caffe.pb.h" #include "caffe/util/io.hpp" #include "caffe/layers/memory_data_layer.hpp" #define NetTy float using namespace caffe; using std::cout; using std::endl; using std::string; /* 加載模型函數(shù) */ template <typename Dtype> caffe::Net<Dtype>* loadNet(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() { cv::Mat src; src = cv::imread("face_example/test.jpg"); // 讀取測(cè)試圖片 cv::resize(src, src, cv::Size(100, 100)); // 這里要將圖片resize到prototxt里面的輸入層指定的大小 caffe::Net<NetTy>* _net = loadNet<NetTy>("face_example/face_deploy.prototxt", "face_example/face.caffemodel", caffe::TEST); // 加載網(wǎng)絡(luò)定義文件和參數(shù)模型 caffe::MemoryDataLayer<NetTy> *m_layer = (caffe::MemoryDataLayer<NetTy> *)_net->layers()[0].get(); // 定義個(gè)內(nèi)存數(shù)據(jù)層指針 std::vector<cv::Mat> dv = { src }; // AddMatVector(const vector<cv::Mat>& mat_vector,const vector<int>& labels) std::vector<int> label = { 0 }; // ------------------------------------------------------------------------- m_layer->AddMatVector(dv, label); // 把圖片和標(biāo)簽,添加到 MemoryData層 std::vector<caffe::Blob<NetTy>*> input_vec; // 無(wú)意義,為了函數(shù)參數(shù)需要 _net->Forward(input_vec); // 執(zhí)行一次前向計(jì)算 boost::shared_ptr<caffe::Blob<NetTy>> layerData = _net->blob_by_name("res5_6"); // 獲得指定層的輸出 const NetTy* pstart = layerData->cpu_data(); // res5_6->cpu_data()返回的是多維數(shù)據(jù)(數(shù)組) /*-----輸出特征-----*/ for (int i = 0; i < 30000; i++) { std::cout << *pstart << endl; pstart++; } return 0; }
以上所述是小編給大家介紹的怎么用C++提取任意一張圖片的特征(從內(nèi)存讀取數(shù)據(jù)),希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- python實(shí)現(xiàn)讀取并顯示圖片的兩種方法
- python從網(wǎng)絡(luò)讀取圖片并直接進(jìn)行處理的方法
- Python讀取圖片屬性信息的實(shí)現(xiàn)方法
- Python讀取圖片EXIF信息類庫(kù)介紹和使用實(shí)例
- python讀取和保存圖片5種方法對(duì)比
- Python 讀取圖片文件為矩陣和保存矩陣為圖片的方法
- C++實(shí)現(xiàn)單張圖片讀取和保存
- OpenCV中C++函數(shù)imread讀取圖片的問題及解決方法
- C++實(shí)現(xiàn)讀取圖片長(zhǎng)度和寬度
- python或C++讀取指定文件夾下的所有圖片
相關(guān)文章
C/C++編程判斷String字符串是否包含某個(gè)字符串實(shí)現(xiàn)示例
這篇文章主要為大家介紹了C++編程中判斷String字符串是否包含某個(gè)字符串的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11Qt+FFMPEG實(shí)現(xiàn)循環(huán)解碼詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Qt+FFMPEG實(shí)現(xiàn)循環(huán)解碼功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定幫助,需要的可以參考一下2022-08-08C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài)
這篇文章主要為大家詳細(xì)介紹了C++判斷主機(jī)是否處于聯(lián)網(wǎng)狀態(tài),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06C語(yǔ)言切割多層字符串(strtok_r strtok使用方法)
這篇文章主要介紹了C語(yǔ)言切割多層字符串的方法,說了strtok的弱點(diǎn),使用strtok_r的方法2013-11-11