我正在开发一个带有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++)
答案 0 :(得分:0)
所以我发现导致问题的原因。这是行
using (MemStorage storage = new MemStorage())
当执行到达DrawAndComputeFingersNum方法中的for (int i = 0; i < defects.Total; i++)
时,memorystorge超出范围或由于某种原因被清除,因此defects.Total访问会引发错误。我删除了使用并将其全局放入,只需放置一个storage.clear
,现在一切正常。