我遇到了带有Capture功能的System.StackOverflowException问题。这是代码,请忽略loadScript函数,但要看一下构造函数和FaceDetect函数:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Data;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.Util;
using System.Runtime.InteropServices;
using PAD_SCRIPT;
using Emgu.CV.GPU;
using Emgu.CV.UI;
namespace PAD_CORE_ENGINE
{
class VisionCore
{
private Capture capture;
private HaarCascade haarCascade;
double[,] faceData = new double[100, 5];
double[,] eyeData = new double[100, 10];
double[,] circleData = new double[100, 5];
int numberOfFaces;
private Image<Bgr, Byte> image;
private System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
public VisionCore()
{
capture = new Capture(0);
capture.ImageGrabbed += updateFaceDetect;
capture.Start();
//haarCascade = new HaarCascade(@"haarcascade_frontalface_default.xml");
}
public double[,] getDetectFaceInfo()
{
return faceData;
}
public double[,] getEyeInfo()
{
return eyeData;
}
public double[,] getCircleData()
{
return circleData;
}
public double getDetectFaceX(int index)
{
return faceData[index, 0];
}
public double getDetectFaceY(int index)
{
return faceData[index, 1];
}
public double getDetectFaceWidth(int index)
{
return faceData[index, 2];
}
public double getDetectFaceHeight(int index)
{
return faceData[index, 3];
}
public double getEyeX(int index)
{
return eyeData[index, 0];
}
public double getEyeY(int index)
{
return eyeData[index, 1];
}
public double getEyeWidth(int index)
{
return eyeData[index, 2];
}
public double getEyeHeight(int index)
{
return eyeData[index, 3];
}
private void DetectFace(Image<Bgr, Byte> image, String faceFileName, String eyeFileName, List<Rectangle> faces, List<Rectangle> eyes, out long detectionTime)
{
Stopwatch watch;
if (GpuInvoke.HasCuda)
{
using (GpuCascadeClassifier face = new GpuCascadeClassifier(faceFileName))
using (GpuCascadeClassifier eye = new GpuCascadeClassifier(eyeFileName))
{
watch = Stopwatch.StartNew();
using (GpuImage<Bgr, Byte> gpuImage = new GpuImage<Bgr, byte>(image))
using (GpuImage<Gray, Byte> gpuGray = gpuImage.Convert<Gray, Byte>())
{
Rectangle[] faceRegion = face.DetectMultiScale(gpuGray, 1.1, 10, Size.Empty);
faces.AddRange(faceRegion);
foreach (Rectangle f in faceRegion)
{
using (GpuImage<Gray, Byte> faceImg = gpuGray.GetSubRect(f))
{
//For some reason a clone is required.
//Might be a bug of GpuCascadeClassifier in opencv
using (GpuImage<Gray, Byte> clone = faceImg.Clone(null))
{
Rectangle[] eyeRegion = eye.DetectMultiScale(clone, 1.1, 10, Size.Empty);
foreach (Rectangle e in eyeRegion)
{
Rectangle eyeRect = e;
eyeRect.Offset(f.X, f.Y);
eyes.Add(eyeRect);
}
}
}
}
}
watch.Stop();
}
}
else
{
//Read the HaarCascade objects
using (CascadeClassifier face = new CascadeClassifier(faceFileName))
using (CascadeClassifier eye = new CascadeClassifier(eyeFileName))
{
watch = Stopwatch.StartNew();
using (Image<Gray, Byte> gray = image.Convert<Gray, Byte>()) //Convert it to Grayscale
{
//normalizes brightness and increases contrast of the image
gray._EqualizeHist();
//Detect the faces from the gray scale image and store the locations as rectangle
//The first dimensional is the channel
//The second dimension is the index of the rectangle in the specific channel
Rectangle[] facesDetected = face.DetectMultiScale(
gray,
1.1,
10,
new Size(20, 20),
Size.Empty);
faces.AddRange(facesDetected);
foreach (Rectangle f in facesDetected)
{
//Set the region of interest on the faces
gray.ROI = f;
Rectangle[] eyesDetected = eye.DetectMultiScale(
gray,
1.1,
10,
new Size(20, 20),
Size.Empty);
gray.ROI = Rectangle.Empty;
foreach (Rectangle e in eyesDetected)
{
Rectangle eyeRect = e;
eyeRect.Offset(f.X, f.Y);
eyes.Add(eyeRect);
}
}
}
watch.Stop();
}
}
detectionTime = watch.ElapsedMilliseconds;
capture.QueryFrame();
}
protected void updateFaceDetect(object sender, EventArgs e)
{
//Image<Bgr, Byte> image, String faceFileName, String eyeFileName, List<Rectangle> faces, List<Rectangle> eyes, out long detectionTime
Image<Bgr, Byte> image = capture.RetrieveBgrFrame();
string faceFileName = "haarcascade_frontalface_default.xml";
string eyeFileName = "haarcascade_eye.xml";
List<Rectangle> faces = new List<Rectangle>();
List<Rectangle> eyes = new List<Rectangle>();
long detectionTime = 0;
DetectFace(image, faceFileName, eyeFileName, faces, eyes, out detectionTime);
DisplayImage(image);
}
public Image<Bgr, Byte> getImage()
{
return image;
}
public void DisplayImage(Image<Bgr, Byte> img)
{
try
{
ImageViewer.Show(image, String.Format(
"Completed face and eye detection using {0}",
GpuInvoke.HasCuda ? "GPU" : "CPU"
));
}
catch (Exception i)
{
Console.WriteLine(i.Message);
}
}
public Image<Bgr, Byte> processFaces(Image<Bgr, Byte> img, List<Rectangle> faces)
{
foreach (Rectangle face in faces)
img.Draw(face, new Bgr(Color.Red), 2);
return img;
}
public Image<Bgr, Byte> processEyes(Image<Bgr, Byte> img, List<Rectangle> eyes)
{
foreach (Rectangle eye in eyes)
img.Draw(eye, new Bgr(Color.Blue), 2);
return img;
}
public void testVision()
{
DisplayImage(capture.RetrieveBgrFrame());
}
public CircleF[] detectCircles(Image<Bgr, Byte> img)
{
Image<Gray, Byte> gray = img.Convert<Gray, Byte>().PyrDown().PyrUp();
Stopwatch watch = Stopwatch.StartNew();
double cannyThreshold = 180.0;
double circleAccumulatorThreshold = 120;
CircleF[] circles = gray.HoughCircles(new Gray(cannyThreshold), new Gray(circleAccumulatorThreshold), 2.0, 20.0, 5, 0)[0];
watch.Stop();
return circles;
}
public Image<Bgr, Byte> ProcessCircles(Image<Bgr, Byte> img, CircleF[] circles)
{
foreach (CircleF circle in circles)
{
img.Draw(circle, new Bgr(Color.Brown), 2);
}
return img;
}
//display the image
public int getNumOfFaces()
{
return numberOfFaces;
}
public PADScript loadScript(PADScript l)
{
l.addLuaCommand("getNumOfFaces", this);
l.addLuaCommand("getDetectFaceInfo", this);
l.addLuaCommand("getImage", this);
l.addLuaCommand("getDetectFaceInfo", this);
l.addLuaCommand("getEyeInfo", this);
l.addLuaCommand("getDetectFaceX", this);
l.addLuaCommand("getDetectFaceY", this);
l.addLuaCommand("getDetectFaceWidth", this);
l.addLuaCommand("getDetectFaceHeight", this);
l.addLuaCommand("getEyeX", this);
l.addLuaCommand("getEyeY", this);
l.addLuaCommand("getEyeWidth", this);
l.addLuaCommand("getEyeHeight", this);
l.addLuaCommand("testVision", this);
return l;
}
}
}
我认为捕获是一次查询过多的捕获,但我也在使用时遇到错误(GpuCascadeClassifier face = new GpuCascadeClassifier(faceFileName))。我不确定这个错误来自哪里。提前感谢您的帮助!
编辑:异常是:类型&#39; System.StackOverflowException&#39;的未处理异常。发生在Emgu.CV.GPU.dll