vector - Error when I push back a pair in C++ -
i've been trying compile program should push string , float pair on vector:
typedef std::pair<string, float> prediction; std::vector<prediction> predictions; ( int = 0 ; < output.size(); i++ ) { std::vector<int> maxn = argmax(output[i], 1); int idx = maxn[0]; predictions.push_back(std::make_pair(labels_[idx], output[idx])); } return predictions;
however, every time try compile this, error:
error: no matching member function call 'push_back' predictions.push_back(std::make_pair(labels_[idx], output[idx]));
i few other warnings saying things like
candidate function not viable: no known conversion 'pair<[...], typename __make_pair_return > &>::type>' 'const pair<[...], float>' 1st argument _libcpp_inline_visibility void push_back(const_reference __x);
and
candidate function not viable: no known conversion 'pair<[...], typename __make_pair_return > &>::type>' 'pair<[...], float>' 1st argument _libcpp_inline_visibility void push_back(value_type&& __x);
i've been trying rewrite things , modify functions can't work out why error remains, know can fix this?
here code in context if helps, header file:
/** * classification system */ #ifndef __classifier_h__ #define __classifier_h__ #include <caffe/caffe.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <algorithm> #include <iosfwd> #include <memory> #include <string> #include <utility> #include <vector> using namespace caffe; // nolint(build/namespaces) using std::string; /* pair (label, confidence) representing prediction. */ typedef std::pair<string, float> prediction; class classifier { public: classifier(const string& model_file, const string& trained_file, const string& label_file); std::vector< prediction > classify(const std::vector<cv::mat>& img); private: std::vector< std::vector<float> > predict(const std::vector<cv::mat>& img, int nimages); void wrapinputlayer(std::vector<cv::mat>* input_channels, int nimages); void preprocess(const std::vector<cv::mat>& img, std::vector<cv::mat>* input_channels, int nimages); private: shared_ptr<net<float> > net_; cv::size input_geometry_; int num_channels_; std::vector<string> labels_; }; #endif /* __classifier_h__ */
class file:
#define cpu_only #include "classifier.h" using namespace caffe; // nolint(build/namespaces) using std::string; classifier::classifier(const string& model_file, const string& trained_file, const string& label_file) { #ifdef cpu_only caffe::set_mode(caffe::cpu); #else caffe::set_mode(caffe::gpu); #endif /* load network. */ net_.reset(new net<float>(model_file, test)); net_->copytrainedlayersfrom(trained_file); check_eq(net_->num_inputs(), 1) << "network should have 1 input."; check_eq(net_->num_outputs(), 1) << "network should have 1 output."; blob<float>* input_layer = net_->input_blobs()[0]; 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 labels. */ std::ifstream labels(label_file.c_str()); check(labels) << "unable open labels file " << label_file; string line; while (std::getline(labels, line)) labels_.push_back(string(line)); blob<float>* output_layer = net_->output_blobs()[0]; check_eq(labels_.size(), output_layer->channels()) << "number of labels different output layer dimension."; } static bool paircompare(const std::pair<float, int>& lhs, const std::pair<float, int>& rhs) { return lhs.first > rhs.first; } /* return indices of 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; (size_t = 0; < 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; (int = 0; < n; ++i) result.push_back(pairs[i].second); return result; } std::vector<prediction> classifier::classify(const std::vector<cv::mat>& img) { std::vector< std::vector<float> > output = predict(img, img.size()); std::vector<prediction> predictions; ( int = 0 ; < output.size(); i++ ) { std::vector<int> maxn = argmax(output[i], 1); int idx = maxn[0]; predictions.push_back(std::make_pair(labels_[idx], output[idx])); } return predictions; } std::vector< std::vector<float> > classifier::predict(const std::vector<cv::mat>& img, int nimages) { blob<float>* input_layer = net_->input_blobs()[0]; input_layer->reshape(nimages, num_channels_, input_geometry_.height, input_geometry_.width); /* forward dimension change layers. */ net_->reshape(); std::vector<cv::mat> input_channels; wrapinputlayer(&input_channels, nimages); preprocess(img, &input_channels, nimages); net_->forwardprefilled(); /* copy output layer std::vector */ blob<float>* output_layer = net_->output_blobs()[0]; std::vector <std::vector<float> > ret; (int = 0; < nimages; i++) { const float* begin = output_layer->cpu_data() + i*output_layer->channels(); const float* end = begin + output_layer->channels(); ret.push_back( std::vector<float>(begin, end) ); } return ret; } /* wrap input layer of network in separate cv::mat objects * (one per channel). way save 1 memcpy operation , * don't need rely on cudamemcpy2d. last preprocessing * operation write separate channels directly input * layer. */ void classifier::wrapinputlayer(std::vector<cv::mat>* input_channels, int nimages) { 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(); (int = 0; < input_layer->channels()* nimages; ++i) { cv::mat channel(height, width, cv_32fc1, input_data); input_channels->push_back(channel); input_data += width * height; } } void classifier::preprocess(const std::vector<cv::mat>& img, std::vector<cv::mat>* input_channels, int nimages) { (int = 0; < nimages; i++) { vector<cv::mat> channels; cv::split(img[i], channels); (int j = 0; j < channels.size(); j++){ channels[j].copyto((*input_channels)[i*num_channels_[0]+j]); } } }
thanks much!
typedef std::pair<string, float> prediction; std::vector<prediction> predictions; std::vector< std::vector<float> > output = predict(img, img.size());
make_pair expects string , float. output[idx] gives vector of floats. need output[i][idx] float.
Comments
Post a Comment