摘要:Cv2.CvtColor(image, dstimg, ColorConversionCodes.BGR2RGB);
Inputs
name:input
tensor:Float[1, 3, 640, 640]
Outputs
name:transposed_output
tensor:Float[1, 5, 8400]
using Microsoft.ML.OnnxRunTime.Tensors;
using OpenCvSharp;
using OpenCvSharp.Dnn;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Onnx_Demo
{
public partial class Form1 : Form
{
publicForm1
{
InitializeComponent;
}
string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
string image_path = "";
string model_path;
string classer_path;
public string class_names;
public int class_num;
DateTime dt1 = DateTime.Now;
DateTime dt2 = DateTime.Now;
int input_height;
int input_width;
InferenceSession onnx_session;
int box_num;
floatconf_threshold;
floatnms_threshold;
StringBuilder sb = new stringBuilder;
///
/// 选择图片
///
///
///
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog;
ofd.Filter = fileFilter;
if(ofd.ShowDialog != DialogResult.OK)return;
pictureBox1.Image = ;
image_path = ofd.FileName;
pictureBox1.Image = new Bitmap(image_path);
textBox1.Text = "";
pictureBox2.Image = ;
}
///
/// 推理
///
private void button2_Click(object sender, EventArgs e)
{
if(image_path == "")
{
return;
}
button2.Enabled =false;
textBox1.Text = "";
sb.Clear;
Application.DoEvents;
Mat image = new Mat(image_path);
floatratio = Math.Min(input_height * 1.0f / image.Rows, input_width * 1.0f / image.Cols);
int neww = (int)(image.Cols * ratio);
int newh = (int)(image.Rows * ratio);
Mat dstimg = new Mat;
Cv2.CvtColor(image, dstimg, ColorConversionCodes.BGR2RGB);
Cv2.Resize(dstimg, dstimg, new OpenCvSharp.Size(neww, newh));
Cv2.CopyMakeBorder(dstimg, dstimg, 0, input_height - newh, 0, input_width - neww, BorderTypes.Constant, new Scalar(1));
//Cv2.ImShow("input_img", dstimg);
//输入Tensor
Tensorfloat> input_tensor = new DenseTensorfloat>(new { 1, 3, 640, 640 });
for(int y = 0; y < dstimg.Height; y++)
{
for(int x = 0; x < dstimg.Width; x++)
{
input_tensor[0, 0, y, x] = dstimg.At(y, x)[0];
input_tensor[0, 1, y, x] = dstimg.At(y, x)[1];
input_tensor[0, 2, y, x] = dstimg.At(y, x)[2];
}
}
dstimg.Dispose;
List input_container = new List
{
NamedOnnxValue.CreateFromTensor("input", input_tensor)
};
//推理
dt1 = DateTime.Now;
var ort_outputs = onnx_session.Run(input_container).ToArray;
dt2 = DateTime.Now;
float data = Transpose(ort_outputs[0].AsTensorfloat>.ToArray, 4 + class_num, box_num);
float confidenceInfo = newfloat[class_num];
float RectData = newfloat[4];
List detResults = new List;
for(int i = 0; i < box_num; i++)
{
Array.Copy(data, i * (class_num + 4), rectData, 0, 4);
Array.Copy(data, i * (class_num + 4) + 4, confidenceInfo, 0, class_num);
floatscore = confidenceInfo.Max; // 获取最大值
int maxIndex = Array.IndexOf(confidenceInfo, score); // 获取最大值的位置
int xmin = (int)(rectData[0] / ratio);
int ymin = (int)(rectData[1] / ratio);
int xmax = (int)(rectData[2] / ratio);
int ymax = (int)(rectData[3] / ratio);
Rect box = new Rect;
box.X = (int)xmin;
box.Y = (int)ymin;
box.Width = (int)(xmax - xmin);
box.Height = (int)(ymax - ymin);
detResults.Add(new detectionResult(
maxIndex,
class_names[maxIndex],
box,
score));
}
//NMS
CvDnn.NMSBoxes(detResults.Select(x => x.Rect), detResults.Select(x => x.Confidence), conf_threshold, nms_threshold, out int indices);
detResults = detResults.Where((x, index) => indices.Contains(index)).ToList;
sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");
sb.AppendLine("");
//绘制结果
Mat result_image = image.Clone;
foreach (DetectionResult rindetResults)
{
Cv2.PutText(result_image, $"{r.Class}:{r.Confidence:P0}", new OpenCvSharp.Point(r.Rect.TopLeft.X, r.Rect.TopLeft.Y - 10), HersheyFonts.HersheySimplex, 1, Scalar.Red, 2);
Cv2.Rectangle(result_image, r.Rect, Scalar.Red, thickness: 2);
sb.AppendLine(string.Format("{0}:{1},({2},{3},{4},{5})"
, r.Class
, r.Confidence.ToString("P0")
, r.Rect.TopLeft.X
, r.Rect.TopLeft.Y
, r.Rect.BottomRight.X
, r.Rect.BottomRight.Y
));
}
if(pictureBox2.Image != )
{
pictureBox2.Image.Dispose;
}
pictureBox2.Image = new Bitmap(result_image.ToMemoryStream);
result_image.Dispose;
textBox1.Text = sb.ToString;
button2.Enabled =true;
}
///
///窗体加载
///
private void Form1_Load(object sender, EventArgs e)
{
model_path = "model/damoyolo_cigarette.onnx";
//创建输出会话,用于输出模型读取信息
SessionOptions options = new SessionOptions;
options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行
// 创建推理模型类,读取模型文件
onnx_session = new InferenceSession(model_path, options);//model_path 为onnx模型文件的路径
input_height = 640;
input_width = 640;
box_num = 8400;
conf_threshold = 0.25f;
nms_threshold = 0.5f;
classer_path = "model/lable.txt";
class_names = File.ReadAllLines(classer_path, Encoding.UTF8);
class_num = class_names.Length;
image_path = "test_img/2.jpg";
}
///
/// 保存
///
private void button3_Click(object sender, EventArgs e)
{
if(pictureBox2.Image == )
{
return;
}
Bitmap output = new Bitmap(pictureBox2.Image);
SaveFileDialog sdf = new SaveFileDialog;
sdf.Title = "保存";
sdf.Filter = "Images (*.jpg)|*.jpg|Images (*.png)|*.png|Images (*.bmp)|*.bmp|Images (*.emf)|*.emf|Images (*.exif)|*.exif|Images (*.gif)|*.gif|Images (*.ico)|*.ico|Images (*.tiff)|*.tiff|Images (*.wmf)|*.wmf";
if(sdf.ShowDialog == DialogResult.OK)
{
switch (sdf.FilterIndex)
{
case1:
{
output.Save(sdf.FileName, ImageFormat.Jpeg);
break;
}
case2:
{
output.Save(sdf.FileName, ImageFormat.Png);
break;
}
case3:
{
output.Save(sdf.FileName, ImageFormat.Bmp);
break;
}
case4:
{
output.Save(sdf.FileName, ImageFormat.Emf);
break;
}
case5:
{
output.Save(sdf.FileName, ImageFormat.Exif);
break;
}
case6:
{
output.Save(sdf.FileName, ImageFormat.Gif);
break;
}
case7:
{
output.Save(sdf.FileName, ImageFormat.Icon);
break;
}
case8:
{
output.Save(sdf.FileName, ImageFormat.Tiff);
break;
}
case9:
{
output.Save(sdf.FileName, ImageFormat.Wmf);
break;
}
}
MessageBox.Show("保存成功,位置:" + sdf.FileName);
}
}
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
ShowNormalImg(pictureBox1.Image);
}
private void pictureBox2_DoubleClick(object sender, EventArgs e)
{
ShowNormalImg(pictureBox2.Image);
}
public void ShowNormalImg(Image img)
{
if(img == )return;
frmShow frm = new frmShow;
frm.Width = Screen.PrimaryScreen.Bounds.Width;
frm.Height = Screen.PrimaryScreen.Bounds.Height;
if(frm.Width > img.Width)
{
frm.Width = img.Width;
}
if(frm.Height > img.Height)
{
frm.Height = img.Height;
}
bool b = frm.richTextBox1.ReadOnly;
Clipboard.SetDataObject(img,true);
frm.richTextBox1.ReadOnly =false;
frm.richTextBox1.Paste(DataFormats.GetFormat(DataFormats.Bitmap));
frm.richTextBox1.ReadOnly = b;
frm.ShowDialog;
}
public unsafefloat Transpose(float tensorData, int rows, int cols)
{
float transposedTensorData = newfloat[tensorData.Length];
fixed (float* pTensorData = tensorData)
{
fixed (float* pTransposedData = transposedTensorData)
{
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
int index = i * cols + j;
int transposedIndex = j * rows + i;
pTransposedData[transposedIndex] = pTensorData[index];
}
}
}
}
returntransposedTensorData;
}
}
public class DetectionResult
{
public DetectionResult(int ClassId, string Class, Rect Rect,floatConfidence)
{
this.ClassId = ClassId;
this.Confidence = Confidence;
this.Rect = Rect;
this.Class = Class;
}
public string Class { get;set; }
public int ClassId { get;set; }
publicfloatConfidence { get;set; }
public Rect Rect { get;set; }
}
}
来源:opendotnet
免责声明:本站系转载,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本站联系,我们将在第一时间删除内容!