using System.Reflection; using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; namespace CandyboxPlugin.Detectors { public class CandyDetector { private const string MODEL_NAME = "model_transparent_candy_resnet.onnx"; private readonly InferenceSession _AIsession; private readonly string _inputName; private readonly int[] _dimensions; public CandyDetector() { var opts = new SessionOptions(); // get this dll path var path = Assembly.GetCallingAssembly().Location; var dir = System.IO.Path.GetDirectoryName(path); var modelPath = Path.Combine(dir, "models\\" + MODEL_NAME); _AIsession = new InferenceSession(modelPath, opts); _inputName = _AIsession.InputMetadata.First().Key; _dimensions = _AIsession.InputMetadata.First().Value.Dimensions; foreach (var input in _AIsession.InputMetadata) { Console.WriteLine($"Name: {input.Key}"); Console.WriteLine($" Type: {input.Value.ElementType}"); Console.WriteLine($" Shape: [{string.Join(", ", input.Value.Dimensions)}]"); } } public Mat Eval(Mat bmpTest) { var currentImage = bmpTest; var rightColor = currentImage.CvtColor(ColorConversionCodes.BGR2RGB); // convert to float32 var floatImage = new Mat(); rightColor.ConvertTo(floatImage, MatType.CV_32FC3, 1.0 / 255); // to array var width = _dimensions[1]; var height = _dimensions[2]; // check if need resize if (floatImage.Width != width || floatImage.Height != height) Cv2.Resize(floatImage, floatImage, new OpenCvSharp.Size(width, height)); float[] data = new float[3 * width * height]; int idx = 0; var rows = floatImage.Rows; var cols = floatImage.Cols; for (int y = 0; y < rows; y++) { for (int x = 0; x < cols; x++) { Vec3f pixel = floatImage.At(y, x); for (int c = 0; c < 3; c++) // channels { data[idx++] = pixel[c]; // width*height*channel } } } var inputTensor = new DenseTensor( data, new int[] { 1, floatImage.Width, floatImage.Height, 3 } ); var inputs = new List { NamedOnnxValue.CreateFromTensor("input", inputTensor) }; var sw = System.Diagnostics.Stopwatch.StartNew(); using var results = _AIsession.Run(inputs); sw.Stop(); Console.WriteLine($"Inference time: {sw.ElapsedMilliseconds} ms"); var output = results.First().AsEnumerable().ToArray(); // convert output to Mat and normalize to 0-255 var outputMat = new Mat(new OpenCvSharp.Size(width, height), MatType.CV_32FC1); outputMat.SetArray(output); outputMat.ConvertTo(outputMat, MatType.CV_8UC1, 255); // resize back to original size Cv2.Resize(outputMat, outputMat, new OpenCvSharp.Size(currentImage.Width, currentImage.Height)); return outputMat; } } }