/// <summary> /// Function takes in a grayscale image and a colour image. Rectangles are located /// in the grayscale image (this is usually a thresholded image - so shapes are /// strongly visible) and borders around them are drawn on the same coordinates in /// the colour image. /// </summary> /// <param name="img">Grayscale image where rectangles would be located</param> /// <param name="original">Original (colour) image where the rectangle borders will be drawn</param> private void drawBoxes(Emgu.CV.Image<Gray, Byte> img, Emgu.CV.Image<Bgr, Byte> original) { Gray cannyThreshold = new Gray(180); Gray cannyThresholdLinking = new Gray(120); Gray circleAccumulatorThreshold = new Gray(120); Image<Gray, Byte> cannyEdges = img.Canny(cannyThreshold, cannyThresholdLinking); LineSegment2D[] lines = cannyEdges.HoughLinesBinary( 1, //Distance resolution in pixel-related units Math.PI / 45.0, //Angle resolution measured in radians. 20, //threshold 30, //min Line width 10 //gap between lines )[0]; //Get the lines from the first channel #region Find rectangles List<MCvBox2D> boxList = new List<MCvBox2D>(); using (MemStorage storage = new MemStorage()) //allocate storage for contour approximation for (Contour<Point> contours = cannyEdges.FindContours(); contours != null; contours = contours.HNext) { Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage); if (contours.Area > 250) //only consider contours with area greater than 250 { if (currentContour.Total == 4) //The contour has 4 vertices. { #region determine if all the angles in the contour are within the range of [80, 100] degree bool isRectangle = true; Point[] pts = currentContour.ToArray(); LineSegment2D[] edges = PointCollection.PolyLine(pts, true); for (int i = 0; i < edges.Length; i++) { double angle = Math.Abs( edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i])); if (angle < 80 || angle > 100) { isRectangle = false; break; } } #endregion if (isRectangle) boxList.Add(currentContour.GetMinAreaRect()); } } } #endregion #region draw rectangles Image<Bgr, Byte> rectangleImage = new Image<Bgr, byte>(img.Width, img.Height); foreach (MCvBox2D box in boxList) { rectangleImage.Draw(box, new Bgr(Color.DarkOrange), 2); original.Draw(box, new Bgr(Color.DarkOrange), 2); } capturedImageBox.Image = rectangleImage; #endregion }