我正在使用此類成功錄制網路攝像頭視頻。但是這段代碼的問題是,我無法將實時視頻顯示到圖片框中
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using Size = OpenCvSharp.Size;
namespace Video_capture_23_08_2022
{
public class Recorder : IDisposable
{
private readonly VideoCaptureAPIs _videoCaptureApi = VideoCaptureAPIs.DSHOW;
private readonly ManualResetEventSlim _threadStopEvent = new ManualResetEventSlim(false);
private readonly VideoCapture _videoCapture;
private VideoWriter _videoWriter;
private Mat _capturedFrame = new Mat();
private Thread _captureThread;
private Thread _writerThread;
//private OutputArray frame;
private bool IsVideoCaptureValid => _videoCapture is not null && _videoCapture.IsOpened();
public Recorder(int deviceIndex, int frameWidth, int frameHeight, double fps, PictureBox pictureBox)
{
_videoCapture = VideoCapture.FromCamera(deviceIndex, _videoCaptureApi);
_videoCapture.Open(deviceIndex, _videoCaptureApi);
_videoCapture.FrameWidth = frameWidth;
_videoCapture.FrameHeight = frameHeight;
_videoCapture.Fps = fps;
// Custom Function to show the webcam view into picturebox
_videoCapture.Read(_capturedFrame);
if (!(_capturedFrame.Empty()))
{
pictureBox.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(_capturedFrame);
}
}
/// <inheritdoc />
public void Dispose()
{
GC.SuppressFinalize(this);
Dispose(true);
}
~Recorder()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
StopRecording();
_videoCapture?.Release();
_videoCapture?.Dispose();
}
}
public void StartRecording(string path)
{
if (_writerThread is not null)
return;
if (!IsVideoCaptureValid)
ThrowHelper.ThrowVideoCaptureNotReadyException();
_videoWriter = new VideoWriter(path, FourCC.XVID, _videoCapture.Fps, new Size(_videoCapture.FrameWidth, _videoCapture.FrameHeight));
_threadStopEvent.Reset();
_captureThread = new Thread(CaptureFrameLoop);
_captureThread.Start();
_writerThread = new Thread(AddCameraFrameToRecordingThread);
_writerThread.Start();
}
public void StopRecording()
{
_threadStopEvent.Set();
_writerThread?.Join();
_writerThread = null;
_captureThread?.Join();
_captureThread = null;
_threadStopEvent.Reset();
_videoWriter?.Release();
_videoWriter?.Dispose();
_videoWriter = null;
}
private void CaptureFrameLoop()
{
while (!_threadStopEvent.Wait(0))
{
_videoCapture.Read(_capturedFrame);
}
}
private void AddCameraFrameToRecordingThread()
{
var waitTimeBetweenFrames = 1_000 / _videoCapture.Fps;
var lastWrite = DateTime.Now;
while (!_threadStopEvent.Wait(0))
{
if (DateTime.Now.Subtract(lastWrite).TotalMilliseconds < waitTimeBetweenFrames)
continue;
lastWrite = DateTime.Now;
_videoWriter.Write(_capturedFrame);
}
}
public Bitmap GetFrameBitmap()
{
if (!IsVideoCaptureValid)
ThrowHelper.ThrowVideoCaptureNotReadyException();
using (Mat frame = new Mat())
return !_videoCapture.Read(frame) ? null : frame.ToBitmap();
}
}
}
但我想稍微修改一下以將網路攝像頭視圖顯示到圖片框中,但是這個自定義部分
// Custom Function to show the webcam view into picturebox
_videoCapture.Read(_capturedFrame);
if (!(_capturedFrame.Empty()))
{
pictureBox.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(_capturedFrame);
}
僅顯示靜止影像而不是實時視頻。請幫助我找出問題所在。
uj5u.com熱心網友回復:
您的實作中缺少的部分是您捕獲網路攝像頭影像并將其顯示在pictureBox建構式中,僅一次而不是CaptureFrameLoop()重復顯示。因此,您需要將此塊移動到CaptureFrameLoop().
_videoCapture.Read(_capturedFrame);
if (!(_capturedFrame.Empty()))
{
pictureBox.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(_capturedFrame);
}
此外,您應該使用從非 UI 執行緒Control.Invoke修改影像。PictureBox
private void CaptureFrameLoop()
{
while (!_threadStopEvent.Wait(0))
{
_videoCapture.Read(_capturedFrame);
if (!(_capturedFrame.Empty()))
{
pictureBox.Invoke(new Action(() => pictureBox.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(_capturedFrame)));
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/516769.html
標籤:C#。网表格opencv
