Reputation: 1
I am creating a web camera capture user control for use in a WPF application. Previously I was using WPF Media Toolkit for the camera capture. That works, but the frame rate I am getting from Open CV is better Also, using Media Toolkit, I haven't been able to save the current frame at high res but I can in Open CV. My Usercontrol is working well with my Logitech Brio web cam. Setting the resolution to 1920 x 1080, my frame rate is very good. When I set it to 3840 x 2160, it is a bit choppy.
What I want to do is view the camera live preview at 1920, bu when I want to capture the current frame, do so at full resolution. I tried stopping the camera, setting the resolution and restarting, but that takes way too long. I can’t seem to change the resolution on the fly.
Any ideas?
I was thinking of setting the image source in the capture loop, and setting another image source less often, after changing its size, but I doubt that is a very good solution.
public async Task Start()
{
// Never run two parallel tasks for the webcam streaming
if (_previewTask != null && !_previewTask.IsCompleted)
return;
var initializationSemaphore = new SemaphoreSlim(0, 1);
_cancellationTokenSource = new CancellationTokenSource();
_previewTask = Task.Run(async () =>
{
try
{
// Creation and disposal of this object should be done in the same thread
// because if not it throws disconnectedContext exception
if (!videoCapture.Open(CameraDeviceId))
{
throw new ApplicationException("Cannot connect to camera");
}
SetResolution();
using (frame)
{
while (!_cancellationTokenSource.IsCancellationRequested)
{
videoCapture.Read(frame);
if (!frame.Empty())
{
// Releases the lock on first not empty frame
if (initializationSemaphore != null)
initializationSemaphore.Release();
_lastFrame = FlipHorizontally
? BitmapConverter.ToBitmap(frame.Flip(FlipMode.Y))
: BitmapConverter.ToBitmap(frame);
_lastFrame.SetResolution(800, 600);
var lastFrameBitmapImage = _lastFrame.ToBitmapSource();
lastFrameBitmapImage.Freeze();
webcamPreview.Dispatcher.Invoke(
() => webcamPreview.Source = lastFrameBitmapImage);
}
// RenderGreenScreenMask(frame, backGroundImage);
// 30 FPS
await Task.Delay(FrameDelay);
}
}
videoCapture?.Dispose();
}
finally
{
if (initializationSemaphore != null)
initializationSemaphore.Release();
}
}, _cancellationTokenSource.Token);
// Async initialization to have the possibility to show an animated loader without freezing the GUI
// The alternative was the long polling. (while !variable) await Task.Delay
await initializationSemaphore.WaitAsync();
initializationSemaphore.Dispose();
initializationSemaphore = null;
if (_previewTask.IsFaulted)
{
// To let the exceptions exit
await _previewTask;
}
}
Upvotes: 0
Views: 129