0

画像内のいくつかのピクセルを移動する単射関数があります。

pixel (x, y) ===func===> pixel (X, Y)
X = funcX(x, y)
Y = funcY(y, x)

この関数を使用して、画像全体を RGB、I420、および NV12 モードで変換したいと考えています。

* RGB * : 画像が RGB モードの場合、それは明らかです。

strideR = strideG = strideB = width;

//Temporary table for the destination
for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        toR[i][j] = j * strideR + i;
        toG[i][j] = j * strideG + i;
        toB[i][j] = j * strideB + i;
    }

//Temporary table for the source
for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        fromR[i][j] = funcY(i, j) * strideR + funcX(i, j);
        fromG[i][j] = funcY(i, j) * strideG + funcX(i, j);
        fromB[i][j] = funcY(i, j) * strideB + funcX(i, j);
    }

for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        destR[ toR[i][j] ] = srcR[ fromR[i][j] ];
        destG[ toG[i][j] ] = srcG[ fromG[i][j] ];
        destb[ toB[i][j] ] = srcB[ fromB[i][j] ];
    }

* I420 * : 画像が I420 モード (YYYYYYYY UU VV) の場合、次のように動作します:

strideY = width;
strideU = strideV = width / 2;

//Temporary table for the destination
for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        toY[i][j] = j * strideY + i;
        toU[i][j] = j / 2 * strideU + i / 2;
        toV[i][j] = j / 2 * strideV + i / 2;
    }

//Temporary table for the source
for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        fromY[i][j] = funcY(i, j) * strideY + funcX(i, j);
        fromU[i][j] = funcY(i, j) / 2 * strideU + funcX(i, j) / 2;
        fromV[i][j] = funcY(i, j) / 2 * strideV + funcX(i, j) / 2;
    }

    for (j = 0; j < height; j++)
        for (i = 0; i < width; i++) {
            destY[ toY[i][j] ] = srcY[ fromY[i][j] ];
            if ((i % 2 == 0) && (j % 2 == 0)) {
                destU[ toU[i][j] ] = srcU[ fromU[i][j] ];
                destV[ toV[i][j] ] = srcV[ fromV[i][j] ];
            }
        }

* NV12 * : 画像が NV12 モード (YYYYYYYY UVUV) の場合、以下は機能しません:

strideY = strideUV = width;

//Temporary table for the destination
for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        toY[i][j] = j * strideY + i;
        toUV[i][j] = j / 2 * strideUV + i;
    }

//Temporary table for the source
for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        fromY[i][j] = funcY(i, j) * strideY + funcX(i, j);
        fromUV[i][j] = funcY(i, j) / 2 * strideUV + funcX(i, j);
    }

for (j = 0; j < height; j++)
    for (i = 0; i < width; i++) {
        destY[ toY[i][j] ] = srcY[ fromY[i][j] ];
        if ((i % 2 == 0) && (j % 2 == 0)) {
            destUV[ toUV[i][j] ] = srcUV[ fromUV[i][j] ];
            destUV[ toUV[i][j] + 1 ] = srcUV[ fromUV[i][j] + 1 ];
        }
    }

画像を取得しましたが、色が間違っています。白黒部分 (別名 Y 部分) は正しいですが、色部分 (別名 UV 部分) は変更されています。私は何を間違っていますか?

4

1 に答える 1

1

問題を発見!解決策は次のとおりです。

fromUV[i][j] = funcY(i, j) / 2 * strideUV + ((int)(funcX(i, j) / 2)) * 2;

UV バイトの開始を取得するには、X/2 をフロアにする必要がありました。

于 2013-10-15T20:00:35.857 に答える