【记录】Anomalib项目中的padim算法在Centos的部署

1.首先获得padim算法的onnx权重。

2.根据该博主的博文https://blog.csdn.net/m0_57315535/article/details/131749856?spm=1001.2014.3001.5502

得到padim算法的c++推理过程,通过本人小修改代码如下:

inferencer.cpp

#include"Inferencer.h"

Inferencer::Inferencer(const char* modelPath)
{
	Ort::Env env(ORT_LOGGING_LEVEL_WARNING);
	Ort::SessionOptions session_options;
	session_options.SetIntraOpNumThreads(1);
	session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
	cout << "Onnxruntime C++ API\n";
	session = new Ort::Session(env, modelPath, session_options);
}

void Inferencer::preProcess(const cv::Mat& image, cv::Mat& image_blob)
{
	cv::Mat input;
	image.copyTo(input);



	std::vector<cv::Mat> channels, channel_p;
	split(input, channels);
	cv::Mat R, G, B;
	B = channels.at(0);
	G = channels.at(1);
	R = channels.at(2);

	B = (B / 255. - 0.406) / 0.225;
	G = (G / 255. - 0.456) / 0.224;
	R = (R / 255. - 0.485) / 0.229;

	channel_p.push_back(R);
	channel_p.push_back(G);
	channel_p.push_back(B);

	cv::Mat outt;
	merge(channel_p, outt);
	image_blob = outt;
}

void Inferencer::InitOnnxEnv()
{

	auto num_input_nodes = session->GetInputCount();
	auto num_output_nodes = session->GetOutputCount();
	cout << "Number of inputs = " << num_input_nodes << endl;
	cout << "Number of outputs = " << num_output_nodes << endl;

	this->input_dims = session->GetInputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
	this->output_dims = session->GetOutputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape();
	cout << "input_dims:" << this->input_dims[3] << endl;
	cout << "output_dims:" << this->output_dims[3] << endl;
	Ort::AllocatorWithDefaultOptions allocator;
	auto input_name_ptr = session->GetInputNameAllocated(0, allocator);
	this->input_node_names.push_back(input_name_ptr.get());
	auto output_name_ptr = session->GetOutputNameAllocated(0, allocator);
	this->output_node_names.push_back(output_name_ptr.get());
}

