C#调用Onnx模型
前言前段时间玩了把yolo,结果卡在用winform调用模型实识别的过程.从网络上找了很长一段时间代码,结果总不尽人意.今天隔离结束,回到工位,继续撸代码.环境vs2019,Net5,ML.OnnxRuntime,SixLabors.准备nuget下载如下包,下载onnx权重文件models/FasterRCNN-10.onnx at main · onnx/models · GitHub代码us
文章共1,088字 · 阅读需要大约4分钟
一键AI生成摘要,助你高效阅读
问答
·
前言
前段时间玩了把yolo,结果卡在用winform调用模型实识别的过程.从网络上找了很长一段时间代码,结果总不尽人意.今天隔离结束,回到工位,继续撸代码.
环境
vs2019,Net5,ML.OnnxRuntime,SixLabors.
准备
nuget下载如下包,
下载onnx权重文件
models/FasterRCNN-10.onnx at main · onnx/models · GitHub
代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.ML.OnnxRuntime.Tensors;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.Fonts;
//using SixLabors.Fonts;
//using System.Drawing;
namespace Microsoft.ML.OnnxRuntime.FasterRcnnSample
{
class Program
{
public static void Main(string[] args)
{
// Read paths
string modelFilePath = @"D:\Test\2022\FasterRCNN-10.onnx";
//string modelFilePath = @"D:\Test\2022\best.onnx";
// string imageFilePath = @"D:\Test\2022\A.jpg";
string imageFilePath = @"D:\Test\2022\B.png";
string outImageFilePath = "outputs.jpg";
//System.IO.Directory.CreateDirectory(outImageFilePath);
// Read image
using Image<Rgb24> image = SixLabors.ImageSharp.Image.Load<Rgb24>(imageFilePath);
// Resize image
float ratio = 800f / Math.Min(image.Width, image.Height);
image.Mutate(x => x.Resize((int)(ratio * image.Width), (int)(ratio * image.Height)));
// Preprocess image
var paddedHeight = (int)(Math.Ceiling(image.Height / 32f) * 32f);
var paddedWidth = (int)(Math.Ceiling(image.Width / 32f) * 32f);
Tensor<float> input = new DenseTensor<float>(new[] { 3, paddedHeight, paddedWidth });
var mean = new[] { 102.9801f, 115.9465f, 122.7717f };
for (int y = paddedHeight - image.Height; y < image.Height; y++)
{
image.ProcessPixelRows(im =>
{
var pixelSpan = im.GetRowSpan(y);
for (int x = paddedWidth - image.Width; x < image.Width; x++)
{
input[0, y, x] = pixelSpan[x].B - mean[0];
input[1, y, x] = pixelSpan[x].G - mean[1];
input[2, y, x] = pixelSpan[x].R - mean[2];
}
});
}
// Setup inputs and outputs
var inputs = new List<NamedOnnxValue>
{
NamedOnnxValue.CreateFromTensor("image", input)
};
// Run inference
using var session = new InferenceSession(modelFilePath);
using IDisposableReadOnlyCollection<DisposableNamedOnnxValue> results = session.Run(inputs);
// Postprocess to get predictions
var resultsArray = results.ToArray();
float[] boxes = resultsArray[0].AsEnumerable<float>().ToArray();
long[] labels = resultsArray[1].AsEnumerable<long>().ToArray();
float[] confidences = resultsArray[2].AsEnumerable<float>().ToArray();
var predictions = new List<Prediction>();
var minConfidence = 0.7f;
for (int i = 0; i < boxes.Length - 4; i += 4)
{
var index = i / 4;
if (confidences[index] >= minConfidence)
{
predictions.Add(new Prediction
{
Box = new Box(boxes[i], boxes[i + 1], boxes[i + 2], boxes[i + 3]),
Label = LabelMap.Labels[labels[index]],
Confidence = confidences[index]
});
}
}
// Put boxes, labels and confidence on image and save for viewing
using var outputImage = File.OpenWrite(outImageFilePath);
Font font = SystemFonts.CreateFont("Arial",16);
foreach (var p in predictions)
{
image.Mutate(x =>
{
x.DrawLines(Color.Red, 2f, new PointF[] {
new SixLabors.ImageSharp.PointF(p.Box.Xmin, p.Box.Ymin),
new SixLabors.ImageSharp.PointF(p.Box.Xmax, p.Box.Ymin),
new PointF(p.Box.Xmax, p.Box.Ymin),
new PointF(p.Box.Xmax, p.Box.Ymax),
new PointF(p.Box.Xmax, p.Box.Ymax),
new PointF(p.Box.Xmin, p.Box.Ymax),
new PointF(p.Box.Xmin, p.Box.Ymax),
new PointF(p.Box.Xmin, p.Box.Ymin)
});
x.DrawText($"{p.Label}, {p.Confidence:0.00}", font, Color.White, new PointF(p.Box.Xmin, p.Box.Ymin));
});
}
image.SaveAsJpeg(outputImage);
}
}
public class Prediction
{
public Box Box { set; get; }
public string Label { set; get; }
public float Confidence { set; get; }
}
public class Box
{
public Box(float xMin,float yMin,float xMax,float yMax)
{
Xmin = xMin;
Ymin = yMin;
Xmax = xMax;
Ymax = yMax;
}
public float Xmin { set; get; }
public float Xmax { set; get; }
public float Ymin { set; get; }
public float Ymax { set; get; }
}
public static class LabelMap
{
static LabelMap()
{
Labels = new string[]
{
"",
"person",
"bicycle",
"car",
"motorcycle",
"airplane",
"bus",
"train",
"truck",
"boat",
"traffic light",
"fire hydrant",
"stop sign",
"parking meter",
"bench",
"bird",
"cat",
"dog",
"horse",
"sheep",
"cow",
"elephant",
"bear",
"zebra",
"giraffe",
"backpack",
"umbrella",
"handbag",
"tie",
"suitcase",
"frisbee",
"skis",
"snowboard",
"sports ball",
"kite",
"baseball bat",
"baseball glove",
"skateboard",
"surfboard",
"tennis racket",
"bottle",
"wine glass",
"cup",
"fork",
"knife",
"spoon",
"bowl",
"banana",
"apple",
"sandwich",
"orange",
"broccoli",
"carrot",
"hot dog",
"pizza",
"donut",
"cake",
"chair",
"couch",
"potted plant",
"bed",
"dining table",
"toilet",
"tv",
"laptop",
"mouse",
"remote",
"keyboard",
"cell phone",
"microwave",
"oven",
"toaster",
"sink",
"refrigerator",
"book",
"clock",
"vase",
"scissors",
"teddy bear",
"hair drier",
"toothbrush"
};
}
public static string[] Labels { set; get; }
}
}
说明
1.NamedOnnxValue.CreateFromTensor("image", input),这里面的"image"可以从WinMLDashboard软件中看到.
2.image.GetPixelRowSpan() 方法已经被 image.ProcessPixelRows()方法取代.这个东西找了半天.
3.Prediction,Box,LabelMap,是自己补全的.没找到网上的源代码.
效果
随便从网上找的图片.如有侵权,请联系本人.
引用
Mr.Q老师的博客
更多推荐
已为社区贡献1条内容
所有评论(0)