observer
observer

Reputation: 3

Simple Emgucv webcam feed appears to be memory leaking

Following code is the method with which I retrieve frames from a webcam in a bigger project of mine:

Imports Emgu.CV
Imports Emgu.CV.CvEnum
Imports Emgu.CV.Structure
Imports Emgu.CV.UI
Imports Emgu.CV.Util

Public Class Form1

    Dim img As Mat
    Dim cam As VideoCapture

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Try
            cam = New VideoCapture(0)
        Catch ex As Exception
            'show error via message box
            MessageBox.Show("unable To read from webcam, error: " + Environment.NewLine + Environment.NewLine +
                                ex.Message + Environment.NewLine + Environment.NewLine +
                                "Try another")
            Return
        End Try

        AddHandler Application.Idle, New EventHandler(AddressOf Me.ProcessFrame)

    End Sub

    Sub ProcessFrame(sender As Object, arg As EventArgs)

        img = cam.QueryFrame()
        ImageBox1.Image = img

    End Sub

End Class

Basically it grabs a frame from the webcam and inserts it into an imagebox on the form. When running the code my memory consumption looks like this:

https://i.sstatic.net/RCbU6.png

What I gather from this is that something is not being properly disposed, but I can't figure out what it is. The more MP the webcam has the higher the memory spike. Same thing when loading local video files.

Upvotes: 0

Views: 1366

Answers (3)

Visual Vincent
Visual Vincent

Reputation: 18310

The Mat class implements IDisposable. Calling Dispose() on the old image before showing the new one might help minimize the spikes, but as Lucas K mentioned not everything is guaranteed to be fully released until the GC runs.

img = cam.QueryFrame()

'Dispose of the old image (if one exists).
If ImageBox1.Image IsNot Nothing Then ImageBox1.Image.Dispose()

ImageBox1.Image = img

In general you should call Dispose() on all classes that implement IDisposable when you're done using them (or wrap them in Using blocks, where applicable).

Upvotes: 2

Lucas K
Lucas K

Reputation: 36

As you can see in the linked image the memory consumption is only reduced by the garbage collector (GC), which is executed based on fixed time cycles (therefore the oscillation). Your code enters ProcessFrame() without releasing the capture device. I suggest the usage of [VideoCapture].release() as detailed here to solve the problem. If you need a consistent framerate there is no way to avoid these memory spikes.

Upvotes: 0

ias
ias

Reputation: 324

Reading frames is one of the slowest parts of video processing. Your minimum example isn't sufficient to help with the memory leak (if one really exists). Make sure you aren't creating the videocapture object repeatedly in a loop.

Upvotes: 0

Related Questions