【问题标题】:How to load image from memory with bitmap or byte array for image processing in ML.net如何使用位图或字节数组从内存中加载图像以在 ML.net 中进行图像处理
【发布时间】:2020-10-14 16:25:00
【问题描述】:

我想从内存中的bitmapbyte[] 加载图像。大多数示例都使用文件。

我想对视频流进行预测。我们可以在bitmapsbyte arrays 中取出帧。

public class MagsData2
{
    public Image ImageData;
}

public class MagsData
{
    public byte[] ImageData;
}   

Image btmap = Bitmap.FromFile("assets/images/img.jpg");
var images = new List<MagsData2>() { new MagsData2() { ImageData = btmap } };
var images = new List<MagsData>() { new MagsData() { ImageData = ImageToByte(btmap) } };

使用第一个会出现异常:

System.ArgumentOutOfRangeException: '无法确定 IDataView 成员 ImageData 的类型和注册的自定义类型(参数 'rawType')'

上线

IDataView imageDataView = mlContext.Data.LoadFromEnumerable(images);

第二个给出异常:

System.ArgumentOutOfRangeException: 'Schema mismatch for input column 'ImageData': 
expected String, got VarVector<Byte> (Parameter 'inputSchema')'

上线

var model = pipeline.Fit(data);

相关代码

var data = mlContext.Data.LoadFromEnumerable(new List<MagsData>());
            var pipeline = mlContext.Transforms.LoadImages(outputColumnName: "image", imageFolder: "", inputColumnName: nameof(MagsData.ImageData))
                .Append(mlContext.Transforms.ResizeImages(outputColumnName: "image", imageWidth: ImageNetSettings.imageWidth, imageHeight: ImageNetSettings.imageHeight, inputColumnName: "image"))
                .Append(mlContext.Transforms.ExtractPixels(outputColumnName: "image"))
                .Append(mlContext.Transforms.ApplyOnnxModel(modelFile: modelLocation, outputColumnNames: new[] { TinyYoloModelSettings.ModelOutput }, inputColumnNames: new[] { TinyYoloModelSettings.ModelInput }));
            var model = pipeline.Fit(data);

【问题讨论】:

    标签: c# ml.net


    【解决方案1】:

    有一些动人的部分,但我会尽力掩盖它们(并希望我能把它们全都拿走!)。

    我假设您使用的是预训练模型?如果您是,则在加载上下文时不需要传递您的 ml 上下文任何图像。我知道这感觉有点古怪,但在预训练模型的情况下,将 LoadFromEnumeable 传递给一个空列表是可以的。另请注意,您不会将任何要处理的图像的位置传递给管道,因为处理图像不再是管道的工作。

    我们不想在管道中加载图像,而是想使用一个预测引擎来获取我们的预测(参见https://docs.microsoft.com/en-us/dotnet/api/microsoft.ml.predictionengine-2?view=ml-dotnet)。这是一个需要输入和输出类型的泛型,所以在我们的例子中我认为你会想要这样做。

    var PredictionEngine<MagsData, MagsPrediction> predictionEngine;
    

    MagsPrediction 是您定义的与模型输出匹配的类。在 TinyYolo2 的情况下,它看起来像

    public class MagsPreidction
        {
            [ColumnName("grid")]
            public float[] PredictedLabels { get; set; }
        }
    

    综合起来,预测代码如下所示。

    var emptyData = new List<MagsData2>();
    var imageDataView = context.Data.LoadFromEnumerable(emptyData);
    
    var pipeline = context.Transforms.ResizeImages(resizing: ImageResizingEstimator.ResizingKind.Fill, outputColumnName: "image", imageWidth: ImageSettings.imageWidth,imageHeight: ImageSettings.imageHeight, inputColumnName: nameof(MagsData2.Image))
    Append(context.Transforms.ExtractPixels(outputColumnName: "image")).Append(context.Transforms.ApplyOnnxModel(modelFile: "LOCATION OF YOUR MODEL", outputColumnName: "grid", inputColumnName: "image"));
    
    var model = pipeline.Fit(data);
    var predictionEngine = context.Model.CreatePredictionEngine<MagsInput, MagsPrediction>(model);
    
    var prediction = predictionEngine.Predict(new MagsData2{ Image = YOURIMAGE});
    

    然后,您可以对每张图像反复使用预测引擎,并且更多地遵循 Microsoft 文档的其余部分以获取边界框等。

    我在 ML.Net 上找到的最好的资源之一是 Jon Wood 的 YouTube 频道 https://www.youtube.com/channel/UCrDke-1ToEZOAPDfrPGNdQw - 一些非常好的东西,我不能推荐他的频道。

    【讨论】:

      【解决方案2】:

      您需要使用ImageType标志如下,并使用Bitmap而不是Image

      public class MagsData2
      {
          [ColumnName("image")]
          [ImageType(512, 512)]
          public Bitmap ImageData;
      }
      

      需要将(512, 512)替换为调整后图片的实际大小(ImageNetSettings.imageWidth, ImageNetSettings.imageHeight)。

      然后加载图像:

      Image btmap = Bitmap.FromFile("assets/images/img.jpg");
      var images = new List<MagsData2>() { new MagsData2() { ImageData = new Bitmap(btmap) } };
      

      那么你的管道就变成了:

      var data = mlContext.Data.LoadFromEnumerable(new List<MagsData2>());
      
      var pipeline = mlContext.Transforms.ResizeImages(outputColumnName: "image", imageWidth: ImageNetSettings.imageWidth, imageHeight: ImageNetSettings.imageHeight, inputColumnName: "image")
          .Append(mlContext.Transforms.ExtractPixels(outputColumnName: "image"))
          .Append(mlContext.Transforms.ApplyOnnxModel(modelFile: modelLocation, outputColumnNames: new[] { TinyYoloModelSettings.ModelOutput }, inputColumnNames: new[] { TinyYoloModelSettings.ModelInput }));
      
      var model = pipeline.Fit(data);
      

      【讨论】:

        【解决方案3】:

        使用ImageType

        你必须添加

        using Microsoft.ML.Transforms.Image;
        

        感谢以上 cmets,我解决了我的问题!

        【讨论】:

        • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 2022-06-11
        • 1970-01-01
        • 1970-01-01
        • 2013-08-27
        • 2013-03-25
        • 1970-01-01
        • 2022-10-06
        • 2014-12-14
        • 1970-01-01
        相关资源
        最近更新 更多