Exemple #1
0
        static void Main(string[] args)
        {
            int errorCode = 0;

            TextRecognizer.InitTextRecognizer();

            InitParameters();

            //foreach (var file in Directory.EnumerateFiles(@"D:\Imagini ANPR auto\1", "*.jpg"))
            foreach (var file in Directory.EnumerateFiles(@"D:\Imagini ANPR auto\5", "2*.png"))
            {
                Stopwatch watch = Stopwatch.StartNew(); // time the detection process

                Mat imgOriginal  = new Mat(file);
                Mat imgGrayScale = new Mat();
                Mat imgThresh    = new Mat();

                List <KeyValuePair <string, bool> > licensePlateNumber = new List <KeyValuePair <string, bool> >();

                ImageProcess.Preprocess(imgOriginal, ref imgGrayScale, ref imgThresh, ref errorCode);

                if (Properties.Settings.Default.debug)
                {
                    CvInvoke.Imshow("Original image", imgOriginal);
                    CvInvoke.Imshow("Threshold", imgThresh);
                }

                List <KeyValuePair <Mat, Mat> > licensePlates = PlateExtraction.DetectPlate(imgGrayScale, imgThresh, ref errorCode);

                foreach (var licensePlate in licensePlates)
                {
                    if (licensePlate.Value != null)
                    {
                        licensePlateNumber.Add(TextRecognizer.RecognizeText(licensePlate.Value));
                    }
                }

                foreach (KeyValuePair <string, bool> pair in licensePlateNumber)
                {
                    if (pair.Value == true)
                    {
                        Console.WriteLine("License plate # " + pair.Key);
                        break;
                    }
                    else
                    {
                        Console.WriteLine("License plate # " + LicensePlateRegex.LicensePlateNumberProcess(pair.Key));
                    }
                }

                watch.Stop(); //stop the timer
                Console.WriteLine(watch.Elapsed);

                CvInvoke.WaitKey();

                CvInvoke.DestroyAllWindows();
            }
            Console.ReadLine();
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="potentialPlates">List of potentials plates</param>
        /// <param name="pass">What pass is executing</param>
        /// <param name="errorCode">Error code</param>
        /// <returns>Key value pair of license plate image and its treshold</returns>
        private static KeyValuePair <Mat, Mat> FindPlateInPotentialPlates(List <Mat> potentialPlates, string pass, ref int errorCode)
        {
            // Initiate license plate variable
            KeyValuePair <Mat, Mat> licensePlate = new KeyValuePair <Mat, Mat>();

            // Initiate variable for if license plate was found
            bool licensePlateFound = false;

            try
            {
                // Check what pass
                if (pass == "firstPass")
                {
                    // Loop through all potential plates
                    foreach (var potentialPlate in potentialPlates)
                    {
                        // Initate images used
                        Mat imgBilateralFilter = new Mat();
                        Mat imgThresh          = new Mat();
                        Mat imgOpen            = new Mat();

                        // Initiate structuring elements used in morphological procedures
                        Mat structuringElement = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(150, 150), new Point(-1, -1));
                        Mat openElement        = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(7, 7), new Point(-1, -1));
                        Mat closeElement       = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(8, 15), new Point(-1, -1));
                        Mat erodeElement       = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), new Point(-1, -1));

                        // Initiate other variables
                        VectorOfVectorOfPoint contours           = new VectorOfVectorOfPoint();
                        List <Rectangle>      boundingRectangles = new List <Rectangle>();

                        // Maximize contrast of a potential plate
                        Mat imgMaxContrast = ImageProcess.MaximizeContrast(potentialPlate, ref errorCode);

                        // Apply bilateral filter to image with contrast maximized
                        CvInvoke.BilateralFilter(imgMaxContrast, imgBilateralFilter, 5, 20, 20); // 40 20 20

                        // Do morphological operation of tophat
                        CvInvoke.MorphologyEx(imgBilateralFilter, imgOpen, MorphOp.Tophat, structuringElement, new Point(-1, -1), 2, BorderType.Default, new MCvScalar());

                        // Do adaptive treshold to tophat image
                        CvInvoke.AdaptiveThreshold(imgOpen, imgThresh, 255, AdaptiveThresholdType.GaussianC, ThresholdType.BinaryInv, 295, 19); // first pass

                        // Do morphological operation of open to thresholded image
                        CvInvoke.MorphologyEx(imgThresh, imgThresh, MorphOp.Open, openElement, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());

                        // Do morphological operation of erode to open image
                        CvInvoke.MorphologyEx(imgThresh, imgThresh, MorphOp.Erode, erodeElement, new Point(-1, -1), 1, BorderType.Constant, new MCvScalar());

                        // Do morphological operation of close to thresholded image
                        CvInvoke.MorphologyEx(imgThresh, imgThresh, MorphOp.Close, closeElement, new Point(-1, -1), 1, BorderType.Constant, new MCvScalar());


                        // Find contours in erode image
                        CvInvoke.FindContours(imgThresh, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

                        Image <Bgr, byte> imgContours = imgThresh.ToImage <Bgr, byte>();

                        // Loop through found contours
                        for (int i = 0; i < contours.Size; i++)
                        {
                            // Create a bounding rectangle of the contour
                            var boundingRectangle = CvInvoke.BoundingRectangle(contours[i]);

                            // Check if contour has required dimensions
                            if (boundingRectangle.Height >= Properties.Settings.Default.boundingRectangleHeightMin && boundingRectangle.Height <= Properties.Settings.Default.boundingRectangleHeightMax && boundingRectangle.Width <= Properties.Settings.Default.boundingRectangleWidthMax)
                            {
                                CvInvoke.Rectangle(imgContours, boundingRectangle, new MCvScalar(0, 0, 255));

                                // Add bounding rectangle to the list of bounding rectangles
                                boundingRectangles.Add(boundingRectangle);
                            }
                        }

                        // Check if the list of bounding rectangles has the required number of items
                        if (boundingRectangles.Count >= 5 && boundingRectangles.Count <= 9)
                        {
                            // Make a key value pair with the cropped image and its threshold
                            licensePlate = new KeyValuePair <Mat, Mat>(potentialPlate, imgThresh);

                            licensePlateFound = true;

                            // Check if debug enabled
                            if (Properties.Settings.Default.debug)
                            {
                                // Show image of plate segmented
                                CvInvoke.Imshow("Plate segmented first pass", imgContours.Mat);
                                //CvInvoke.Imshow("Plate segmented first pass", potentialPlate);
                            }

                            // Stop from searching further
                            break;
                        }
                    }
                }
                else if (pass == "secondPass")
                {
                    foreach (var potentialPlate in potentialPlates)
                    {
                        // Initate images used
                        Mat imgBilateralFilter = new Mat();
                        Mat imgThresh          = new Mat();
                        Mat imgOpen            = new Mat();

                        // Initiate structuring elements used in morphological procedures
                        Mat structuringElement = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(150, 150), new Point(-1, -1));
                        Mat openElement        = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(7, 7), new Point(-1, -1));
                        Mat closeElement       = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(5, 5), new Point(-1, -1));
                        Mat erodeElement       = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(3, 3), new Point(-1, -1));

                        // Initiate other variables
                        VectorOfVectorOfPoint contours           = new VectorOfVectorOfPoint();
                        List <Rectangle>      boundingRectangles = new List <Rectangle>();

                        // Maximize contrast of a potential plate
                        Mat imgMaxContrast = ImageProcess.MaximizeContrast(potentialPlate, ref errorCode);

                        // Apply bilateral filter to image with contrast maximized
                        CvInvoke.BilateralFilter(imgMaxContrast, imgBilateralFilter, 5, 10, 10); // 20 10 10


                        // Do morphological operation of tophat
                        CvInvoke.MorphologyEx(imgBilateralFilter, imgOpen, MorphOp.Tophat, structuringElement, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());

                        // Do adaptive treshold to tophat image
                        CvInvoke.AdaptiveThreshold(imgOpen, imgThresh, 255, AdaptiveThresholdType.GaussianC, ThresholdType.BinaryInv, 105, 5); // second pass

                        // Do morphological operation of open to thresholded image
                        CvInvoke.MorphologyEx(imgThresh, imgThresh, MorphOp.Open, openElement, new Point(-1, -1), 1, BorderType.Constant, new MCvScalar());

                        // Do morphological operation of erode to open image
                        CvInvoke.MorphologyEx(imgThresh, imgThresh, MorphOp.Erode, erodeElement, new Point(-1, -1), 1, BorderType.Constant, new MCvScalar());

                        // Do morphological operation of close to thresholded image
                        CvInvoke.MorphologyEx(imgThresh, imgThresh, MorphOp.Close, closeElement, new Point(-1, -1), 1, BorderType.Constant, new MCvScalar());

                        // Find contours in erode image
                        CvInvoke.FindContours(imgThresh, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);


                        Image <Bgr, byte> imgContours = imgThresh.ToImage <Bgr, byte>();

                        // Loop through found contours
                        for (int i = 0; i < contours.Size; i++)
                        {
                            // Create a bounding rectangle of the contour
                            var boundingRectangle = CvInvoke.BoundingRectangle(contours[i]);

                            // Check if contour has required dimensions
                            if (boundingRectangle.Height >= Properties.Settings.Default.boundingRectangleHeightMin && boundingRectangle.Height <= Properties.Settings.Default.boundingRectangleHeightMax)
                            {
                                CvInvoke.Rectangle(imgContours, boundingRectangle, new MCvScalar(0, 0, 255));

                                // Add bounding rectangle to the list of bounding rectangles
                                boundingRectangles.Add(boundingRectangle);
                            }
                        }

                        // Check if the list of bounding rectangles has the required number of items
                        if (boundingRectangles.Count >= 5 && boundingRectangles.Count <= 9)
                        {
                            // Make a key value pair with the cropped image and its threshold
                            licensePlate = new KeyValuePair <Mat, Mat>(potentialPlate, imgThresh);

                            licensePlateFound = true;

                            // Check if debug enabled
                            if (Properties.Settings.Default.debug)
                            {
                                // Show image of plate segmented
                                CvInvoke.Imshow("Plate segmented second pass", imgContours.Mat);
                                //CvInvoke.Imshow("Plate segmented second pass", potentialPlate);
                            }

                            // Stop from searching further
                            break;
                        }
                    }
                }

                // Check if license plate has been found
                if (!licensePlateFound)
                {
                    // Return null
                    return(new KeyValuePair <Mat, Mat>());
                }
                else
                {
                    // Return the key value pair
                    return(licensePlate);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                errorCode = 8;
                return(new KeyValuePair <Mat, Mat>());
            }
        }