分割一切模型 Fast SAM C++推理部署

晓理紫
0 XX开局一张图,剩下…
本文记录只为日后更好学习
1 Fast SAM 简介
Fast SAM是仅使用SAM作者发布的SA-1B数据集的2%进行训练的CNN任意分割模型 。的性能与SAM方法相当,运行速度提高了50倍 。
2 部署 2.1 环境与条件

分割一切模型 Fast SAM C++推理部署

文章插图
这个就网上自行解决
2.2 onnx模型转换
本文参考进行转换,在转换过程中需要把设置为None,采用静态维度进行,在核心源码中我们提供了640以及1024大小的onnx模型 。相关核心代码如下:
torch.onnx.export(model, img,output_model_path,export_params=True,opset_version=11,do_constant_folding=True,input_names = ['images'],output_names = output_names,dynamic_axes=None)
注意:=None这个最为关键,当然你也可以试试设置为
2.3 部署核心代码
模型转换完成以后,剩下的就是部署推理 。部署推理里面最为重要也是最难搞的是数据解析部分 。其中模型加载是很标准的流程,当然我这里不一定是标准的 。
sessionOptions.SetExecutionMode(ORT_SEQUENTIAL);sessionOptions.EnableCpuMemArena();sessionOptions.SetIntraOpNumThreads(1);sessionOptions.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);ort_session = new Session(env, model_path.data(), sessionOptions);size_t numInputNodes = ort_session->GetInputCount();size_t numOutputNodes = ort_session->GetOutputCount();Ort::AllocatorWithDefaultOptions allocator;for (int i = 0; i < numInputNodes; i++) {this->input_names.emplace(ort_session->GetInputNameAllocated(i, allocator));Ort::TypeInfo input_type_info = ort_session->GetInputTypeInfo(i);auto input_tensor_info = input_type_info.GetTensorTypeAndShapeInfo();auto input_dims = input_tensor_info.GetShape();input_node_dims.push_back(input_dims);}for (int i = 0; i < numOutputNodes; i++) {this->output_names.emplace(ort_session->GetOutputNameAllocated(i, allocator));Ort::TypeInfo output_type_info = ort_session->GetOutputTypeInfo(i);auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();auto output_dims = output_tensor_info.GetShape();output_node_dims.push_back(output_dims);}this->inpHeight = input_node_dims[0][2];this->inpWidth = input_node_dims[0][3];input_names__[0] = input_names->get();
模型加载以后,就可以送入数据进行推理
xiaoliziprocessImage(frame, tmp);this->xiaoliziNormalize_(tmp);array input_shape_{1, 3, this->inpHeight, this->inpWidth};auto allocator_info =MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);Value input_tensor_ = Value::CreateTensor(allocator_info, input_image_.data(), input_image_.size(),input_shape_.data(), input_shape_.size());vector ort_outputs = ort_session->Run(RunOptions{nullptr}, input_names__, &input_tensor_, 1, output_names__,sizeof(output_names__) / sizeof(char *)); // 开始推理
推理以后就可以获取数据并进行解析
std::vector matVec;float *pdata = http://www.kingceram.com/post/nullptr;pdata = ort_outputs[0].GetTensorMutableData();if (pdata =http://www.kingceram.com/post/= nullptr) {std::cout <<"pdata is nullptr" << std::endl;return;}cv::Mat matData(37, OUTPUT0w, CV_32F, pdata);matVec.push_back(matData);float *pdata5 = nullptr;pdata5 = ort_outputs[5].GetTensorMutableData();if (pdata5 == nullptr) {std::cout << "pdata or pdata5 is nullptr" << std::endl;return;}cv::Mat matData5(32, OUTPUT1167w * OUTPUT1167w, CV_32F, pdata5);matVec.push_back(matData5);
首先是对数据进行分割处理并进行NMS获取box、lab以及mask相关信息
cv::Mat box;cv::Mat cls;cv::Mat mask;box = temData.colRange(0, 4).clone();cls = temData.colRange(4, 5).clone();mask = temData.colRange(5, temData.cols).clone();cv::Mat j = cv::Mat::zeros(cls.size(), CV_32F);cv::Mat dst;cv::hconcat(box, cls, dst); // dst=[AB]cv::hconcat(dst, j, dst);cv::hconcat(dst, mask, dst);std::vector