/// <summary>
        /// Filters unwanted contours by checking their width and height based on defined min/max values.
        /// </summary>
        /// <param name="contours"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <returns>Filtered list of contours and their bounding boxes</returns>
        public (IList <MatOfPoint>, List <Rect>) FilterContoursBySize(IList <MatOfPoint> contours, int min, int max)
        {
            IList <MatOfPoint> filteredContours = new JavaList <MatOfPoint>();
            List <Rect>        boundingBoxes    = new List <Rect>();

            foreach (MatOfPoint contour in contours)
            {
                Rect bounds = Imgproc.BoundingRect(contour);
                if (bounds.Height > min && bounds.Height < max && bounds.Width > 10 && bounds.Width < bounds.Height)
                {
                    boundingBoxes.Add(bounds);
                    filteredContours.Add(contour);
                }
            }
            return(filteredContours, boundingBoxes);
        }
Ejemplo n.º 2
0
        private bool Detect(Mat bin)
        {
            // Reset
            mRects.Clear();

            // Find contours
            Mat hierarchy = new Mat();
            IList <MatOfPoint> contoursList = new JavaList <MatOfPoint>();

            Imgproc.FindContours(bin.Clone(), contoursList, hierarchy, Imgproc.RetrTree, Imgproc.ChainApproxSimple);

            // Filter contours
            bool detected = false;

            for (int iContour = 0; iContour < contoursList.Count(); iContour++)
            {
                // Areas
                Core.Rect rect        = Imgproc.BoundingRect(contoursList[iContour]);
                double    ellipseArea = PI * (rect.Width / 2) * (rect.Height / 2);
                double    area        = Imgproc.ContourArea(contoursList[iContour]);

                // Ratios
                double boundWidthPerHeight = (double)rect.Width / rect.Height;
                double areaPerEllipse      = (double)(area) / ellipseArea;
                double rectPerFrame        = (double)(rect.Area()) / (bin.Size().Width *bin.Size().Height);

                // Check constraints
                if (rectPerFrame > MIN_SIGN_SIZE_PER_FRAME)
                {
                    if (1 - LIMIT_DIF_SIGN_SIZE < boundWidthPerHeight && boundWidthPerHeight < 1 + LIMIT_DIF_SIGN_SIZE)
                    {
                        if (1 - LIMIT_DIF_SIGN_AREA < areaPerEllipse && areaPerEllipse < 1 + LIMIT_DIF_SIGN_AREA)
                        {
                            mRects.Add(rect);
                            detected = true;
                        }
                    }
                }
            }

            return(detected);
        }
Ejemplo n.º 3
0
        public static async Task <string> detectAndExtractText(Bitmap img)
        {
            //Matrix für die Bilder
            Mat large = new Mat();
            Mat small = new Mat();
            Mat rgb   = new Mat();

            //Bild zu Matrix umwandeln
            Utils.BitmapToMat(img, large);

            // downsample and use it for processing
            Imgproc.PyrDown(large, rgb);

            //Grey
            Imgproc.CvtColor(rgb, small, Imgproc.ColorBgr2gray);

            //Gradiant
            Mat  grad        = new Mat();
            Size morphsize   = new Size(3.0, 3.0);
            Mat  morphKernel = Imgproc.GetStructuringElement(Imgproc.MorphEllipse, morphsize);

            Imgproc.MorphologyEx(small, grad, Imgproc.MorphGradient, morphKernel);

            //Binarize
            Mat bw = new Mat();

            Imgproc.Threshold(grad, bw, 0.0, 255.0, Imgproc.ThreshBinary | Imgproc.ThreshOtsu);

            // connect horizontally oriented regions
            Mat  connected   = new Mat();
            Size connectsize = new Size(9.0, 1.0);

            morphKernel = Imgproc.GetStructuringElement(Imgproc.MorphRect, connectsize);
            Imgproc.MorphologyEx(bw, connected, Imgproc.MorphClose, morphKernel);

            // find contours
            Mat mask = Mat.Zeros(bw.Size(), CvType.Cv8uc1);

            JavaList <MatOfPoint> contours = new JavaList <MatOfPoint>();
            Mat hierarchy = new Mat();

            OpenCV.Core.Point contourPoint = new OpenCV.Core.Point(0, 0);

            Imgproc.FindContours(connected, contours, hierarchy, Imgproc.RetrCcomp, Imgproc.ChainApproxSimple, contourPoint);

            Scalar zero        = new Scalar(0, 0, 0);
            Scalar contourscal = new Scalar(255, 255, 255);

            Scalar rectScalar = new Scalar(0, 255, 0);


            OpenCV.Core.Rect rect;
            Mat    maskROI;
            double r;

            double[] contourInfo;

            string resulttext = "";
            string part;

            Bitmap bmpOcr;
            Mat    croppedPart;


            for (int i = 0; i >= 0;)
            {
                rect = Imgproc.BoundingRect(contours[i]);

                maskROI = new Mat(mask, rect);
                maskROI.SetTo(zero);

                //fill the contour
                Imgproc.DrawContours(mask, contours, i, contourscal, Core.Filled);

                // ratio of non-zero pixels in the filled region
                r = (double)Core.CountNonZero(maskROI) / (rect.Width * rect.Height);

                /* assume at least 45% of the area is filled if it contains text */
                /* constraints on region size */

                /* these two conditions alone are not very robust. better to use something
                 * like the number of significant peaks in a horizontal projection as a third condition */
                if (r > .45 && (rect.Height > 8 && rect.Width > 8))
                {
                    //Imgproc.Rectangle(rgb, rect.Br(), rect.Tl(), rectScalar, 2);
                    try
                    {
                        croppedPart = rgb.Submat(rect);

                        bmpOcr = Bitmap.CreateBitmap(croppedPart.Width(), croppedPart.Height(), Bitmap.Config.Argb8888);
                        Utils.MatToBitmap(croppedPart, bmpOcr);

                        part = await OCR.getText(bmpOcr);

                        resulttext = resulttext + part;
                        Console.WriteLine("------------------Durchlauf-------------");
                    }
                    catch (Exception e)
                    {
                        Android.Util.Log.Debug("Fehler", "cropped part data error " + e.Message);
                    }
                }


                //Nächste Element bestimmen
                contourInfo = hierarchy.Get(0, i);
                i           = (int)contourInfo[0];
            }


            return(resulttext);
        }