113 lines
4.2 KiB
C#
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; }
|
|
}
|
|
}
|