private List<GridQuad> FindBoardQuads(BoardFinder boardLineFinder) { List<GridQuad> quads = new List<GridQuad>(); for (int hi1 = 0; hi1 < boardLineFinder.HorizLines.Length - 1; hi1++) for (int hi2 = hi1 + 1; hi2 < boardLineFinder.HorizLines.Length; hi2++) { var lineH1 = boardLineFinder.HorizLines[hi1]; var lineH2 = boardLineFinder.HorizLines[hi2]; for (int vi1 = 0; vi1 < boardLineFinder.VertLines.Length - 1; vi1++) for (int vi2 = vi1 + 1; vi2 < boardLineFinder.VertLines.Length; vi2++) { var lineV1 = boardLineFinder.VertLines[vi1]; var lineV2 = boardLineFinder.VertLines[vi2]; PointF[] points = FindQuad(lineH1, lineH2, lineV1, lineV2); if (points != null) { quads.Add(new GridQuad(points)); } } } return quads; }
public void FindBoard() { // Convert the image to grayscale and filter out the noise GrayImage = BoardImage.Convert<Gray, Byte>().PyrDown().PyrUp(); // Do canny filter CannyImage = GrayImage.Canny(170.0, 50.0); // Do Edge finder Lines = CannyImage.HoughLinesBinary( 1, //Distance resolution in pixel-related units Math.PI / 360.0, //Angle resolution measured in radians. 50, //threshold 30, //min Line width 20 //gap between lines )[0]; //Get the lines from the first channel // Find board BoardFinder boardLineFinder1 = new BoardFinder(); boardLineFinder1.BuildLineSets(Lines, Lines, Math.PI / 10.0, Math.PI / 40.0); // Make lines image Image<Bgr, Byte> linesImage = BoardImage.CopyBlank(); foreach (LineSegment2D line in Lines) linesImage.Draw(line, new Bgr(System.Drawing.Color.Gray), 1); foreach (LineSegment2D line in boardLineFinder1.HorizLines) linesImage.Draw(line, new Bgr(System.Drawing.Color.Red), 1); foreach (LineSegment2D line in boardLineFinder1.VertLines) linesImage.Draw(line, new Bgr(System.Drawing.Color.Green), 1); LinesImage = linesImage; // Remove perspective from image RemovePerspective(boardLineFinder1.GetBoardRegression()); // Convert the warped image to grayscale and filter out the noise WarpedGrayImage = WarpedImage.Convert<Gray, Byte>().PyrDown().PyrUp(); // Do canny filter on warped image WarpedCannyImage = WarpedGrayImage.Canny(160, 90); // Do Edge finder on warped image WarpedVertLines = WarpedCannyImage.HoughLinesBinary( 1, //Distance resolution in pixel-related units Math.PI / 360, //Angle resolution measured in radians. 30, //threshold 40, //min Line width 20 //gap between lines )[0]; //Get the lines from the first channel WarpedHorizLines = WarpedCannyImage.HoughLinesBinary( 1, //Distance resolution in pixel-related units Math.PI / 360, //Angle resolution measured in radians. 60, //threshold 70, //min Line width 40 //gap between lines )[0]; //Get the lines from the first channel // Find board BoardFinder boardLineFinder2 = new BoardFinder(); boardLineFinder2.BuildLineSets(WarpedVertLines, WarpedHorizLines, Math.PI / 60.0, Math.PI / 60.0); // Make lines image Image<Bgr, Byte> warpedLinesImage = WarpedImage.CopyBlank(); Image<Gray, Byte> warpedGridLinesImage = WarpedGrayImage.CopyBlank(); //foreach (LineSegment2D line in WarpedVertLines.Union(WarpedHorizLines)) // warpedLinesImage.Draw(line, new Bgr(System.Drawing.Color.Gray), 1); foreach (LineSegment2D line in boardLineFinder2.HorizLines) { warpedGridLinesImage.Draw(line, new Gray(100), 1); warpedLinesImage.Draw(line, new Bgr(System.Drawing.Color.Red), 1); } foreach (LineSegment2D line in boardLineFinder2.VertLines) { warpedGridLinesImage.Draw(line, new Gray(100), 1); warpedLinesImage.Draw(line, new Bgr(System.Drawing.Color.Green), 1); } WarpedLinesImage = warpedLinesImage; GridQuadsImage = WarpedImage.Copy(); BoardImageWithBoxes = BoardImage.Copy(); try { // Find grid quads List<GridQuad> quads = FindBoardQuads(boardLineFinder2); GridQuad[] quadsToChase = FilterOutBadQuads(quads); GridQuad[,] quadsToDraw = ChaseThe64Quads(quadsToChase); for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) { if (quadsToDraw[i, j] != null) DrawRectangle(GridQuadsImage, quadsToDraw[i, j].p, new Bgr(120, 190, 20), 2); } DrawRectangle(GridQuadsImage, medianBox.p, new Bgr(220, 250, 20), 2); // Set up return array Quads = new GridQuad[8, 8]; for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) { if (quadsToDraw[i, j] != null) { Quads[i, j] = new GridQuad(quadsToDraw[i, j].p); m_InverseWarpMatrix.ProjectPoints(Quads[i, j].p); DrawRectangle(BoardImageWithBoxes, Quads[i, j].p, new Bgr(120, 190, 20), 2); } } } catch { } }