void Inferencer::generateHeatMap(cv::Mat& input, cv::Mat& heatMap, cv::Mat& predMask, cv::Mat& contourMap, cv::Mat& boxMap)
{
	float image_threshold = 13.793981552124023;
	float pixel_threshold = 13.793981552124023;
	float min_val = 2.551008462905884;
	float max_val = 27.169368743896484;
	cv::Mat det1, det2;
	cv::resize(input, det1, cv::Size(256,256), cv::INTER_AREA);
	det1.convertTo(det1, CV_32FC3);
	Inferencer::preProcess(det1, det2);
	cv::Mat blob = cv::dnn::blobFromImage(det2, 1., cv::Size(256,256), cv::Scalar(0, 0, 0), false, true);
	cout << "���سɹ�!" << endl;

	clock_t startTime, endTime;

	auto memory_info = Ort::MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault);
	vector<Ort::Value> input_tensors;
	input_tensors.push_back(Ort::Value::CreateTensor<float>(memory_info, blob.ptr<float>(), blob.total(), input_dims.data(), input_dims.size()));
	startTime = clock();
	//auto output_tensors = session->Run(Ort::RunOptions{ nullptr }, input_node_names.data(), input_tensors.data(), input_node_names.size(), output_node_names.data(), output_node_names.size());
	const char* ch_in = "input";
	const char* const* p_in = &ch_in;
	const char* ch_out = "output";
	const char* const* p_out = &ch_out;

	auto output_tensors = session->Run(Ort::RunOptions{ nullptr }, p_in, input_tensors.data(), 1, p_out, 1);
	endTime = clock();
	assert(output_tensors.size() == 1 && output_tensors.front().IsTensor());

	float* floatarr = output_tensors[0].GetTensorMutableData<float>();
	cv::Mat anomalyMap = cv::Mat_<float>(256,256);
	int k = 0;
	for (int i = 0; i < 256; i++)
	{
		for (int j = 0; j < 256; j++) 
		{
			float val = floatarr[++k];
			//cout << val << endl;
			anomalyMap.at<float>(i, j) = val;

		}
	}
	cv::Mat norm = ((anomalyMap - pixel_threshold) / (max_val - min_val)) + 0.5;
	norm *= 255;
	cv::Mat normUint8;
	norm.convertTo(normUint8, CV_8UC1);
	cv::Mat colorMap;
	cv::applyColorMap(normUint8, colorMap, cv::COLORMAP_JET);
	cv::imwrite("colormap.jpg", colorMap);
	cv::resize(input, input, cv::Size(256,256));
	cv::addWeighted(colorMap, 0.4, input, 0.6, 0, heatMap);
	cv::imwrite("heatmap.jpg", heatMap);
	cv::threshold(anomalyMap, predMask, pixel_threshold, 255, CV_THRESH_BINARY);
	predMask.convertTo(predMask, CV_8UC1);
	cv::resize(input, contourMap, cv::Size(256,256));
	vector<vector<cv::Point>> contours;
	cv::findContours(predMask, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
	cv::drawContours(contourMap, contours, -1, cv::Scalar(0, 0, 255), 2);
	cv::resize(input, boxMap, cv::Size(256,256));
	for (int i = 0; i < contours.size(); i++)
	{
		cv::Rect rect = cv::boundingRect(contours[i]);
		cv::rectangle(boxMap, rect, cv::Scalar(0, 255, 0), 1);
	}
	cv::imwrite("bad.jpg", boxMap);
}
int main(void)
{
	//string onnxpth = "model.onnx";
	const char* modelPath = "/home/master/code/code2/model.onnx";
	cout << "1111" << endl;
	
	string imgpath = "/home/master/code/code2/011.png";
	cv::Mat srcimg = cv::imread(imgpath);
	cv::Mat heatMap, predMask, contourMap,boxMap;
	cout << "daoda" << endl;
	Inferencer myinfer(modelPath);
	myinfer.InitOnnxEnv();
	myinfer.generateHeatMap(srcimg, heatMap, predMask, contourMap, boxMap);
	system("pause");
	return 0;
}

inferencer.h

#pragma once
#include<onnxruntime_cxx_api.h>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/dnn.hpp>
#include <iostream>
#include <assert.h>
#include <vector>
#include <fstream>

using namespace std;

class Inferencer
{
private:
	Ort::Session* session;                                        
	Ort::Env _env;
	void preProcess(const cv::Mat& image, cv::Mat& image_blob);    
	vector<int64_t> input_dims;
	vector<int64_t> output_dims;
	vector<char*> input_node_names;
	vector<char*> output_node_names;

public:
	Inferencer(const char* modelPath);                        
	void InitOnnxEnv();                                         
	void generateHeatMap(cv::Mat& input, cv::Mat& heatMap, cv::Mat& predMask, cv::Mat& contourMap, cv::Mat& boxMap);

};

3.安装相关环境

        3.1 安装opencv

                参考该博主博文https://blog.csdn.net/qq_42950957/article/details/123899581

         3.2下载onnxruntime.

                https://github.com/microsoft/onnxruntime

                通过该链接下载linux版本的即可。

4.编写CMakeList.txt

cmake_minimum_required(VERSION 3.0.0)
project(ov_cpp VERSION 0.1.0 LANGUAGES C CXX)

include(CTest)
enable_testing()


set(CMAKE_CXX_FLAGS "-std=c++11")
include_directories(${INC_DIR})


add_executable(ov_cpp inferencer.cpp)

include(CPack)

find_package(OpenCV)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(ov_cpp ${OpenCV_LIBS})


#onnxruntime
set(ONNXRUNTIME_ROOT_PATH /home/master/onnxruntime-linux-x64-1.14.0/)
set(ONNXRUNTIME_INCLUDE_DIRS ${ONNXRUNTIME_ROOT_PATH}/include/)
set(ONNXRUNTIME_LIB ${ONNXRUNTIME_ROOT_PATH}lib/libonnxruntime.so)

# name of executable file and path of source file

include_directories(${ONNXRUNTIME_INCLUDE_DIRS})
target_link_libraries(ov_cpp ${ONNXRUNTIME_LIB})

4.编译

创建build文件夹在下面打开终端

cmake ..
make

生成ov_cpp,运行ov_cpp获得检测结果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mmasterer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值