1

I try to render image from the Emgu's camera capture on new Unity3D UI system. Till now, I used ImageToTexture2d from this repository: https://github.com/neutmute/emgucv/blob/3ceb85cba71cf957d5e31ae0a70da4bbf746d0e8/Emgu.CV/PInvoke/Unity/TextureConvert.cs and then used Sprite.Create() to finally achieve the wanted result.

BUT! It appears there is some massive memory leak as after 2-3 minutes of my game running Unity editor suddenly takes about 3GB of RAM where it started with about 200MB.

I have two susspects:

  1. (More Probabble) The method I'm using does not clean the memory. It uses InterOp and creates some unsafe pointers - it smells leakage.
  2. The Sprite.Create runned every frame holds old sprites in memory and does not remove them.

Does any of You knows any other way to convert Emgu's Image to Sprite/Texture(without using an InterOp) or any other way I could show it on New Unity's UI. It has to be the Emgu's Image as I also do some operations on the images I recieve from camera.

Thanks in advance for responses and help. :D

Janusz-kun
  • 89
  • 2
  • 11

4 Answers4

0

Without knowing about the bulk of the game, are you destroying possible replicates of the objects created in memory?

Is the sudden 3GB increase related to any behaviour in the game? Does it increase, even without activity?

CyberFox
  • 780
  • 6
  • 24
0

After some research I've found what was the problem, but didn't have time to describe it. I didn't knew that Textures created each frame are held somewhere in engine. They must be destroyed before generating a new one from Emgu Image.

Here's a part of my code used in my project:

//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));
}
Janusz-kun
  • 89
  • 2
  • 11
0
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;
}
0
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;
  • 5
    Please consider to edit and explain your answer with a little text. Help other readers to understand the essence of the issue. – Asger Apr 13 '19 at 14:34