简体   繁体   English

YUV NV21转换为RGB的困惑

[英]Confusion on YUV NV21 conversion to RGB

According to http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21 , NV21 is the default used format. 根据http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21,NV21是默认使用的格式。

There are quite a number of code on web regarding YUV NV21 to RGB conversion. 网上有很多关于YUV NV21到RGB转换的代码。 However, when I go through the code, I doubt on the correctness of the code. 但是,当我查看代码时,我怀疑代码的正确性。

The first component V should come first, followed by first component U 首先应该是第一个组件V,然后是第一个组件U.

According to http://wiki.videolan.org/YUV#NV21 , NV21 is like NV12, but with U and V order reversed: it starts with V. However, when I went through the code implementation 根据http://wiki.videolan.org/YUV#NV21,NV21与 NV21 is like NV12, but with U and V order reversed: it starts with V.但是,当我完成代码实现时

R should be the most significant position According implementation of int argb in Color.java , R suppose to be at the most significant position. R应该是最重要的位置根据Color.javaint argb实现 ,R假设处于最重要的位置。 However, I went through the following code implementation 但是,我经历了以下代码实现

I was wondering, are they making common mistake, or I have overlooked something? 我想知道,他们是否犯了常见错误,或者我忽略了什么?

Currently, my implementation is as follow. 目前,我的实施如下。

public static void YUV_NV21_TO_RGB(int[] argb, byte[] yuv, int width, int height) {
    final int frameSize = width * height;

    final int ii = 0;
    final int ij = 0;
    final int di = +1;
    final int dj = +1;

    int a = 0;
    for (int i = 0, ci = ii; i < height; ++i, ci += di) {
        for (int j = 0, cj = ij; j < width; ++j, cj += dj) {
            int y = (0xff & ((int) yuv[ci * width + cj]));
            int v = (0xff & ((int) yuv[frameSize + (ci >> 1) * width + (cj & ~1) + 0]));
            int u = (0xff & ((int) yuv[frameSize + (ci >> 1) * width + (cj & ~1) + 1]));
            y = y < 16 ? 16 : y;

            int r = (int) (1.164f * (y - 16) + 1.596f * (v - 128));
            int g = (int) (1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128));
            int b = (int) (1.164f * (y - 16) + 2.018f * (u - 128));

            r = r < 0 ? 0 : (r > 255 ? 255 : r);
            g = g < 0 ? 0 : (g > 255 ? 255 : g);
            b = b < 0 ? 0 : (b > 255 ? 255 : b);

            argb[a++] = 0xff000000 | (r << 16) | (g << 8) | b;
        }
    }
}

First of all, I am not super experienced with image encoding (has some limited exposure to this about a year ago). 首先,我对图像编码没有超级经验(大约一年前对此有一定的了解)。 So, take my answer with grain of salt. 所以,我的答案是盐。

However, I believe you are right. 但是,我相信你是对的。 I think in their code both a) V and U are flipped b) R and B are flipped 我认为在他们的代码中,a)V和U都被翻转b)R和B被翻转

I have a feeling that when both of these things are flipped, it will produce the same result as if they arent' flipped. 我有一种感觉,当这些东西都被翻转时,它会产生相同的结果,好像它们没有被翻转一样。 That's the reason why you can find wrong code in many places (originally, somebody got it wrong and after it was copied all over the places, because the resulting code works (however, variables named incorrectly)). 这就是为什么你可以在许多地方找到错误的代码的原因(最初,有人弄错了,并且在整个地方复制之后,因为生成的代码有效(但是,变量命名不正确))。

Here is another example of code (which works the same as yours): http://www.41post.com/3470/programming/android-retrieving-the-camera-preview-as-a-pixel-array 这是另一个代码示例(与您的代码相同): http//www.41post.com/3470/programming/android-retrieving-the-camera-preview-as-a-pixel-array

Terms like "most significant position" are ambiguous, because it depends on the endian of the machine. 像“最重要的位置”这样的术语含糊不清,因为它取决于机器的端点。

When all data types are 8 bits, there is an easy unambiguous specification: byte order. 当所有数据类型都是8位时,有一个简单明确的规范:字节顺序。 For example, unsigned char rgba[4]; 例如,unsigned char rgba [4]; would have the data stored as rgba[0] = r; 将数据存储为rgba [0] = r; rgba[1] = g; rgba [1] = g; rgba[2] = b; rgba [2] = b; rgba[3] = a; rgba [3] = a;

or {r, g, b, a } regardless of the endianness of the processor. 或{r,g,b,a},无论处理器的字节顺序如何。

If instead you did 如果你做了

int32 color = (r << 24) | int32 color =(r << 24)| (g << 16) | (g << 16)| (b << 8) | (b << 8)| (a << 0); (a << 0);

you would get { r, g, b, a } on a big-endian system, and { a, r, g, b } on a little-endian system. 你会得到一个大端系统上的{r,g,b,a},以及一个小端系统上的{a,r,g,b}。 Do you work on systems that have heterogeneous processors? 您是否在具有异构处理器的系统上工作? Like maybe you have a CPU and a GPU? 也许你有CPU和GPU? How do they know which endian the other is using? 他们如何知道对方使用的是哪个端? You are much better off defining the byte ordering. 你最好定义字节顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM