部署系列六基于nndeploy的深度学习 图像降噪unet部署

文章目录

    • 1.直接在源代码demo中修改
    • 2. 如何修改呢?

https://github.com/DeployAI/nndeploy
https://nndeploy-zh.readthedocs.io/zh/latest/introduction/index.html

1.直接在源代码demo中修改

如果你想运行yolo5:
onnxruntime:115ms
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeOnnxRuntime --device_type kDeviceTypeCodeX86:0 --model_type kModelTypeOnnx --is_path --model_value …/…/yolov5s.onnx --input_type kInputTypeImage --input_path …/…/sample.jpg --output_path …/…/sample_output.jpg

openvino:57ms
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeOpenVino --device_type kDeviceTypeCodeX86:0 --model_type kModelTypeOnnx --is_path --model_value …/…/yolov5s.onnx --input_type kInputTypeImage --input_path …/…/sample.jpg --output_path …/…/sample_output.jpg

mnn:78ms
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeMnn --device_type kDeviceTypeCodeX86:0 --model_type kModelTypeMnn --is_path --model_value …/…/yolov5s.mnn --input_type kInputTypeImage --input_path …/…/sample.jpg --output_path …/…/sample_output.jpg

tensorrt: 17ms
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeTensorRt --device_type kDeviceTypeCodeCuda:0 --model_type kModelTypeOnnx --is_path --model_value …/…/yolov5s.onnx --input_type kInputTypeImage --input_path …/…/sample.jpg --output_path …/…/sample_output.jpg

然后我直接修改源码然后通过下面的命令 可以运行 unet de model
modify for unet
tensorrt
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeTensorRt --device_type kDeviceTypeCodeCuda:0 --model_type kModelTypeOnnx --is_path --model_value /home/tony/nndeploy/mymodel/scripts/unet8.opt.onnx --input_type kInputTypeImage --input_path …/…/1007_01_06_40_000101.png --output_path …/…/sample_output.jpg

onnxruntime
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeOnnxRuntime --device_type kDeviceTypeCodeX86:0 --model_type kModelTypeOnnx --is_path --model_value /home/tony/nndeploy/mymodel/scripts/unet8.opt.onnx --input_type kInputTypeImage --input_path …/…/1007_01_06_40_000101.png --output_path …/…/sample_output.jpg

openvino:
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeOpenVino --device_type kDeviceTypeCodeX86:0 --model_type kModelTypeOnnx --is_path --model_value /home/tony/nndeploy/mymodel/scripts/unet8.opt.onnx --input_type kInputTypeImage --input_path …/…/1007_01_06_40_000101.png --output_path …/…/sample_output.jpg

MNN:
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeMnn --device_type kDeviceTypeCodeX86:0 --model_type kModelTypeMnn --is_path --model_value /home/tony/nndeploy/mymodel/scripts/unet8.opt.mnn --input_type kInputTypeImage --input_path …/…/1007_01_06_40_000101.png --output_path …/…/sample_output.jpg

TNN:
./install/lib/demo_nndeploy_detect --name NNDEPLOY_YOLOV5 --inference_type kInferenceTypeTnn --device_type kDeviceTypeCodeX86:0 --model_type kModelTypeTnn --is_path --model_value /home/tony/nndeploy/mymodel/scripts/unet8.sim.tnnproto,/home/tony/nndeploy/mymodel/scripts/unet8.sim.tnnmodel --input_type kInputTypeImage --input_path …/…/1007_01_06_40_000101.png --output_path …/…/sample_output.jpg

2. 如何修改呢?

首先修改demo.cc

输入是 h,w,c float32
输出也是h,w,c float32
在这里插入图片描述
完整代码:

#include "flag.h"
#include "nndeploy/base/glic_stl_include.h"
#include "nndeploy/base/time_profiler.h"
#include "nndeploy/dag/node.h"
#include "nndeploy/device/device.h"
#include "nndeploy/model/detect/yolo/yolo.h"

using namespace nndeploy;

