C# Onnx Ultra-Fast-Lane-Detection-v2 车道线检测

效果

项目

代码

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;namespace Onnx_Demo
{public partial class frmMain : Form{public frmMain(){InitializeComponent();}string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";string image_path = "";string startupPath;string model_path;DateTime dt1 = DateTime.Now;DateTime dt2 = DateTime.Now;Mat image;Mat result_image;SessionOptions options;InferenceSession onnx_session;Tensor<float> input_tensor;List<NamedOnnxValue> input_ontainer;IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;DisposableNamedOnnxValue[] results_onnxvalue;StringBuilder sb = new StringBuilder();int inpHeight = 320;int inpWidth = 1600;int num_row;int num_col;List<float> row_anchor = new List<float>();List<float> col_anchor = new List<float>();float crop_ratio;string dataset;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 Bitmap(image_path);image = new Mat(image_path);}private void Form1_Load(object sender, EventArgs e){startupPath = Application.StartupPath + "\\model\\";model_path = startupPath + "ufldv2_culane_res18_320x1600.onnx";// 创建输出会话options = new SessionOptions();options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行// 创建推理模型类,读取本地模型文件onnx_session = new InferenceSession(model_path, options);if (model_path.Contains("culane")){dataset = "culane";num_row = 72;num_col = 81;crop_ratio = 0.6f;}else{num_row = 56;num_col = 41;crop_ratio = 0.8f;}// 创建输入容器input_ontainer = new List<NamedOnnxValue>();GenerateAnchor();}void GenerateAnchor(){for (int i = 0; i < num_row; i++){if (dataset == "culane"){row_anchor.Add((float)(0.42 + i * (1.0 - 0.42) / (num_row - 1)));}else{row_anchor.Add((float)((160 + i * (710 - 160) / (num_row - 1)) / 720.0));}}for (int i = 0; i < num_col; i++){col_anchor.Add((float)(0.0 + i * (1.0 - 0.0) / (num_col - 1)));}}private void button2_Click(object sender, EventArgs e){if (image_path == ""){return;}textBox1.Text = "检测中,请稍等……";pictureBox2.Image = null;Application.DoEvents();//图片image = new Mat(image_path);int img_h = image.Rows;int img_w = image.Cols;Mat resize_image = new Mat();Cv2.Resize(image, resize_image, new OpenCvSharp.Size(inpWidth, inpHeight / crop_ratio));Mat dstimg = Common.Normalize(resize_image,inpHeight);var sourceData = Common.ExtractMat(dstimg);int[] dimensions = new int[4] { 1, 3, inpHeight, inpWidth };input_tensor = new DenseTensor<float>(sourceData, dimensions);input_ontainer.Add(NamedOnnxValue.CreateFromTensor("input", input_tensor));dt1 = DateTime.Now;//运行 Inference 并获取结果result_infer = onnx_session.Run(input_ontainer);dt2 = DateTime.Now;//将输出结果转为DisposableNamedOnnxValue数组results_onnxvalue = result_infer.ToArray();var loc_row = results_onnxvalue[0].AsTensor<float>().ToArray();var loc_col = results_onnxvalue[1].AsTensor<float>().ToArray();var exist_row = results_onnxvalue[2].AsTensor<float>().ToArray();var exist_col = results_onnxvalue[3].AsTensor<float>().ToArray();var loc_row_dims = results_onnxvalue[0].AsTensor<float>().Dimensions.ToArray();int num_grid_row = loc_row_dims[1];int num_cls_row = loc_row_dims[2];int num_lane_row = loc_row_dims[3];var loc_col_dims = results_onnxvalue[1].AsTensor<float>().Dimensions.ToArray();int num_grid_col = loc_col_dims[1];int num_cls_col = loc_col_dims[2];int num_lane_col = loc_col_dims[3];int[] exist_row_dims = results_onnxvalue[2].AsTensor<float>().Dimensions.ToArray();int[] exist_col_dims = results_onnxvalue[3].AsTensor<float>().Dimensions.ToArray();int[] max_indices_row = Common.argmax_1(loc_row, loc_row_dims);int[] valid_row = Common.argmax_1(exist_row, exist_row_dims);int[] max_indices_col = Common.argmax_1(loc_col, loc_col_dims);int[] valid_col = Common.argmax_1(exist_col, exist_col_dims);List<List<OpenCvSharp.Point>> line_list = new List<List<OpenCvSharp.Point>>();List<OpenCvSharp.Point> temp = new List<OpenCvSharp.Point>();line_list.Add(temp);line_list.Add(temp);line_list.Add(temp);line_list.Add(temp);int[] item = new int[2] { 1, 2 };foreach (var i in item){if (Common.sum_valid(valid_row, num_cls_row, num_lane_row, i) > num_cls_row * 0.5){for (int k = 0; k < num_cls_row; k++){int index = k * num_lane_row + i;if (valid_row[index] != 0){List<float> pred_all_list = new List<float>();List<int> all_ind_list = new List<int>();for (int all_ind = Math.Max(0, (int)(max_indices_row[index] - 1)); all_ind <= (Math.Min(num_grid_row - 1, max_indices_row[index]) + 1); all_ind++){pred_all_list.Add(loc_row[all_ind * num_cls_row * num_lane_row + index]);all_ind_list.Add(all_ind);}List<float> pred_all_list_softmax = new List<float>();float[] pred_all_list_softmax_temp = new float[pred_all_list.Count];Common.SoftMaxFast(pred_all_list.ToArray(), ref pred_all_list_softmax_temp, pred_all_list.Count);pred_all_list_softmax = pred_all_list_softmax_temp.ToList();float out_temp = 0;for (int l = 0; l < pred_all_list.Count; l++){out_temp += pred_all_list_softmax[l] * all_ind_list[l];}float x = (float)((out_temp + 0.5) / (num_grid_row - 1.0));float y = row_anchor[k];line_list[i].Add(new OpenCvSharp.Point((int)(x * img_w), (int)(y * img_h)));}}}}item = new int[4] { 0, 1, 2, 3 };foreach (var i in item){if (Common.sum_valid(valid_col, num_cls_col, num_lane_col, i) > num_cls_col / 4){for (int k = 0; k < num_cls_col; k++){int index = k * num_lane_col + i;if (valid_col[index] != 0){List<float> pred_all_list = new List<float>();List<int> all_ind_list = new List<int>();for (int all_ind = Math.Max(0, (int)(max_indices_col[index] - 1)); all_ind <= (Math.Min(num_grid_col - 1, max_indices_col[index]) + 1); all_ind++){pred_all_list.Add(loc_col[all_ind * num_cls_col * num_lane_col + index]);all_ind_list.Add(all_ind);}List<float> pred_all_list_softmax = new List<float>();float[] pred_all_list_softmax_temp = new float[pred_all_list.Count];Common.SoftMaxFast(pred_all_list.ToArray(), ref pred_all_list_softmax_temp, pred_all_list.Count);pred_all_list_softmax = pred_all_list_softmax_temp.ToList();float out_temp = 0;for (int l = 0; l < pred_all_list.Count; l++){out_temp += pred_all_list_softmax[l] * all_ind_list[l];}float y = (float)((out_temp + 0.5) / (num_grid_col - 1.0));float x = col_anchor[k];line_list[i].Add(new OpenCvSharp.Point((int)(x * img_w), (int)(y * img_h)));}}}}result_image = image.Clone();foreach (var line in line_list){foreach (var p in line){Cv2.Circle(result_image, p, 3, new Scalar(0, 255, 0), -1);}}sb.Clear();sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");sb.AppendLine("------------------------------");pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());textBox1.Text = sb.ToString();}private void pictureBox2_DoubleClick(object sender, EventArgs e){Common.ShowNormalImg(pictureBox2.Image);}private void pictureBox1_DoubleClick(object sender, EventArgs e){Common.ShowNormalImg(pictureBox1.Image);}}
}

