/// <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);
        }
        /// <summary>
        /// Filters unwanted contours by checking the amount of similar contours on the same horizontal coordinates.
        /// </summary>
        /// <param name="contours"></param>
        /// <param name="bounds"></param>
        /// <returns>List of matching contours and their bounding boxes</returns>
        public (IList <MatOfPoint>, List <Rect>) FilterContoursByYPosition(IList <MatOfPoint> contours, List <Rect> bounds)
        {
            IList <MatOfPoint> alignedContours = new JavaList <MatOfPoint>();
            IList <MatOfPoint> tmpC;
            List <Rect>        alignedBounds = new List <Rect>();
            List <Rect>        tmpB;

            for (int i = 0; i < bounds.Count; i++)
            {
                Rect bound = bounds[i];
                tmpC = new JavaList <MatOfPoint>()
                {
                    contours[i]
                };
                tmpB = new List <Rect>()
                {
                    bound
                };

                for (int j = i + 1; j < bounds.Count; j++)
                {
                    Rect bound2 = bounds[j];
                    if (bound.Y - bound2.Y < 30 && bound2.X > bound.X + bound.Width)
                    {
                        tmpB.Add(bound2);
                        tmpC.Add(contours[j]);
                    }
                }

                if (tmpB.Count > alignedBounds.Count)
                {
                    alignedContours = tmpC;
                    alignedBounds   = tmpB;
                }
            }

            return(alignedContours, alignedBounds);
        }
 public Mat DrawRectangle(Mat mat, Rect rect, Scalar colour)
 {
     Imgproc.Rectangle(mat, new Point(rect.X - 2, rect.Y - 2), new Point(rect.X + rect.Width + 2, rect.Y + rect.Height + 2), new Scalar(0, 255, 0));
     return(mat);
 }