cv::Mat drawBox(cv::Mat &cv_mat, model::DetectResult &result) {
  // float w_ratio = float(cv_mat.cols) / float(640);
  // float h_ratio = float(cv_mat.rows) / float(640);
  float w_ratio = float(cv_mat.cols);
  float h_ratio = float(cv_mat.rows);
  const int CNUM = 80;
  cv::RNG rng(0xFFFFFFFF);
  cv::Scalar_<int> randColor[CNUM];
  for (int i = 0; i < CNUM; i++)
    rng.fill(randColor[i], cv::RNG::UNIFORM, 0, 256);
  int i = -1;
  for (auto bbox : result.bboxs_) {
    std::array<float, 4> box;
    box[0] = bbox.bbox_[0];  // 640.0;
    box[2] = bbox.bbox_[2];  // 640.0;
    box[1] = bbox.bbox_[1];  // 640.0;
    box[3] = bbox.bbox_[3];  // 640.0;
    box[0] *= w_ratio;
    box[2] *= w_ratio;
    box[1] *= h_ratio;
    box[3] *= h_ratio;
    int width = box[2] - box[0];
    int height = box[3] - box[1];
    int id = bbox.label_id_;
    NNDEPLOY_LOGE("box[0]:%f, box[1]:%f, width :%d, height :%d\n", box[0],
                  box[1], width, height);
    cv::Point p = cv::Point(box[0], box[1]);
    cv::Rect rect = cv::Rect(box[0], box[1], width, height);
    cv::rectangle(cv_mat, rect, randColor[id]);
    std::string text = " ID:" + std::to_string(id);
    cv::putText(cv_mat, text, p, cv::FONT_HERSHEY_PLAIN, 1, randColor[id]);
  }
  return cv_mat;
}

//
int main(int argc, char *argv[]) {
  gflags::ParseCommandLineNonHelpFlags(&argc, &argv, true);
  if (demo::FLAGS_usage) {
    demo::showUsage();
    return -1;
  }

  // 检测模型的有向无环图graph名称,例如:
  // NNDEPLOY_YOLOV5/NNDEPLOY_YOLOV6/NNDEPLOY_YOLOV8
  std::string name = demo::getName();
  // 推理后端类型,例如:
  // kInferenceTypeOpenVino / kInferenceTypeTensorRt / kInferenceTypeOnnxRuntime
  base::InferenceType inference_type = demo::getInferenceType();
  // 推理设备类型,例如:
  // kDeviceTypeCodeX86:0/kDeviceTypeCodeCuda:0/...
  base::DeviceType device_type = demo::getDeviceType();
  // 模型类型,例如:
  // kModelTypeOnnx/kModelTypeMnn/...
  base::ModelType model_type = demo::getModelType();
  // 模型是否是路径
  bool is_path = demo::isPath();
  // 模型路径或者模型字符串
  std::vector<std::string> model_value = demo::getModelValue();
  // 有向无环图graph的输入边packert
  dag::Edge input("detect_in");
  // 有向无环图graph的输出边packert
  dag::Edge output("detect_out");
  // 创建检测模型有向无环图graph
  dag::Graph *graph =
      dag::createGraph(name, inference_type, device_type, &input, &output,
                       model_type, is_path, model_value);
  if (graph == nullptr) {
    NNDEPLOY_LOGE("graph is nullptr");
    return -1;
  }

  // 初始化有向无环图graph
  NNDEPLOY_TIME_POINT_START("graph->init()");
  base::Status status = graph->init();
  if (status != base::kStatusCodeOk) {
    NNDEPLOY_LOGE("graph init failed");
    return -1;
  }
  NNDEPLOY_TIME_POINT_END("graph->init()");

  // 有向无环图graph的输入图片路径
  std::string input_path = demo::getInputPath();
  // opencv读图
  cv::Mat input_mat = cv::imread(input_path);
  int img_h = input_mat.rows;
  int img_w = input_mat.cols;
  input_mat.convertTo(input_mat, CV_32FC3, 1.0/255);
  // 将图片写入有向无环图graph输入边
  input.set(input_mat);
  // 定义有向无环图graph的输出结果
  cv::Mat result(img_h, img_w, CV_32FC3);
  //model::DetectResult result;
  // 将输出结果写入有向无环图graph输出边
  output.set(result);

  // 有向无环图Graphz运行
  NNDEPLOY_TIME_POINT_START("graph->run()");
  status = graph->run();
  if (status != base::kStatusCodeOk) {
    NNDEPLOY_LOGE("graph run failed");
    return -1;
  }
  NNDEPLOY_TIME_POINT_END("graph->run()");

  //drawBox(input_mat, result);
  std::string ouput_path = demo::getOutputPath();
  result.convertTo(result, CV_8UC3, 255);
  //cv::imwrite("ret.png", output);
  cv::imwrite(ouput_path, result);

  // 有向无环图graphz反初始化
  NNDEPLOY_TIME_POINT_START("graph->deinit()");
  status = graph->deinit();
  if (status != base::kStatusCodeOk) {
    NNDEPLOY_LOGE("graph deinit failed");
    return -1;
  }
  NNDEPLOY_TIME_POINT_END("graph->deinit()");

  NNDEPLOY_TIME_PROFILER_PRINT("detetct time profiler");

  // 有向无环图graphz销毁
  delete graph;

  NNDEPLOY_LOGE("hello world!\n");

  return 0;
}

然后在
dag::Graph* createYoloV5Graph(const std::string& name,
base::InferenceType inference_type,
base::DeviceType device_type, dag::Edge* input,
dag::Edge* output, base::ModelType model_type,
bool is_path,
std::vectorstd::string model_value)
中修改前后处理函数即可。