下载

源码下载

ufldv2-culane-res34-320x1600.onnx

ufldv2-tusimple-res18-320x800.onnx

ufldv2-tusimple-res34-320x800.onnx

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

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

相关文章

你真的会学习网络安全吗?

我敢说&#xff0c;现在网上90%的文章都没有把网络安全该学的东西讲清楚。 为什么&#xff1f;因为全网更多的都是在讲如何去渗透和公鸡&#xff0c;却没有把网安最注重的防御讲明白。 老话说得好&#xff1a;“攻击&#xff0c;是为了更好的防御。”如果连初衷都忘了&#xff…

数据结构和算法——用C语言实现所有图状结构及相关算法

文章目录 前言图的基本概念图的存储方式邻接矩阵邻接表十字链表临界多重表 图的遍历最小生成树普里姆算法&#xff08;Prim&#xff09;克鲁斯卡尔算法&#xff08;Kruskal&#xff09; 最短路径BFS求最短路径迪杰斯特拉算法&#xff08;Dijkstra&#xff09;弗洛伊德算法&…

Android Studio打包AAR

注意 依赖的Android Studio版本为4.2.2 更高的Android Studio版本使用方法可能有所不同&#xff0c;gradle的版本和gradle plugins的版本都会影响使用方式。 基于此&#xff0c;本文只能作为参考&#xff0c;而不能作为唯一答案&#xff0c;如果要完全依赖本文&#xff0c;则…

