我正在开发一款应用程序,它将RGB图像转换为YV12,将其转换为NV12,然后再转换为RGB。
我的转化时出现以下错误: http://www.pic-upload.de/view-21874004/ConversionError.jpg.html
所以左边是,我想要的。简单的蓝色。右侧显示我得到的东西。看起来,转换结果中有太多的绿色。
以下是将rgb转换为yv12的代码:
__global__ void RGBtoYV12(unsigned char* yuv, unsigned char* pData)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int width = gridDim.x * blockDim.x * 1.5;
int iwidth = gridDim.x;
int rgbID = i * 4;
int upos = blockDim.x * gridDim.x;
int vpos = upos + upos / 4;
int col = i % iwidth;
int row = i / iwidth; //bzw. threadIdx.x;
int r = pData[rgbID], g = pData[rgbID+1], b = pData[rgbID+2];
//Y
unsigned char y = 0.299 * r + 0.587 * g + 0.114 * b;
yuv[upos - (row+1)*iwidth + col] = y;
if ( !((i/gridDim.x)%2) && !(i%2))
{
//YV12
// U
yuv[width - ( (iwidth/2) * ((row/2)+1) - ((col/2)+1) )] = 0.493 * (b - y);//((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
// V
yuv[vpos - ( (iwidth/2) * ((row/2)+1) - ((col/2)+1) )] = 0.887 * (r - y); //((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
}
}
NV12的转换处理如下:
__global__ void NV12toRGB(unsigned char* nv12, unsigned char* rgba, int decodedPitch)
{
int ix = blockIdx.x * blockDim.x + threadIdx.x;
int iy = blockIdx.y * blockDim.y + threadIdx.y;
int i = iy * decodedPitch + ix;
int rgbStart = (iy * gridDim.x * blockDim.x + ix) * 4;
int quadX = (ix / 2);
int quadY = (iy / 2);
int uvAdr = decodedPitch / 2 * quadY + quadX;
int uvStart = decodedPitch * gridDim.y * blockDim.y;
int y = nv12[i];
int u = nv12[uvStart + 2 * uvAdr];
int v = nv12[uvStart + 2 * uvAdr + 1];
// R
int r = y + 1.13983 * v;
// G
int g = y - 0.39393 * u - 0.58081 * v;
// B
int b = y + 2.028 * u;
rgba[rgbStart] = r;
rgba[rgbStart+1] = g;
rgba[rgbStart+2] = b;
rgba[rgbStart+3] = 255;
}
正如您所看到的,我在GPU上使用cuda进行转换。我认为颜色值的索引是正确的,但我不知道,颜色转换出了什么问题。任何帮助或其他转换公式,我可以尝试,将不胜感激。
问候
答案 0 :(得分:1)
您有浮点乘法,但结果声明为整数。你失去了那里的所有精确度。例如
int r = y + 1.13983 * v;
将其替换为
float r = y + 1.13983 * v;
也可能存在其他问题,但这很突出。