前处理,infer , 后处理是一个 graph , 也就是demo中完整的图。
demo中的input和output是 完整的图的输入输出。

然后前处理,infer, 后处理 内部也有自己的input和output,不要搞混淆了。

比如模型infer输出是c,h,w, float32的结果,后处理 input是 c,h,w float32 的数据,output转换为 h,w,c float32的数据(对应上面的cv::Mat result(img_h, img_w, CV_32FC3);)

base::Status YoloPostProcess::runV5V6() {
  YoloPostParam* param = (YoloPostParam*)param_.get();
  float score_threshold = param->score_threshold_;
  int num_classes = param->num_classes_;

  device::Tensor* tensor = inputs_[0]->getTensor();
  //很多代码都是冗余的,这一步只要获得 output的tensor的指针,然后进行c,h,w -> h, w, c即可。
  float* data = (float*)tensor->getPtr();
  int batch = tensor->getBatch();
  int channel = tensor->getChannel();
  int height = tensor->getHeight();
  int width = tensor->getWidth();
NNDEPLOY_LOGE("batch:%d, channel:%d, height:%d, width:%d. (%f,%f,%f))\n", batch,  channel, height, width, data[0], data[1], data[2]);
cv::Mat* dst = outputs_[0]->getCvMat();
NNDEPLOY_LOGE("mat  channel:%d, height:%d, width:%d.\n", dst->channels(),   dst->rows, dst->cols);
    
    auto* img_data = (float*)dst->data;
    for (int h = 0; h < height; h++)
    {
        for (int w = 0; w < width; w++)
        {
            for (int c = 0; c < 3; c++)
            {
                int in_index = h * width * 3 + w * 3 + c;
                int out_index = c * width * height + h * width + w;
                // if (w < 10)
                //   if(h < 10)
                //     printf("%.2f,", data[out_index]);
                img_data[in_index] = data[out_index];
            }
            
        }
          // if(h < 10)
          //   printf("\n");
    }
    


  return base::kStatusCodeOk;
}

前处理也是同样的道理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/184273.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【华为数通HCIP | 网络工程师】821-IGP高频题、易错题之OSPF(5)

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

Android 提示框代码 java语言

在Android中&#xff0c;你可以使用 AlertDialog 类来创建提示框。以下是一个简单的Java代码示例&#xff0c;演示如何创建和显示一个基本的提示框&#xff1a; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; im…

EXIT外部中断 HAL库+cubeMX

一.cubeMX外部中断配置 1.系统内核 2.中断管理 3.选择抢占优先级和响应优先级&#xff0c;共有5个等级&#xff0c;在这里就使用库函数编写代码时最常用的2位抢占优先级2位响应优先级。 4.勾选使能选项&#xff0c;后面的两个零&#xff0c;第一个代表抢占优先级的等级&#xf…

怎么申请IP地址证书?

IP地址证书&#xff0c;也称为SSL证书&#xff0c;是一种数字证书&#xff0c;用于在网络传输过程中对IP地址进行加密和解密。它是由受信任的证书颁发机构&#xff08;CA&#xff09;颁发的&#xff0c;用于证明网站所有者身份的真实性和合法性。 一、选择证书颁发机构。首先需…

图片上传加时水印

做园区巡检需求时&#xff0c;需要巡检打卡拍照上传功能&#xff0c;并且在照片上添加当前时间的水印 创建canvas拍照后拿着图片画到canvas上同时获取当前时间也画到canvas上&#xff0c;再将canvas生成base64的url拿着合成的图片url进行下面的逻辑上代码 function addWaterm…

HR9110H 单通道低压 H 桥电机驱动芯片

HR9110H为消费类产品、玩具和其它低电压或者电池供电的运动控制类应用提供了一个集成的电机驱动器解决方案。HR9110H是SOP8封装&#xff0c;且是无铅产品&#xff0c;符合环保标准。 HR9110H能够驱动一个直流有刷电机或其他诸如螺线管的器件。输出驱动模块由PMOSNMOS功率管构成…

WPF实战项目十六(客户端):备忘录接口

1、新增IMemoService接口&#xff0c;继承IBaseService接口 public interface IMemoService : IBaseService<MemoDto>{} 2、新增MemoService类&#xff0c;继承BaseService和IMemoService接口 public class MemoService : BaseService<MemoDto>, IMemoService{pub…

G1垃圾收集器

1.G1的目的&#xff1a; Garbage First&#xff0c;也就是垃圾优先原则&#xff0c;也就是空间方面的关注点。同时照顾到停顿时间以及吞吐量。 G1垃圾收集器的设计目的是避免完全回收&#xff0c;但是当并发收集不能足够快地回收内存时&#xff0c;就会发生完全回收GC。G1的完…

