使用backgroundworker的AccessViolationException

时间:2013-09-01 14:59:48

标签: c# backgroundworker access-violation

我正在开发一个带有finger-facedetection的项目(Visual Studio 2012,C#)。当我使用组合框从面部检测切换到手指检测时,我得到一个AccessViolationException。 我查看了Exception的详细信息,这是stacktrace:

  

在System.ComponentModel.DoWorkEventHandler.Invoke(对象发送者,   DoWorkEventArgs e)at   System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)

所以这是我的背景工作代码和代码组合代码组合代码:

private void bgw_DoWork(object sender, DoWorkEventArgs e)
    {

        BackgroundWorker worker = sender as BackgroundWorker;

        while (!bgw.CancellationPending)
        {
            System.Threading.Thread.Sleep(100);

            if(faceDetection){
            Image<Bgr, Byte> screengrab2 = capture.QueryFrame();
            screengrab2 = screengrab2.Flip(FLIP.HORIZONTAL);
            screengrab2 = screengrab2.Resize(183, 166, 0);
            Image<Gray, Byte> GrayImage = screengrab2.Convert<Gray, Byte>();
            var HaarCascadeXML = new HaarCascade(@"C:\Emgu\emgucv-windows-x86-gpu 2.4.2.1777\opencv_attic\opencv\data\haarcascades\haarcascade_frontalface_default.xml");
            var faces = HaarCascadeXML.Detect(GrayImage, 1.1, 10, HAAR_DETECTION_TYPE.DEFAULT, new System.Drawing.Size(40, 40), new System.Drawing.Size(100, 100));
            int i = faces.Length;

            if (screengrab2 != null)
            {
                if (faces.Length != 0)
                {
                    foreach (var face in faces)
                    {
                        GrayImage.Draw(face.rect, new Gray(255), 1);

                    }   
                    imageBox2.Image = GrayImage;


                    if (m_CurrentStatus != MediaStatus.Stopped)
                    {
                       m_objMediaControl.Run();
                       m_CurrentStatus = MediaStatus.Running;
                       UpdateStatusBar();
                       UpdateToolBar();
                    }       
                }
                else
                {
                    if (m_CurrentStatus != MediaStatus.Paused)
                    {

                        m_objMediaControl.Pause();
                        m_CurrentStatus = MediaStatus.Paused;
                        UpdateStatusBar();
                        UpdateToolBar();
                    }
                }
            }
            }
            else if (fingerDetection)
            {
                Image<Bgr, Byte> screencapt = capture.QueryFrame();
                screencapt = screencapt.Flip(FLIP.HORIZONTAL);
                screencapt = screencapt.Resize(183, 166, 0);

                detector = new AdaptiveSkinDetector(1, AdaptiveSkinDetector.MorphingMethod.NONE);
                hsv_min = new Hsv(0, 45, 0);
                hsv_max = new Hsv(20, 255, 255);
                YCrCb_min = new Ycc(0, 131, 80);
                YCrCb_max = new Ycc(255, 185, 135);
                box = new MCvBox2D();
                ellip = new Ellipse();

                if (screencapt != null)
                {
                    currentFrameCopy = screencapt.Copy();
                    skinDetector = new HsvSkinDetector();
                    Image<Gray, Byte> skin = skinDetector.DetectSkin(currentFrameCopy, hsv_min, hsv_max);

                    //Extract Contour And Hull
                    using (MemStorage storage = new MemStorage())
                    {
                        Contour<Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                        Contour<Point> biggestContour = null;

                        Double Result1 = 0;
                        Double Result2 = 0;
                        while (contours != null)
                        {
                            Result1 = contours.Area;
                            if (Result1 > Result2)
                            {
                                Result2 = Result1;
                                biggestContour = contours;
                            }
                            contours = contours.HNext;
                        }

                        if (biggestContour != null)
                        {
                            Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);
                            screencapt.Draw(currentContour, new Bgr(Color.LimeGreen), 2);
                            biggestContour = currentContour;
                            hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                            box = biggestContour.GetMinAreaRect();
                            PointF[] points = box.GetVertices();
                            //handRect = box.MinAreaRect();
                            //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);

                            Point[] ps = new Point[points.Length];
                            for (int j = 0; j < points.Length; j++)
                                ps[j] = new Point((int)points[j].X, (int)points[j].Y);

                            screencapt.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2);
                            screencapt.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2);

                            filteredHull = new Seq<Point>(storage);
                            for (int k = 0; k < hull.Total; k++)
                            {
                                if (Math.Sqrt(Math.Pow(hull[k].X - hull[k + 1].X, 2) + Math.Pow(hull[k].Y - hull[k + 1].Y, 2)) > box.size.Width / 10)
                                {
                                    filteredHull.Push(hull[k]);
                                }
                            }

                            defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                            defectArray = defects.ToArray();
                        }
                    }

                    //Draw And Compute Fingers

                    int fingerNum = 0;

                    #region defects drawing
                    for (int l = 0; l < defects.Total; l++)
                    {
                        PointF startPoint = new PointF((float)defectArray[l].StartPoint.X,
                                                        (float)defectArray[l].StartPoint.Y);

                        PointF depthPoint = new PointF((float)defectArray[l].DepthPoint.X,
                                                        (float)defectArray[l].DepthPoint.Y);

                        PointF endPoint = new PointF((float)defectArray[l].EndPoint.X,
                                                        (float)defectArray[l].EndPoint.Y);

                        LineSegment2D startDepthLine = new LineSegment2D(defectArray[l].StartPoint, defectArray[l].DepthPoint);

                        LineSegment2D depthEndLine = new LineSegment2D(defectArray[l].DepthPoint, defectArray[l].EndPoint);

                        CircleF startCircle = new CircleF(startPoint, 5f);

                        CircleF depthCircle = new CircleF(depthPoint, 5f);

                        CircleF endCircle = new CircleF(endPoint, 5f);


                        if ((startCircle.Center.Y < box.center.Y || depthCircle.Center.Y < box.center.Y) && (startCircle.Center.Y < depthCircle.Center.Y) && (Math.Sqrt(Math.Pow(startCircle.Center.X - depthCircle.Center.X, 2) + Math.Pow(startCircle.Center.Y - depthCircle.Center.Y, 2)) > box.size.Height / 6.5))
                        {
                            fingerNum++;
                            screencapt.Draw(startDepthLine, new Bgr(Color.Green), 2);
                            //screencapt.Draw(depthEndLine, new Bgr(Color.Magenta), 2);
                        }


                        screencapt.Draw(startCircle, new Bgr(Color.Red), 2);
                        screencapt.Draw(depthCircle, new Bgr(Color.Yellow), 5);
                        //screencapt.Draw(endCircle, new Bgr(Color.DarkBlue), 4);
                    }
                    #endregion

                    MCvFont font = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_DUPLEX, 5d, 5d);
                    screencapt.Draw(fingerNum.ToString(), ref font, new Point(50, 150), new Bgr(Color.White));

                    imageBoxSkin.Image = skin;
                    imageBoxFrameGrabber.Image = screencapt;
                }
            }
     }
 }


            private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if ((e.Cancelled == true))
                {


                }
                else if (!(e.Error == null))
                {

                }
                else
                {

                }
            }

                private void cboDetection_SelectedIndexChanged(object sender, EventArgs e)
                {
                    if (cboDetection.SelectedIndex == 0)
                    {
                        faceDetection = true;
                        fingerDetection = false;
                    }
                    else if (cboDetection.SelectedIndex == 1)
                    {
                        faceDetection = false;
                        fingerDetection = true;
                    }
                }

有谁知道如何解决这个问题?

编辑:似乎Exception被抛出这一行:

for (int l = 0; l < defects.Total; l++)

1 个答案:

答案 0 :(得分:0)

所以我发现导致问题的原因。这是行

using (MemStorage storage = new MemStorage())

当执行到达DrawAndComputeFingersNum方法中的for (int i = 0; i < defects.Total; i++)时,memorystorge超出范围或由于某种原因被清除,因此defects.Total访问会引发错误。我删除了使用并将其全局放入,只需放置一个storage.clear,现在一切正常。