You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:37:03