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 System.Windows.Forms;
using OpenCvSharp.Extensions;
using System;
using System.Threading;
using System.Windows.Forms;
namespace AIParkingApplication namespace AIParkingApplication
{ {
public partial class AIParkingApplicationForm : Form public partial class AIParkingApplicationForm : Form
{ {
private Camera camera;
public AIParkingApplicationForm() public AIParkingApplicationForm()
{ {
InitializeComponent(); InitializeComponent();
LaneIn laneIn = new LaneIn(@"C:\HS_test.mp4", @"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", true, true); //@"C:\CongRa_1.mp4";
string url = @"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"; // @"C:\HS_test.mp4"; // @"rtsp://admin:admin@192.168.2.10" //LaneIn laneOut = new LaneIn();
camera = new Camera(url); Controls.Add(laneIn);
camera.OnVideoFrameReceived += Camera_OnVideoFrameReceived; //laneOut.Location = new System.Drawing.Point(550, 0);
camera.Startcapture(); //Controls.Add(laneOut);
//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);
} }
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;
using OpenCvSharp.Extensions; using OpenCvSharp.Extensions;
using System; using System;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
@ -11,16 +12,20 @@ namespace AIParkingApplication
private Camera overviewCamera; private Camera overviewCamera;
private Camera plateCamera; private Camera plateCamera;
private PlateProcessor plateProcessor; 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(); InitializeComponent();
string overviewCameraVideo = @"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov"; //@"C:\HS_test.mp4" this.isSupportSquarePlate = isSupportSquarePlate;
string plateCameraVideo = @"C:\HS_test.mp4"; this.isSupportLongPlate = isSupportLongPlate;
//string plateCameraVideo = @"C:\CongRa_1.mp4"; this.isRetryMode = isRetryMode;
this.isRetryModeUntilOk = isRetryModeUntilOk;
overviewCamera = new Camera(overviewCameraVideo); overviewCamera = new Camera(overviewStream);
plateCamera = new Camera(plateCameraVideo); plateCamera = new Camera(plateStream);
plateCamera.OnVideoFrameReceived += PlateCameraOnVideoFrameReceived; plateCamera.OnVideoFrameReceived += PlateCameraOnVideoFrameReceived;
plateCamera.OnOneVideoFrameRequested += PlateCamera_OnOneVideoFrameRequested; plateCamera.OnOneVideoFrameRequested += PlateCamera_OnOneVideoFrameRequested;
@ -31,53 +36,97 @@ namespace AIParkingApplication
overviewCamera.Startcapture(); overviewCamera.Startcapture();
plateCamera.Startcapture(); plateCamera.Startcapture();
plateProcessor = new PlateProcessor(true, false); plateProcessor = new PlateProcessor(this.isSupportSquarePlate, this.isSupportLongPlate);
} }
private void OverviewCamera_OnOneVideoFrameRequested(Mat videoFrame) private void OverviewCamera_OnOneVideoFrameRequested(Mat videoFrame)
{ {
pictureBoxOverviewImage.Invoke(new Action(() => try
{ {
pictureBoxOverviewImage.Image?.Dispose(); pictureBoxOverviewImage.Invoke(new Action(() =>
pictureBoxOverviewImage.Image = videoFrame.ToBitmap(); {
})); pictureBoxOverviewImage.Image?.Dispose();
pictureBoxOverviewImage.Image = videoFrame.ToBitmap();
}));
}
catch (Exception ex)
{
Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}");
}
} }
private void PlateCamera_OnOneVideoFrameRequested(Mat videoFrame) private void PlateCamera_OnOneVideoFrameRequested(Mat videoFrame)
{ {
Task.Factory.StartNew(new Action(async () => Task.Factory.StartNew(new Action(async () =>
{ {
var finalPlateResult = await plateProcessor.ProcessPlate(videoFrame); try
lblPlateString.Invoke(new Action(() =>
{ {
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(); Console.WriteLine($"PlateCamera_OnOneVideoFrameRequested\texMessage: {ex.Message}");
pictureBoxPlateImage.Image = finalPlateResult.PlateImage; }
}));
})); }));
} }
private void OverviewCameraOnVideoFrameReceived(Mat videoFrame) private void OverviewCameraOnVideoFrameReceived(Mat videoFrame)
{ {
pictureBoxOverviewVideo.Invoke(new Action(() => try
{ {
pictureBoxOverviewVideo.Image?.Dispose(); pictureBoxOverviewVideo.Invoke(new Action(() =>
pictureBoxOverviewVideo.Image = videoFrame.ToBitmap(); {
})); pictureBoxOverviewVideo.Image?.Dispose();
pictureBoxOverviewVideo.Image = videoFrame.ToBitmap();
}));
}
catch (Exception ex)
{
Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}");
}
} }
private void PlateCameraOnVideoFrameReceived(Mat videoFrame) private void PlateCameraOnVideoFrameReceived(Mat videoFrame)
{ {
pictureBoxPlateVideo.Invoke(new Action(() => try
{ {
pictureBoxPlateVideo.Image?.Dispose(); pictureBoxPlateVideo.Invoke(new Action(() =>
pictureBoxPlateVideo.Image = videoFrame.ToBitmap(); {
})); pictureBoxPlateVideo.Image?.Dispose();
pictureBoxPlateVideo.Image = videoFrame.ToBitmap();
}));
}
catch (Exception ex)
{
Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}");
}
} }
private void CaptureAllCamera() private void CaptureAllCamera()

