VideoCapture.Retrieve()上的System.AccessViolationException - EmguCV / OpenCV

时间:2018-01-12 10:10:50

标签: c# opencv face-recognition emgucv

我是新手打开简历,我正在尝试使用人脸识别功能,但一度陷入困境。在VideoCapture-Object上调用Retrieve() - 方法会在以下三种情况之一中引发System.AccessViolationException。我找到了很多关于这个问题的主题,但没有解决方案。

这是我得到的StackTrace:

  

bei Emgu.CV.CvInvoke.cveVideoCaptureRetrieve(IntPtr capture,IntPtr   image,Int32 flag)

     

bei Emgu.CV.VideoCapture.Retrieve(IOutputArray image,Int32 channel)

     

bei OpenCVGenericAssembly.OpenCVGenericAssembly.Capture(String   sensorSerialNo,FeatureType功能,布尔压缩,Int32   timeOut)in   C:\用户\ SL \文档\来源\共享\ OpenCVGenericAssembly \ OpenCVGenericAssembly \ OpenCVGenericAssembly.cs:Zeile   81。

     

bei OpenCVGenericAssembly.OpenCVGenericAssembly.Enroll(String   sensorSerialNo,String firstName,String lastName,String company,   FeatureType功能,Int32 templateDestination,布尔压缩,   Int32 timeOut,String connectionString,String templateQuery)in   C:\用户\ SL \文档\来源\共享\ OpenCVGenericAssembly \ OpenCVGenericAssembly \ OpenCVGenericAssembly.cs:Zeile   125。

     

bei Testing.Program.Main(String [] args)in   C:\用户\ SL \文档\来源\共享\ OpenCVGenericAssembly \测试\的Program.cs:Zeile   20。

我正在调用一个Enroll方法,除了调用Capture-Method并等待其响应之外别无其他。捕获方法应该运行,直到它只检测到一个面,然后返回。这就是Capture-Method看起来的样子:

public DResponse Capture(string sensorSerialNo, FeatureType feature, bool compressed = false, int timeOut = 0)
{
    capture = new VideoCapture(); 
    DResponse rsp = DResponse();

    while(string.IsNullOrWhiteSpace(rsp.templateData))
    {
        using (Mat mat = new Mat())
        {
            capture.Retrieve(mat);
            Image<Bgr, Byte> currentFrame = mat.ToImage<Bgr, Byte>();

            if (currentFrame != null)
            {
                Image<Gray, Byte> grayFrame = currentFrame.Convert<Gray, Byte>();

                Rectangle[] detectedFaces = cascadeClassifier.DetectMultiScale(grayFrame, DMS_SCALE_FACTORS, DMS_MIN_NEIGHBORS);

                if (detectedFaces.Length == 1)
                {
                    Image<Gray, byte> result = currentFrame.Copy(detectedFaces[0]).Convert<Gray, byte>().Resize(IMG_WIDTH, IMG_HEIGHT, Emgu.CV.CvEnum.Inter.Cubic);
                    result._EqualizeHist();
                    rsp.templateData = Convert.ToBase64String(result.Bytes);
                    break;
                }
                Thread.Sleep(100);
            }
        }
    }

    return rsp;
}

我首先尝试了一个教程。它是一个wpf-app,显示视频流和检测到的面部周围的框架(如果识别出某人,则加上名称)。它非常相似,但他们在教程中使用DispatcherTimer,我无法使用,因为我的代码应该用作程序集。无论如何,这段代码并没有抛出这个错误,所以这可能会帮助别人在上面的源代码中捕获问题。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    capture = new VideoCapture();
    haarCascade = new CascadeClassifier(System.AppDomain.CurrentDomain.BaseDirectory + "haarcascade_frontalface_alt_tree.xml");
    timer = new DispatcherTimer();
    timer.Tick += new EventHandler(timer_Tick);
    timer.Interval = new TimeSpan(0, 0, 0, 0, 1);
    timer.Start();
}

void timer_Tick(object sender, EventArgs e)
{
    Mat mat = new Mat();
    capture.Retrieve(mat);
    Image<Bgr, Byte> currentFrame = mat.ToImage<Bgr, Byte>();

    if (currentFrame != null)
    {
        Image<Gray, Byte> grayFrame = currentFrame.Convert<Gray, Byte>();
        Rectangle[] detectedFaces = haarCascade.DetectMultiScale(grayFrame, 1.1, 1);

        for (int i = 0; i < detectedFaces.Length; i++)
        {
            result = currentFrame.Copy(detectedFaces[i]).Convert<Gray, byte>().Resize(100, 100, Emgu.CV.CvEnum.Inter.Cubic);
            result._EqualizeHist();

            currentFrame.Draw(detectedFaces[i], new Bgr(System.Drawing.Color.Green), 3);

            if (eigenRecog.IsTrained)
            {
                // do some stuff
            }
        }

        image1.Source = ToBitmapSource(currentFrame);
    }
}

任何提示?任何问题?我感谢每一个输入! STL

1 个答案:

答案 0 :(得分:1)

必须处理VideoCapture-Object(手动或将其放入使用块)。这解决了这个问题。