混乱的YUV NV21转换为RGB转换为、混乱、YUV、RGB

由网友(随风)分享简介:据http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21, NV21是默认使用的格式。有相当数量的code网络上关于YUV NV21到RGB转换。然而,当我经过code,我怀疑的code是正确的。第一分量V应该是第一位的...

据http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21, NV21是默认使用的格式。

有相当数量的code网络上关于YUV NV21到RGB转换。然而,当我经过code,我怀疑的code是正确的。

第一分量V应该是第一位的,其次是第一个组件U

据http://wiki.videolan.org/YUV#NV21, NV21就像是NV12,但与U和V顺序颠倒:它采用V开头然而,当我在code实现去

。 http://pastebin.com/T0my7zSc - 它假定ü至上 http://stackoverflow.com/a/8394202/72437 - 它假定ü至上太 http://stackoverflow.com/a/10125048/72437 - 它assmesü至上太

研究应该是最有显著位置 根据实施 INT的argb 的Color.java, ř假设是在最显著的位置。但是,我通过以下code实现去

http://pastebin.com/T0my7zSc - 它假定r是至少显著位置 http://stackoverflow.com/a/8394202/72437 - 它假定r是至少显著位置

我在想,是他们使常见的错误,或者我忽略了一些东西?

目前,我实现如下。

 公共静态无效YUV_NV21_TO_RGB(INT [] ARGB,byte []的YUV,诠释的宽度,高度INT){
    最终诠释框架尺寸=宽*高;

    最终诠释II = 0;
    最终诠释IJ = 0;
    最终诠释迪= + 1;
    最终诠释DJ = + 1;

    INT一个= 0;
    的for(int i = 0,CI = II; I<高度; ++我,CI + =二){
        对于(INT J = 0,CJ = IJ; J<宽度; ++Ĵ,CJ + = DJ){
            INT Y =(0xFF的及((int)的YUV [CI *宽+ CJ]));
            INT V =(0xFF的及((int)的YUV [框架尺寸+(CI>> 1)*宽+(CJ&安培;〜1)+ 0]));
            INT U =(0xFF的及((int)的YUV [框架尺寸+(CI>> 1)*宽+(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:克);
            B = b将0? 0:(B个255 255:二);

            ARGB [A +] = 0xff000000 | (为r&所述; 16)| (G<< 8)| B:
        }
    }
}
 
RGB,YUV的来历

解决方案

首先,我不是超级经验与图像编码(有一些有限的接触到这个大约一年前)。所以,把我的回答与盐粮。

不过,我相信你是对的。我想,在他们的code这两种 A)V和U翻转 二)R和B翻转

我有一种感觉,当这两个东西翻转,它会产生相同的结果,如果他们不是'翻转。这就是为什么你可以找到错误的code在很多地方的原因(最初,有人听错了,它被复制遍布的地方,因为得到的code ++工程(但是,变量命名错误)之后)。

下面是code另一个例子(它的工作原理和你的一样): http://www.41post.com/3470/programming/android-retrieving-the-camera-$p$pview-as-a-pixel-array

According to http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21, NV21 is the default used format.

There are quite a number of code on web regarding YUV NV21 to RGB conversion. 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

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://pastebin.com/T0my7zSc - It assumes U comes first http://stackoverflow.com/a/8394202/72437 - It assumes U comes first too http://stackoverflow.com/a/10125048/72437 - It assmes U comes first too

R should be the most significant position According implementation of int argb in Color.java, R suppose to be at the most significant position. However, I went through the following code implementation

http://pastebin.com/T0my7zSc - It assumes R is in least significant position http://stackoverflow.com/a/8394202/72437 - It assumes R is in least significant position

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

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

阅读全文

相关推荐

最新文章