public void MarkSegmentOnMap(List <DirectionLineSegment>[,] segmentsCount, int width, int height) { double angle = DirectionLine.GetAngleBetweenLines(Line, new DirectionLine(new Vector2d(0, 0), new Vector2d(1, 0))); if (angle > Math.PI / 4.0 && angle < Math.PI * 3.0 / 4.0) { int start = (int)(BeginPoint.Y < EndPoint.Y ? BeginPoint.Y : EndPoint.Y); double end = BeginPoint.Y > EndPoint.Y ? BeginPoint.Y : EndPoint.Y; for (int y = start; y < end; y++) { int x = (int)Line.GetPointByY(y).X; if (x >= 0 && x < width) { segmentsCount[y, x].Add(this); } } } else { int start = (int)(BeginPoint.X < EndPoint.X ? BeginPoint.X : EndPoint.X); double end = BeginPoint.X > EndPoint.X ? BeginPoint.X : EndPoint.X; for (int x = start; x < end; x++) { int y = (int)Line.GetPointByX(x).Y; if (y >= 0 && y < height) { segmentsCount[y, x].Add(this); } } } }
public List <DirectionLine> GetLines(int thresold) { List <DirectionLine> lines = new List <DirectionLine>(); double default1 = 0, default2 = 100; double x1, x2, y1, y2; for (int i = 0; i < numberOfLines; i++) { for (int j = 0; j < numberOfColumns; j++) { if (houghMatrix[i, j] > thresold) { if ((j < 45) || (j > 135 && j < 225)) { y1 = default1; y2 = default2; x1 = (i - y1 * cosValues[j]) / sinValues[j]; x2 = (i - y2 * cosValues[j]) / sinValues[j]; } else { x1 = default1; x2 = default2; y1 = (i - x1 * sinValues[j]) / cosValues[j]; y2 = (i - x2 * sinValues[j]) / cosValues[j]; } DirectionLine line = new DirectionLine(new Vector2d(x1, y1), new Vector2d(x2 - x1, y2 - y1)); lines.Add(line); } } } return(lines); }
public static Wall2D GetWallBetweenTwoSegments(DirectionLineSegment segment1, DirectionLineSegment segment2) { DirectionLine line1Test = new DirectionLine(segment1.BeginPoint, new Vector2d((int)(segment1.EndPoint.X - segment1.BeginPoint.X), (int)(segment1.EndPoint.Y - segment1.BeginPoint.Y))); DirectionLine line2Test = new DirectionLine(segment2.BeginPoint, new Vector2d((int)(segment2.EndPoint.X - segment2.BeginPoint.X), (int)(segment2.EndPoint.Y - segment2.BeginPoint.Y))); List <double> line1Alphas = new List <double>(); line1Alphas.Add(line1Test.AlphaProjection(segment1.BeginPoint)); line1Alphas.Add(line1Test.AlphaProjection(segment1.EndPoint)); line1Alphas.Add(line1Test.AlphaProjection(segment2.BeginPoint)); line1Alphas.Add(line1Test.AlphaProjection(segment2.EndPoint)); if (line1Alphas[0] > line1Alphas[1]) { double aux = line1Alphas[0]; line1Alphas[0] = line1Alphas[1]; line1Alphas[1] = aux; } if (line1Alphas[2] > line1Alphas[1] && line1Alphas[3] > line1Alphas[1] || line1Alphas[2] < line1Alphas[0] && line1Alphas[3] < line1Alphas[0]) { return(null); } line1Alphas.Sort(); Vector2d p1 = line1Test.GetPointByPosition(line1Alphas[0]); Vector2d p2 = line1Test.GetPointByPosition(line1Alphas[3]); Vector2d p3 = line2Test.GetPointProjection(p2); Vector2d p4 = line2Test.GetPointProjection(p1); return(new Wall2D(new Vector2d[] { p1, p2, p3, p4 }, DirectionLine.GetMiddle(line1Test, line2Test))); }
public LineSortHelper(DirectionLine lineSegment) { this.lineSegment = lineSegment; DirectionLine oxLine = new DirectionLine(new Vector2d(0, 0), new Vector2d(1, 0)); OXAngle = (int)(DirectionLine.GetAngleBetweenLines(lineSegment, oxLine) * tolerance / Math.PI); }
public LineSegments(Image <Gray, byte> imageContext, DirectionLine line, double errorMargin, double minSegmentSize) { this.ImageContext = imageContext; this.Line = line; this.ErrorMargin = errorMargin; segmentPoints = CalculateSegmentPoints(); EliminateErrorPoints(); EliminateSmallSegments(minSegmentSize); }
public DirectionLineSegment(DirectionLine line, double startAlpha, double endAlpha) { this.Line = line; this.startAlpha = startAlpha; this.endAlpha = endAlpha; BeginPoint = line.GetPointByPosition(startAlpha); EndPoint = line.GetPointByPosition(endAlpha); this.Size = (BeginPoint - EndPoint).Magnitude; }
public Wall2D(Vector2d[] corners, DirectionLine direction) { this.Corners = corners; this.Direction = direction; v1 = Corners[1] - Corners[0]; v1.X += 0.0001; v1.Y += 0.0001; v2 = Corners[3] - Corners[0]; v2.X += 0.0001; v2.Y += 0.0001; c = Corners[0]; }
private List <double> CalculateSegmentPoints() { List <double> positions = new List <double>(); int width = ImageContext.Width; int height = ImageContext.Height; double angle = DirectionLine.GetAngleBetweenLines(Line, new DirectionLine(new Vector2d(0, 0), new Vector2d(1, 0))); byte colorSearch = 0; if (angle > Math.PI / 4.0 && angle < Math.PI * 3.0 / 4.0) { for (int y = 0; y < height; y++) { int x = (int)Line.GetPointByY(y).X; if (x >= 0 && x < width) { if (ImageContext.Data[y, x, 0] == colorSearch) { positions.Add(Line.GetPositionOfY(y)); colorSearch = (byte)(255 - colorSearch); } } } } else { for (int x = 0; x < width; x++) { int y = (int)Line.GetPointByX(x).Y; if (y >= 0 && y < height) { if (ImageContext.Data[y, x, 0] == colorSearch) { positions.Add(Line.GetPositionOfX(x)); colorSearch = (byte)(255 - colorSearch); } } } } return(positions); }
public static DirectionLine GetMiddle(DirectionLine line1, DirectionLine line2) { return(new DirectionLine((line1.Point + line2.Point) * 0.5, line1.Direction + line2.Direction)); }
public static double GetDistanceBetweenLines(DirectionLine line1, DirectionLine line2) { Vector2d prim = line1.GetPointProjection(line2.Point); return((prim - line2.Point).Magnitude); }
public static double GetAngleBetweenLines(DirectionLine line1, DirectionLine line2) { return(Math.Acos((line1.Direction * line2.Direction) / (line1.Direction.Magnitude * line2.Direction.Magnitude))); }
public static List <Wall2D> GetWalls(Image <Gray, byte> currentImage) { NewProject.ProgressMessage = "Processing house plan"; //currentImage = StandardOperation.Binarize(currentImage, 127); currentImage = StandardOperation.GetImageWithExtraPixels(currentImage, StandardOperation.BinaryColor.Black, 3); NewProject.ProgressValue = 3.35; currentImage = Skeletation.GetProcessedImage(StandardOperation.Binarize(currentImage, 127), 0); NewProject.ProgressValue = 5.51; currentImage = StandardOperation.Binarize(currentImage, 127); StandardOperation.Invert(currentImage); NewProject.ProgressValue = 10.38; NewProject.ProgressMessage = "Detecting lines"; Hough hough = new Hough(currentImage); NewProject.ProgressValue = 64.73; NewProject.ProgressMessage = "Generating walls"; List <DirectionLine> lines = hough.GetLines(15); int width = currentImage.Width; int height = currentImage.Height; List <LineSortHelper> lineSortHelper = new List <LineSortHelper>(); List <DirectionLine> auxLines = new List <DirectionLine>(); List <DirectionLineSegment>[,] segmentCounts = new List <DirectionLineSegment> [height, width]; for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { segmentCounts[i, j] = new List <DirectionLineSegment>(); } } double startValue = 64.73; double step = (99.58 - startValue) / lines.Count; for (int i = 0; i < lines.Count; i++) { NewProject.ProgressValue = startValue + i * step; LineSegments segmentedLine = new LineSegments(currentImage, lines[i], 2, 10); List <DirectionLineSegment> segments = segmentedLine.GetSegments(); for (int j = 0; j < segments.Count; ++j) { segments[j].MarkSegmentOnMap(segmentCounts, width, height); } } NewProject.ProgressValue = 99.58; auxLines = new List <DirectionLine>(); List <DirectionLineSegment> directionSegments = new List <DirectionLineSegment>(); for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { if (currentImage.Data[i, j, 0] == 0) { if (segmentCounts[i, j].Count > 0) { DirectionLineSegment biggestSegment = segmentCounts[i, j][0]; for (int k = 1; k < segmentCounts[i, j].Count; ++k) { if (biggestSegment.Size < segmentCounts[i, j][k].Size) { biggestSegment = segmentCounts[i, j][k]; } } if (!directionSegments.Contains(biggestSegment)) { directionSegments.Add(biggestSegment); } } } } } List <DirectionLine> actualLines = new List <DirectionLine>(); Dictionary <DirectionLine, List <DirectionLineSegment> >[] angleSorted = new Dictionary <DirectionLine, List <DirectionLineSegment> > [tolerance + 1]; for (int i = 0; i <= tolerance; ++i) { angleSorted[i] = new Dictionary <DirectionLine, List <DirectionLineSegment> >(); } //ELIMINATE NON PARALEL LINES for (int i = 0; i < directionSegments.Count; i++) { LineSortHelper lineHelper = new LineSortHelper(directionSegments[i].Line); if (!angleSorted[lineHelper.OXAngle].Keys.Contains(directionSegments[i].Line)) { angleSorted[lineHelper.OXAngle].Add(directionSegments[i].Line, new List <DirectionLineSegment>()); } angleSorted[lineHelper.OXAngle][directionSegments[i].Line].Add(directionSegments[i]); } List <Wall2D> walls = new List <Wall2D>(); for (int i = 0; i <= tolerance; ++i) { if (angleSorted[i].Count > 1) { List <List <DirectionLineSegment> > segmentsGroup = new List <List <DirectionLineSegment> >(); List <DirectionLine> linesGroup = new List <DirectionLine>(); foreach (KeyValuePair <DirectionLine, List <DirectionLineSegment> > pair in angleSorted[i]) { segmentsGroup.Add(pair.Value); linesGroup.Add(pair.Key); } for (int j = 0; j < segmentsGroup.Count - 1; ++j) { for (int k = j + 1; k < segmentsGroup.Count; ++k) { if (DirectionLine.GetDistanceBetweenLines(linesGroup[j], linesGroup[k]) < 15) { foreach (DirectionLineSegment first in segmentsGroup[j]) { foreach (DirectionLineSegment second in segmentsGroup[k]) { Wall2D wall = DirectionLineSegment.GetWallBetweenTwoSegments(first, second); if (wall != null) { walls.Add(wall); } } } } } } } } for (int i = 0; i < walls.Count - 1; ++i) { for (int j = i + 1; j < walls.Count; ++j) { Wall2D newWall = walls[i].Combine(walls[j]); if (newWall != null) { walls[j] = newWall; walls.RemoveAt(i); i--; break; } } } return(walls); }