【问题标题】:YUV to RGB Conversion ErrorYUV 到 RGB 转换错误
【发布时间】:2014-01-25 00:36:54
【问题描述】:

我目前正在开发一个应用程序,它将 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 进行转换。我认为颜色值的索引是正确的,但我不知道颜色转换出了什么问题。任何帮助或其他转换公式,我可以尝试,将不胜感激。

问候

【问题讨论】:

    标签: cuda rgb decoding yuv color-codes


    【解决方案1】:

    您有浮点乘法,但结果声明为整数。你在那里失去了所有的精确度。例如

    int r = y + 1.13983 * v;

    替换为

    float r = y + 1.13983 * v;

    可能还有其他问题,但这很突出。

    【讨论】:

    • 太棒了,你明白了!非常感谢。
    猜你喜欢
    • 2017-04-21
    • 2021-05-28
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多