View File

@ -20,7 +20,7 @@ namespace AIParkingApplication
this.maxSizePlate = maxSizePlate; this.maxSizePlate = maxSizePlate;
this.scaleFactor = scaleFactor; this.scaleFactor = scaleFactor;
this.minNeighbors = minNeighbors; 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) public Mat DetectPlate(Mat frame)
@ -56,7 +56,6 @@ namespace AIParkingApplication
Console.WriteLine($"{i}\t{plateRects[i].Width}\t{plateRects[i].Height}"); Console.WriteLine($"{i}\t{plateRects[i].Width}\t{plateRects[i].Height}");
} }
Console.WriteLine($"GetBiggestPlate - Width: {biggestPlateRect.Width}\tHeight: {biggestPlateRect.Height}"); Console.WriteLine($"GetBiggestPlate - Width: {biggestPlateRect.Width}\tHeight: {biggestPlateRect.Height}");
Rect extendedRect = ExtendPlateRect(biggestPlateRect); Rect extendedRect = ExtendPlateRect(biggestPlateRect);
//TODO: check oversize frame //TODO: check oversize frame
Mat plateImage; Mat plateImage;
@ -66,9 +65,8 @@ namespace AIParkingApplication
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine("Error While Extending Plate Rect");
plateImage = frame[biggestPlateRect]; plateImage = frame[biggestPlateRect];
throw; Console.WriteLine($"Error While Extending Plate Rect: {ex.Message}");
} }
return plateImage; return plateImage;
} }
@ -82,6 +80,9 @@ namespace AIParkingApplication
public static class PlateDetectorConstant 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 const double SCALE_FACTOR_DEFAULT_SQUARE_PLATE = 1.03;
public static int MIN_NEIGHBORS_DEFAULT_SQUARE_PLATE = 2; public static int MIN_NEIGHBORS_DEFAULT_SQUARE_PLATE = 2;
public static Size MIN_SIZE_DEFAULT_SQUARE_PLATE = new Size(105, 100); 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) 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); Mat plateDetected = plateType == PlateType.Square ? squarePlateDetector.DetectPlate(frame) : longPlateDetector.DetectPlate(frame);
//TODO: check size before resizing //TODO: check size before resizing
@ -63,25 +62,33 @@ namespace AIParkingApplication
public async Task<FinalPlateResult> ProcessPlate(Mat frame) public async Task<FinalPlateResult> ProcessPlate(Mat frame)
{ {
//TODO: check size before resizing try
Cv2.Resize(frame, frame, new OpenCvSharp.Size(1280, 720));
FinalPlateResult plateResult;
if (isSupportLongPlate)
{ {
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Long, frame); //TODO: check size before resizing
if (string.IsNullOrEmpty(plateResult.PlateString)) 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); 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 //TODO: Complete this
@ -90,17 +97,16 @@ namespace AIParkingApplication
return plateString; return plateString;
} }
//TODO: Complete this public bool IsPlateStringValid(string plateString, int minPlateStringLength = 5)
private bool IsPlateStringValid(string plateString)
{ {
bool isValid = true; bool isValid = !string.IsNullOrEmpty(plateString) && plateString.Length > minPlateStringLength;
return isValid; return isValid;
} }
}
public class FinalPlateResult public class FinalPlateResult
{ {
public string PlateString { get; set; } public string PlateString { get; set; }
public Bitmap PlateImage { get; set; } public Bitmap PlateImage { get; set; }
}
} }
} }

View File

@ -1,12 +1,9 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using OpenCvSharp; using OpenCvSharp;
using System; using System;
using System.Net; using System.Diagnostics;
using System.CodeDom.Compiler;
using System.Net.Http; using System.Net.Http;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AIParkingApplication 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) public static async Task<OcrResult> SendEngineRequestAsync(Mat plateImage, PlateType plateType)
{ {
string plateImageBase64 = Convert.ToBase64String(plateImage.ToBytes()); string plateImageBase64 = Convert.ToBase64String(plateImage.ToBytes());
@ -100,6 +104,5 @@ namespace AIParkingApplication
public const string HTTP_POST_METHOD = "POST"; public const string HTTP_POST_METHOD = "POST";
public const string HTTP_POST_CONTENTTYPE = "application/json"; public const string HTTP_POST_CONTENTTYPE = "application/json";
} }
} }