0

我正在按照这个 WinML示例创建一个回归模型并对其进行推理。我尝试使用 WinML/WinRT 运行 onnx 模型,但结果错误。我强制将数据读取为 RGB 而不是 BGR,但其中包含一个 alpha 组件,例如 RGBA,我怀疑错误的结果是由于 alpha 而我的原始模型中没有它。我该如何解决这个问题? 代码片段 控制台输出

VideoFrame LoadImageFile(hstring filePath, ColorManagementMode colorManagementMode)
{
    BitmapDecoder decoder = NULL;
    try
    {
        // open the file
        StorageFile file = StorageFile::GetFileFromPathAsync(filePath).get();
        // get a stream on it
        auto stream = file.OpenAsync(FileAccessMode::Read).get();
        // Create the decoder from the stream
        decoder = BitmapDecoder::CreateAsync(stream).get();
        decoder.GetPixelDataAsync().get().DetachPixelData()[3] = 1;
        decoder.GetPixelDataAsync().get().DetachPixelData()[7] = 1;
        auto pix = decoder.GetPixelDataAsync(BitmapPixelFormat::Rgba8, BitmapAlphaMode::Ignore, BitmapTransform(), ExifOrientationMode::IgnoreExifOrientation, ColorManagementMode::DoNotColorManage);
        for (auto b : pix.get().DetachPixelData())printf("%d\n", b);
       // printf("my pixels: %d", pix.get().DetachPixelData();
    }
    catch (...)
    {
        printf("    Failed to load the image file, make sure you are using fully qualified paths\r\n");
        exit(EXIT_FAILURE);
    }
    SoftwareBitmap softwareBitmap = NULL;
    try
    {
        softwareBitmap = decoder.GetSoftwareBitmapAsync(
            //decoder.BitmapPixelFormat(),
            BitmapPixelFormat::Rgba8,
            //decoder.BitmapAlphaMode(),
            BitmapAlphaMode::Ignore,
            BitmapTransform(),
            ExifOrientationMode::RespectExifOrientation,
            colorManagementMode
        ).get();
        
        printf("Image format: %d\n", softwareBitmap.BitmapPixelFormat());
    }

当我从解码器读取像素时,我得到 RGBA,其中 A (alpha) 设置为 255。我尝试将其替换为 1,但似乎该解码器是不可变的。如果我可以确保输入到模型的像素是正确的,那么这将产生正确的结果。

4

1 回答 1

1

请按照示例创建 VideoFrame,创建 videoFrame 时无需担心 alpha 通道,因为 WinML 无论如何都会忽略此通道。如果需要,调用SoftwareBitmap.Convert()在不同的像素格式之间进行转换

VideoFrame LoadImageFile(hstring filePath)
{
    printf("Loading the image...\n");
    DWORD ticks = GetTickCount();
    VideoFrame inputImage = nullptr;

    try
    {
        // open the file
        StorageFile file = StorageFile::GetFileFromPathAsync(filePath).get();
        // get a stream on it
        auto stream = file.OpenAsync(FileAccessMode::Read).get();
        // Create the decoder from the stream
        BitmapDecoder decoder = BitmapDecoder::CreateAsync(stream).get();
        // get the bitmap
        SoftwareBitmap softwareBitmap = decoder.GetSoftwareBitmapAsync().get();
        // load a videoframe from it
        inputImage = VideoFrame::CreateWithSoftwareBitmap(softwareBitmap);
    }
    catch (...)
    {
        printf("failed to load the image file, make sure you are using fully qualified paths\r\n");
        exit(EXIT_FAILURE);
    }

    ticks = GetTickCount() - ticks;
    printf("image file loaded in %d ticks\n", ticks);
    // all done
    return inputImage;
}
于 2021-01-21T22:29:24.800 回答