C# 如何使用位图或字节数组从内存加载图像,以便在ML.net中进行图像处理

C# 如何使用位图或字节数组从内存加载图像,以便在ML.net中进行图像处理,c#,ml.net,C#,Ml.net,我想从内存中的位图或字节[]加载图像。大多数示例都使用文件 我想在视频流上运行预测。我们可以在位图或字节数组中获取帧 public class MagsData2 { public Image ImageData; } public class MagsData { public byte[] ImageData; } Image btmap = Bitmap.FromFile("assets/images/img.jpg"); var images

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

我想在视频流上运行预测。我们可以在
位图
字节数组
中获取帧

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: 'Schema mismatch for input column 'ImageData': 
expected String, got VarVector<Byte> (Parameter 'inputSchema')'
相关代码

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);
var data=mlContext.data.LoadFromEnumerable(new List());
var pipeline=mlContext.Transforms.LoadImages(outputColumnName:“图像”,imageFolder:,inputColumnName:nameof(MagsData.ImageData))
.Append(mlContext.Transforms.ResizeImages(outputColumnName:“图像”,imageWidth:ImageNetSettings.imageWidth,imageHeight:ImageNetSettings.imageHeight,inputColumnName:“图像”))
.Append(mlContext.Transforms.ExtractPixels(outputColumnName:“image”))
.Append(mlContext.Transforms.ApplyOnnxModel(modelFile:modelLocation,outputColumnNames:new[]{TinyYoloModelSettings.ModelOutput},inputColumnNames:new[]{TinyYoloModelSettings.ModelInput});
var模型=pipeline.Fit(数据);

有一些移动的片段,但我会尽我最大的努力来掩盖它们(希望我能把它们都弄到手!)

我假设您使用的是预训练模型?如果是,则在加载上下文时不需要向ml上下文传递任何图像。我知道这感觉有点怪,但是对于预训练模型来说,将LoadFromEnumerable传递给空列表是可以的。还要注意的是,由于处理图像不再是管道的工作,因此不会向管道传递要处理的任何图像的位置

我们不希望在管道中加载图像,而是希望使用一个可以用来获取预测的预测引擎(请参阅)。这是一个需要输入和输出类型的泛型,因此在我们的例子中,我认为您需要这样做

var PredictionEngine<MagsData, MagsPrediction> predictionEngine;
将所有这些放在一起,预测代码如下所示

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});
var emptyData=new List();
var imageDataView=context.Data.LoadFromEnumerable(emptyData);
var pipeline=context.Transforms.ResizeImages(调整大小:ImageResizingImator.ResizingKind.Fill,outputColumnName:“图像”,imageWidth:ImageSettings.imageWidth,imageHeight:ImageSettings.imageHeight,inputColumnName:nameof(MagsData2.image))
Append(context.Transforms.ExtractPixels(outputColumnName:“image”)).Append(context.Transforms.ApplyOnnxModel(modelFile:“模型的位置”、outputColumnName:“网格”、inputColumnName:“图像”);
var模型=pipeline.Fit(数据);
var predictionEngine=context.Model.CreatePredictionEngine(Model);
var prediction=predictionEngine.Predict(新的MagsData2{Image=YOURIMAGE});
然后,您可以对每个图像反复使用预测引擎,更多的后续Microsoft文档将获得边界框等


我在ML.Net上找到的最好的资源之一是Jon Wood的YouTube频道-一些非常好的东西,我不能充分推荐他的频道。

您需要使用
ImageType
标志,如下所示,并使用
位图
而不是
图像

public class MagsData2
{
[栏目名称(“图片”)]
[图像类型(512、512)]
公共位图图像数据;
}
您需要用调整大小的图像的实际大小(ImageNetSettings.imageWidth、ImageNetSettings.imageHeight)替换(512、512)

然后使用以下内容加载图像:

Image btmap=Bitmap.FromFile(“assets/images/img.jpg”);
var images=new List(){new MagsData2(){ImageData=new Bitmap(btmap)};
然后,您的管道变成:

var data=mlContext.data.LoadFromEnumerable(new List());
var pipeline=mlContext.Transforms.ResizeImages(outputColumnName:“图像”,imageWidth:ImageNetSettings.imageWidth,imageHeight:ImageNetSettings.imageHeight,inputColumnName:“图像”)
.Append(mlContext.Transforms.ExtractPixels(outputColumnName:“image”))
.Append(mlContext.Transforms.ApplyOnnxModel(modelFile:modelLocation,outputColumnNames:new[]{TinyYoloModelSettings.ModelOutput},inputColumnNames:new[]{TinyYoloModelSettings.ModelInput});
var模型=pipeline.Fit(数据);
var PredictionEngine<MagsData, MagsPrediction> predictionEngine;
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});