I am encountering an ObjectDisposedException while processing video frames using OpenCvSharp in a C# application. The exception occurs during a loop where video frames are being read, processed, and displayed.
Here's the core part of my code:
public async Task GetFrame(CancellationToken token, VideoCapture capture, Image imageControl)
{
List<BoundingBoxData> lastBoundingBoxes = new List<BoundingBoxData>();
Mat frame = new Mat();
int framesWithoutDetections = 0;
const int detectionThreshold = 10; // Threshold number of frames without new detections
while (!token.IsCancellationRequested)
{
if (token.IsCancellationRequested)
{
await System.Windows.Application.Current.Dispatcher.InvokeAsync(() =>
{
imageControl.Source = null;
});
token.ThrowIfCancellationRequested();
}
// Read the frame from the capture
if (!capture.Read(frame) || frame.Empty())
{
continue; // If the frame cannot be read or is empty, continue to the next iteration
}
FrameData newFrameData = new FrameData(frame.Clone());
frameQueue.Enqueue(newFrameData);
while (frameQueue.Count > maxBufferSize)
{
if (frameQueue.TryDequeue(out FrameData oldFrameData))
{
// Draw bounding boxes on the oldest frame
var boxesToDraw = oldFrameData.BoundingBoxes.Any() ? oldFrameData.BoundingBoxes : lastBoundingBoxes;
DrawBboxThree(oldFrameData.Frame, boxesToDraw);
if (oldFrameData.BoundingBoxes.Any())
{
lastBoundingBoxes = oldFrameData.BoundingBoxes;
framesWithoutDetections = 0; // Reset the counter as new bounding boxes are found
}
else
{
framesWithoutDetections++; // Increment the counter if no new bounding boxes are found
}
// Update display with the oldest frame
await UpdateDisplay(oldFrameData.Frame, imageControl);
// Dispose of the old frame after it's no longer needed
oldFrameData.Frame.Dispose();
}
}
if (framesWithoutDetections >= detectionThreshold)
{
lastBoundingBoxes.Clear(); // Clear lastBoundingBoxes if no new bounding boxes for a set number of frames
framesWithoutDetections = 0; // Reset the counter
}
await Task.Delay(10); // Wait for the next frame time
}
// Dispose of the current frame
frame.Dispose();
// Ensure all frames in the queue are disposed
while (frameQueue.TryDequeue(out var frameData))
{
frameData.Frame.Dispose();
}
}
Issue:
On the second iteration of the loop, when the capture.Read(frame) line executes, I receive an ObjectDisposedException. This issue seems to be related to the handling of the Mat objects in the frameQueue.
Attempts to Resolve:
- Ensured that each frame is cloned using frame.CopyTo(clonedFrame) to create independent Mat objects.
- Made sure to dispose of each cloned frame only after the asynchronous UpdateDisplay method completes.
Despite these attempts, the issue persists. I suspect it might be related to the concurrent handling of these Mat objects, but I'm not certain how to resolve it.
Any insights or suggestions on how to fix this exception would be greatly appreciated.