gpt4 book ai didi

Android : Preview frame, 从 YCbCr_420_SP (NV21) 格式转换为 RGB 渲染正确图片但为绿色

转载 作者:行者123 更新时间:2023-11-29 00:13:08 26 4
gpt4 key购买 nike

我发布这个问题是因为我没有在以下帖子中找到解决我的问题的答案:

Converting preview frame to bitmap

Android decodeYUV420SP results in green images?

Displaying YUV Image in Android

我的数据和 cameraResolution(在选择 BestPreviewSize 之后)来自:

  public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
Handler thePreviewHandler = previewHandler;
if (cameraResolution != null && thePreviewHandler != null) {
Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
cameraResolution.y, data);
message.sendToTarget();
previewHandler = null;
} else {
Log.d(TAG, "Got preview callback, but no handler or resolution available");
}
}

稍后从转换为 RGB,我使用:

  int[] pixels=new int[yuvData.length];
// int size = dataWidth*dataHeight;
// int[] pixels=new int[size]; replacing yuvData.length by size is not working too
pixels=decodeYUV420SP(pixels,yuvData, dataWidth, dataHeight);
Bitmap bitmap = Bitmap.createBitmap(dataWidth, dataHeight, Bitmap.Config.RGB_565);
bitmap.setPixels(pixels, 0, dataWidth, 0, 0, dataWidth, dataHeight);

我尝试了两种方法,一种使用 RenderScript,一种使用 decodeYUV420SP:

public Bitmap convertYUV420_NV21toRGB8888_RenderScript(byte [] data,int W, int H, CaptureActivityOCR fragment) { 
// https://stackoverflow.com/questions/20358803/how-to-use-scriptintrinsicyuvtorgb-converting-byte-yuv-to-byte-rgba
RenderScript rs;
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
rs = RenderScript.create(fragment.getActivity());
yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); //Create an intrinsic for converting YUV to RGB.

Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); //an Allocation will be populated with empty data when it is first created

Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT); //an Allocation will be populated with empty data when it is first created

in.copyFrom(data);//Populate Allocations with data.

yuvToRgbIntrinsic.setInput(in); //Set the input yuv allocation, must be U8(RenderScript).
yuvToRgbIntrinsic.forEach(out); //Launch the appropriate kernels,Convert the image to RGB.


Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
out.copyTo(bmpout); //Copy data out of Allocation objects.
return bmpout;

}

int[] decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { 
Log.e("camera", " decodeYUV420SP ");

// TODO Auto-generated method stub
final int frameSize = width * height;

for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0) y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}

int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);

if (r < 0) r = 0; else if (r > 262143) r = 262143;
if (g < 0) g = 0; else if (g > 262143) g = 262143;
if (b < 0) b = 0; else if (b > 262143) b = 262143;

rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);

}
}
return rgb;
}

但是我仍然不知道为什么我得到了一些好的图像但是是绿色的。 (我有另一种类似的黑白方法有效)除了上面的链接之外,我还在 SO 上尝试了所有链接到这个主题的帖子,所以如果有人可以帮忙提供另一个提示吗?我可能对申请的尺寸感到困惑?

在 OnPreviewFrame 方法之后和转换为 RGB 方法之前的某处,我使用另一种方法和下面的说明,因为我需要旋转接收到的数据。我想知道这是否不是问题的根源:

  byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
int tmp = width;
width = height;
height = tmp;

请帮帮我好吗?

最佳答案

我认为你的轮换程序是错误的。它适用于 Luma (Y),因此您可以在黑白图片上获得不错的效果,但在色度上却不行。如果宽度和高度是图片的尺寸,则根本不会旋转色度值。因此,您需要为色度添加第二个循环并移动字节对(V 和 U)。

如果您在没有这种旋转的情况下尝试过它并且您的图片仍然偏绿,则问题也可能出在您的 decodeYUV420SP 函数中。

yuv 到 rgba 的转换没有一个通用的公式。它必须匹配相反的。
看这里http://www.codeproject.com/Articles/402391/RGB-to-YUV-conversion-with-different-chroma-sampli在这里 http://www.fourcc.org/fccyvrgb.php

这个对我有用

B = 1.164(Y - 16)                   + 2.018(U - 128)
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
R = 1.164(Y - 16) + 1.596(V - 128)

这似乎与您只使用 float 版本相同,因此您可以尝试其他版本。

关于Android : Preview frame, 从 YCbCr_420_SP (NV21) 格式转换为 RGB 渲染正确图片但为绿色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28798728/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com