Exemplo n.º 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();
        }
Exemplo n.º 2
0
        public static KeyValuePair <string, bool> RecognizeText(Mat imgInput)
        {
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            List <ContoursWithData> listOfContoursWithData = new List <ContoursWithData>();          // declare a list of contours with data

            CvInvoke.FindContours(imgInput, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

            //imgInput.Save(@"D:\Visual Studio Projects\KNNtrain\Imagini\4\" + i + ".jpg");
            //i++;

            // populate list of contours with data
            for (int i = 0; i <= contours.Size - 1; i++)                   // for each contour
            {
                if ((CvInvoke.ContourArea(contours[i]) > MIN_CONTOUR_AREA))
                {
                    ContoursWithData contourWithData = new ContoursWithData();                               // declare new contour with data
                    contourWithData.contour           = contours[i];                                         // populate contour member variable
                    contourWithData.boundingRectangle = CvInvoke.BoundingRectangle(contourWithData.contour); // calculate bounding rectangle
                    contourWithData.dblArea           = CvInvoke.ContourArea(contourWithData.contour);       // calculate area

                    if (contourWithData.checkIfContourIsValid())
                    {
                        listOfContoursWithData.Add(contourWithData);// add to list of contours with data
                    }
                    else
                    {
                        if (contourWithData.boundingRectangle.Width > Properties.Settings.Default.boundingRectangleWidthMax)
                        {
                            Mat imgROItoBeCloned = new Mat(imgInput, contourWithData.boundingRectangle);

                            Mat imgROI = imgROItoBeCloned.Clone();

                            Rectangle rectangleFirst  = new Rectangle(0, 0, contourWithData.boundingRectangle.Width / 2, contourWithData.boundingRectangle.Height);
                            Rectangle rectangleSecond = new Rectangle(contourWithData.boundingRectangle.Width / 2, 0, contourWithData.boundingRectangle.Width / 2, contourWithData.boundingRectangle.Height);

                            Mat firstImage  = new Mat(imgROI, rectangleFirst);
                            Mat secondImage = new Mat(imgROI, rectangleSecond);

                            VectorOfVectorOfPoint contoursSplitImage = new VectorOfVectorOfPoint();

                            CvInvoke.FindContours(firstImage, contoursSplitImage, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

                            for (int j = 0; j <= contoursSplitImage.Size - 1; j++)                   // for each contour
                            {
                                if ((CvInvoke.ContourArea(contoursSplitImage[j]) > MIN_CONTOUR_AREA))
                                {
                                    ContoursWithData contourWithDataFirstImage = new ContoursWithData();                                           // declare new contour with data
                                    contourWithDataFirstImage.contour             = contoursSplitImage[j];                                         // populate contour member variable
                                    contourWithDataFirstImage.boundingRectangle   = CvInvoke.BoundingRectangle(contourWithDataFirstImage.contour); // calculate bounding rectangle
                                    contourWithDataFirstImage.boundingRectangle.X = contourWithData.boundingRectangle.X;
                                    contourWithDataFirstImage.boundingRectangle.Y = contourWithData.boundingRectangle.Y;
                                    contourWithDataFirstImage.dblArea             = CvInvoke.ContourArea(contourWithDataFirstImage.contour);     // calculate area

                                    if (contourWithDataFirstImage.checkIfContourIsValid())
                                    {
                                        listOfContoursWithData.Add(contourWithDataFirstImage);// add to list of contours with data
                                    }
                                }
                            }

                            contoursSplitImage = new VectorOfVectorOfPoint();

                            CvInvoke.FindContours(secondImage, contoursSplitImage, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

                            for (int j = 0; j <= contoursSplitImage.Size - 1; j++)                   // for each contour
                            {
                                if ((CvInvoke.ContourArea(contoursSplitImage[j]) > MIN_CONTOUR_AREA))
                                {
                                    ContoursWithData contourWithDataSecondImage = new ContoursWithData();                                            // declare new contour with data
                                    contourWithDataSecondImage.contour             = contoursSplitImage[j];                                          // populate contour member variable
                                    contourWithDataSecondImage.boundingRectangle   = CvInvoke.BoundingRectangle(contourWithDataSecondImage.contour); // calculate bounding rectangle
                                    contourWithDataSecondImage.boundingRectangle.X = contourWithData.boundingRectangle.X + contourWithData.boundingRectangle.Width / 2;
                                    contourWithDataSecondImage.boundingRectangle.Y = contourWithData.boundingRectangle.Y;
                                    contourWithDataSecondImage.dblArea             = CvInvoke.ContourArea(contourWithDataSecondImage.contour);     // calculate area

                                    if (contourWithDataSecondImage.checkIfContourIsValid())
                                    {
                                        listOfContoursWithData.Add(contourWithDataSecondImage);// add to list of contours with data
                                    }
                                }
                            }
                        }
                    }
                }
            }

            float averageLocationY = 0;
            float sumLocationY     = 0;

            foreach (var item in listOfContoursWithData)
            {
                sumLocationY += item.boundingRectangle.Y + item.boundingRectangle.Height / 2;
            }

            averageLocationY = sumLocationY / listOfContoursWithData.Count;

            float minLocationY = averageLocationY - 0.15f * averageLocationY;
            float maxLocationY = averageLocationY + 0.15f * averageLocationY;

            listOfContoursWithData.RemoveAll(x => minLocationY > x.boundingRectangle.Y + x.boundingRectangle.Height / 2 || maxLocationY < x.boundingRectangle.Y + x.boundingRectangle.Height / 2);

            // sort contours with data from left to right
            listOfContoursWithData.Sort((oneContourWithData, otherContourWithData) => oneContourWithData.boundingRectangle.X.CompareTo(otherContourWithData.boundingRectangle.X));

            string strFinalString = "";                                                                           // declare final string, this will have the final number sequence by the end of the program

            foreach (ContoursWithData contourWithData in listOfContoursWithData)                                  // for each contour in list of valid contours
            {
                CvInvoke.Rectangle(imgInput, contourWithData.boundingRectangle, new MCvScalar(200, 0.0, 0.0), 2); // draw green rect around the current char

                Mat imgROItoBeCloned = new Mat(imgInput, contourWithData.boundingRectangle);                      // get ROI image of bounding rect

                Mat imgROI = imgROItoBeCloned.Clone();                                                            // clone ROI image so we don't change original when we resize

                Mat imgROIResized = new Mat();

                // resize image, this is necessary for char recognition
                CvInvoke.Resize(imgROI, imgROIResized, new System.Drawing.Size(RESIZED_IMAGE_WIDTH, RESIZED_IMAGE_HEIGHT));

                // declare a Matrix of the same dimensions as the Image we are adding to the data structure of training images
                Matrix <float> mtxTemp = new Matrix <float>(imgROIResized.Size);

                // declare a flattened (only 1 row) matrix of the same total size
                Matrix <float> mtxTempReshaped = new Matrix <float>(1, RESIZED_IMAGE_WIDTH * RESIZED_IMAGE_HEIGHT);

                imgROIResized.ConvertTo(mtxTemp, DepthType.Cv32F);                 // convert Image to a Matrix of Singles with the same dimensions

                for (int intRow = 0; intRow <= RESIZED_IMAGE_HEIGHT - 1; intRow++) // flatten Matrix into one row by RESIZED_IMAGE_WIDTH * RESIZED_IMAGE_HEIGHT number of columns
                {
                    for (int intCol = 0; intCol <= RESIZED_IMAGE_WIDTH - 1; intCol++)
                    {
                        mtxTempReshaped[0, (intRow * RESIZED_IMAGE_WIDTH) + intCol] = mtxTemp[intRow, intCol];
                    }
                }

                float sngCurrentChar;

                sngCurrentChar = kNearest.Predict(mtxTempReshaped);                        // finally we can call Predict !!!

                strFinalString = strFinalString + (char)(Convert.ToInt32(sngCurrentChar)); // append current char to full string of chars
            }

            bool licensePlateRegex = LicensePlateRegex.MatchRegex(strFinalString);

            return(new KeyValuePair <string, bool>(strFinalString, licensePlateRegex));
        }