1 #ifndef CAFFEFEATEXTRACTOR_H_
2 #define CAFFEFEATEXTRACTOR_H_
7 #include <opencv2/opencv.hpp>
8 #include <opencv2/imgproc.hpp>
13 #include <cuda_runtime.h>
17 #include "boost/algorithm/string.hpp"
18 #include "boost/make_shared.hpp"
21 #include "caffe-version.h"
23 #if (CAFFE_MAJOR >= 1)
25 #include "caffe/caffe.hpp"
26 #include "caffe/layers/memory_data_layer.hpp"
29 #include "caffe/blob.hpp"
30 #include "caffe/common.hpp"
31 #include "caffe/net.hpp"
32 #include "caffe/proto/caffe.pb.h"
33 #include "caffe/util/io.hpp"
34 #include "caffe/vision_layers.hpp"
38 using namespace caffe;
41 class CaffeFeatExtractor {
43 string caffemodel_file;
46 caffe::shared_ptr<Net<Dtype> > feature_extraction_net;
52 vector<string> blob_names;
61 CaffeFeatExtractor(
string _caffemodel_file,
62 string _prototxt_file,
int _resizeWidth,
int _resizeHeight,
66 bool _timing_extraction);
68 bool extractBatch_multipleFeat(vector<cv::Mat> &images,
int new_batch_size, vector< Blob<Dtype>* > &features,
float (×)[2]);
70 bool extractBatch_singleFeat(vector<cv::Mat> &images,
int new_batch_size, vector< Blob<Dtype>* > &features,
float (×)[2]);
72 bool extractBatch_multipleFeat_1D(vector<cv::Mat> &images,
int new_batch_size, vector< vector<Dtype> > &features,
float (×)[2]);
74 bool extractBatch_singleFeat_1D(vector<cv::Mat> &images,
int new_batch_size, vector< vector<Dtype> > &features,
float (×)[2]);
76 bool extract_multipleFeat(cv::Mat &image, vector< Blob<Dtype>* > &features,
float (×)[2]);
78 bool extract_singleFeat(cv::Mat &image, Blob<Dtype> *feature,
float (×)[2]);
80 bool extract_multipleFeat_1D(cv::Mat &image, vector< vector<Dtype> > &features,
float (×)[2]);
82 bool extract_singleFeat_1D(cv::Mat &image, vector<Dtype> &features,
float (×)[2]);
85 template <
class Dtype>
86 CaffeFeatExtractor<Dtype>::CaffeFeatExtractor(
string _caffemodel_file,
87 string _prototxt_file,
int _resizeWidth,
int _resizeHeight,
94 if (strcmp(_compute_mode.c_str(),
"GPU") == 0 || strcmp(_compute_mode.c_str(),
"gpu") == 0) {
96 std::cout <<
"CaffeFeatExtractor::CaffeFeatExtractor(): using GPU" << std::endl;
99 device_id = _device_id;
101 Caffe::CheckDevice(device_id);
103 std::cout <<
"CaffeFeatExtractor::CaffeFeatExtractor(): using device_id = " << device_id << std::endl;
105 Caffe::set_mode(Caffe::GPU);
106 Caffe::SetDevice(device_id);
109 Caffe::DeviceQuery();
113 std::cout <<
"CaffeFeatExtractor::CaffeFeatExtractor(): using CPU" << std::endl;
118 Caffe::set_mode(Caffe::CPU);
122 caffemodel_file = _caffemodel_file;
123 prototxt_file = _prototxt_file;
126 feature_extraction_net = boost::make_shared<Net<Dtype> > (prototxt_file, caffe::TEST);
129 feature_extraction_net->CopyTrainedLayersFrom(caffemodel_file);
137 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
139 TransformationParameter tp = memory_data_layer->layer_param().transform_param();
141 if (tp.has_mean_file())
143 const string& mean_file = tp.mean_file();
144 std::cout <<
"CaffeFeatExtractor::CaffeFeatExtractor(): loading mean file from " << mean_file << std::endl;
146 BlobProto blob_proto;
147 ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);
149 Blob<Dtype> data_mean;
150 data_mean.FromProto(blob_proto);
152 mean_channels = data_mean.channels();
153 mean_width = data_mean.width();
154 mean_height = data_mean.height();
156 }
else if (tp.mean_value_size()>0)
159 const int b = tp.mean_value(0);
160 const int g = tp.mean_value(1);
161 const int r = tp.mean_value(2);
163 mean_channels = tp.mean_value_size();
164 mean_width = _resizeWidth;
165 mean_height = _resizeHeight;
167 std::cout <<
"CaffeFeatExtractor::CaffeFeatExtractor(): B " << b <<
" G " << g <<
" R " << r << std::endl;
168 std::cout <<
"CaffeFeatExtractor::CaffeFeatExtractor(): resizing anysotropically to " <<
" W: " << mean_width <<
" H: " << mean_height << std::endl;
172 std::cout <<
"CaffeFeatExtractor::CaffeFeatExtractor(): Error: neither mean file nor mean value in prototxt!" << std::endl;
176 boost::split(blob_names, _blob_names, boost::is_any_of(
","));
177 for (
size_t i = 0; i < blob_names.size(); i++) {
178 if (!feature_extraction_net->has_blob(blob_names[i]))
180 std::cout <<
"CaffeFeatExtractor::CaffeFeatExtractor(): unknown feature blob name " << blob_names[i] <<
" in the network " << prototxt_file << std::endl;
190 template<
class Dtype>
191 bool CaffeFeatExtractor<Dtype>::extractBatch_multipleFeat(vector<cv::Mat> &images,
int new_batch_size, vector< Blob<Dtype>* > &features,
float (×)[2]) {
198 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty images!" << std::endl;
205 cudaEvent_t startPrep, stopPrep, startNet, stopNet;
209 cudaEventCreate(&startPrep);
210 cudaEventCreate(&stopPrep);
211 cudaEventCreate(&startNet);
212 cudaEventCreate(&stopNet);
214 cudaEventRecord(startPrep, NULL);
220 double startPrep, stopPrep, startNet, stopNet;
224 startPrep = yarp::os::Time::now();
232 Caffe::set_mode(Caffe::GPU);
233 Caffe::SetDevice(device_id);
237 Caffe::set_mode(Caffe::CPU);
241 vector<int> labels(images.size(), 0);
244 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
248 if (memory_data_layer->batch_size()!=new_batch_size)
250 if (images.size()%new_batch_size==0)
252 memory_data_layer->set_batch_size(new_batch_size);
253 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
257 if (images.size()%memory_data_layer->batch_size()==0)
259 cout <<
"WARNING: image number is not multiple of requested batch size, leaving the old one..." << endl;
260 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
263 cout <<
"WARNING: image number is not multiple of batch size, setting it to 1 (performance issue)..." << endl;
264 memory_data_layer->set_batch_size(1);
265 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
272 if (images.size()%memory_data_layer->batch_size()!=0)
274 cout <<
"WARNING: image number is not multiple of batch size, setting it to 1 (performance issue)..." << endl;
275 memory_data_layer->set_batch_size(1);
276 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
280 int num_batches = images.size()/new_batch_size;
288 for (
int i=0; i<images.size(); i++)
291 if (images[i].empty())
293 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty image!" << std::endl;
297 if (images[i].rows != mean_height || images[i].cols != mean_height)
299 if (images[i].rows > mean_height || images[i].cols > mean_height)
301 cv::resize(images[i], images[i], cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LANCZOS4);
305 cv::resize(images[i], images[i], cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LINEAR);
310 memory_data_layer->AddMatVector(images,labels);
312 size_t num_features = blob_names.size();
319 cudaEventRecord(stopPrep, NULL);
322 cudaEventSynchronize(stopPrep);
324 cudaEventElapsedTime(times, startPrep, stopPrep);
325 times[0] = times[0]/images.size();
328 cudaEventRecord(startNet, NULL);
333 stopPrep = yarp::os::Time::now();
334 times[0] = ( stopPrep - startPrep ) / images.size() * 1000;
337 startNet = yarp::os::Time::now();
345 std::vector<Blob<Dtype>*> results;
347 for (
int b=0; b<num_batches; b++)
349 results = feature_extraction_net->Forward();
351 for (
int i = 0; i < num_features; ++i) {
353 const caffe::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[i]);
355 int batch_size = feature_blob->num();
356 int channels = feature_blob->channels();
357 int width = feature_blob->width();
358 int height = feature_blob->height();
360 features.push_back(
new Blob<Dtype>(batch_size, channels, height, width));
362 features.back()->CopyFrom(*feature_blob);
372 cudaEventRecord(stopNet, NULL);
375 cudaEventSynchronize(stopNet);
377 cudaEventElapsedTime(times+1, startNet, stopNet);
378 times[1] = times[1]/images.size();
382 stopNet = yarp::os::Time::now();
383 times[1] = ( stopNet - startNet ) / images.size() * 1000;
392 template<
class Dtype>
393 bool CaffeFeatExtractor<Dtype>::extractBatch_singleFeat(vector<cv::Mat> &images,
int new_batch_size, vector< Blob<Dtype>* > &features,
float (×)[2]) {
400 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty images!" << std::endl;
407 cudaEvent_t startPrep, stopPrep, startNet, stopNet;
411 cudaEventCreate(&startPrep);
412 cudaEventCreate(&stopPrep);
413 cudaEventCreate(&startNet);
414 cudaEventCreate(&stopNet);
416 cudaEventRecord(startPrep, NULL);
422 double startPrep, stopPrep, startNet, stopNet;
426 startPrep = yarp::os::Time::now();
434 Caffe::set_mode(Caffe::GPU);
435 Caffe::SetDevice(device_id);
439 Caffe::set_mode(Caffe::CPU);
443 vector<int> labels(images.size(), 0);
446 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
450 if (memory_data_layer->batch_size()!=new_batch_size)
452 if (images.size()%new_batch_size==0)
454 memory_data_layer->set_batch_size(new_batch_size);
455 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
459 if (images.size()%memory_data_layer->batch_size()==0)
461 cout <<
"WARNING: image number is not multiple of requested batch size, leaving the old one." << endl;
462 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
465 cout <<
"WARNING: image number is not multiple of batch size, setting it to 1 (performance issue)." << endl;
466 memory_data_layer->set_batch_size(1);
467 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
474 if (images.size()%memory_data_layer->batch_size()!=0)
476 cout <<
"WARNING: image number is not multiple of batch size, setting it to 1 (performance issue)." << endl;
477 memory_data_layer->set_batch_size(1);
478 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
482 int num_batches = images.size()/new_batch_size;
490 for (
int i=0; i<images.size(); i++)
492 if (images[i].rows != mean_height || images[i].cols != mean_height)
495 if (images[i].empty())
497 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty image!" << std::endl;
501 if (images[i].rows > mean_height || images[i].cols > mean_height)
503 cv::resize(images[i], images[i], cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LANCZOS4);
507 cv::resize(images[i], images[i], cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LINEAR);
512 memory_data_layer->AddMatVector(images,labels);
514 size_t num_features = blob_names.size();
517 cout<<
"Error! The list of features to be extracted has not size one!" << endl;
526 cudaEventRecord(stopPrep, NULL);
529 cudaEventSynchronize(stopPrep);
531 cudaEventElapsedTime(times, startPrep, stopPrep);
532 times[0] = times[0]/images.size();
535 cudaEventRecord(startNet, NULL);
540 stopPrep = yarp::os::Time::now();
541 times[0] = ( stopPrep - startPrep ) / images.size() * 1000;
544 startNet = yarp::os::Time::now();
552 std::vector<Blob<Dtype>*> results;
554 for (
int b=0; b<num_batches; b++)
556 results = feature_extraction_net->Forward();
558 const caffe::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[0]);
560 int batch_size = feature_blob->num();
561 int channels = feature_blob->channels();
562 int width = feature_blob->width();
563 int height = feature_blob->height();
565 features.push_back(
new Blob<Dtype>(batch_size, channels, height, width));
567 features.back()->CopyFrom(*feature_blob);
576 cudaEventRecord(stopNet, NULL);
579 cudaEventSynchronize(stopNet);
581 cudaEventElapsedTime(times+1, startNet, stopNet);
582 times[1] = times[1]/images.size();
586 stopNet = yarp::os::Time::now();
587 times[1] = ( stopNet - startNet ) / images.size() * 1000;
595 template<
class Dtype>
596 bool CaffeFeatExtractor<Dtype>::extract_multipleFeat(cv::Mat &image, vector< Blob<Dtype>* > &features,
float (×)[2]) {
604 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty image!" << std::endl;
611 cudaEvent_t startPrep, stopPrep, startNet, stopNet;
615 cudaEventCreate(&startPrep);
616 cudaEventCreate(&stopPrep);
617 cudaEventCreate(&startNet);
618 cudaEventCreate(&stopNet);
620 cudaEventRecord(startPrep, NULL);
626 double startPrep, stopPrep, startNet, stopNet;
630 startPrep = yarp::os::Time::now();
638 Caffe::set_mode(Caffe::GPU);
639 Caffe::SetDevice(device_id);
643 Caffe::set_mode(Caffe::CPU);
650 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
654 if (memory_data_layer->batch_size()!=1)
656 memory_data_layer->set_batch_size(1);
657 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
667 if (image.rows != mean_height || image.cols != mean_height)
669 if (image.rows > mean_height || image.cols > mean_height)
671 cv::resize(image, image, cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LANCZOS4);
675 cv::resize(image, image, cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LINEAR);
679 memory_data_layer->AddMatVector(vector<cv::Mat>(1, image),vector<int>(1,label));
681 size_t num_features = blob_names.size();
688 cudaEventRecord(stopPrep, NULL);
691 cudaEventSynchronize(stopPrep);
693 cudaEventElapsedTime(times, startPrep, stopPrep);
696 cudaEventRecord(startNet, NULL);
701 stopPrep = yarp::os::Time::now();
702 times[0] = (stopPrep - startPrep) * 1000;
705 startNet = yarp::os::Time::now();
713 std::vector<Blob<Dtype>*> results = feature_extraction_net->Forward();
715 for (
int f = 0; f < num_features; ++f) {
717 const caffe::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[f]);
719 int batch_size = feature_blob->num();
722 cout <<
"Error! Retrieved more than one feature, exiting..." << endl;
726 int channels = feature_blob->channels();
727 int width = feature_blob->width();
728 int height = feature_blob->height();
730 features.push_back(
new Blob<Dtype>(1, channels, height, width));
732 features.back()->CopyFrom(*feature_blob);
741 cudaEventRecord(stopNet, NULL);
744 cudaEventSynchronize(stopNet);
746 cudaEventElapsedTime(times+1, startNet, stopNet);
750 stopNet = yarp::os::Time::now();
751 times[1] = (stopNet - startNet) * 1000;
760 template<
class Dtype>
761 bool CaffeFeatExtractor<Dtype>::extract_singleFeat(cv::Mat &image, Blob<Dtype> *features,
float (×)[2]) {
768 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty image!" << std::endl;
775 cudaEvent_t startPrep, stopPrep, startNet, stopNet;
779 cudaEventCreate(&startPrep);
780 cudaEventCreate(&stopPrep);
781 cudaEventCreate(&startNet);
782 cudaEventCreate(&stopNet);
784 cudaEventRecord(startPrep, NULL);
790 double startPrep, stopPrep, startNet, stopNet;
794 startPrep = yarp::os::Time::now();
802 Caffe::set_mode(Caffe::GPU);
803 Caffe::SetDevice(device_id);
807 Caffe::set_mode(Caffe::CPU);
814 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
818 if (memory_data_layer->batch_size()!=1)
820 memory_data_layer->set_batch_size(1);
821 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
830 if (image.rows != mean_height || image.cols != mean_height)
832 if (image.rows > mean_height || image.cols > mean_height)
834 cv::resize(image, image, cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LANCZOS4);
838 cv::resize(image, image, cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LINEAR);
842 memory_data_layer->AddMatVector(vector<cv::Mat>(1, image),vector<int>(1,label));
844 size_t num_features = blob_names.size();
847 cout<<
"Error! The list of features to be extracted has not size one!" << endl;
856 cudaEventRecord(stopPrep, NULL);
859 cudaEventSynchronize(stopPrep);
861 cudaEventElapsedTime(times, startPrep, stopPrep);
864 cudaEventRecord(startNet, NULL);
869 stopPrep = yarp::os::Time::now();
870 times[0] = (stopPrep - startPrep) * 1000;
873 startNet = yarp::os::Time::now();
881 std::vector<Blob<Dtype>*> results = feature_extraction_net->Forward();
883 const caffe::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[0]);
885 int batch_size = feature_blob->num();
888 cout <<
"Error! Retrieved more than one feature, exiting..." << endl;
892 int channels = feature_blob->channels();
893 int width = feature_blob->width();
894 int height = feature_blob->height();
898 features =
new Blob<Dtype>(1, channels, height, width);
901 features->Reshape(1, channels, height, width);
904 features->CopyFrom(*feature_blob);
911 cudaEventRecord(stopNet, NULL);
914 cudaEventSynchronize(stopNet);
916 cudaEventElapsedTime(times+1, startNet, stopNet);
920 stopNet = yarp::os::Time::now();
921 times[1] = (stopNet - startNet) * 1000;
929 template<
class Dtype>
930 bool CaffeFeatExtractor<Dtype>::extractBatch_multipleFeat_1D(vector<cv::Mat> &images,
int new_batch_size, vector< vector<Dtype> > &features,
float (×)[2]) {
937 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty images!" << std::endl;
944 cudaEvent_t startPrep, stopPrep, startNet, stopNet;
948 cudaEventCreate(&startPrep);
949 cudaEventCreate(&stopPrep);
950 cudaEventCreate(&startNet);
951 cudaEventCreate(&stopNet);
953 cudaEventRecord(startPrep, NULL);
959 double startPrep, stopPrep, startNet, stopNet;
963 startPrep = yarp::os::Time::now();
971 Caffe::set_mode(Caffe::GPU);
972 Caffe::SetDevice(device_id);
976 Caffe::set_mode(Caffe::CPU);
980 vector<int> labels(images.size(), 0);
983 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
987 if (memory_data_layer->batch_size()!=new_batch_size)
989 if (images.size()%new_batch_size==0)
991 memory_data_layer->set_batch_size(new_batch_size);
992 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
996 if (images.size()%memory_data_layer->batch_size()==0)
998 cout <<
"WARNING: image number is not multiple of requested batch size,leaving the old one." << endl;
999 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
1002 cout <<
"WARNING: image number is not multiple of batch size, setting it to 1 (performance issue)." << endl;
1003 memory_data_layer->set_batch_size(1);
1004 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
1011 if (images.size()%memory_data_layer->batch_size()!=0)
1013 cout <<
"WARNING: image number is not multiple of batch size, setting it to 1 (performance issue)." << endl;
1014 memory_data_layer->set_batch_size(1);
1015 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
1019 int num_batches = images.size()/new_batch_size;
1028 for (
int i=0; i<images.size(); i++)
1030 if (images[i].rows != mean_height || images[i].cols != mean_height)
1032 if (images[i].empty())
1034 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty image!" << std::endl;
1038 if (images[i].rows > mean_height || images[i].cols > mean_height)
1040 cv::resize(images[i], images[i], cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LANCZOS4);
1044 cv::resize(images[i], images[i], cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LINEAR);
1049 memory_data_layer->AddMatVector(images,labels);
1051 size_t num_features = blob_names.size();
1058 cudaEventRecord(stopPrep, NULL);
1061 cudaEventSynchronize(stopPrep);
1063 cudaEventElapsedTime(times, startPrep, stopPrep);
1064 times[0] = times[0]/images.size();
1067 cudaEventRecord(startNet, NULL);
1072 stopPrep = yarp::os::Time::now();
1073 times[0] = ( stopPrep - startPrep ) / images.size() * 1000;
1076 startNet = yarp::os::Time::now();
1084 std::vector<Blob<Dtype>*> results;
1086 for (
int b=0; b<num_batches; ++b)
1088 results = feature_extraction_net->Forward();
1090 for (
int f = 0; f < num_features; ++f) {
1092 const caffe::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[f]);
1094 int batch_size = feature_blob->num();
1096 int feat_dim = feature_blob->count() / batch_size;
1098 if (feat_dim!=feature_blob->channels())
1100 cout<<
"Attention! The feature is not 1D: unrolling according to Caffe's order (i.e. channel, width, height)" << endl;
1103 for (
int i=0; i<batch_size; ++i)
1105 features.push_back(vector <Dtype>(feature_blob->mutable_cpu_data() + feature_blob->offset(i), feature_blob->mutable_cpu_data() + feature_blob->offset(i) + feat_dim));
1117 cudaEventRecord(stopNet, NULL);
1120 cudaEventSynchronize(stopNet);
1122 cudaEventElapsedTime(times+1, startNet, stopNet);
1123 times[1] = times[1]/images.size();
1127 stopNet = yarp::os::Time::now();
1128 times[1] = ( stopNet - startNet ) / images.size() * 1000;
1136 template<
class Dtype>
1137 bool CaffeFeatExtractor<Dtype>::extractBatch_singleFeat_1D(vector<cv::Mat> &images,
int new_batch_size, vector< vector<Dtype> > &features,
float (×)[2]) {
1144 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty images!" << std::endl;
1151 cudaEvent_t startPrep, stopPrep, startNet, stopNet;
1155 cudaEventCreate(&startPrep);
1156 cudaEventCreate(&stopPrep);
1157 cudaEventCreate(&startNet);
1158 cudaEventCreate(&stopNet);
1160 cudaEventRecord(startPrep, NULL);
1166 double startPrep, stopPrep, startNet, stopNet;
1170 startPrep = yarp::os::Time::now();
1178 Caffe::set_mode(Caffe::GPU);
1179 Caffe::SetDevice(device_id);
1183 Caffe::set_mode(Caffe::CPU);
1187 vector<int> labels(images.size(), 0);
1190 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
1194 if (memory_data_layer->batch_size()!=new_batch_size)
1196 if (images.size()%new_batch_size==0)
1198 memory_data_layer->set_batch_size(new_batch_size);
1199 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
1203 if (images.size()%memory_data_layer->batch_size()==0)
1205 cout <<
"WARNING: image number is not multiple of requested batch size,leaving the old one." << endl;
1206 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
1209 cout <<
"WARNING: image number is not multiple of batch size, setting it to 1 (performance issue)." << endl;
1210 memory_data_layer->set_batch_size(1);
1211 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
1218 if (images.size()%memory_data_layer->batch_size()!=0)
1220 cout <<
"WARNING: image number is not multiple of batch size, setting it to 1 (performance issue)." << endl;
1221 memory_data_layer->set_batch_size(1);
1222 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
1226 int num_batches = images.size()/new_batch_size;
1234 for (
int i=0; i<images.size(); i++)
1236 if (images[i].rows != mean_height || images[i].cols != mean_height)
1238 if (images[i].empty())
1240 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty image!" << std::endl;
1244 if (images[i].rows > mean_height || images[i].cols > mean_height)
1246 cv::resize(images[i], images[i], cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LANCZOS4);
1250 cv::resize(images[i], images[i], cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LINEAR);
1255 memory_data_layer->AddMatVector(images,labels);
1257 size_t num_features = blob_names.size();
1258 if (num_features!=1)
1260 cout<<
"Error! The list of features to be extracted has not size one!" << endl;
1269 cudaEventRecord(stopPrep, NULL);
1272 cudaEventSynchronize(stopPrep);
1274 cudaEventElapsedTime(times, startPrep, stopPrep);
1275 times[0] = times[0]/images.size();
1278 cudaEventRecord(startNet, NULL);
1283 stopPrep = yarp::os::Time::now();
1284 times[0] = ( stopPrep - startPrep ) / images.size() * 1000;
1287 startNet = yarp::os::Time::now();
1294 std::vector<Blob<Dtype>*> results;
1296 for (
int b=0; b<num_batches; ++b)
1298 results = feature_extraction_net->Forward();
1300 const caffe::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[0]);
1302 int batch_size = feature_blob->num();
1304 int feat_dim = feature_blob->count() / batch_size;
1305 if (feat_dim!=feature_blob->channels())
1307 cout<<
"Attention! The feature is not 1D: unrolling according to Caffe's order (i.e. channel, width, height)" << endl;
1310 for (
int i=0; i<batch_size; ++i)
1312 features.push_back(vector <Dtype>(feature_blob->mutable_cpu_data() + feature_blob->offset(i), feature_blob->mutable_cpu_data() + feature_blob->offset(i) + feat_dim));
1322 cudaEventRecord(stopNet, NULL);
1325 cudaEventSynchronize(stopNet);
1327 cudaEventElapsedTime(times+1, startNet, stopNet);
1328 times[1] = times[1]/images.size();
1332 stopNet = yarp::os::Time::now();
1333 times[1] = ( stopNet - startNet ) / images.size() * 1000;
1342 template<
class Dtype>
1343 bool CaffeFeatExtractor<Dtype>::extract_multipleFeat_1D(cv::Mat &image, vector< vector<Dtype> > &features,
float (×)[2]) {
1350 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty images!" << std::endl;
1357 cudaEvent_t startPrep, stopPrep, startNet, stopNet;
1361 cudaEventCreate(&startPrep);
1362 cudaEventCreate(&stopPrep);
1363 cudaEventCreate(&startNet);
1364 cudaEventCreate(&stopNet);
1366 cudaEventRecord(startPrep, NULL);
1372 double startPrep, stopPrep, startNet, stopNet;
1376 startPrep = yarp::os::Time::now();
1384 Caffe::set_mode(Caffe::GPU);
1385 Caffe::SetDevice(device_id);
1389 Caffe::set_mode(Caffe::CPU);
1396 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
1400 if (memory_data_layer->batch_size()!=1)
1402 memory_data_layer->set_batch_size(1);
1403 cout <<
"BATCH SIZE = " << memory_data_layer->batch_size() << endl;
1412 if (image.rows != mean_height || image.cols != mean_height)
1414 if (image.rows > mean_height || image.cols > mean_height)
1416 cv::resize(image, image, cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LANCZOS4);
1420 cv::resize(image, image, cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LINEAR);
1424 memory_data_layer->AddMatVector(vector<cv::Mat>(1, image),vector<int>(1,label));
1426 size_t num_features = blob_names.size();
1433 cudaEventRecord(stopPrep, NULL);
1436 cudaEventSynchronize(stopPrep);
1438 cudaEventElapsedTime(times, startPrep, stopPrep);
1441 cudaEventRecord(startNet, NULL);
1446 stopPrep = yarp::os::Time::now();
1447 times[0] = (stopPrep - startPrep) * 1000;
1450 startNet = yarp::os::Time::now();
1458 std::vector<Blob<Dtype>*> results = feature_extraction_net->Forward();
1460 for (
int f = 0; f < num_features; ++f) {
1462 const caffe::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[f]);
1464 int batch_size = feature_blob->num();
1467 cout <<
"Error! Retrieved more than one feature, exiting..." << endl;
1471 int feat_dim = feature_blob->count();
1472 if (feat_dim!=feature_blob->channels())
1474 cout<<
"Attention! The feature is not 1D: unrolling according to Caffe's order (i.e. channel, width, height)" << endl;
1477 features.push_back(vector <Dtype>(feature_blob->mutable_cpu_data() + feature_blob->offset(0), feature_blob->mutable_cpu_data() + feature_blob->offset(0) + feat_dim));
1486 cudaEventRecord(stopNet, NULL);
1489 cudaEventSynchronize(stopNet);
1491 cudaEventElapsedTime(times+1, startNet, stopNet);
1495 stopNet = yarp::os::Time::now();
1496 times[1] = (stopNet - startNet) * 1000;
1505 template<
class Dtype>
1506 bool CaffeFeatExtractor<Dtype>::extract_singleFeat_1D(cv::Mat &image, vector<Dtype> &features,
float (×)[2]) {
1513 std::cout <<
"CaffeFeatExtractor::extractBatch_multipleFeat(): empty images!" << std::endl;
1520 cudaEvent_t startPrep, stopPrep, startNet, stopNet;
1524 cudaEventCreate(&startPrep);
1525 cudaEventCreate(&stopPrep);
1526 cudaEventCreate(&startNet);
1527 cudaEventCreate(&stopNet);
1529 cudaEventRecord(startPrep, NULL);
1535 double startPrep, stopPrep, startNet, stopNet;
1539 startPrep = yarp::os::Time::now();
1547 Caffe::set_mode(Caffe::GPU);
1548 Caffe::SetDevice(device_id);
1552 Caffe::set_mode(Caffe::CPU);
1559 caffe::shared_ptr<MemoryDataLayer<Dtype> > memory_data_layer = boost::dynamic_pointer_cast<caffe::MemoryDataLayer<Dtype> >(feature_extraction_net->layers()[0]);
1562 if (memory_data_layer->batch_size()!=1)
1564 memory_data_layer->set_batch_size(1);
1565 std::cout <<
"CaffeFeatExtractor::extract_singleFeat_1D(): BATCH SIZE = " << memory_data_layer->batch_size() << std::endl;
1572 if (image.rows != mean_height || image.cols != mean_height)
1574 if (image.rows > mean_height || image.cols > mean_height)
1576 cv::resize(image, image, cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LANCZOS4);
1580 cv::resize(image, image, cv::Size(mean_height, mean_width), 0, 0, cv::INTER_LINEAR);
1584 memory_data_layer->AddMatVector(vector<cv::Mat>(1, image),vector<int>(1,label));
1586 size_t num_features = blob_names.size();
1589 std::cout <<
"CaffeFeatExtractor::extract_singleFeat_1D(): Error! The list of features to be extracted has not size one!" << std::endl;
1598 cudaEventRecord(stopPrep, NULL);
1601 cudaEventSynchronize(stopPrep);
1603 cudaEventElapsedTime(times, startPrep, stopPrep);
1606 cudaEventRecord(startNet, NULL);
1611 stopPrep = yarp::os::Time::now();
1612 times[0] = (stopPrep - startPrep) * 1000;
1615 startNet = yarp::os::Time::now();
1623 std::vector<Blob<Dtype>*> results = feature_extraction_net->Forward();
1625 const caffe::shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net->blob_by_name(blob_names[0]);
1627 int batch_size = feature_blob->num();
1630 std::cout <<
"CaffeFeatExtractor::extract_singleFeat_1D(): Error! Retrieved more than one feature, exiting..." << std::endl;
1634 int feat_dim = feature_blob->count();
1635 if (feat_dim!=feature_blob->channels())
1637 std::cout <<
"CaffeFeatExtractor::extract_singleFeat_1D(): Attention! The feature is not 1D: unrolling according to Caffe's order (i.e. channel, height, width)" << std::endl;
1640 features.insert(features.end(), feature_blob->mutable_cpu_data() + feature_blob->offset(0), feature_blob->mutable_cpu_data() + feature_blob->offset(0) + feat_dim);
1647 cudaEventRecord(stopNet, NULL);
1650 cudaEventSynchronize(stopNet);
1652 cudaEventElapsedTime(times+1, startNet, stopNet);
1656 stopNet = yarp::os::Time::now();
1657 times[1] = (stopNet - startNet) * 1000;