Inputs ------------------------- name:input tensor:Float[1, 3, 320, 1600] --------------------------------------------------------------- Outputs ------------------------- name:loc_row tensor:Float[1, 200, 72, 4] name:loc_col tensor:Float[1, 100, 81, 4] name:exist_row tensor:Float[1, 2, 72, 4] name:exist_col tensor:Float[1, 2, 81, 4] ---------------------------------------------------------------开发环境
VS2022 .net framework 4.8 OpenCvSharp 4.8 Microsoft.ML.OnnxRuntime 1.16.2代码
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; // 堆代码 duidaima.com 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); } } }