8年经验之谈 —— Redis的性能测试与优化!

Redis作为一种高性能的Key-Value数据库&#xff0c;一直受到众多开发者和企业的青睐。然而&#xff0c;在高并发、大数据存储的应用场景中&#xff0c;如何测试并优化Redis的性能&#xff0c;成为了问题。本文将从测试与优化两个方面来讲解如何达到最优的Redis性能。 一、性能…

深入浅出排序算法之计数排序

目录 1. 原理 2. 代码实现 3. 性能分析 1. 原理 首先看一个题目&#xff0c;有n个数&#xff0c;取值范围是 0~n&#xff0c;写出一个排序算法&#xff0c;要求时间复杂度和空间复杂度都是O(n)的。 为了达到这种效果&#xff0c;这一篇将会介绍一种不基于比较的排序方法。这…

K-means(K-均值)算法

K-means&#xff08;k-均值&#xff0c;也记为kmeans&#xff09;是聚类算法中的一种&#xff0c;由于其原理简单&#xff0c;可解释强&#xff0c;实现方便&#xff0c;收敛速度快&#xff0c;在数据挖掘、聚类分析、数据聚类、模式识别、金融风控、数据科学、智能营销和数据运…

我和云栖有个约会

云栖大会&#xff1a;聚焦创新&#xff0c;驱动未来 2009年&#xff0c;一场地方网站峰会在中国掀起了技术的浪潮。随着时间的推移&#xff0c;这场峰会逐渐演变成了全球领先的科技盛会——云栖大会。回首历史&#xff0c;云栖大会不仅是中国云计算产业发展的见证者&#xff0c…

高效分割分段视频:提升您的视频剪辑能力

在数字媒体时代&#xff0c;视频剪辑已经成为一项重要的技能。无论是制作个人影片、广告还是其他类型的视频内容&#xff0c;掌握高效的视频剪辑技巧都是必不可少的。本文将介绍如何引用云炫AI智剪高效地分割和分段视频&#xff0c;以提升您的视频剪辑能力。以下是详细的操作步…

2023-11-01 LeetCode每日一题(参加会议的最多员工数)

2023-11-01每日一题 一、题目编号 2127. 参加会议的最多员工数二、题目链接 点击跳转到题目位置 三、题目描述 一个公司准备组织一场会议&#xff0c;邀请名单上有 n 位员工。公司准备了一张 圆形 的桌子&#xff0c;可以坐下 任意数目 的员工。 员工编号为 0 到 n - 1 。…

appium操控微信小程序的坑

appium操控微信小程序的坑 打不开启动页面driver的context只有NATIVE_APP小程序上元素找不到 我打算使用appium操控微信小程序&#xff0c;只要能够获取到小程序的页面元素就算成功。下面都是我遇到的问题。 打不开启动页面 以下是我的appium的配置参数和代码&#xff1a; de…

