Linux下C++调用python中训好的mxnet模型
这段时间在搞C++调用mxnet模型,感觉网上资料很少,所以这里分享一下自己写好的代码#include// Path for c_predict_api#include#include#include#include#include#includeconst mx_float DEFAULT_MEAN = 117.0;// Read file to b
·
这段时间在搞C++调用mxnet模型,感觉网上资料很少,所以这里分享一下自己写好的代码
#include <stdio.h>
// Path for c_predict_api
#include </home/nvidia/incubator-mxnet/include/mxnet/c_predict_api.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
const mx_float DEFAULT_MEAN = 117.0;
// Read file to buffer
class BufferFile {
public :
std::string file_path_;
int length_;
char* buffer_;
explicit BufferFile(std::string file_path)
:file_path_(file_path) {
std::ifstream ifs(file_path.c_str(), std::ios::in | std::ios::binary);
if (!ifs) {
std::cerr << "Can't open the file. Please check " << file_path << ". \n";
length_ = 0;
buffer_ = NULL;
return;
}
ifs.seekg(0, std::ios::end);
length_ = ifs.tellg();
ifs.seekg(0, std::ios::beg);
std::cout << file_path.c_str() << " ... "<< length_ << " bytes\n";
buffer_ = new char[sizeof(char) * length_];
ifs.read(buffer_, length_);
ifs.close();
}
int GetLength() {
return length_;
}
char* GetBuffer() {
return buffer_;
}
~BufferFile() {
if (buffer_) {
delete[] buffer_;
buffer_ = NULL;
}
}
};
void GetImageFile(const std::string image_file,
mx_float* image_data, const int channels,
const cv::Size resize_size, const mx_float* mean_data = NULL) {
// Read all kinds of file into a BGR color 3 channels image
cv::Mat im_ori = cv::imread(image_file, cv::IMREAD_COLOR);
if (im_ori.empty()) {
std::cerr << "Can't open the image. Please check " << image_file << ". \n";
assert(false);
}
cv::Mat im;
resize(im_ori, im, resize_size);
int size = im.rows * im.cols * channels;
mx_float* ptr_image_r = image_data;
mx_float* ptr_image_g = image_data + size / 3;
mx_float* ptr_image_b = image_data + size / 3 * 2;
float mean_b, mean_g, mean_r;
mean_b = mean_g = mean_r = DEFAULT_MEAN;
for (int i = 0; i < im.rows; i++) {
uchar* data = im.ptr<uchar>(i);
for (int j = 0; j < im.cols; j++) {
if (mean_data) {
mean_r = *mean_data;
if (channels > 1) {
mean_g = *(mean_data + size / 3);
mean_b = *(mean_data + size / 3 * 2);
}
mean_data++;
}
if (channels > 1) {
*ptr_image_b++ = static_cast<mx_float>(*data++) - mean_b;
*ptr_image_g++ = static_cast<mx_float>(*data++) - mean_g;
}
*ptr_image_r++ = static_cast<mx_float>(*data++) - mean_r;;
}
printf("get an image");
}
}
// LoadSynsets
// Code from : https://github.com/pertusa/mxnet_predict_cc/blob/master/mxnet_predict.cc
void PrintOutputResult(const std::vector<float>& data) {
float best_accuracy = 0.0;
int best_idx = 0;
for ( int i = 0; i < static_cast<int>(data.size()); i++ ) {
printf("Accuracy[%d] = %.8f\n", i, data[i]);
if ( data[i] > best_accuracy ) {
best_accuracy = data[i];
best_idx = i;
}
}
printf("Best Result: id = %d, accuracy = %.8f\n", best_idx, best_accuracy);
}
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cout << "No test image here." << std::endl
<< "Usage: ./image-classification-predict apple.jpg" << std::endl;
return 0;
}
std::string test_file;
test_file = std::string(argv[1]);
// Models path for your model, you have to modify it
std::string json_file = "lenet.json";
std::string param_file = "lenet.params";
BufferFile json_data(json_file);
BufferFile param_data(param_file);
// Parameters
int dev_type = 2; // 1: cpu, 2: gpu
int dev_id = 0; // arbitrary.
mx_uint num_input_nodes = 1; // 1 for feedforward
const char* input_key[1] = {"data"};
const char** input_keys = input_key;
// Image size and channels
int width = 32;
int height = 32;
int channels = 1;
const mx_uint input_shape_indptr[2] = { 0, 4 };
const mx_uint input_shape_data[4] = { 1,
static_cast<mx_uint>(channels),
static_cast<mx_uint>(height),
static_cast<mx_uint>(width)};
PredictorHandle pred_hnd = 0;
if (json_data.GetLength() == 0 ||
param_data.GetLength() == 0) {
return -1;
}
// Create Predictor
assert(0==MXPredCreate((const char*)json_data.GetBuffer(),
(const char*)param_data.GetBuffer(),
static_cast<size_t>(param_data.GetLength()),
dev_type,
dev_id,
num_input_nodes,
input_keys,
input_shape_indptr,
input_shape_data,
&pred_hnd));
assert(pred_hnd);
int image_size = width * height * channels;
// Read Mean Data
const mx_float* nd_data = NULL;
// Read Image Data
std::vector<mx_float> image_data = std::vector<mx_float>(image_size);
GetImageFile(test_file, image_data.data(),
channels, cv::Size(width, height));
// Set Input Image
MXPredSetInput(pred_hnd, "data", image_data.data(), image_size);
// Do Predict Forward
MXPredForward(pred_hnd);
mx_uint output_index = 0;
mx_uint *shape = 0;
mx_uint shape_len;
// Get Output Result
MXPredGetOutputShape(pred_hnd, output_index, &shape, &shape_len);
size_t size = 1;
for (mx_uint i = 0; i < shape_len; ++i) size *= shape[i];
std::vector<float> data(size);
MXPredGetOutput(pred_hnd, output_index, &(data[0]), size);
// Release Predictor
MXPredFree(pred_hnd);
// Print Output Data
PrintOutputResult(data);
return 0;
}
这个代码可以直接用,只要改一下json和params文件路径以及图片的大小和通道数,假设编译完成后为main,则./main test.jpg即可
更多推荐
已为社区贡献1条内容
所有评论(0)