Compare commits

..

12 Commits

Author SHA1 Message Date
7fcb3cc5c6 LaneIn - Method PlateCamera_OnOneVideoFrameRequested: Add overviewCamera.RequestCaptureOneFrame When use isRetryMode 2020-06-19 14:31:32 +07:00
325ad27bf6 PlateProcessor - Change IsPlateStringValid Default: int minPlateStringLength = 5 2020-06-19 14:28:51 +07:00
e987a410d1 LaneIn - Add Constructor Params: isSupportSquarePlate, isSupportLongPlate 2020-06-19 14:18:45 +07:00
13d591ada3 PlateProcessor - Update IsPlateStringValid to check valid plate string. LaneIn - Add option Retry Mode. 2020-06-19 13:44:09 +07:00
88b2e3524e PlateProcessor - Add Try Catch In Method DetectPlateAndDoOcrEngineAsync 2020-06-19 10:30:32 +07:00
e3ebc951fb LaneIn - Rename Exception Message Logging 2020-06-19 10:29:57 +07:00
8e7cf287f5 Util - Refactor Method GetCurrentMethodName 2020-06-19 10:29:12 +07:00
2bd45cf43f LaneIn - Add TryCatch For Methods: OverviewCamera_OnOneVideoFrameRequested, PlateCamera_OnOneVideoFrameRequested, OverviewCameraOnVideoFrameReceived, PlateCameraOnVideoFrameReceived 2020-06-19 10:13:22 +07:00
2caffc6adf Util - Add Method: GetCurrentMethodName 2020-06-19 10:11:16 +07:00
e7fe1de33e Remove Commented Code In AIParkingApplicationForm 2020-06-19 10:06:56 +07:00
d1d1640a31 PlateDetector - Move weight file name to constant 2020-06-18 17:41:39 +07:00
267e6cfaa3 Util: Remove unused namespace. 2020-06-18 17:30:58 +07:00
5 changed files with 126 additions and 178 deletions

View File

@ -1,128 +1,17 @@
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Forms;
namespace AIParkingApplication
{
public partial class AIParkingApplicationForm : Form
{
private Camera camera;
public AIParkingApplicationForm()
{
InitializeComponent();
string url = @"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"; // @"C:\HS_test.mp4"; // @"rtsp://admin:admin@192.168.2.10"
camera = new Camera(url);
camera.OnVideoFrameReceived += Camera_OnVideoFrameReceived;
camera.Startcapture();
//Thread thread1 = new Thread(ShowFrame);
//thread1.IsBackground = true;
//thread1.Start();
//CaptureFrame();
LaneIn laneIn = new LaneIn();
LaneOut laneOut = new LaneOut();
this.Controls.Add(laneIn);
laneOut.Location = new System.Drawing.Point(550, 0);
this.Controls.Add(laneOut);
LaneIn laneIn = new LaneIn(@"C:\HS_test.mp4", @"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", true, true); //@"C:\CongRa_1.mp4";
//LaneIn laneOut = new LaneIn();
Controls.Add(laneIn);
//laneOut.Location = new System.Drawing.Point(550, 0);
//Controls.Add(laneOut);
}
private void Camera_OnVideoFrameReceived(Mat videoFrame)
{
//pictureBox1.Invoke(new Action(() =>
//{
// pictureBox1.Image?.Dispose();
// pictureBox1.Width = videoFrame.Width;
// pictureBox1.Height = videoFrame.Height;
// pictureBox1.Image = videoFrame.ToBitmap();
//}));
}
//public void ShowFrame()
//{
// while (true)
// {
// Thread.Sleep(1);
// if (camera.VideoFrames.Count == 0)
// {
// continue;
// }
// Mat videoFrame = camera.VideoFrames.Dequeue();
// pictureBox1.Invoke(new Action(() =>
// {
// pictureBox1.Image?.Dispose();
// pictureBox1.Width = videoFrame.Width;
// pictureBox1.Height = videoFrame.Height;
// pictureBox1.Image = videoFrame.ToBitmap();
// }));
// }
//}
//public void CaptureFrame()
//{
// Thread thread = new Thread(new ThreadStart(() =>
// {
// Mat frame1 = new Mat();
// Mat frame2 = new Mat();
// Mat frame3 = new Mat();
// Mat frame4 = new Mat();
// VideoCapture capture1 = new VideoCapture();
// VideoCapture capture2 = new VideoCapture();
// VideoCapture capture3 = new VideoCapture();
// VideoCapture capture4 = new VideoCapture();
// capture1.Open(@"C:\HS_test.mp4");
// capture2.Open(@"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov");
// capture3.Open(@"C:\HS_test.mp4");
// capture4.Open(@"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov");
// while (true)
// {
// Thread.Sleep(TimeSpan.FromMilliseconds(1));
// try
// {
// capture1.Read(frame1);
// capture2.Read(frame2);
// capture3.Read(frame3);
// capture4.Read(frame4);
// pictureBox1.Image?.Dispose();
// var image1 = frame1.ToBitmap();
// pictureBox1.Invoke(new Action(() =>
// {
// pictureBox1.Image = image1;
// }));
// pictureBox2.Image?.Dispose();
// var image2 = frame2.ToBitmap();
// pictureBox2.Invoke(new Action(() =>
// {
// pictureBox2.Image = image2;
// }));
// pictureBox3.Image?.Dispose();
// var image3 = frame3.ToBitmap();
// pictureBox3.Invoke(new Action(() =>
// {
// pictureBox3.Image = image3;
// }));
// pictureBox4.Image?.Dispose();
// var image4 = frame4.ToBitmap();
// pictureBox4.Invoke(new Action(() =>
// {
// pictureBox4.Image = image4;
// }));
// }
// catch (Exception ex)
// {
// Console.WriteLine("Error: " + ex.Message);
// }
// }
// }));
// thread.IsBackground = true;
// thread.Start();
//}
}
}