工业以太网交换机未来发展中的几个趋势

随着工业自动化不断发展和智能制造的推进&#xff0c;工业以太网交换机在未来的应用中将面临更多的发展机遇和挑战。在工业以太网交换机的未来发展中&#xff0c;有几个方面将成为趋势。 网络虚拟化 随着工业自动化系统规模的不断扩展&#xff0c;网络虚拟化将成为未来的发展方…

基于亚马逊云科技大语言模型等服务打造企业知识库

背景 大语言模型是自然语言处理领域的一项重要技术&#xff0c;能够通过学习大量的文本数据&#xff0c;生成具有语法和意义的自然语言文本。目前大语言模型已经成为了自然语言处理领域的一个热门话题&#xff0c;引起了广泛的关注和研究。 知识库需求在各行各业中普遍存在&a…

阿里云OSS代码集成部分问题分析

公司内部开发了一个文件相关的应用&#xff0c;由于服务器带宽限制导致多个用户同时上传或者下载文件时速度很慢&#xff0c;遂将文件迁移至阿里云OSS服务器。下面是迁移的过程中遇到的部分问题。 问题1. 跨域错误 错误信息如下&#xff1a; Access to XMLHttpRequest at htt…

关于同一接口有多个不同实现的设计方案

关于同一接口有多个不同实现的设计方案 前言 最近公司做了一个银行相关的项目&#xff0c;告诉我公司对接了多个银行的支付&#xff0c;每个银行都有对应的接口要去对接&#xff0c;比如&#xff1a;交易申请&#xff0c;交易取消&#xff0c;支付&#xff0c;回单&#xff0…

工作流引擎架构设计

一个应用MIS的系统的架构离不开工作流引擎&#xff0c;具有流程引擎思维的架构人员设计系统的时候就有流程的思维&#xff0c;他区别于过程思维&#xff0c;过程思维开发出来的系统&#xff0c;用户面对的是菜单、模块。而流程思维设计出来的系统就是发起、待办、在途、查询、近…

电子商务活动中无处不在的电商API接口|淘宝/天猫/京东/1688

我们的日常生活中无处不是API API已经成为我们日常生活中无处不在的技术&#xff0c;我们日常生活中的许多时刻都会涉及到API的应用&#xff1a; 支付API&#xff1a;支付API允许电商平台将其支付系统与第三方支付系统进行集成&#xff0c;从而为客户提供多种支付选项并实现更…

虚拟机系列:vmware和Oracle VM VirtualBox虚拟机的区别,简述哪一个更适合我?以及相互转换

一. VMware和Oracle VM VirtualBox虚拟机的区别主要体现在以下几个方面: 首先两种软件的安装使用教程如下: VMware ESXI 安装使用教程 Oracle VM VirtualBox安装使用教程 商业模式:VMware是一家商业公司,而Oracle VM VirtualBox是开源软件; 功能:VMware拥有更多的功能和…

docker安装nacos,实现和mysql容器的通信

1.下载nacos镜像 docker pull nacos/nacos-server2. 启动nacos 启动命令如下&#xff1a; docker run -d -p 8848:8848 --name nacos \ -e JVM_XMS256m \ -e JVM_XMX256m \ -e MODEstandalone \ -e SPRING_DATASOURCE_PLATFORMmysql \ -e MYSQL_SERVICE_HOST192.168.131.223…

css中flex两列布局(一列自适应其他固定)

问题 最近写一个布局的时候&#xff0c;遇到一个问题。如下图的布局。在没有图片的时候布局是正常的&#xff0c;如果有图片且设置了width:100%;height: 100%; 则会出现图片将自适应布局撑开的情况。 我的解决方式是让图片不缩放&#xff0c;图片外层再添加一个div元素。形如…

css Vue尺子样式

原生css生成尺子样式 <template><div class"page"><div class"Light"></div><div class"rile"><ul id"list"><!--尺子需要几个单位就加几个--><li></li><li></li&…

创意设计与个性化定制:酒精壁炉的独特之处

在当今家居装饰的潮流中&#xff0c;人们越来越注重个性化和创意&#xff0c;而酒精壁炉正是在这一趋势中崭露头角。它不仅成为家居的温馨之选&#xff0c;更因其设计的灵活性而成为创意焦点&#xff0c;吸引了越来越多注重家居设计的人群。 酒精壁炉的设计灵活性为家居注入了新…

kali部署ARL灯塔资产系统及使用教程

网上有很多ARL部署到centos系统的教程,但是部署到ubuntu或kali linux系统的教程都是乱七八糟,互相抄,而且没有一个能部署成功,鉴于此,写下此教程,帮助大家出坑 一、安装docker环境(网上什么弄钥匙呀,什么稳定源啊都是垃圾) 准备一个纯净的最新的kali linux系统 1、配…
最新文章