Exemplo n.º 1
0
        /// <summary>
        /// Filter the license plate to remove noise
        /// </summary>
        /// <param name="plate">The license plate image</param>
        /// <returns>License plate image without the noise</returns>
        private static UMat FilterPlate(UMat plate, int threshold_parameter)
        {
            UMat thresh = new UMat();

            //Modify line height(modifica captura de linea por color de pixel)
            CvInvoke.Threshold(plate, thresh, threshold_parameter, 255, ThresholdType.BinaryInv);
            //Image<Gray, Byte> thresh = plate.ThresholdBinaryInv(new Gray(120), new Gray(255));

            SaveImageClass.SaveImage(plate, "plate.jpg");
            Size plateSize = plate.Size;

            using (Mat plateMask = new Mat(plateSize.Height, plateSize.Width, DepthType.Cv8U, 1))
                using (Mat plateCanny = new Mat())
                    using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
                    {
                        plateMask.SetTo(new MCvScalar(255.0));
                        CvInvoke.Canny(plate, plateCanny, 100, 50);
                        CvInvoke.FindContours(plateCanny, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

                        int count = contours.Size;
                        for (int i = 0; i < count; i++)
                        {
                            using (VectorOfPoint contour = contours[i])
                            {
                                Rectangle rect = CvInvoke.BoundingRectangle(contour);
                                if (rect.Height > (plateSize.Height >> 1))
                                {
                                    rect.X -= 1; rect.Y -= 1; rect.Width += 2; rect.Height += 2;
                                    Rectangle roi = new Rectangle(Point.Empty, plate.Size);
                                    rect.Intersect(roi);
                                    CvInvoke.Rectangle(plateMask, rect, new MCvScalar(), -1);
                                    //plateMask.Draw(rect, new Gray(0.0), -1);
                                }
                            }
                        }

                        thresh.SetTo(new MCvScalar(), plateMask);
                    }

            SaveImageClass.SaveImage(thresh, "thresh1.jpg");

            CvInvoke.Erode(thresh, thresh, null, new Point(-1, -1), 1, BorderType.Constant, CvInvoke.MorphologyDefaultBorderValue);
            SaveImageClass.SaveImage(thresh, "threshErode.jpg");
            CvInvoke.Dilate(thresh, thresh, null, new Point(-1, -1), 1, BorderType.Constant, CvInvoke.MorphologyDefaultBorderValue);
            SaveImageClass.SaveImage(thresh, "threshDilate.jpg");

            return(thresh);
        }
Exemplo n.º 2
0
        private void FindLicensePlate(
            VectorOfVectorOfPoint contours, int[,] hierachy, int idx, IInputArray gray, IInputArray canny,
            List <IInputOutputArray> licensePlateImagesList, List <IInputOutputArray> filteredLicensePlateImagesList, List <RotatedRect> detectedLicensePlateRegionList,
            List <String> licenses, int ocr_mode, int threshold_parameter)
        {
            for (; idx >= 0; idx = hierachy[idx, 0])
            {
                int numberOfChildren = GetNumberOfChildren(hierachy, idx);
                //if it does not contains any children (charactor), it is not a license plate region
                if (numberOfChildren == 0)
                {
                    continue;
                }

                using (VectorOfPoint contour = contours[idx])
                {
                    if (CvInvoke.ContourArea(contour) > 400)
                    {
                        if (numberOfChildren < 6)
                        {
                            //If the contour has less than 6 children, it is not a license plate (assuming license plate has at least 3 charactor)
                            //However we should search the children of this contour to see if any of them is a license plate
                            FindLicensePlate(contours, hierachy, hierachy[idx, 2], gray, canny, licensePlateImagesList,
                                             filteredLicensePlateImagesList, detectedLicensePlateRegionList, licenses, ocr_mode, threshold_parameter);
                            continue;
                        }

                        RotatedRect box = CvInvoke.MinAreaRect(contour);
                        if (box.Angle < -45.0)
                        {
                            float tmp = box.Size.Width;
                            box.Size.Width  = box.Size.Height;
                            box.Size.Height = tmp;
                            box.Angle      += 90.0f;
                        }
                        else if (box.Angle > 45.0)
                        {
                            float tmp = box.Size.Width;
                            box.Size.Width  = box.Size.Height;
                            box.Size.Height = tmp;
                            box.Angle      -= 90.0f;
                        }

                        double whRatio = (double)box.Size.Width / box.Size.Height;
                        if (!(3.0 < whRatio && whRatio < 10.0))
                        //if (!(1.0 < whRatio && whRatio < 2.0))
                        {
                            //if the width height ratio is not in the specific range,it is not a license plate
                            //However we should search the children of this contour to see if any of them is a license plate
                            //Contour<Point> child = contours.VNext;
                            if (hierachy[idx, 2] > 0)
                            {
                                FindLicensePlate(contours, hierachy, hierachy[idx, 2], gray, canny, licensePlateImagesList,
                                                 filteredLicensePlateImagesList, detectedLicensePlateRegionList, licenses, ocr_mode, threshold_parameter);
                            }
                            continue;
                        }

                        using (UMat tmp1 = new UMat())
                            using (UMat tmp2 = new UMat())
                            {
                                PointF[] srcCorners = box.GetVertices();

                                PointF[] destCorners = new PointF[] {
                                    new PointF(0, box.Size.Height - 1),
                                    new PointF(0, 0),
                                    new PointF(box.Size.Width - 1, 0),
                                    new PointF(box.Size.Width - 1, box.Size.Height - 1)
                                };

                                using (Mat rot = CvInvoke.GetAffineTransform(srcCorners, destCorners))
                                {
                                    //box.Center.X -= 20;
                                    //box.Size.Height += 20;
                                    //box.Size.Width += 20;
                                    //box.Center.Y -= 20;

                                    CvInvoke.WarpAffine(gray, tmp1, rot, Size.Round(box.Size));
                                }
                                SaveImageClass.SaveImage(gray, "gray2.jpg");
                                SaveImageClass.SaveImage(tmp1, "tmp1.jpg");
                                //resize the license plate such that the front is ~ 10-12. This size of front results in better accuracy from tesseract
                                Size   approxSize = new Size(240, 180);
                                double scale      = Math.Min(approxSize.Width / box.Size.Width, approxSize.Height / box.Size.Height);
                                Size   newSize    = new Size((int)Math.Round(box.Size.Width * scale), (int)Math.Round(box.Size.Height * scale));
                                CvInvoke.Resize(tmp1, tmp2, newSize, 0, 0, Inter.Cubic);

                                SaveImageClass.SaveImage(tmp1, "tmp1after.jpg");
                                SaveImageClass.SaveImage(tmp2, "tmp2.jpg");

                                //removes some pixels from the edge
                                int       edgePixelSize = 3;
                                Rectangle newRoi        = new Rectangle(new Point(edgePixelSize, edgePixelSize),
                                                                        tmp2.Size - new Size(2 * edgePixelSize, 2 * edgePixelSize));

                                UMat plate = new UMat(tmp2, newRoi);

                                SaveImageClass.SaveImage(plate, "plate.jpg");
                                UMat filteredPlate = new UMat();

                                filteredPlate = FilterPlate(plate, threshold_parameter);

                                SaveImageClass.SaveImage(filteredPlate, "filtered.jpg");
                                StringBuilder strBuilder = new StringBuilder();
                                switch (ocr_mode)
                                {
                                case 1:
                                {
                                    strBuilder = TesseractOCR.GetText(filteredPlate, _ocr);
                                    break;
                                }

                                case 2:
                                {
                                    strBuilder = GoogleApiOCR.GetText(filteredPlate);
                                    break;
                                }

                                case 3:
                                {
                                    strBuilder = ComputerVisionOCR.GetText(filteredPlate);
                                    break;
                                }

                                default:
                                    break;
                                }
                                if (strBuilder != null)
                                {
                                    licenses.Add(strBuilder.ToString());
                                    licensePlateImagesList.Add(plate);
                                    filteredLicensePlateImagesList.Add(filteredPlate);
                                    detectedLicensePlateRegionList.Add(box);
                                }
                            }
                    }
                }
            }
        }
Exemplo n.º 3
0
        /*
         * /// <summary>
         * /// Compute the white pixel mask for the given image.
         * /// A white pixel is a pixel where:  saturation &lt; 40 AND value &gt; 200
         * /// </summary>
         * /// <param name="image">The color image to find white mask from</param>
         * /// <returns>The white pixel mask</returns>
         * private static Image<Gray, Byte> GetWhitePixelMask(Image<Bgr, byte> image)
         * {
         * using (Image<Hsv, Byte> hsv = image.Convert<Hsv, Byte>())
         * {
         *    Image<Gray, Byte>[] channels = hsv.Split();
         *
         *    try
         *    {
         *       //channels[1] is the mask for satuation less than 40, this is the mask for either white or black pixels
         *       channels[1]._ThresholdBinaryInv(new Gray(40), new Gray(255));
         *
         *       //channels[2] is the mask for bright pixels
         *       channels[2]._ThresholdBinary(new Gray(200), new Gray(255));
         *
         *       CvInvoke.BitwiseAnd(channels[1], channels[2], channels[0], null);
         *    }
         *    finally
         *    {
         *       channels[1].Dispose();
         *       channels[2].Dispose();
         *    }
         *    return channels[0];
         * }
         * }*/

        /// <summary>
        /// Detect license plate from the given image
        /// </summary>
        /// <param name="img">The image to search license plate from</param>
        /// <param name="licensePlateImagesList">A list of images where the detected license plate regions are stored</param>
        /// <param name="filteredLicensePlateImagesList">A list of images where the detected license plate regions (with noise removed) are stored</param>
        /// <param name="detectedLicensePlateRegionList">A list where the regions of license plate (defined by an MCvBox2D) are stored</param>
        /// <param name="ocr_mode">Bool to check the ocr mode </param>
        /// <param name="canny_thres">Canny threshold will take 3 values 20, 30, 40, 50</param>
        /// <returns>The list of words for each license plate</returns>
        /// <returns></returns>
        public List <String> DetectLicensePlate(
            IInputArray img,
            List <IInputOutputArray> licensePlateImagesList,
            List <IInputOutputArray> filteredLicensePlateImagesList,
            List <RotatedRect> detectedLicensePlateRegionList,
            int ocr_mode)
        {
            List <String> licenses = new List <String>();

            using (Mat gray = new Mat())
                using (Mat canny = new Mat())
                    using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
                    {
                        CvInvoke.CvtColor(img, gray, ColorConversion.Bgr2Gray);
                        CvInvoke.Canny(gray, canny, 100, 50, 3, false);
                        int[,] hierachy = CvInvoke.FindContourTree(canny, contours, ChainApproxMethod.ChainApproxSimple);

                        SaveImageClass.SaveImage(gray, "gray.jpg");
                        SaveImageClass.SaveImage(canny, "canny.jpg");
                        for (int i = 0; i <= 5; i++)
                        {
                            switch (i)
                            {
                            case 0:
                            {
                                FindLicensePlate(contours, hierachy, 0, gray, canny, licensePlateImagesList, filteredLicensePlateImagesList, detectedLicensePlateRegionList, licenses, ocr_mode, 80);
                                break;
                            }

                            case 1:
                            {
                                FindLicensePlate(contours, hierachy, 0, gray, canny, licensePlateImagesList, filteredLicensePlateImagesList, detectedLicensePlateRegionList, licenses, ocr_mode, 100);
                                break;
                            }

                            case 2:
                            {
                                FindLicensePlate(contours, hierachy, 0, gray, canny, licensePlateImagesList, filteredLicensePlateImagesList, detectedLicensePlateRegionList, licenses, ocr_mode, 120);
                                break;
                            }

                            case 3:
                            {
                                FindLicensePlate(contours, hierachy, 0, gray, canny, licensePlateImagesList, filteredLicensePlateImagesList, detectedLicensePlateRegionList, licenses, ocr_mode, 130);
                                break;
                            }

                            case 4:
                            {
                                FindLicensePlate(contours, hierachy, 0, gray, canny, licensePlateImagesList, filteredLicensePlateImagesList, detectedLicensePlateRegionList, licenses, ocr_mode, 150);
                                break;
                            }

                            case 5:
                            {
                                FindLicensePlate(contours, hierachy, 0, gray, canny, licensePlateImagesList, filteredLicensePlateImagesList, detectedLicensePlateRegionList, licenses, ocr_mode, 170);
                                break;
                            }

                            default:
                                break;
                            }
                        }
                    }
            return(licenses);
        }