【问题标题】:Image binary interpretation: unknown image format图像二进制解释:未知图像格式
【发布时间】:2020-03-24 05:27:41
【问题描述】:

假设我有一个某种格式的图像(它的二进制表示,例如来自 OpenCV 的 cv::Mat 或来自 Android 的 YuvImage,未压缩),并将其数据解释为 YUV NV21(嗯,这是示例由 DJI SDK 提供,差不多)。这是我得到的:

据此,我假设原始格式不是 NV21。 YUV2? RGB888? RGB32?一些其他的东西?

如何猜测二进制数据的原始格式是什么?

如果这会有所帮助,则从 DJI 无人机流中获取帧。

【问题讨论】:

  • 建议:将数据解释为灰度,并将结果作为图像发布。添加有关帧大小(以字节为单位)和预期分辨率的信息。以灰度读取时,保持原始宽度,并将图像高度设置为以字节为单位的大小/宽度。 (以 NV21 为例,灰度高度为 original_height*1.5)
  • 发现了问题,自己回答了这个问题。无论如何,感谢您的评论 :) 您的见解有助于了解发生了什么。

标签: image opencv image-processing rgb dji-sdk


【解决方案1】:

YUV 图像输出使用 Android 库,该库会根据使用的设备产生不同的 YUV 格式。

就我而言,根据我使用的两个设备中的哪一个,我需要切换两个颜色通道(NV12 到 NV21)的字节。

真正帮助我理解我所使用的格式是使用以下 YUV 播放器: https://github.com/Tee0125/yuvplayer

在播放器中,您可以主动更改数据的解释方式,只需测试不同的设置,直到找到正确的设置。

虽然我不知道你是否需要,但我会提供我用来切换频道的方法。

/**
 * Changes a NV12 yuv Frame to the NV21 format. Basically the two color channels are switched.
 *
 * @param yuvFrameNV12 The YUV Frame in the NV12 format.
 * @param width The width of the frame.
 * @param height The height of the frame.
 * @return The YUV Frame in the NV21 format.
 */
private static byte[] convertNV12toNV21(byte[] yuvFrameNV12, int width, int height) {
    final int length = yuvFrameNV12.length;
    for (int i1 = 0; i1 < length; i1 += 2) {
        if (i1 >= width * height) { //start after the luminance bytes
            byte tmp = yuvFrameNV12[i1];
            yuvFrameNV12[i1] = yuvFrameNV12[i1+1];
            yuvFrameNV12[i1+1] = tmp;
        }
    }
    return yuvFrameNV12;
}

【讨论】:

  • 感谢您的回复。最后,我发现了问题,并自己回答了这个问题。不过,您的一些信息确实很有用(yuvplayer),所以,请点赞! :)
【解决方案2】:

好吧,最后,我们发现了图像处理中的一些不一致之处。

Android 的 YuvImage 期望你给它提供 NV21,所以我有一个从 I420 到 NV21 的有效转换方法。当我更改视频源(同一供应商,不同型号)时,我希望它具有相同的格式,但实际上它是 NV12。

将 NV12 重新解释为 I420,然后将其转换为 NV21,这就是这里发生的事情。

【讨论】:

    猜你喜欢
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 2014-06-10
    • 2015-04-11
    • 2019-01-04
    • 1970-01-01
    相关资源
    最近更新 更多