Open danijerez opened 4 years ago
please attach source code.
abjoint the test that I am doing in Unity, although it also happens to me with a similar code in windows forms
using DlibDotNet;
using System.IO;
using UnityEngine;
public class Camera : MonoBehaviour
{
public static WebCamTexture backCam;
public string filePath;
private ShapePredictor sp;
private Texture2D snap;
void Start()
{
if (backCam == null)
backCam = new WebCamTexture();
filePath = Path.GetTempFileName();
sp = ShapePredictor.Deserialize(Path.Combine(Application.dataPath, "Resources/shape_predictor_68_face_landmarks.dat"));
if (!backCam.isPlaying)
backCam.Play();
}
private void Update()
{
if (backCam != null && backCam.isPlaying)
{
snap = new Texture2D(backCam.width, backCam.height);
snap.SetPixels(backCam.GetPixels());
snap.Apply();
File.WriteAllBytes(filePath, snap.EncodeToPNG());
using (var fd = Dlib.GetFrontalFaceDetector())
{
var img = Dlib.LoadImage<RgbPixel>(filePath);
var faces = fd.Operator(img);
foreach (var face in faces)
{
// find the landmark points for this face
var shape = sp.Detect(img, face);
// draw the landmark points on the image
for (var i = 0; i < shape.Parts; i++)
{
var point = shape.GetPart((uint)i);
var rect = new Rectangle(point);
Dlib.DrawRectangle(img, rect, color: new RgbPixel(255, 255, 255), thickness: 2);
}
}
if (faces.Length > 0)
Dlib.SavePng(img, filePath);
var rawData = File.ReadAllBytes(filePath);
var texture = new Texture2D(backCam.width, backCam.height);
texture.LoadImage(rawData);
GetComponent<Renderer>().material.mainTexture = texture;
}
}
}
}
@danijerez
img
, faces
and shape
are disposable object. You must dispose them.
ok, i will try it, thanks!
How do you make a dispose of faces? (Rectagle [])
I have added all the possible disposes and the ram continues to act the same, the consumption is exponential.
using DlibDotNet;
using System;
using System.IO;
using UnityEngine;
public class Camera : MonoBehaviour
{
public static WebCamTexture backCam;
public string filePath;
private ShapePredictor sp;
private Texture2D snap;
void Start()
{
if (backCam == null)
backCam = new WebCamTexture();
filePath = Path.GetTempFileName();
sp = ShapePredictor.Deserialize(Path.Combine(Application.dataPath, "Resources/shape_predictor_68_face_landmarks.dat"));
if (!backCam.isPlaying)
backCam.Play();
}
private void Update()
{
if (backCam != null && backCam.isPlaying)
{
snap = new Texture2D(backCam.width, backCam.height);
snap.SetPixels(backCam.GetPixels());
snap.Apply();
File.WriteAllBytes(filePath, snap.EncodeToPNG());
using (var fd = Dlib.GetFrontalFaceDetector())
{
var img = Dlib.LoadImage<RgbPixel>(filePath);
var faces = fd.Operator(img);
foreach (var face in faces)
{
// find the landmark points for this face
var shape = sp.Detect(img, face);
// draw the landmark points on the image
for (var i = 0; i < shape.Parts; i++)
{
var point = shape.GetPart((uint)i);
var rect = new Rectangle(point);
Dlib.DrawRectangle(img, rect, color: new RgbPixel(255, 255, 255), thickness: 2);
}
shape.Dispose();
}
if (faces.Length > 0)
Dlib.SavePng(img, filePath);
faces = null;
img.Dispose();
var rawData = File.ReadAllBytes(filePath);
var texture = new Texture2D(backCam.width, backCam.height);
texture.LoadImage(rawData);
GetComponent<Renderer>().material.mainTexture = texture;
GC.Collect();
}
}
}
}
@danijerez you create two Texture2D objects on every web camera frame, but I don't see a code that release/destroy those textures and frees a memory they consumed. GC.Collect() is not enough to release Unity objects. You need to use Unity specific calls to release Texture2D.
You can do a simple test to understand if the issue in DLib or Unity - just don't create new Texture2D but use a static bitmap in your sample which doesn't change on every frame and then check if memory leak is still there. If not - then it's Unity, not DLib.
I have already discovered the problem, it is what you mentioned @Megadino had to use the Destroy of unity for the texture.
Thank you!
I've been doing some benchmarks capturing rectangles of faces in a continuous loop and the RAM consumption seems exponential, is it possible that there is some memory leak somewhere? In EMGU it doesn't happen when I apply a shape.