AIParkingApplication/AIParkingApplication/Camera.cs

84 lines
2.4 KiB
C#

using OpenCvSharp;
using System.Threading;
namespace AIParkingApplication
{
public delegate void CameraEvent(Mat videoFrame);
public class Camera
{
private string streamUrl;
private volatile bool isFrameRequested;
private Thread readStreamThread;
public volatile Mat CurrentFrame;
public event CameraEvent OnVideoFrameReceived;
public event CameraEvent OnOneVideoFrameRequested;
public event CameraEvent OnOpenVideoStreamFailed;
public Camera(string streamUrl)
{
this.streamUrl = streamUrl;
isFrameRequested = false;
readStreamThread = new Thread(new ThreadStart(ReadVideoStream));
readStreamThread.IsBackground = true;
}
~Camera()
{
Stop();
}
public void Start()
{
if (!readStreamThread.IsAlive)
{
readStreamThread = new Thread(new ThreadStart(ReadVideoStream));
readStreamThread.IsBackground = true;
readStreamThread.Start();
}
}
public void RequestCaptureOneFrame()
{
isFrameRequested = true;
}
public void ReadVideoStream()
{
VideoCapture videoCapture = new VideoCapture(); //TODO: Need to dispose this videoCapture?
Mat videoFrame = new Mat();
if (!videoCapture.Open(streamUrl))
{
OnOpenVideoStreamFailed?.Invoke(Cv2.ImRead(AppConstant.CAMERA_FAILED_IMAGE_PATH));
return;
}
while (true)
{
Thread.Sleep(50); //Stream Thread Sleep
//Thread.Sleep(40); //Video Thread Sleep
if (videoCapture.Read(videoFrame) && videoFrame.Width > 0 && videoFrame.Height > 0)
{
OnVideoFrameReceived?.Invoke(videoFrame);
if (isFrameRequested)
{
CurrentFrame = videoFrame;
OnOneVideoFrameRequested?.Invoke(videoFrame);
isFrameRequested = false;
}
}
}
}
public void Stop()
{
if (readStreamThread.IsAlive)
{
readStreamThread.Abort();
}
}
}
}