Размер входного изображения модели составляет 576x720, хотя она была обучена с использованием изображений 720x576. Это не серьезная проблема, потому что я могу легко изменить размер изображений, выполнить прогнозы, а затем изменить их размер обратно. Я не знаю, почему это произошло во время обучения, возможно, это как-то связано с моей проблемой.
Результаты, которые я получаю от C#, не очень хорошие. На моих изображениях вообще не обнаруживаются объекты, тогда как в моем коде Python все работает нормально. Я заметил, что в C# большую часть времени я получаю сообщение об ошибке от ONNX, в котором говорится, что он пытался разделить на ноль, но когда я не получаю этой ошибки, объекты, которые он обнаруживает, являются просто мусором.
-resultsArray {Microsoft.ML.OnnxRuntime.DisposableNamedOnnxValue[3]} Microsoft.ML.OnnxRuntime.DisposableNamedOnnxValue[]
-
Код: Выделить всё
[0] {Microsoft.ML.OnnxRuntime.DisposableNamedOnnxValue} Microsoft.ML.OnnxRuntime.DisposableNamedOnnxValue
-
Код: Выделить всё
[1] {Microsoft.ML.OnnxRuntime.DisposableNamedOnnxValue} Microsoft.ML.OnnxRuntime.DisposableNamedOnnxValue ElementType Int64 Microsoft.ML.OnnxRuntime.Tensors.TensorElementType Name "2546" string
-
Код: Выделить всё
Value {"Attempted to divide by zero."} object {Microsoft.ML.OnnxRuntime.Tensors.DenseTensor} ValueType ONNX_TYPE_TENSOR Microsoft.ML.OnnxRuntime.OnnxValueType _disposed false bool _mapHelper null Microsoft.ML.OnnxRuntime.MapHelper _name "2546" string -
Код: Выделить всё
_ortValueHolder {Microsoft.ML.OnnxRuntime.OrtValueTensor} Microsoft.ML.OnnxRuntime.IOrtValueOwner {Microsoft.ML.OnnxRuntime.OrtValueTensor} -
Код: Выделить всё
_value {"Attempted to divide by zero."} object {Microsoft.ML.OnnxRuntime.Tensors.DenseTensor} -
Код: Выделить всё
[2] {Microsoft.ML.OnnxRuntime.DisposableNamedOnnxValue} Microsoft.ML.OnnxRuntime.DisposableNamedOnnxValue
Модель была обучена без любая явная нормализация и т. д., только необработанное изображение RGB. Несмотря на это, мне удалось достичь среднего показателя IoU проверки, приближающегося к 95 %.
Код: Выделить всё
private void cmdAnalyse_Click(object sender, EventArgs e)
{
// begin analysis
if (this.txtONNXFile.Text == "")
{
MessageBox.Show("Please select an ONNX file");
return;
}
if (this.originalImage == null)
{
MessageBox.Show("Please select an image");
return;
}
// flip the width and height dimensions. Images are 720x576, but the model expects 576x720
this.rescaledImage = new Bitmap(originalImage.Height, originalImage.Width);
Graphics graphics = Graphics.FromImage(rescaledImage);
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.DrawImage(originalImage, 0, 0, rescaledImage.Width, rescaledImage.Height);
Microsoft.ML.OnnxRuntime.Tensors.Tensor input = new Microsoft.ML.OnnxRuntime.Tensors.DenseTensor(new[] { 1, 3, 720, 576 });
BitmapData bitmapData = rescaledImage.LockBits(new System.Drawing.Rectangle(0, 0, rescaledImage.Width, rescaledImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
int stride = bitmapData.Stride;
IntPtr scan0 = bitmapData.Scan0;
unsafe
{
byte* ptr = (byte*)scan0;
for (int y = 0; y < rescaledImage.Height; y++)
{
for (int x = 0; x < rescaledImage.Width; x++)
{
int offset = y * stride + x * 3;
input[0, 0, y, x] = ptr[offset + 2]; // Red channel
input[0, 1, y, x] = ptr[offset + 1]; // Green channel
input[0, 2, y, x] = ptr[offset]; // Blue channel
}
}
}
rescaledImage.UnlockBits(bitmapData);
var inputs = new List
{
Microsoft.ML.OnnxRuntime.NamedOnnxValue.CreateFromTensor("images", input)
};
// run inference
var session = new Microsoft.ML.OnnxRuntime.InferenceSession(this.txtONNXFile.Text);
Microsoft.ML.OnnxRuntime.IDisposableReadOnlyCollection results = session.Run(inputs);
// process results
var resultsArray = results.ToArray();
float[] boxes = resultsArray[0].AsEnumerable().ToArray();
long[] labels = resultsArray[1].AsEnumerable().ToArray();
float[] confidences = resultsArray[2].AsEnumerable().ToArray();
var predictions = new List
();
var minConfidence = 0.0f;
for (int i = 0; i < boxes.Length; 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]
});
}
}
System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(this.rescaledImage);
// Put boxes, labels and confidence on image and save for viewing
foreach (var p in predictions)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Red, 2);
graph.DrawRectangle(pen, p.Box.Xmin, p.Box.Ymin, p.Box.Xmax - p.Box.Xmin, p.Box.Ymax - p.Box.Ymin);
}
graph.Flush();
graph.Dispose();
// rescale image back
System.Drawing.Bitmap bmpResult = new Bitmap(this.originalImage.Width, this.originalImage.Height);
graphics = Graphics.FromImage(bmpResult);
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.DrawImage(rescaledImage, 0, 0, originalImage.Width, originalImage.Height);
graphics.Flush();
graphics.Dispose();
//graph.ScaleTransform(720, 576);
this.pbRibeye.Width = bmpResult.Width;
this.pbRibeye.Height = bmpResult.Height;
this.pbRibeye.Image = bmpResult;
//bmpResult.Dispose();
rescaledImage.Dispose();
}
Код: Выделить всё
ort_session = onnxruntime.InferenceSession(ONNXFile)
# Preprocess the input image
image = Image.open(image_path) # Load the image using PIL
resized_image = image.resize((576, 720)) # If this is omitted then I receive an error regarding the expected input dimensions
transform = torchvision.transforms.Compose([
torchvision.transforms.ToTensor(), # Convert PIL image to tensor
])
input_tensor = transform(resized_image)
input_tensor = input_tensor.unsqueeze(0) # Add a batch dimension
# Run the model
outputs = ort_session.run(None, {'images': input_tensor.numpy()})
Подробнее здесь: https://stackoverflow.com/questions/765 ... in-c-sharp
Мобильная версия