C# Onnx LSTR 基于Transformer的端到端实时车道线检测

目录

效果

模型信息

项目

代码

下载


效果

模型信息

lstr_360x640.onnx

Inputs
-------------------------
name:input_rgb
tensor:Float[1, 3, 360, 640]
name:input_mask
tensor:Float[1, 1, 360, 640]
---------------------------------------------------------------

Outputs
-------------------------
name:pred_logits
tensor:Float[1, 7, 2]
name:pred_curves
tensor:Float[1, 7, 8]
name:foo_out_1
tensor:Float[1, 7, 2]
name:foo_out_2
tensor:Float[1, 7, 8]
name:weights
tensor:Float[1, 240, 240]
---------------------------------------------------------------

项目

VS2022+.net framework 4.8+OpenCvSharp 4.8 +Microsoft.ML.OnnxRuntime 1.16.2

代码

using Microsoft.ML.OnnxRuntime.Tensors;
using Microsoft.ML.OnnxRuntime;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Linq;
using System.IO;
using System.Text;
using System.Drawing;namespace Onnx_Demo
{public partial class frmMain : Form{public frmMain(){InitializeComponent();}string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";string image_path = "";DateTime dt1 = DateTime.Now;DateTime dt2 = DateTime.Now;int inpWidth;int inpHeight;Mat image;string model_path = "";float[] factors = new float[2];SessionOptions options;InferenceSession onnx_session;Tensor<float> input_tensor;Tensor<float> mask_tensor;List<NamedOnnxValue> input_ontainer;IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;DisposableNamedOnnxValue[] results_onnxvalue;Tensor<float> result_tensors;int len_log_space = 50;float[] log_space;float[] mean = new float[] { 0.485f, 0.456f, 0.406f };float[] std = new float[] { 0.229f, 0.224f, 0.225f };Scalar[] lane_colors = new Scalar[] { new Scalar(68, 65, 249), new Scalar(44, 114, 243), new Scalar(30, 150, 248), new Scalar(74, 132, 249), new Scalar(79, 199, 249), new Scalar(109, 190, 144), new Scalar(142, 144, 77), new Scalar(161, 125, 39) };private void button1_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() != DialogResult.OK) return;pictureBox1.Image = null;pictureBox2.Image = null;textBox1.Text = "";image_path = ofd.FileName;pictureBox1.Image = new System.Drawing.Bitmap(image_path);image = new Mat(image_path);}private void Form1_Load(object sender, EventArgs e){// 创建输入容器input_ontainer = new List<NamedOnnxValue>();// 创建输出会话options = new SessionOptions();options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行// 创建推理模型类,读取本地模型文件model_path = "model/lstr_360x640.onnx";inpWidth = 640;inpHeight = 360;onnx_session = new InferenceSession(model_path, options);// 创建输入容器input_ontainer = new List<NamedOnnxValue>();FileStream fileStream = new FileStream("model/log_space.bin", FileMode.Open);BinaryReader br = new BinaryReader(fileStream, Encoding.UTF8);log_space = new float[len_log_space];byte[] byteTemp;float fTemp;for (int i = 0; i < len_log_space; i++){byteTemp = br.ReadBytes(4);fTemp = BitConverter.ToSingle(byteTemp, 0);log_space[i] = fTemp;}br.Close();image_path = "test_img/0.jpg";pictureBox1.Image = new Bitmap(image_path);}private unsafe void button2_Click(object sender, EventArgs e){if (image_path == ""){return;}textBox1.Text = "检测中,请稍等……";pictureBox2.Image = null;System.Windows.Forms.Application.DoEvents();//图片缩放image = new Mat(image_path);int img_height = image.Rows;int img_width = image.Cols;Mat resize_image = new Mat();Cv2.Resize(image, resize_image, new OpenCvSharp.Size(inpWidth, inpHeight));int row = resize_image.Rows;int col = resize_image.Cols;float[] input_tensor_data = new float[1 * 3 * inpHeight * inpWidth];for (int c = 0; c < 3; c++){for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){float pix = ((byte*)(resize_image.Ptr(i).ToPointer()))[j * 3 + c];input_tensor_data[c * row * col + i * col + j] = (float)((pix / 255.0 - mean[c]) / std[c]);}}}input_tensor = new DenseTensor<float>(input_tensor_data, new[] { 1, 3, inpHeight, inpWidth });float[] input_mask_data = new float[1 * 1 * inpHeight * inpWidth];for (int i = 0; i < input_mask_data.Length; i++){input_mask_data[i] = 0.0f;}mask_tensor = new DenseTensor<float>(input_mask_data, new[] { 1, 1, inpHeight, inpWidth });//将 input_tensor 放入一个输入参数的容器,并指定名称input_ontainer.Add(NamedOnnxValue.CreateFromTensor("input_rgb", input_tensor));input_ontainer.Add(NamedOnnxValue.CreateFromTensor("input_mask", mask_tensor));dt1 = DateTime.Now;//运行 Inference 并获取结果result_infer = onnx_session.Run(input_ontainer);dt2 = DateTime.Now;//将输出结果转为DisposableNamedOnnxValue数组results_onnxvalue = result_infer.ToArray();float[] pred_logits = results_onnxvalue[0].AsTensor<float>().ToArray();float[] pred_curves = results_onnxvalue[1].AsTensor<float>().ToArray();int logits_h = results_onnxvalue[0].AsTensor<float>().Dimensions[1];int logits_w = results_onnxvalue[0].AsTensor<float>().Dimensions[2];int curves_w = results_onnxvalue[1].AsTensor<float>().Dimensions[2];List<int> good_detections = new List<int>();List<List<OpenCvSharp.Point>> lanes = new List<List<OpenCvSharp.Point>>();for (int i = 0; i < logits_h; i++){float max_logits = -10000;int max_id = -1;for (int j = 0; j < logits_w; j++){float data = pred_logits[i * logits_w + j];if (data > max_logits){max_logits = data;max_id = j;}}if (max_id == 1){good_detections.Add(i);int index = i * curves_w;List<OpenCvSharp.Point> lane_points = new List<OpenCvSharp.Point>();for (int k = 0; k < len_log_space; k++){float y = pred_curves[0 + index] + log_space[k] * (pred_curves[1 + index] - pred_curves[0 + index]);float x = (float)(pred_curves[2 + index] / Math.Pow(y - pred_curves[3 + index], 2.0) + pred_curves[4 + index] / (y - pred_curves[3 + index]) + pred_curves[5 + index] + pred_curves[6 + index] * y - pred_curves[7 + index]);lane_points.Add(new OpenCvSharp.Point(x * img_width, y * img_height));}lanes.Add(lane_points);}}Mat result_image = image.Clone();//draw linesList<int> right_lane = new List<int>();List<int> left_lane = new List<int>();for (int i = 0; i < good_detections.Count; i++){if (good_detections[i] == 0){right_lane.Add(i);}if (good_detections[i] == 5){left_lane.Add(i);}}if (right_lane.Count() == left_lane.Count()){Mat lane_segment_img = result_image.Clone();List<OpenCvSharp.Point> points = new List<OpenCvSharp.Point>();points.AddRange(lanes.First());points.Reverse();points.AddRange(lanes[left_lane[0]]);Cv2.FillConvexPoly(lane_segment_img, points, new Scalar(0, 191, 255));Cv2.AddWeighted(result_image, 0.7, lane_segment_img, 0.3, 0, result_image);}for (int i = 0; i < lanes.Count(); i++){for (int j = 0; j < lanes[i].Count(); j++){Cv2.Circle(result_image, lanes[i][j], 3, lane_colors[good_detections[i]], -1);}}pictureBox2.Image = new System.Drawing.Bitmap(result_image.ToMemoryStream());textBox1.Text = "推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms";}private void pictureBox2_DoubleClick(object sender, EventArgs e){Common.ShowNormalImg(pictureBox2.Image);}private void pictureBox1_DoubleClick(object sender, EventArgs e){Common.ShowNormalImg(pictureBox1.Image);}}
}

下载

源码下载

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发vue3 UI组件库,并且发布到NPM

目录 1.创建vue3工程 2.创建package文件 3.编写组件&#xff0c;并且导出 4.编写package.json 5.npm账号注册登录并发布 6.从npm安装使用 7.注意事项 1.创建vue3工程 &#xff08;1&#xff09;初始化Vue项目 cnpm create vite &#xff08;2&#xff09;进入文件夹…

计算机基础知识50

数据的增删改查(insert update delete select) # 用户列表的展示&#xff1a; # 把数据表中得用户数据都给查询出来展示在页面上 1. 查询 from app01 import models models.UserInfo.objects.all() # 查询所有的字段信息和数据 resmodels.UserInfo.objects.first() # 查询…

sass 生成辅助色

背景 一个按钮往往有 4 个状态。 默认状态hover鼠标按下禁用状态 为了表示这 4 个状态&#xff0c;需要设置 4 个颜色来提示用户。 按钮类型一般有 5 个&#xff1a; 以 primary 类型按钮为例&#xff0c;设置它不同状态下的颜色&#xff1a; <button class"btn…

ros2_control的简单应用

文章目录 简介插件实现函数介绍代码 调用原理局限性 简介 在利用moveit_setup_assistant配置我们自己机械手后&#xff0c;当运行demo.launch.py时&#xff0c;会实例化一个moveit对象以及一个基于ros2_control的、虚拟的控制对象&#xff0c;从而可以实现一个完整的控制闭环。…

Rust 中的引用与借用

目录 1、引用与借用 1.1 可变引用 1.2 悬垂引用 1.3 引用的规则 2、slice 类型 2.1 字符串字面量其实就是一个slice 2.2 总结 1、引用与借用 在之前我们将String 类型的值返回给调用函数&#xff0c;这样会导致这个String会被移动到函数中&#xff0c;这样在原来的作用域…

【PC】开发者日志:竞技比赛验证系统强化

各位玩家大家好&#xff01;欢迎收看本期开发者日志。 在11月1日发布的第26赛季第2轮更新公告中&#xff0c;我们提到了有关强化比赛验证系统的内容。想必各位玩家一定会对我们加强验证系统的背景和意图感到好奇&#xff0c;为此我们想通过今天这篇反作弊开发者日志来向大家更详…

考研分享第1期 | 末9生物跨专业考研北京大学电子信息404分经验分享

全文概览 一、个人信息 二、关于考研的经验分享 三、最后的小Tips 一、个人信息 姓名&#xff1a;Jackson 本科院校&#xff1a;某末流985生物专业 报考院校&#xff1a;北京大学电子信息专业 择校意向&#xff1a;北航计算机、人大高瓴、复旦软院、清华大学深研院、北…

初认识vue,v-for,v-if,v-bind,v-model,v-html等指令

vue 一.vue3介绍 1.为什么data是函数而不是对象? 因为vue是组件开发,组件会多次复用,data如果是对象,多次复用是共享,必须函数返回一个新的对象 1. 官网初识 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS …

相机以及其它传感器传感器

深度相机点云质量对比 比较点云质量时需要注意的点&#xff1a; 1.对特殊材质、颜色的检测效果&#xff1a;透明塑料、金属、毛玻璃、高反光物体&#xff08;镜子、水坑&#xff09;、吸光物体&#xff08;黑色物体&#xff09;。 2.特殊环境&#xff1a;雨、雪、雾、明暗交替位…

打开word文档报错,提示HRESULT 0x80004005 位置: 部分: /word/comments.xml,行: 0,列: 0

某用户遇到这样一个奇怪的问题&#xff0c;就是回复完word的批注后&#xff0c;保存文档再打开就会报错&#xff0c;提示很抱歉&#xff0c;无法打开XXX&#xff0c;因为内容有问题。&#xff0c;详细信息提示HRESULT 0x80004005 位置: 部分: /word/comments.xml,行: 0,列: 0 c…

Rust-使用dotenvy加载和使用环境变量

系统的开发&#xff0c;测试和部署离不开环境变量&#xff0c;今天分享在Rust的系统开发中&#xff0c;使用dotenvy来读取和使用环境变量。 安装 cargo add dotenvy dotenv_codegen 加载环境变量 use dotenvy::dotenv;fn main() {dotenv().expect(".env不存在");…

mysql数据库时间

记录MySQL今天又一个新的问题&#xff1a; 场景&#xff1a;nodejs后台容器部署 问题原因&#xff1a;纯属好心办坏事&#xff0c;由于考虑了时区&#xff08;现在看来纯属多余&#xff09;&#xff0c;在写入时间时使用了time_str.toLocaleString("chinese", { ti…