Pytorch学习系列之十二:OpenCV(C++)加载onnx模型进行推理

Pytorch学习系列之十二:OpenCV(C++)加载onnx模型进行推理,第1张

1 前言

博客Pytorch学习系列之九:OpenCV加载onnx模型进行推理_thequitesunshine007的博客-CSDN博客_opencv 加载onnx记载了python版本opencv加载onnx模型进行推理的方法。


这里记录的是C++版本OpenCV加载onnx模型进行推理。


2 代码
#include
#include
#include
#include 
#include
#include
#include
#include
using namespace cv;
using namespace std;

class ONNXClassifier
{
public:
	ONNXClassifier(const std::string& model_path, const std::string& label_path, cv::Size _input_size);
	void Classify(const cv::Mat& input_image, std::string& out_name, double& confidence);
private:
	void preprocess_input(cv::Mat& image);
	bool read_labels(const std::string& label_paht);
private:
	cv::Size		input_size;
	cv::dnn::Net	net;
	cv::Scalar		default_mean;
	cv::Scalar		default_std;
	std::vector labels;
};

ONNXClassifier::ONNXClassifier(const std::string& model_path, const std::string& label_path, cv::Size _input_size) 
	:default_mean(0.485, 0.456, 0.406),
	default_std(0.229, 0.224, 0.225), input_size(_input_size)
{
	if (!read_labels(label_path))
	{
		throw std::runtime_error("label read fail!");
	}
	net = cv::dnn::readNet(model_path);
	net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
	net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
}

bool ONNXClassifier::read_labels(const std::string& label_path)
{
	std::ifstream ifs(label_path);
	assert(ifs.is_open());
	std::string line;
	while (std::getline(ifs, line))
	{
		std::size_t index = line.find_first_of(':');
		labels.push_back(line.substr(index + 1));
	}
	if (labels.size() > 0)
		return true;
	else
		return false;
}

//数据规范化Normalization
void ONNXClassifier::preprocess_input(cv::Mat& image)
{
	image.convertTo(image, CV_32F, 1.0 / 255.0);
	cv::subtract(image, default_mean, image);
	cv::divide(image, default_std, image);
}

void ONNXClassifier::Classify(const cv::Mat& input_image, std::string& out_name, double& confidence)
{
	out_name.clear();
	cv::Mat image = input_image.clone();
	preprocess_input(image);
	cv::Mat input_blob = cv::dnn::blobFromImage(image, 1.0, input_size, cv::Scalar(0, 0, 0), true);
	net.setInput(input_blob);
	const std::vector& out_names = net.getUnconnectedOutLayersNames();
	cv::Mat out_tensor = net.forward(out_names[0]);
	cv::Point maxLoc;
	double minV;
	cv::minMaxLoc(out_tensor, &minV, &confidence, (cv::Point*)0, &maxLoc);
	out_name = labels[maxLoc.x];
}


int main(int argc, char* argv[])
{
	cv::utils::logging::setLogLevel(cv::utils::logging::LogLevel::LOG_LEVEL_SILENT);
	
	//std::string model_path("../model/classifier.onnx");
	//std::string label_path("../model/labels.txt");
	//cv::Size input_size(224, 224);


	std::vector imgVec;
	cv::glob("./defect_test/", imgVec);
	std::string model_path("../model/surface_defect_model.onnx");
	std::string label_path("../model/labels_defect.txt");
	cv::Size input_size(300, 300);

	for (size_t i = 0; i < imgVec.size(); i++)
	{
		cv::Mat test_image = cv::imread(imgVec[i], cv::IMREAD_COLOR);
		ONNXClassifier classifier(model_path, label_path, input_size);
		std::string result;
		double confidence = 0;
		classifier.Classify(test_image, result, confidence);
		std::cout << imgVec[i] <<",预测结果为:"<< result<<",confidence: " << confidence << std::endl;
	}

	
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/577592.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存