代码之家  ›  专栏  ›  技术社区  ›  stl

系统VideoCapture上的AccessViolationException。Retrieve()-EmguCV/OpenCV

  •  0
  • stl  · 技术社区  · 7 年前

    我是新开简历的,我正在尝试人脸识别功能,但有一次遇到了麻烦。对VideoCapture对象调用Retrieve()-方法会引发系统。三种情况之一的AccessViolationException。我发现了很多关于这个问题的话题,但没有解决方案。

    这是我得到的StackTrace:

    贝恩古。个人简历CvInvoke。cveVideoCaptureRetrieve(IntPtr捕获,IntPtr 图像,Int32标志)

    贝恩古。个人简历视频捕获。检索(IOutputArray映像,Int32通道)

    bei打开CVGenericaAssembly。打开CVGenericaAssembly。捕获(字符串 sensorSerialNo,FeatureType功能,布尔压缩,Int32 超时)输入 C: \用户\sl\Documents\Source\Share\OpenCVGenericAssembly\OpenCVGenericAssembly\OpenCVGenericAssembly。cs:Zeile 81

    bei打开CVGenericaAssembly。打开CVGenericaAssembly。注册(字符串 sensorSerialNo、String firstName、String lastName、String company、, FeatureType功能,Int32 templateDestination,布尔压缩, Int32超时,字符串连接字符串,字符串模板查询) C: \用户\sl\Documents\Source\Share\OpenCVGenericAssembly\OpenCVGenericAssembly\OpenCVGenericAssembly。cs:Zeile 125

    bei测试。程序主(字符串[]参数)输入 C: \Users\sl\Documents\Source\Share\OpenCVGenericaAssembly\Testing\Program。cs:Zeile 20

    我正在调用一个Enroll方法,它只调用一个Capture方法并等待其响应,而不执行其他操作。捕获方法应运行,直到它检测到一个面,然后返回。捕获方法就是这样的:

    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应用程序,显示视频流和检测到的人脸周围的一帧(如果识别出一个人,则加上一个名字)。这很相似,但他们在教程中使用了Dispatcher,我不能使用它,因为我的代码应该用作程序集。无论如何,这段代码不会引发此错误,因此这可能会帮助某人在我的上述源代码中捕获问题。

    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 回复  |  直到 7 年前
        1
  •  1
  •   stl    7 年前

    必须处理VideoCapture对象(手动或通过将其放入using块)。这就解决了问题。