如何修复Emgu VideoCapture / ImageViewer内存泄漏?

时间:2019-01-16 19:03:01

标签: c# memory-leaks opencv3.0 emgucv motion-detection

我正在使用Emgu CV使用HAAR级联来检测对象,然后将HAAR级联的边界框发送给CSRT运动跟踪器。然后,我计算CSRT运动跟踪器的质心,并安装一个云台望远镜,该云台将移动相机,直到跟踪器的质心和图像相同。在下面的代码中,我正在使用.avi视频文件,但最终我将在实时摄像机中使用它。

我正在使用ImageViewer来同时显示HAAR级联和CSRT运动跟踪器。问题是CSRT运动跟踪器查看器正在使用我的所有RAM。如果我注释掉viewer.ShowDialog();行,则没有内存泄漏,但我也看不到跟踪器。

顺便说一下,这是在Windows 7上,运行Visual Studio 2017,.NET 4.7.3,Emgu 3.4.3.3016。

HAAR级联函数也导致内存泄漏,但是我可以通过在函数末尾的mat文件上使用.Dispose()来修复它。 CSRT运动跟踪器功能无济于事。

public void Tracker()
    {
        if (!this.detectedBBox.Width.Equals(0))
        {
            Emgu.CV.UI.ImageViewer viewer = new Emgu.CV.UI.ImageViewer();
            Emgu.CV.Tracking.TrackerCSRT myTracker = new Emgu.CV.Tracking.TrackerCSRT();

            using (Emgu.CV.VideoCapture capture1 = new Emgu.CV.VideoCapture("c:\\Users\\Windows7\\33a.avi"))
            using (Emgu.CV.VideoStab.CaptureFrameSource frameSource = new Emgu.CV.VideoStab.CaptureFrameSource(capture1))
            {
                Rectangle myRectangle = this.detectedBBox;
                Emgu.CV.Mat myFrame = frameSource.NextFrame().Clone();
                myTracker.Init(myFrame, myRectangle);
                Application.Idle += delegate (object c, EventArgs f)
                {
                    myFrame = frameSource.NextFrame().Clone();
                    myTracker.Update(myFrame, out myRectangle);
                    if (myFrame != null)
                    {

                        int fXcenter = myFrame.Width / 2;
                        int fYcenter = myFrame.Height / 2;
                        int dx;
                        int dy;
                        int swidth = myRectangle.Width;
                        int sheight = myRectangle.Height;
                        int shalfwidth = swidth / 2;
                        int shalfheight = sheight / 2;
                        int sXcentroid = myRectangle.X + shalfwidth;
                        int sYcentroid = myRectangle.Y + shalfheight;
                        if (sXcentroid >= fXcenter) { dx = sXcentroid - fXcenter; } else { dx = fXcenter - sXcentroid; }
                        if (sYcentroid >= fYcenter) { dy = sYcentroid - fYcenter; } else { dy = fXcenter - sYcentroid; }
                        string caption = "Center point: (" + sXcentroid + "," + sYcentroid + ")";
                        string caption2 = "Dist from center: (" + dx + "," + dy + ")";

                        Emgu.CV.CvInvoke.Rectangle(myFrame, myRectangle, new Emgu.CV.Structure.Bgr(Color.Red).MCvScalar, 2);
                        Emgu.CV.CvInvoke.PutText(myFrame, caption, new System.Drawing.Point(10, 20), Emgu.CV.CvEnum.FontFace.HersheyComplex, .5, new Emgu.CV.Structure.Bgr(0, 255, 0).MCvScalar);
                        Emgu.CV.CvInvoke.PutText(myFrame, caption2, new System.Drawing.Point(10, 35), Emgu.CV.CvEnum.FontFace.HersheyComplex, .5, new Emgu.CV.Structure.Bgr(0, 255, 0).MCvScalar);
                        Point start = new Point(fXcenter, fYcenter);
                        Point end = new Point(sXcentroid, sYcentroid);

                        Emgu.CV.Structure.LineSegment2D line = new Emgu.CV.Structure.LineSegment2D(start, end);
                        Emgu.CV.CvInvoke.Line(myFrame, start, end, new Emgu.CV.Structure.Bgr(0, 255, 0).MCvScalar, 2, new Emgu.CV.CvEnum.LineType(), 0);
                        string caption3 = "Line length: " + line.Length.ToString();
                        Emgu.CV.CvInvoke.PutText(myFrame, caption3, new System.Drawing.Point(10, 50), Emgu.CV.CvEnum.FontFace.HersheyComplex, .5, new Emgu.CV.Structure.Bgr(0, 255, 0).MCvScalar);

                    }
                    viewer.Image = myFrame;
                };
                viewer.Text = "Tracker";
                viewer.ShowDialog();
            }
        }
    }

除了内存泄漏外,代码中的所有内容都可以正常工作。

0 个答案:

没有答案