AIParkingApplication/AIParkingApplication/PlateProcessor.cs

115 lines
4.3 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 if plateDetected empty
OcrResult plateOcrResultFromEngine = await Util.SendEngineRequestAsync(plateDetected, plateType);
Mat finalPlateImage;
if (!string.IsNullOrEmpty(plateOcrResultFromEngine.PlateString) && !string.IsNullOrEmpty(plateOcrResultFromEngine.PlateImageBase64))
{
byte[] imageData = Convert.FromBase64String(plateOcrResultFromEngine.PlateImageBase64);
using (var ms = new MemoryStream(imageData))
{
Bitmap image = new Bitmap(ms);
finalPlateImage = BitmapConverter.ToMat(image);
}
}
else
{
finalPlateImage = plateDetected;
}
return new FinalPlateResult
{
PlateString = plateOcrResultFromEngine.PlateString,
PlateImage = finalPlateImage,
PlateType = plateType
};
}
public async Task<FinalPlateResult> ProcessPlate(Mat frame)
{
try
{
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
{
PlateString = string.Empty,
PlateImage = frame,
PlateType = PlateType.Square
};
}
}
//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 Mat PlateImage { get; set; }
public PlateType PlateType { get; set; }
}
}