RGB LUT转YUV后用于UYVY帧色彩校正出现异色问题求助
色彩校正LUT应用异常问题排查
我有一个33×33×33×3的RGB色彩空间LUT,经三线性插值得到256×256×256×3的LUT后,将其转换为UYV格式以方便使用。随后用该LUT对UYVY格式的视频帧逐一做色彩校正,但出现了异常色彩问题。LUT文件的值为float类型。
RGB转UYV LUT的CUDA核函数
// input is a 256x256x256x3 RGB interpolated LUT containing values from 0-255 __global__ void cudargblut2yuv(uint8_t *input, uint8_t *output) { int idx = blockIdx.x * blockDim.x + threadIdx.x; int idy = blockIdx.y * blockDim.y + threadIdx.y; int idz = blockIdx.z * blockDim.z + threadIdx.z; if (idx < 256 && idy < 256 && idz < 256) { int index = idx * 256 * 256 * 3 + idy * 256 * 3 + idz * 3; float red = input[index]; float green = input[index + 1]; float blue = input[index + 2]; float y = 16 + 0.256 * red + 0.504 * green + 0.0979 * blue; float u = 128 + 0.439 * red - 0.368 * green - 0.0714 * blue; float v = 128 - 0.148 * red - 0.291 * green + 0.439 * blue; // clamping 0-255 if(y > 255) y = 255; else if(y < 0) y = 0; if(u < 0) u = 0; else if(u > 255) u = 255; if(v < 0) v = 0; else if(v > 255) v = 255; output[index] = u; output[index + 1] = y; output[index + 2] = v; } }
应用LUT到像素的CUDA核函数
__global__ void applyLUTKernel(const uint8_t* input, uint8_t* output, int frameSize, const uint8_t* lut) { int index = blockIdx.x * blockDim.x + threadIdx.x; int stride = blockDim.x * gridDim.x; frameSize >>= 1; for(int i = index; i < frameSize; i += stride) { // UYV values from UYVY frame uint8_t U = input[(i << 2)]; uint8_t Y1 = input[(i << 2) + 1]; uint8_t V = input[(i << 2) + 2]; uint8_t Y2 = input[(i << 2) + 3]; uint8_t pixel1U = lut[256 * 256 * 3 * U + 256 * 3 * Y1 + 3 * V]; uint8_t pixel1Y = lut[256 * 256 * 3 * U + 256 * 3 * Y1 + 3 * V + 1]; uint8_t pixel1V = lut[256 * 256 * 3 * U + 256 * 3 * Y1 + 3 * V + 2]; uint8_t pixel2U = lut[256 * 256 * 3 * U + 256 * 3 * Y2 + 3 * V]; uint8_t pixel2Y = lut[256 * 256 * 3 * U + 256 * 3 * Y2 + 3 * V + 1]; uint8_t pixel2V = lut[256 * 256 * 3 * U + 256 * 3 * Y2 + 3 * V + 2]; // getting corresponding LUT[U1][Y1][V1] values to put back into the frame output[(i << 2)] = (pixel1U + pixel2U) >> 1; output[(i << 2) + 1] = pixel1Y; output[(i << 2) + 2] = (pixel1V + pixel2V) >> 1; output[(i << 2) + 3] = pixel2Y; // normal frame // output[(i << 2)] = U; // output[(i << 2) + 1] = Y1; // output[(i << 2) + 2] = V; // output[(i << 2) + 3] = Y2; } }
恳请帮忙排查问题所在?
我怀疑问题出在LUT转UYV的过程,或是将LUT结果替换回帧的操作上。插值应该是准确的,因为之前把UYVY帧转成RGB后应用LUT,结果完全符合预期。
对U1/U2、V1/V2取平均值是因为逻辑上相邻像素值不该有巨大差异,取平均能让过渡更自然。
相关帧效果:
- 原始帧:色彩表现正常的视频帧
- LUT校正后的异常帧:色彩出现错误偏差的校正后帧
- 预期的LUT校正帧:色彩校正后符合预期效果的目标帧
内容的提问来源于stack exchange,提问作者Shikhin Dahikar
相关产品推荐
相关产品推荐