View File

@ -1,6 +1,7 @@
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -11,16 +12,20 @@ namespace AIParkingApplication
private Camera overviewCamera;
private Camera plateCamera;
private PlateProcessor plateProcessor;
private bool isSupportSquarePlate;
private bool isSupportLongPlate;
private bool isRetryMode;
private bool isRetryModeUntilOk; //TODO: Test mode
public LaneIn()
public LaneIn(string plateStream, string overviewStream, bool isSupportSquarePlate = true, bool isSupportLongPlate = false, bool isRetryMode = false, bool isRetryModeUntilOk = false)
{
InitializeComponent();
string overviewCameraVideo = @"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"; //@"C:\HS_test.mp4"
string plateCameraVideo = @"C:\HS_test.mp4";
//string plateCameraVideo = @"C:\CongRa_1.mp4";
overviewCamera = new Camera(overviewCameraVideo);
plateCamera = new Camera(plateCameraVideo);
this.isSupportSquarePlate = isSupportSquarePlate;
this.isSupportLongPlate = isSupportLongPlate;
this.isRetryMode = isRetryMode;
this.isRetryModeUntilOk = isRetryModeUntilOk;
overviewCamera = new Camera(overviewStream);
plateCamera = new Camera(plateStream);
plateCamera.OnVideoFrameReceived += PlateCameraOnVideoFrameReceived;
plateCamera.OnOneVideoFrameRequested += PlateCamera_OnOneVideoFrameRequested;
@ -31,53 +36,97 @@ namespace AIParkingApplication
overviewCamera.Startcapture();
plateCamera.Startcapture();
plateProcessor = new PlateProcessor(true, false);
plateProcessor = new PlateProcessor(this.isSupportSquarePlate, this.isSupportLongPlate);
}
private void OverviewCamera_OnOneVideoFrameRequested(Mat videoFrame)
{
pictureBoxOverviewImage.Invoke(new Action(() =>
try
{
pictureBoxOverviewImage.Image?.Dispose();
pictureBoxOverviewImage.Image = videoFrame.ToBitmap();
}));
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 () =>
{
var finalPlateResult = await plateProcessor.ProcessPlate(videoFrame);
lblPlateString.Invoke(new Action(() =>
try
{
lblPlateString.Text = finalPlateResult.PlateString;
}));
FinalPlateResult finalPlateResult = await plateProcessor.ProcessPlate(videoFrame);
pictureBoxPlateImage.Invoke(new Action(() =>
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);
}
}
lblPlateString.Invoke(new Action(() =>
{
lblPlateString.Text = finalPlateResult.PlateString;
}));
pictureBoxPlateImage.Invoke(new Action(() =>
{
pictureBoxPlateImage.Image?.Dispose();
pictureBoxPlateImage.Image = finalPlateResult.PlateImage;
}));
}
catch (Exception ex)
{
pictureBoxPlateImage.Image?.Dispose();
pictureBoxPlateImage.Image = finalPlateResult.PlateImage;
}));
Console.WriteLine($"PlateCamera_OnOneVideoFrameRequested\texMessage: {ex.Message}");
}
}));
}
private void OverviewCameraOnVideoFrameReceived(Mat videoFrame)
{
pictureBoxOverviewVideo.Invoke(new Action(() =>
try
{
pictureBoxOverviewVideo.Image?.Dispose();
pictureBoxOverviewVideo.Image = videoFrame.ToBitmap();
}));
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)
{
pictureBoxPlateVideo.Invoke(new Action(() =>
try
{
pictureBoxPlateVideo.Image?.Dispose();
pictureBoxPlateVideo.Image = videoFrame.ToBitmap();
}));
pictureBoxPlateVideo.Invoke(new Action(() =>
{
pictureBoxPlateVideo.Image?.Dispose();
pictureBoxPlateVideo.Image = videoFrame.ToBitmap();
}));
}
catch (Exception ex)
{
Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}");
}
}
private void CaptureAllCamera()

