You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EmguCV/OpenCV中VideoCapture.Retrieve()触发System.AccessViolationException

Troubleshooting System.AccessViolationException with Emgu CV's VideoCapture.Retrieve()

Hey there, let's break down the AccessViolationException you're hitting every third call to Retrieve()—I've run into similar quirks with Emgu CV before, so here are some targeted fixes and explanations:

Key Observations from Your Code

Your WPF tutorial code uses a DispatcherTimer (running on the UI thread) without issues, while your Capture method uses a blocking while loop with Thread.Sleep(100) and recreates the VideoCapture instance every time. These differences are likely driving the exception.

Likely Causes & Fixes

1. Stop Recreating VideoCapture Instances

Your current code creates a new VideoCapture every time Capture() runs. This leads to resource contention with the camera (multiple instances trying to access the same hardware) and can leave unmanaged resources hanging, triggering memory access errors.

Fix: Initialize VideoCapture once as a class-level variable, not inside the Capture method:

// Class-level fields
private VideoCapture _cameraCapture;
private CascadeClassifier _faceCascade;

// Initialize in your class constructor or setup method
public OpenCVGenericAssembly()
{
    _cameraCapture = new VideoCapture();
    _faceCascade = new CascadeClassifier("haarcascade_frontalface_alt_tree.xml"); // Verify path is correct!
}

2. Explicitly Call Grab() Before Retrieve()

While some Emgu CV versions auto-call Grab() from Retrieve(), skipping this step can lead to race conditions where Retrieve() tries to access an uninitialized frame buffer.

Fix: Add a Grab() check before retrieving the frame:

using (Mat mat = new Mat())
{
    if (_cameraCapture.Grab()) // Ensure a frame is ready first
    {
        _cameraCapture.Retrieve(mat);
        // Rest of your frame processing logic
    }
}

3. Properly Dispose All Emgu CV Objects

Your code creates Image instances (like result) without disposing them, leading to unmanaged memory leaks. Over time, this can corrupt memory and trigger access violations.

Fix: Wrap all Image and Mat instances in using blocks:

if (detectedFaces.Length == 1)
{
    using (var faceRegion = currentFrame.Copy(detectedFaces[0]))
    using (var grayFace = faceRegion.Convert<Gray, byte>())
    using (var resizedFace = grayFace.Resize(IMG_WIDTH, IMG_HEIGHT, Emgu.CV.CvEnum.Inter.Cubic))
    {
        resizedFace._EqualizeHist();
        rsp.templateData = Convert.ToBase64String(resizedFace.Bytes);
        break;
    }
}

4. Fix Threading & Timing Issues

Thread.Sleep(100) blocks the thread and can cause the camera's frame buffer to overflow, leading to invalid memory access. Additionally, if Capture() is called from multiple threads, you need to synchronize access to the shared VideoCapture instance.

Fixes:

  • Shorten the sleep interval to 30ms to reduce buffer pressure
  • Add a lock to ensure thread-safe access to _cameraCapture
  • Consider using await Task.Delay(30) instead of Thread.Sleep for non-blocking waits (requires making Capture async)

Example with locking:

private readonly object _cameraLock = new object();

public DResponse Capture(string sensorSerialNo, FeatureType feature, bool compressed = false, int timeOut = 0)
{
    lock (_cameraLock) // Ensure only one thread accesses the camera at a time
    {
        DResponse rsp = new DResponse(); // Fix: You missed `new` here in your original code!
        DateTime startTime = DateTime.Now;

        while (string.IsNullOrWhiteSpace(rsp.templateData))
        {
            // Handle timeout
            if (timeOut > 0 && (DateTime.Now - startTime).TotalMilliseconds > timeOut)
            {
                rsp.ErrorMessage = "Capture timed out";
                break;
            }

            using (Mat mat = new Mat())
            {
                if (_cameraCapture.Grab())
                {
                    _cameraCapture.Retrieve(mat);
                    // Rest of your frame processing logic
                }
            }
            Thread.Sleep(30);
        }
        return rsp;
    }
}

5. Verify Version Compatibility

Access violations can also stem from mismatched Emgu CV and underlying OpenCV library versions. Ensure you're using a stable Emgu CV release, and all required OpenCV DLLs are present in your output directory.

Final Notes

The WPF tutorial works because it reuses a single VideoCapture instance and processes frames in a controlled UI thread loop. Applying the fixes above should align your code with that stable pattern and eliminate the System.AccessViolationException.

内容的提问来源于stack exchange,提问作者stl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:01:56