AIParkingApplication/AIParkingApplication/PlateDetector.cs

97 lines
3.7 KiB
C#

using OpenCvSharp;
using System;
using System.Linq;
namespace AIParkingApplication
{
public class PlateDetector
{
private PlateType plateType;
private Size minSizePlate;
private Size maxSizePlate;
private double scaleFactor;
private int minNeighbors;
private CascadeClassifier plateCascadeClassifier;
public PlateDetector(PlateType plateType, Size minSizePlate, Size maxSizePlate, double scaleFactor, int minNeighbors)
{
this.plateType = plateType;
this.minSizePlate = minSizePlate;
this.maxSizePlate = maxSizePlate;
this.scaleFactor = scaleFactor;
this.minNeighbors = minNeighbors;
plateCascadeClassifier = new CascadeClassifier(this.plateType == PlateType.Square ? PlateDetectorConstant.SQUARE_PLATE_WEIGHT_FILENAME : PlateDetectorConstant.LONG_PLATE_WEIGHT_FILENAME);
}
public Mat DetectPlate(Mat frame)
{
Rect[] plateRectsDetected = plateCascadeClassifier.DetectMultiScale(frame, scaleFactor, minNeighbors, HaarDetectionType.ScaleImage, minSizePlate, maxSizePlate);
Console.WriteLine("Plate Detected Length: " + plateRectsDetected.Length);
if (plateRectsDetected.Length > 0)
{
Mat plateImage = GetBiggestPlate(plateRectsDetected, frame);
return plateImage;
}
else
{
return frame;
}
}
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}");
Rect extendedRect = ExtendPlateRect(biggestPlateRect);
//TODO: check oversize frame
Mat plateImage;
try
{
plateImage = frame[extendedRect];
}
catch (Exception ex)
{
plateImage = frame[biggestPlateRect];
Console.WriteLine($"Error While Extending Plate Rect: {ex.Message}");
}
return plateImage;
}
}
public enum PlateType
{
Square,
Long
}
public static class PlateDetectorConstant
{
public const string SQUARE_PLATE_WEIGHT_FILENAME = "plate.xml";
public const string LONG_PLATE_WEIGHT_FILENAME = "plateLong.xml";
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(105, 100);
public static Size MAX_SIZE_DEFAULT_SQUARE_PLATE = new Size(450, 400);
public static double SCALE_FACTOR_DEFAULT_LONG_PLATE = 1.5;
public static int MIN_NEIGHBORS_DEFAULT_LONG_PLATE = 5;
public static Size MIN_SIZE_DEFAULT_LONG_PLATE = new Size(120, 40);
public static Size MAX_SIZE_DEFAULT_LONG_PLATE = new Size(660, 220);
}
}