【问题标题】:Expand dimension of "EmguCV.Mat" or "Onnx Tensor"展开“EmguCV.Mat”或“Onnx Tensor”的维度
【发布时间】:2023-01-15 21:27:27
【问题描述】:

我在 C# 中为 yolov4 使用 Onnxruntime。 这是预训练的 yolo 模型: https://github.com/onnx/models/tree/main/vision/object_detection_segmentation/yolov4/model

EmguCV 用于获取图像,然后对其进行预处理以适合 Yolo 的输入。

这是我的预处理代码:

    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;
    }

它工作正常,但它真的很慢,肯定是因为嵌套的fors。

所以我决定把它改成下面的代码:

    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;
    }

它不使用嵌套 for 并且运行速度更快,但是......

此代码的输出张量形状为 (416,416,3),但 yoloV4 需要形状为 (1,416,416,3) 的输入张量。

如何将单一维度添加到 onnx 张量或 CV.Mat 图像,以使我的张量适合 yoloV4 输入?

如果你能帮我解决这个问题,你会很高兴。

提前致谢 玛丽

【问题讨论】:

  • 重新考虑你的标签。 C# 与特定问题无关(但没关系,因为你问的是 C#),其他标签非常小,几乎没有人监视它们。

标签: c# onnx image-preprocessing yolov4 onnxruntime


【解决方案1】:

我自己找到了一个解决方案:D

它可能会帮助遇到同样问题的其他人。

对我来说,这段代码比原始代码(问题中的 preprocess_CV 函数)快大约 10 倍。

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, float>().Data;

        float[] imDataFlat = new float[imData.Length];
        Buffer.BlockCopy(imData, 0, imDataFlat, 0, imData.Length * 4);

        var inputTensor = new DenseTensor<float>(imDataFlat, new int[] { 1, im.Height, im.Width, 3 });
        List<NamedOnnxValue> inputs = new List<NamedOnnxValue> { NamedOnnxValue.CreateFromTensor("input_1:0", inputTensor) };
        return inputs;
    }

【讨论】:

    猜你喜欢
    • 2016-05-01
    • 2021-09-16
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    相关资源
    最近更新 更多