问题描述
我想从位图或byte []中加载图像。大多数样本正在使用文件。
我们想对视频流进行预测。我们可以将帧输出为位图或字节数组。
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 类型和成员图像数据的注册自定义类型(参数 '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);
解决方法
有一些动人的作品,但我会尽力掩盖它们(并希望我能把它们全部拿走!)。
我假设您使用的是预训练模型?如果您是您,则在加载上下文时不需要传递您的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-一些非常棒的东西,我不能推荐他的频道。
,您需要按照以下方式使用ImageType
标志,并使用Bitmap
代替Image
:
public class MagsData2
{
[ColumnName("image")]
[ImageType(512,512)]
public Bitmap ImageData;
}
您需要用调整大小后的图像的实际大小(ImageNetSettings.imageWidth,ImageNetSettings.imageHeight)替换(512,512)。
然后通过以下方式加载图像:
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);