34

http://developer.android.com/reference/android/graphics/ImageFormat.html#NV21によると、NV21がデフォルトで使用される形式です。

YUV NV21からRGBへの変換に関しては、Web上にかなりの数のコードがあります。しかし、私がコードを調べているとき、私はコードの正確さに疑問を持っています。

最初のコンポーネントVが最初に来て、次に最初のコンポーネントUが来るはずです

http://wiki.videolan.org/YUV#NV21によると、NV21 is like NV12, but with U and V order reversed: it starts with V.しかし、私がコードの実装を行ったとき

Rは最も重要な位置である必要がありますColor.java の実装によるint argbと、Rは最も重要な位置にあると想定されます。ただし、次のコード実装を実行しました

私は疑問に思っていました、彼らはよくある間違いを犯していますか、それとも私は何かを見落としていますか?

現在、私の実装は次のとおりです。

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;
        }
    }
}
4

2 に答える 2

12

まず第一に、私は画像エンコーディングの経験があまりありません(約1年前にこれにある程度の露出があります)。だから、私の答えを塩の粒で取ってください。

しかし、私はあなたが正しいと信じています。彼らのコードでは、a)VとUの両方が反転しているb)RとBが反転していると思います

両方をひっくり返すと、ひっくり返ったのと同じ結果になると思います。これが、多くの場所で間違ったコードを見つけることができる理由です(元々、誰かが間違って、コピーした後、結果のコードが機能するため(ただし、変数の名前が間違っている))。

コードの別の例を次に示します(これはあなたのコードと同じように機能します): http ://www.41post.com/3470/programming/android-retrieveing-the-camera-preview-as-a-pixel-array

于 2012-09-26T21:06:07.567 に答える
0

「最も重要な位置」などの用語は、マシンのエンディアンに依存するため、あいまいです。

すべてのデータ型が8ビットの場合、バイトオーダーという簡単で明確な指定があります。たとえば、unsigned char rgba [4]; データはrgba[0]=rとして保存されます。rgba [1] = g; rgba [2] = b; rgba [3] = a;

または、プロセッサのエンディアンに関係なく、{r、g、b、a}。

代わりにあなたがした場合

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

ビッグエンディアンシステムでは{r、g、b、a}を取得し、リトルエンディアンシステムでは{a、r、g、b}を取得します。異種プロセッサを搭載したシステムで作業していますか?多分あなたはCPUとGPUを持っていますか?他のエンディアンが使用しているエンディアンをどのようにして知ることができますか?バイト順序を定義する方がはるかに優れています。

于 2013-05-13T22:38:12.573 に答える