gpt4 book ai didi

java - Android Camera Preview YUV格式在GPU上转成RGB

转载 作者:太空宇宙 更新时间:2023-11-03 10:24:46 24 4
gpt4 key购买 nike

我已经复制粘贴了一些我在stackoverflow上找到的代码,将默认的相机预览YUV转换成RGB格式,然后上传到OpenGL进行处理。这工作正常,问题是大部分 CPU 忙于将 YUV 图像转换为 RGB 格式,这变成了瓶颈。

我想将 YUV 图像上传到 GPU,然后在 fragment 着色器中将其转换为 RGB。我采用了相同的 Java YUV 到 RGB 函数,我发现它在 CPU 上工作,并试图让它在 GPU 上工作。

这变成了一场噩梦,因为在 Java 和 GPU 上进行计算存在一些差异。首先,预览图像在 Java 中来自 byte[],但字节是有符号的,因此可能存在负值。

此外, fragment 着色器通常处理 [0..1] 浮点值而不是字节。

我确信这是可以解决的,而且我几乎解决了它。但我花了几个小时试图找出我做错了什么,但无法让它发挥作用。

最重要的是,我要求有人只编写此着色器函数并最好对其进行测试。对我来说,这将是一项乏味的猴子工作,因为我真的不明白为什么这种转换会这样工作,我只是尝试在 GPU 上模仿相同的功能。

这与我在 Java 中使用的函数非常相似: Displaying YUV Image in Android

我在CPU上做了一些工作,比如把1.5*wh字节的YUV格式转成wh*YUV,如下:

static public void decodeYUV420SP(int[] rgba, byte[] yuv420sp, int width,
int height) {
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 = (int) yuv420sp[yp]+127;
if ((i & 1) == 0) {
v = (int)yuv420sp[uvp++]+127;
u = (int)yuv420sp[uvp++]+127;
}
rgba[yp] = 0xFF000000+(y<<16) | (u<<8) | v;
}
}
}

我添加了 127,因为字节是有符号的。然后,我将 rgba 加载到 OpenGL 纹理中,并尝试在 GPU 上完成剩余的计算。

任何帮助将不胜感激...

最佳答案

我使用维基百科中的这段代码来计算 GPU 上从 YUV 到 RGB 的转换:

private static int convertYUVtoRGB(int y, int u, int v) {
int r,g,b;

r = y + (int)1.402f*v;
g = y - (int)(0.344f*u +0.714f*v);
b = y + (int)1.772f*u;
r = r>255? 255 : r<0 ? 0 : r;
g = g>255? 255 : g<0 ? 0 : g;
b = b>255? 255 : b<0 ? 0 : b;
return 0xff000000 | (b<<16) | (g<<8) | r;
}

我将 float 转换为 0.0..255.0,然后使用上面的代码。CPU 上的部分是将原始 YUV 像素重新排列为 YUV 矩阵(也显示在维基百科中)。基本上我使用维基百科代码并做了最简单的 float<->byte conersions 来解决它。将 16 添加到 Y 或不将 128 添加到 U 和 V 等小错误会产生不良结果。所以你需要照顾它。但是一旦我使用维基百科代码作为基础,就没有太多工作了。

关于java - Android Camera Preview YUV格式在GPU上转成RGB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14024713/

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