Add class PlateProcessor. Update Event PlateCamera_OnOneVideoFrameRequested. PlateDetector add method: ExtendPlateRect
This commit is contained in:
parent
1cd0195fe7
commit
8b2319fe81
|
@ -92,6 +92,7 @@
|
|||
<DependentUpon>LaneOut.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="PlateDetector.cs" />
|
||||
<Compile Include="PlateProcessor.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Util.cs" />
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using OpenCvSharp;
|
||||
using OpenCvSharp.Extensions;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
@ -12,18 +10,20 @@ namespace AIParkingApplication
|
|||
{
|
||||
private Camera overviewCamera;
|
||||
private Camera plateCamera;
|
||||
private PlateDetector squarePlateDetector;
|
||||
private PlateProcessor plateProcessor;
|
||||
|
||||
public LaneIn()
|
||||
{
|
||||
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);
|
||||
|
||||
plateCamera.OnVideoFrameReceived += PlateCameraOnVideoFrameReceived;
|
||||
plateCamera.OnOneVideoFrameRequested += PlateCamera_OnOneVideoFrameRequested; ;
|
||||
plateCamera.OnOneVideoFrameRequested += PlateCamera_OnOneVideoFrameRequested;
|
||||
|
||||
overviewCamera.OnVideoFrameReceived += OverviewCameraOnVideoFrameReceived;
|
||||
overviewCamera.OnOneVideoFrameRequested += OverviewCamera_OnOneVideoFrameRequested;
|
||||
|
@ -31,7 +31,7 @@ namespace AIParkingApplication
|
|||
overviewCamera.Startcapture();
|
||||
plateCamera.Startcapture();
|
||||
|
||||
squarePlateDetector = new PlateDetector(PlateType.Square, PlateDetectorConstant.MIN_SIZE_DEFAULT_SQUARE_PLATE, PlateDetectorConstant.MAX_SIZE_DEFAULT_SQUARE_PLATE, PlateDetectorConstant.SCALE_FACTOR_DEFAULT_SQUARE_PLATE, PlateDetectorConstant.MIN_NEIGHBORS_DEFAULT_SQUARE_PLATE);
|
||||
plateProcessor = new PlateProcessor(true, false);
|
||||
}
|
||||
|
||||
private void OverviewCamera_OnOneVideoFrameRequested(Mat videoFrame)
|
||||
|
@ -47,38 +47,17 @@ namespace AIParkingApplication
|
|||
{
|
||||
Task.Factory.StartNew(new Action(async () =>
|
||||
{
|
||||
//TODO: check size before resizing
|
||||
Cv2.Resize(videoFrame, videoFrame, new OpenCvSharp.Size(1280, 720));
|
||||
Mat result = squarePlateDetector.DetectPlate(videoFrame);
|
||||
|
||||
//TODO: check size before resizing
|
||||
Cv2.Resize(result, result, new OpenCvSharp.Size(272, 272));
|
||||
OcrResult ocrResult = await Util.SendEngineRequestAsync(result, PlateType.Square);
|
||||
|
||||
//TODO: Exception Here
|
||||
Bitmap resultPlateImage;
|
||||
if (!string.IsNullOrEmpty(ocrResult.Ocr) && !string.IsNullOrEmpty(ocrResult.Plate))
|
||||
{
|
||||
var imageData = Convert.FromBase64String(ocrResult.Plate);
|
||||
using (var ms = new MemoryStream(imageData))
|
||||
{
|
||||
resultPlateImage = new Bitmap(ms);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resultPlateImage = result.ToBitmap();
|
||||
}
|
||||
var finalPlateResult = await plateProcessor.ProcessPlate(videoFrame);
|
||||
|
||||
lblPlateString.Invoke(new Action(() =>
|
||||
{
|
||||
lblPlateString.Text = ocrResult.Ocr;
|
||||
lblPlateString.Text = finalPlateResult.PlateString;
|
||||
}));
|
||||
|
||||
pictureBoxPlateImage.Invoke(new Action(() =>
|
||||
{
|
||||
pictureBoxPlateImage.Image?.Dispose();
|
||||
pictureBoxPlateImage.Image = resultPlateImage;
|
||||
pictureBoxPlateImage.Image = finalPlateResult.PlateImage;
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
@ -103,8 +82,8 @@ namespace AIParkingApplication
|
|||
|
||||
private void CaptureAllCamera()
|
||||
{
|
||||
this.plateCamera.RequestCaptureOneFrame();
|
||||
this.overviewCamera.RequestCaptureOneFrame();
|
||||
plateCamera.RequestCaptureOneFrame();
|
||||
overviewCamera.RequestCaptureOneFrame();
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
|
|
|
@ -38,11 +38,31 @@ namespace AIParkingApplication
|
|||
}
|
||||
}
|
||||
|
||||
private Rect ExtendPlateRect(Rect plateRect, int extendWidth = 50, int extendHeigh = 50) //TODO: 50 for plate square.
|
||||
{
|
||||
int newX = plateRect.X - extendWidth;
|
||||
int newY = plateRect.Y - extendHeigh;
|
||||
int newWidth = plateRect.Width + extendWidth * 2;
|
||||
int newHeigh = plateRect.Height + extendHeigh * 2;
|
||||
return new Rect(newX, newY, newWidth, newHeigh);
|
||||
}
|
||||
|
||||
private Mat GetBiggestPlate(Rect[] plateRects, Mat frame)
|
||||
{
|
||||
Rect biggestPlateRect = plateRects.OrderByDescending(x => x.Width).FirstOrDefault();
|
||||
Console.WriteLine("===================================================");
|
||||
for (int i = 0; i < plateRects.Length; i++)
|
||||
{
|
||||
Console.WriteLine($"{i}\t{plateRects[i].Width}\t{plateRects[i].Height}");
|
||||
}
|
||||
Console.WriteLine($"GetBiggestPlate - Width: {biggestPlateRect.Width}\tHeight: {biggestPlateRect.Height}");
|
||||
Mat plateImage = frame[biggestPlateRect];
|
||||
|
||||
Rect extendedRect = ExtendPlateRect(biggestPlateRect);
|
||||
//TODO: check oversize frame
|
||||
Mat plateImage = frame[extendedRect];
|
||||
//Cv2.ImShow("Old", frame[biggestPlateRect]);
|
||||
//Cv2.ImShow("New", frame[extendedRect]);
|
||||
//Cv2.WaitKey();
|
||||
return plateImage;
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +77,7 @@ namespace AIParkingApplication
|
|||
{
|
||||
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(80, 75);
|
||||
public static Size MIN_SIZE_DEFAULT_SQUARE_PLATE = new Size(105, 100);
|
||||
public static Size MAX_SIZE_DEFAULT_SQUARE_PLATE = new Size(450, 400);
|
||||
|
||||
public static double SCALE_FACTOR_DEFAULT_LONG_PLATE = 1.5;
|
||||
|
|
101
AIParkingApplication/PlateProcessor.cs
Normal file
101
AIParkingApplication/PlateProcessor.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
using OpenCvSharp;
|
||||
using OpenCvSharp.Extensions;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AIParkingApplication
|
||||
{
|
||||
public class PlateProcessor
|
||||
{
|
||||
private bool isSupportSquarePlate;
|
||||
private bool isSupportLongPlate;
|
||||
private PlateDetector squarePlateDetector;
|
||||
private PlateDetector longPlateDetector;
|
||||
|
||||
public PlateProcessor(bool isSupportSquarePlate = true, bool isSupportLongPlate = false)
|
||||
{
|
||||
this.isSupportSquarePlate = isSupportSquarePlate;
|
||||
this.isSupportLongPlate = isSupportLongPlate;
|
||||
|
||||
if (this.isSupportSquarePlate)
|
||||
{
|
||||
squarePlateDetector = new PlateDetector(PlateType.Square, PlateDetectorConstant.MIN_SIZE_DEFAULT_SQUARE_PLATE, PlateDetectorConstant.MAX_SIZE_DEFAULT_SQUARE_PLATE, PlateDetectorConstant.SCALE_FACTOR_DEFAULT_SQUARE_PLATE, PlateDetectorConstant.MIN_NEIGHBORS_DEFAULT_SQUARE_PLATE);
|
||||
}
|
||||
|
||||
if (this.isSupportLongPlate)
|
||||
{
|
||||
longPlateDetector = new PlateDetector(PlateType.Long, PlateDetectorConstant.MIN_SIZE_DEFAULT_LONG_PLATE, PlateDetectorConstant.MAX_SIZE_DEFAULT_LONG_PLATE, PlateDetectorConstant.SCALE_FACTOR_DEFAULT_LONG_PLATE, PlateDetectorConstant.MIN_NEIGHBORS_DEFAULT_LONG_PLATE);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<FinalPlateResult> DetectPlateAndDoOcrEngineAsync(PlateType plateType, Mat frame)
|
||||
{
|
||||
//TODO: check size before resizing
|
||||
//Cv2.Resize(frame, frame, new OpenCvSharp.Size(1280, 720));
|
||||
Mat plateDetected = plateType == PlateType.Square ? squarePlateDetector.DetectPlate(frame) : longPlateDetector.DetectPlate(frame);
|
||||
//Cv2.ImShow("dasdas", plateDetected);
|
||||
//Cv2.WaitKey(1);
|
||||
//if (plateType == PlateType.Square)
|
||||
//{
|
||||
// //TODO: check size before resizing
|
||||
// Cv2.Resize(plateDetected, plateDetected, new OpenCvSharp.Size(272, 272));
|
||||
//}
|
||||
|
||||
//TODO: check size before resizing
|
||||
Cv2.Resize(plateDetected, plateDetected, new OpenCvSharp.Size(272, 272));
|
||||
|
||||
//TODO: Check if plateDetected empty
|
||||
OcrResult plateOcrResultFromEngine = await Util.SendEngineRequestAsync(plateDetected, plateType);
|
||||
Bitmap finalPlateImage;
|
||||
if (!string.IsNullOrEmpty(plateOcrResultFromEngine.Ocr) && !string.IsNullOrEmpty(plateOcrResultFromEngine.Plate))
|
||||
{
|
||||
byte[] imageData = Convert.FromBase64String(plateOcrResultFromEngine.Plate);
|
||||
using (var ms = new MemoryStream(imageData))
|
||||
{
|
||||
finalPlateImage = new Bitmap(ms);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
finalPlateImage = plateDetected.ToBitmap();
|
||||
}
|
||||
|
||||
return new FinalPlateResult
|
||||
{
|
||||
PlateString = plateOcrResultFromEngine.Ocr,
|
||||
PlateImage = finalPlateImage
|
||||
};
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Long, frame);
|
||||
if (string.IsNullOrEmpty(plateResult.PlateString))
|
||||
{
|
||||
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Square, frame);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Recall Square Plates");
|
||||
plateResult = await DetectPlateAndDoOcrEngineAsync(PlateType.Square, frame);
|
||||
}
|
||||
|
||||
return plateResult;
|
||||
}
|
||||
|
||||
public class FinalPlateResult
|
||||
{
|
||||
public string PlateString { get; set; }
|
||||
public Bitmap PlateImage { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user