115 lines
4.3 KiB
C#
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; }
|
|
}
|
|
}
|