97 lines
3.7 KiB
C#
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);
|
|
}
|
|
}
|