【问题标题】:Load single channel 16-bit image to a texture in Unity3D将单通道 16 位图像加载到 Unity3D 中的纹理
【发布时间】:2021-11-08 20:21:13
【问题描述】:

我正在使用深度传感器 (Orbbec Astra Pro),并希望在 Unity 中显示红外图像。我收到的数据是ushort[](或任何其他类型,大于8bit)。
所以我可以创建一个单通道16位纹理infraredTexture = new Texture2D(infraredFrame.Width, infraredFrame.Height, TextureFormat.R16, false);,但我不知道如何用红外数据填充纹理,因为LoadRawTextureData只需要byte[]IntPtr

所以最后我希望在 Unity 中看到 16 位灰度纹理。这甚至可能吗?提前谢谢!

【问题讨论】:

    标签: unity3d textures orbbec


    【解决方案1】:

    来自TextureFormat.R16的一般说明

    目前,这种纹理格式仅对运行时或本机代码插件有用,因为不支持这种格式的纹理导入。

    注意不是所有显卡都支持所有纹理格式,请使用SystemInfo.SupportsTextureFormat查看。

    如果您真的想使用R16 格式纹理,我没有直接的解决方案,除非以某种方式将数据序列化为byte[],例如使用Buffer.BlockCopy - 注意:根本不知道这会起作用!

    ushort[] yourData = // wherever you get this from;
    byte[] byteData = new byte[sizeof(ushort) * yourData.Length];
    
    // On memory level copy the bytes from yourData into byteData
    Buffer.BlockCopy(yourData, 0, byteData, 0, byteData.Length);
    
    infraredTexture = new Texture2D(infraredFrame.Width, infraredFrame.Height, TextureFormat.R16, false);
    infraredTexture.LoadRawTextureData(byteData);
    infraredTexture.Apply();
    

    再一次不知道它是否可以这样工作。


    但是,我认为您可以在 Unity 中简单地“伪造”它。如果它仅用于显示纹理,您可以使用“普通”RGB24 纹理,只需将 16 位单通道数据映射为灰度 24 位 RGB 颜色,然后使用 Texture2D.SetPixels 应用它,例如

    ushort[] yourData = // wherever you get this from;
    var pixels = new Color[yourData.Length];
    
    for(var i = 0; i < pixels.Length; i++)
    {
        // Map the 16-bit ushort value (0 to 65535) into a normal 8-bit float value (0 to 1)
        var scale = (float)yourData[i] / ushort.MaxValue;
        // Then simply use that scale value for all three channels R,G and B
        // => grey scaled pixel colors
        var pixel = new Color(scale, scale, scale);
        pixels[i] = pixel;
    }
    
    infraredTexture = new Texture2D(infraredFrame.Width, infraredFrame.Height, TextureFormat.RGB24, false);
    
    // Then rather use SetPixels to apply all these pixel colors to your texture
    infraredTexture.SetPixels(pixels);
    infraredTexture.Apply();
    

    【讨论】:

    • 感谢您的建议 :) 我稍后会测试它们。
    • 我用带符号的 16 位短数据尝试了上面的 Buffer.BlockCopy 示例,但返回了错误的红色纹理 - GetPixels() 显示红色填充了 bga 为 1。@derHugo 在第二个示例中,是 ushort。 MaxValue 是 ushort 的最大范围(即 65535)还是为数据找到的最大 ushort 值?
    • @SergioSolorzano 我写这篇文章已经有一段时间了,但我认为这将是您数据中的值意味着全白
    猜你喜欢
    • 2018-07-30
    • 2013-03-27
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多