I am using Onnxruntime in C# for yolov4. Here is the pretrained yolo model: https://github.com/onnx/models/tree/main/vision/object_detection_segmentation/yolov4/model
EmguCV is used to get an image, and then preprocess it to suit Yolo's input.
This is my preprocessing code:
static List<NamedOnnxValue> preprocess_CV(Mat im)
{
CvInvoke.Resize(im, im, new Size(416, 416));
var imData = im.ToImage<Bgr, Byte>().Data;
Tensor<float> input = new DenseTensor<float>(new[] {1, im.Height, im.Width, 3});
for (int x = 0; x < im.Width; x++)
for (int y = 0; y < im.Height; y++)
{
input[0, x, y, 0] = imData[x, y, 2] / (float)255.0;
input[0, x, y, 1] = imData[x, y, 1] / (float)255.0;
input[0, x, y, 2] = imData[x, y, 0] / (float)255.0;
}
List<NamedOnnxValue> inputs = new List<NamedOnnxValue> { NamedOnnxValue.CreateFromTensor("input_1:0", input) };
return inputs;
}
It works fine, but it is really slow, definitely because of nested fors.
So I decide to change it to the following code:
static List<NamedOnnxValue> preprocess_CV_v2(Mat im)
{
CvInvoke.Resize(im, im, new Size(416, 416));
im.ConvertTo(im, DepthType.Cv32F, 1 / 255.0);
CvInvoke.CvtColor(im, im, ColorConversion.Bgr2Rgb);
var imData = im.ToImage<Bgr, Byte>().Data;
var input = imData.ToTensor<float>();
List<NamedOnnxValue> inputs = new List<NamedOnnxValue> { NamedOnnxValue.CreateFromTensor("input_1:0", input) };
return inputs;
}
It does not use nested for and runs faster, but...
Output tensor shape of this code is (416,416,3), but yoloV4 need input tensor with shape (1,416,416,3).
How can I add a single dimension to onnx tensor or CV.Mat image, to fit my tensor to yoloV4 input?
It would be nice of you if you would help me with this problem.
Thanks in advance Mary