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

Unity中Barracuda推理ONNX模型时色彩空间不匹配导致与Python推理结果差异过大的问题求助

Unity中Barracuda推理ONNX模型时色彩空间不匹配导致与Python推理结果差异过大的问题求助

嘿,我一眼就看出你踩了Unity和Python跨平台推理时最常见的色彩空间gamma校正不匹配的坑!我之前做语义分割模型移植的时候也卡过一模一样的问题,给你把根因和解决方法讲得明明白白:

问题本质:你喂给模型的颜色空间错了!

你看Unity打印的0.196和Python输出的0.533,这俩数值正好对应线性空间转sRGB空间的关系:pow(0.196, 1/2.2) ≈ 0.533。具体为啥会这样:

  1. 你的RenderTexture用的是R8G8B8A8_SRGB格式,相机渲染后会把线性空间的画面做gamma校正,转成sRGB格式存储
  2. 但Unity里你用TextureFormat.RGBA32(线性格式)读取像素时,会自动把sRGB格式的存储值转成线性空间的数值,所以GetPixels()拿到的Color.r/g/b是线性空间的0-1值
  3. 而Python里PIL打开JPG(天生sRGB格式)后,ToTensor()只是把0-255的像素值缩放到0-1的sRGB数值,完全没做gamma转换——你的模型是用sRGB空间的图片训练的,喂线性空间的值进去,结果能对才怪!

两种解决方法,选哪个都行

方法一:直接用sRGB格式的Texture2D读像素(最简单!)

让Unity读取像素时不做gamma转换,直接拿到和Python一致的sRGB空间数值:
修改你Start()里创建inputTexture的代码:

// 把原来的RGBA32改成RGBA32_SRGB(sRGB专用格式的Texture2D)
inputTexture = new Texture2D(modelInputWidth, modelInputHeight, TextureFormat.RGBA32_SRGB, false);

还有重新加载JPG的Texture2D也要改成sRGB格式:

// 把TextureFormat.RGBA32换成RGBA32_SRGB
Texture2D jpgTex = new Texture2D(2, 2, TextureFormat.RGBA32_SRGB, false, false);
jpgTex.LoadImage(jpgBytes);

这样GetPixels()拿到的r/g/b就是和Python完全对齐的sRGB空间0-1值,直接喂给模型就行,不需要额外转换。

方法二:手动把线性空间值转成sRGB空间

如果不想改Texture2D的格式,就在生成Tensor的时候做gamma逆转换:
先写个转换函数:

float LinearToSRGB(float linearValue)
{
    if (linearValue <= 0.0031308f)
    {
        return linearValue * 12.92f;
    }
    else
    {
        return 1.055f * Mathf.Pow(linearValue, 1f / 2.4f) - 0.055f;
    }
}

然后修改Tensor转换的循环代码:

Color[] pixels = jpgTex.GetPixels();
float[] floatValues = new float[pixels.Length * 3];
for (int i = 0; i < pixels.Length; i++)
{
    Color c = pixels[i];
    // 把线性空间颜色转成sRGB空间,再赋值给Tensor
    floatValues[i * 3 + 0] = LinearToSRGB(c.r);
    floatValues[i * 3 + 1] = LinearToSRGB(c.g);
    floatValues[i * 3 + 2] = LinearToSRGB(c.b);
}

嫌写函数麻烦?直接用Unity自带的API偷懒:

Color sRGBColor = Color.LinearToGammaSpace(c);
floatValues[i * 3 + 0] = sRGBColor.r;
floatValues[i * 3 + 1] = sRGBColor.g;
floatValues[i * 3 + 2] = sRGBColor.b;

验证方式

改完之后再打印Tensor前12个值,应该会和Python的0.533左右的数值完全一致,这时候再跑推理,结果就会和Python里的正确输出对齐了!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.09 03:05:30