【问题标题】:Simple Emgucv webcam feed appears to be memory leaking简单的 Emgucv 网络摄像头提要似乎存在内存泄漏
【发布时间】:2019-04-07 12:54:27
【问题描述】:

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

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 越多,内存峰值就越高。加载本地视频文件时也是如此。

【问题讨论】:

    标签: vb.net opencv memory-leaks emgucv


    【解决方案1】:

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

    【讨论】:

    • 释放视频捕捉将关闭它(相机流)。你不想那样做。 videocapture 被初始化一次并反复查询以获取帧,直到您完成。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      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
      

      一般来说,您应该在使用完所有实现IDisposable 的类上调用Dispose()(或将它们包装在Using blocks 中,如果适用)。

      【讨论】:

      • 谢谢!内存使用线现在非常平坦。
      • @observer :很高兴我能帮上忙!祝你的项目好运!
      • @VisualVincent,您好,我尝试了您的解决方案,但抛出了以下异常:“System.AccessViolationException: '尝试读取或写入受保护的内存。这通常表明其他内存已损坏。 ' "
      • @AchuthaperumalRK:你好!很抱歉没有看到您的评论,我已经有一段时间没有上 Stack Overflow 了。不幸的是,这种错误非常难以诊断,并且主要在使用非托管代码时抛出(EmguCV 就是这样做的)。您可能做错了事或有问题,但也可能是库本身没有正确编码并在某些情况下中断。
      • @AchuthaperumalRK :恐怕我能给你的唯一故障排除技巧就是用最基本的代码设置一个新项目,看看错误是否仍然存在。如果没有,请添加越来越多的代码,并尝试找出导致其中断的具体差异。如果您找不到解决方案,请在此处发布问题并描述您采取的步骤。
      猜你喜欢
      • 1970-01-01
      • 2015-05-11
      • 2021-09-14
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多