基于Taro + React 实现微信小程序半圆滑块组件、半圆进度条、弧形进度条、半圆滑行轨道(附源码)

效果&#xff1a; 功能点&#xff1a; 1、四个档位 2、可点击加减切换档位 3、可以点击区域切换档位 4、可以滑动切换档位 目的&#xff1a; 给大家提供一些实现思路&#xff0c;找了一圈&#xff0c;一些文章基本不能直接用&#xff0c;错漏百出&#xff0c;代码还藏着掖…

Kubernetes - Ingress HTTP 升级 HTTPS 配置解决方案(新版本v1.21+)

之前我们讲解过 Kubernetes - Ingress HTTP 搭建解决方案&#xff0c;并分别提供了旧版本和新版本。如果连 HTTP 都没搞明白的可以先去过一下这两篇 Kubernetes - Ingress HTTP 负载搭建部署解决方案_放羊的牧码的博客-CSDN博客Kubernetes - Ingress HTTP 负载搭建部署解决方案…

SpringMVC Day 07 : 表单验证

前言 表单验证在Web开发中是非常常见和重要的一部分&#xff0c;它用于确保用户提交的数据符合预期的规则和限制。 通过表单验证&#xff0c;我们可以有效地捕获并处理用户输入中的错误或不正确的数据&#xff0c;从而提高应用程序的数据质量和用户体验。在本教程中&#xff…

Thread

Thread 线程启动线程第一种创建线程线程的第二种创建方式使用匿名内部类完成线程的两种创建 Thread API线程的优先级线程提供的静态方法守护线程用户线程和守护线程的区别体现在进程结束时 多线并发安全问题同步块 线程 启动线程 启动线程:调用线程的start方法,而不是直接调用…

lua-resty-request库写入爬虫ip实现数据抓取

根据提供的引用内容&#xff0c;正确的库名称应该是lua-resty-http&#xff0c;而不是lua-resty-request。使用lua-resty-http库可以方便地进行爬虫&#xff0c;需要先安装OpenResty和lua-resty-http库&#xff0c;并将其引入到Lua脚本中。然后&#xff0c;可以使用lua-resty-h…

【网络协议】聊聊http协议

当我们输入www.baidu.com的时候&#xff0c;其实是先将baidu.com的域名进行DNS解析&#xff0c;转换成对应的ip地址&#xff0c;然后开始进行基于TCP构建三次握手的连接&#xff0c;目前使用的是1.1 默认是开启了keep-Alive。可以在多次请求中进行连接复用。 HTTP 请求的构建…

【k8s】pod详解

一、Pod介绍 1、Pod的基础概念 Pod是kubernetes中最小的资源管理组件&#xff0c;Pod也是最小化运行容器化应用的资源对象&#xff0c;一个pod代表着集群中运行的一个进程。kubernetes中其它大多数组件都是围绕着pod来进行支持和扩展pod功能的。 例如&#xff0c;用于管理po…

计算机基础知识41

前端 # 前端是所有跟用户直接打交道 比如&#xff1a;PC页面、手机页面、汽车显示屏&#xff0c;肉眼可以看见的 # 后端&#xff1a;一堆代码&#xff0c;用户不能够直接看到&#xff0c;不直接与用户打交道 常见的后端&#xff1a;Python、Java、Go等 # 学了前端就可以做全栈…

算法题:二叉树的层序遍历

层序遍历&#xff0c;看似简单&#xff0c;实则陷阱很多&#xff0c;怪不得该题目被认定为中等难度题。此处运用了迭代求解法。&#xff08;完整题目附在了最后&#xff09; # Definition for a binary tree node. class TreeNode:def __init__(self, val0, leftNone, rightNon…

Vectrosity 插件使用

1 下载 https://download.csdn.net/download/moonlightpeng/88490704?spm1001.2014.3001.5503 2 使用&#xff0c;目前在2020.3.3上测试可以 导入时选5.6 再导入demo