【问题标题】:How to convert EmguCV Image to Unity3D Sprite?如何将 EmguCV 图像转换为 Unity3D Sprite?
【发布时间】:2015-03-10 22:20:22
【问题描述】:

我尝试在新的 Unity3D UI 系统上渲染来自 Emgu 相机捕获的图像。 到目前为止,我使用了这个存储库中的 ImageToTexture2d: https://github.com/neutmute/emgucv/blob/3ceb85cba71cf957d5e31ae0a70da4bbf746d0e8/Emgu.CV/PInvoke/Unity/TextureConvert.cs 然后使用 Sprite.Create() 最终达到想要的结果。

但是!似乎存在大量内存泄漏,因为在我的游戏运行 Unity 编辑器 2-3 分钟后突然占用了大约 3GB 的 RAM,而它开始时大约为 200MB。

我有两个嫌疑人:

  1. (更可能)我使用的方法不会清理内存。它使用 InterOp 并创建了一些不安全的指针 - 它闻到了泄漏的味道。
  2. 每帧运行的 Sprite.Create 将旧的 sprite 保存在内存中,并且不会删除它们。

你们是否知道任何其他方式将 Emgu 的图像转换为 Sprite/Texture(不使用 InterOp)或我可以在 New Unity 的 UI 上显示它的任何其他方式。它必须是 Emgu 的图像,因为我还对从相机收到的图像进行了一些操作。

提前感谢您的回复和帮助。 :D

【问题讨论】:

    标签: c# unity3d emgucv unity3d-gui


    【解决方案1】:
    RawImage targetRawImage;
    Image<Rgb, byte> scanned = new Image<Rgb, byte>("Assets/Textures/scanned.png");
    Texture2D loaded = new Texture2D(scanned.Width, scanned.Height);
    loaded.LoadImage(scanned.ToJpegData());
    targetRawImage.texture = loaded;
    

    【讨论】:

    • 请考虑用一点文字来编辑和解释您的答案。帮助其他读者理解问题的本质。
    【解决方案2】:
    public static Texture2D ArrayToTexture2d(Image<Rgb, byte> picture) {
        Array bytes = picture.ManagedArray;
        int h = bytes.GetLength(0);
        int w = bytes.GetLength(1);
        Texture2D t2d = new Texture2D(w, h);
        double r, b, g;
    
        for (int heigth = 0; heigth < bytes.GetLength(0); heigth++)
        {
            for (int width = 0; width < bytes.GetLength(1); width++)
            {
                r = Convert.ToDouble(bytes.GetValue(heigth, width, 0));
                g = Convert.ToDouble(bytes.GetValue(heigth, width, 1));
                b = Convert.ToDouble(bytes.GetValue(heigth, width, 2));
    
                t2d.SetPixel(width, h - heigth - 1, new Color((float)r / 256, (float)g / 256, (float)b / 256, 1f));                
            }
        }
    
        t2d.Apply();
        return t2d;
    }
    

    【讨论】:

    • 但是您是如何从 EmguCV 图像中实现阵列的?另外,你拼错了高度这个词。
    【解决方案3】:

    在不了解游戏的大部分内容的情况下,您是否正在破坏内存中创建的对象的可能复制品?

    突然增加 3GB 是否与游戏中的任何行为有关?即使没有活动,它也会增加吗?

    【讨论】:

      【解决方案4】:

      经过一些研究,我发现了问题所在,但没有时间描述它。我不知道每帧创建的纹理都保存在引擎的某个地方。在从 Emgu Image 生成新的之前,必须将它们销毁。

      这是我的项目中使用的部分代码:

      //Capture used for taking frames from webcam
      private Capture capture;
      //Frame image which was obtained and analysed by EmguCV
      private Image<Bgr,byte> frame;
      //Unity's Texture object which can be shown on UI
      private Texture2D cameraTex;
      
      //...
      
      if(frame!=null)
          frame.Dispose();
      frame = capture.QueryFrame();
      if (frame != null)
      {
          GameObject.Destroy(cameraTex);
          cameraTex = TextureConvert.ImageToTexture2D<Bgr, byte>(frame, true);
          Sprite.DestroyImmediate(CameraImageUI.GetComponent<UnityEngine.UI.Image>().sprite);
          CameraImageUI.sprite = Sprite.Create(cameraTex, new Rect(0, 0, cameraTex.width, cameraTex.height), new Vector2(0.5f, 0.5f));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多