View File

@ -20,7 +20,7 @@ namespace AIParkingApplication
this.maxSizePlate = maxSizePlate;
this.scaleFactor = scaleFactor;
this.minNeighbors = minNeighbors;
plateCascadeClassifier = new CascadeClassifier(this.plateType == PlateType.Square ? "plate.xml" : "plateLong.xml");
plateCascadeClassifier = new CascadeClassifier(this.plateType == PlateType.Square ? PlateDetectorConstant.SQUARE_PLATE_WEIGHT_FILENAME : PlateDetectorConstant.LONG_PLATE_WEIGHT_FILENAME);
}
public Mat DetectPlate(Mat frame)
@ -56,7 +56,6 @@ namespace AIParkingApplication
Console.WriteLine($"{i}\t{plateRects[i].Width}\t{plateRects[i].Height}");
}
Console.WriteLine($"GetBiggestPlate - Width: {biggestPlateRect.Width}\tHeight: {biggestPlateRect.Height}");
Rect extendedRect = ExtendPlateRect(biggestPlateRect);
//TODO: check oversize frame
Mat plateImage;
@ -66,9 +65,8 @@ namespace AIParkingApplication
}
catch (Exception ex)
{
Console.WriteLine("Error While Extending Plate Rect");
plateImage = frame[biggestPlateRect];
throw;
Console.WriteLine($"Error While Extending Plate Rect: {ex.Message}");
}
return plateImage;
}
@ -82,6 +80,9 @@ namespace AIParkingApplication
public static class PlateDetectorConstant
{
public const string SQUARE_PLATE_WEIGHT_FILENAME = "plate.xml";
public const string LONG_PLATE_WEIGHT_FILENAME = "plateLong.xml";
public const double SCALE_FACTOR_DEFAULT_SQUARE_PLATE = 1.03;
public static int MIN_NEIGHBORS_DEFAULT_SQUARE_PLATE = 2;
public static Size MIN_SIZE_DEFAULT_SQUARE_PLATE = new Size(105, 100);

View File

@ -32,7 +32,6 @@ namespace AIParkingApplication
private async Task<FinalPlateResult> DetectPlateAndDoOcrEngineAsync(PlateType plateType, Mat frame)
{
//TODO: check size before resizing
Mat plateDetected = plateType == PlateType.Square ? squarePlateDetector.DetectPlate(frame) : longPlateDetector.DetectPlate(frame);
//TODO: check size before resizing
@ -63,25 +62,33 @@ namespace AIParkingApplication
public async Task<FinalPlateResult> ProcessPlate(Mat frame)
{
//TODO: check size before resizing
Cv2.Resize(frame, frame, new OpenCvSharp.Size(1280, 720));
FinalPlateResult plateResult;
if (isSupportLongPlate)
try
{
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Long, frame);
if (string.IsNullOrEmpty(plateResult.PlateString))
//TODO: check size before resizing
Cv2.Resize(frame, frame, new OpenCvSharp.Size(1280, 720));
FinalPlateResult plateResult;
if (isSupportLongPlate)
{
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Long, frame);
if (!IsPlateStringValid(plateResult.PlateString))
{
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Square, frame);
}
}
else
{
Console.WriteLine("Recall Square Plates");
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Square, frame);
}
}
else
{
Console.WriteLine("Recall Square Plates");
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Square, frame);
}
return plateResult;
return plateResult;
}
catch (Exception ex)
{
Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}");
return new FinalPlateResult();
}
}
//TODO: Complete this
@ -90,17 +97,16 @@ namespace AIParkingApplication
return plateString;
}
//TODO: Complete this
private bool IsPlateStringValid(string plateString)
public bool IsPlateStringValid(string plateString, int minPlateStringLength = 5)
{
bool isValid = true;
bool isValid = !string.IsNullOrEmpty(plateString) && plateString.Length > minPlateStringLength;
return isValid;
}
}
public class FinalPlateResult
{
public string PlateString { get; set; }
public Bitmap PlateImage { get; set; }
}
public class FinalPlateResult
{
public string PlateString { get; set; }
public Bitmap PlateImage { get; set; }
}
}

View File

@ -1,12 +1,9 @@
using Newtonsoft.Json;
using OpenCvSharp;
using System;
using System.Net;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace AIParkingApplication
@ -46,6 +43,13 @@ namespace AIParkingApplication
}
}
public static string GetCurrentMethodName()
{
var strackTrace = new StackTrace();
var sf = strackTrace.GetFrame(1);
return sf.GetMethod().Name;
}
public static async Task<OcrResult> SendEngineRequestAsync(Mat plateImage, PlateType plateType)
{
string plateImageBase64 = Convert.ToBase64String(plateImage.ToBytes());
@ -100,6 +104,5 @@ namespace AIParkingApplication
public const string HTTP_POST_METHOD = "POST";
public const string HTTP_POST_CONTENTTYPE = "application/json";
}
}