效果
项目
代码
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