/// <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); }
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); }
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); }