简单的Emgucv网络摄像头提要似乎内存泄漏

时间:2018-11-03 15:33:44

标签: vb.net opencv memory-leaks emgucv

以下代码是我从一个较大的项目中从网络摄像头检索帧的方法:

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

基本上,它从网络摄像头抓取一个框架并将其插入表单上的图像框。运行代码时,我的内存消耗如下所示:

https://i.imgur.com/PRGULG9.png

我从中得出的结论是某些东西没有得到适当处置,但我不知道是什么。网络摄像头的MP越多,内存峰值越大。加载本地视频文件时也是一样。

3 个答案:

答案 0 :(得分:1)

Mat class实现IDisposable。在显示新图像之前在旧图像上调用Dispose()可能有助于最大程度地减少尖峰,但是正如Lucas K提到的那样,在GC运行之前,不能保证所有内容都会完全释放。

img = cam.QueryFrame()

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

ImageBox1.Image = img

通常,在使用完Dispose()的所有类之后,应该调用IDisposable(或将它们包装在Using blocks中,如果适用)。

答案 1 :(得分:0)

正如您在链接的图像中看到的那样,仅通过垃圾回收器(GC)减少了内存消耗,垃圾回收器(GC)基于固定的时间周期(因此发生振荡)执行。 您的代码无需释放捕获设备即可进入ProcessFrame()。我建议使用here来详细说明[VideoCapture] .release()来解决此问题。如果需要一致的帧速率,则无法避免这些内存峰值。

答案 2 :(得分:0)

阅读帧是视频处理最慢的部分之一。您的最小示例不足以帮助解决内存泄漏(如果确实存在)。确保您没有循环重复创建videocapture对象。