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

效果

项目

代码

cs 复制代码
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

相关推荐
向宇it6 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
向宇it7 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
坐井观老天12 小时前
在C#中使用资源保存图像和文本和其他数据并在运行时加载
开发语言·c#
pchmi14 小时前
C# OpenCV机器视觉:模板匹配
opencv·c#·机器视觉
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭16 小时前
C#都可以找哪些工作?
开发语言·c#
boligongzhu18 小时前
Dalsa线阵CCD相机使用开发手册
c#
向宇it1 天前
【从零开始入门unity游戏开发之——C#篇23】C#面向对象继承——`as`类型转化和`is`类型检查、向上转型和向下转型、里氏替换原则(LSP)
java·开发语言·unity·c#·游戏引擎·里氏替换原则
sukalot1 天前
windows C#-命名实参和可选实参(下)
windows·c#
小码编匠1 天前
.NET 下 RabbitMQ 队列、死信队列、延时队列及小应用
后端·c#·.net