using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using OpenCvSharp; using OpenCvSharp.Extensions; namespace AIParkingApplication { public partial class LaneIn : UserControl, ILane { private Camera overviewCamera; private Camera plateCamera; private PlateProcessor plateProcessor; private int doorId; private bool isSupportSquarePlate; private bool isSupportLongPlate; private bool isAutoOpenDoor; private bool isRetryMode; private bool isRetryModeUntilOk; //TODO: Test mode private C3DeviceController c3Device; public LaneIn(int doorId, string plateStream, string overviewStream, C3DeviceController c3Device, bool isSupportSquarePlate = true, bool isSupportLongPlate = false, bool isAutoOpenDoor = true, bool isRetryMode = false, bool isRetryModeUntilOk = false) { InitializeComponent(); this.doorId = doorId; this.isSupportSquarePlate = isSupportSquarePlate; this.isSupportLongPlate = isSupportLongPlate; this.isAutoOpenDoor = isAutoOpenDoor; this.isRetryMode = isRetryMode; this.isRetryModeUntilOk = isRetryModeUntilOk; overviewCamera = new Camera(overviewStream); plateCamera = new Camera(plateStream); this.c3Device = c3Device; this.c3Device.OnNewCardReceived += C3Device_OnNewCardReceived; plateCamera.OnVideoFrameReceived += PlateCameraOnVideoFrameReceived; plateCamera.OnOneVideoFrameRequested += PlateCamera_OnOneVideoFrameRequested; plateCamera.OnOpenVideoStreamFailed += PlateCamera_OnOpenVideoStreamFailed; overviewCamera.OnVideoFrameReceived += OverviewCameraOnVideoFrameReceived; overviewCamera.OnOneVideoFrameRequested += OverviewCamera_OnOneVideoFrameRequested; overviewCamera.OnOpenVideoStreamFailed += OverviewCamera_OnOpenVideoStreamFailed; plateProcessor = new PlateProcessor(this.isSupportSquarePlate, this.isSupportLongPlate); if (!this.c3Device.Connect().HasError) { _ = this.c3Device.GetLogToReceiveNewCard(); } } private void C3Device_OnNewCardReceived(int doorId, string cardNumber) { //Request To Capture And Process Frame. CaptureAllCamera(); //Request Card Info if (isAutoOpenDoor) { if (this.doorId == doorId) { c3Device.OpenDoor(doorId); } } } private void PlateCamera_OnOpenVideoStreamFailed(Mat videoFrame) { pictureBoxPlateVideo.Invoke(new Action(() => { pictureBoxPlateVideo.Image?.Dispose(); pictureBoxPlateVideo.Image = videoFrame.ToBitmap(); })); } private void OverviewCamera_OnOpenVideoStreamFailed(Mat videoFrame) { pictureBoxOverviewVideo.Invoke(new Action(() => { pictureBoxOverviewImage.Image?.Dispose(); pictureBoxOverviewVideo.Image = videoFrame.ToBitmap(); })); } private void OverviewCamera_OnOneVideoFrameRequested(Mat videoFrame) { try { pictureBoxOverviewImage.Invoke(new Action(() => { pictureBoxOverviewImage.Image?.Dispose(); pictureBoxOverviewImage.Image = videoFrame.ToBitmap(); })); } catch (Exception ex) { Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}"); } } private void PlateCamera_OnOneVideoFrameRequested(Mat videoFrame) { Task.Factory.StartNew(new Action(async () => { try { //TODO: check size before resizing Cv2.Resize(videoFrame, videoFrame, new Size(1280, 720)); FinalPlateResult finalPlateResult = await plateProcessor.ProcessPlate(videoFrame); if (isRetryMode && !plateProcessor.IsPlateStringValid(finalPlateResult.PlateString)) { if (isRetryModeUntilOk) //TODO: TestMode { Thread.Sleep(500); CaptureAllCamera(); } else { Console.WriteLine("PlateCamera_OnOneVideoFrameRequested Retry Mode"); Thread.Sleep(1000); overviewCamera.RequestCaptureOneFrame(); finalPlateResult = await plateProcessor.ProcessPlate(videoFrame); } } pictureBoxPlateImage.Invoke(new Action(() => { pictureBoxPlateImage.Image?.Dispose(); pictureBoxPlateImage.Image = finalPlateResult.PlateImage; })); ShowCardInfoOnUI("224", finalPlateResult.PlateString, "Thẻ tháng", DateTime.Now.ToString(AppConstant.DATETIME_FORMAT)); } catch (Exception ex) { Console.WriteLine($"PlateCamera_OnOneVideoFrameRequested\texMessage: {ex.Message}"); } })); } public void Stop() { plateCamera.Stop(); overviewCamera.Stop(); } public void Start() { plateCamera.Start(); overviewCamera.Start(); } private void ShowCardInfoOnUI(string cardNumber, string plateString, string cardType, string cardTime) { lblCardNumber.Invoke(new Action(() => { lblCardNumber.Text = $"Số thẻ: {cardNumber}"; })); lblPlateString.Invoke(new Action(() => { lblPlateString.Text = $"Biển số: {plateString}"; })); lblCardType.Invoke(new Action(() => { lblCardType.Text = $"Loại thẻ: {cardType}"; })); lblCardTime.Invoke(new Action(() => { lblCardTime.Text = $"Thời gian: {cardTime}"; })); lblRecogizePlateStatus.Invoke(new Action(() => { lblRecogizePlateStatus.Text = string.IsNullOrEmpty(plateString) ? "KHÔNG NHẬN DIỆN ĐƯỢC BIỂN SỐ" : $"MỜI XE {plateString} VÀO"; lblRecogizePlateStatus.BackColor = string.IsNullOrEmpty(plateString) ? System.Drawing.Color.Red : System.Drawing.Color.Green; })); } private void OverviewCameraOnVideoFrameReceived(Mat videoFrame) { try { pictureBoxOverviewVideo.Invoke(new Action(() => { pictureBoxOverviewVideo.Image?.Dispose(); pictureBoxOverviewVideo.Image = videoFrame.ToBitmap(); })); } catch (Exception ex) { Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}"); } } private void PlateCameraOnVideoFrameReceived(Mat videoFrame) { try { pictureBoxPlateVideo.Invoke(new Action(() => { pictureBoxPlateVideo.Image?.Dispose(); pictureBoxPlateVideo.Image = videoFrame.ToBitmap(); })); } catch (Exception ex) { Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}"); } } private void CaptureAllCamera() { plateCamera.RequestCaptureOneFrame(); overviewCamera.RequestCaptureOneFrame(); } private void button1_Click(object sender, EventArgs e) { CaptureAllCamera(); } } }