AIParkingApplication/AIParkingApplication/PlateProcessor.cs

113 lines
4.2 KiB
C#

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)
{
Mat plateDetected = plateType == PlateType.Square ? squarePlateDetector.DetectPlate(frame) : longPlateDetector.DetectPlate(frame);
//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)
{
try
{
//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);
}
return plateResult;
}
catch (Exception ex)
{
Console.WriteLine($"{Util.GetCurrentMethodName()}\texMessage: {ex.Message}");
return new FinalPlateResult();
}
}
//TODO: Complete this
private string NormalizePlateString(string plateString)
{
return plateString;
}
public bool IsPlateStringValid(string plateString, int minPlateStringLength = 5)
{
bool isValid = !string.IsNullOrEmpty(plateString) && plateString.Length > minPlateStringLength;
return isValid;
}
}
public class FinalPlateResult
{
public string PlateString { get; set; }
public Bitmap PlateImage { get; set; }
}
}