/* * Forms solid lines from set of raw lines. * Discards lines that have cyclic patterns in them. */ public static List <Line> FilterLines(List <Point> edgePoints, List <RawLine> rawLines, RecognitionOptions options) { List <Line> lines = new List <Line>(); foreach (var rawLine in rawLines) { // convert rawLine to list of black/white pixels bool[] linePoints = new bool[options.imageWidth]; foreach (var pt in edgePoints) { if (Math.Abs(rawLine.yInt - (pt.Y - pt.X * rawLine.k)) < 2) { linePoints[pt.X] = true; } } var segments = SegmentDetector.GetSegments(linePoints, rawLine); if (segments.Count > 0) { Line solidLine = SegmentDetector.GetSolidLine(segments); if (!options.detectCyclicPatterns || !CyclicPatternDetector.HasCyclicPatterns(linePoints, solidLine.p1.X, solidLine.p2.X, options)) { lines.Add(solidLine); } } } return(lines); }
private void RunOCR(Bitmap sourceImage) { this.sourceImagePV.Image = sourceImage; Bitmap bw = ImageUtil.ToBlackAndWhite(sourceImage); this.bwImagePV.Image = bw; Bitmap rotBw = ImageUtil.RotateCounterClockwise(bw); this.rotBwImagePV.Image = rotBw; var horizOptions = RecognitionOptions.HorizontalOptions(); horizOptions.imageWidth = bw.Width; horizOptions.imageHeight = bw.Height; var vertOptions = RecognitionOptions.VerticalOptions(); vertOptions.imageWidth = rotBw.Width; vertOptions.imageHeight = rotBw.Height; List <Point> horizEdgePoints = EdgePointExtraction.ExtractEdgePoints(bw); this.edgePointsPV.Image = EdgePointExtraction.DrawPoints(bw, horizEdgePoints); int[,] horizHough = PseudoHoughTransform.HoughTransform(horizEdgePoints, horizOptions); List <Point> horizHoughPeaks = PseudoHoughTransform.FindHoughPeaks(horizHough, horizOptions); Bitmap horizHoughPlainImage = PseudoHoughTransform.HoughTransformImage(horizHough); Bitmap horizHoughImage = PseudoHoughTransform.HoughTransformImageWithPeaks(horizHough, horizHoughPeaks); List <RawLine> horizRawLines = PseudoHoughTransform.ExtractRawLines(horizHoughPeaks, horizOptions); List <Line> horizLines = LineFilter.FilterLines(horizEdgePoints, horizRawLines, horizOptions); List <Point> vertEdgePoints = EdgePointExtraction.ExtractEdgePoints(rotBw); this.rotEdgePointsPV.Image = EdgePointExtraction.DrawPoints(rotBw, vertEdgePoints); int[,] vertHough = PseudoHoughTransform.HoughTransform(vertEdgePoints, vertOptions); List <Point> vertHoughPeaks = PseudoHoughTransform.FindHoughPeaks(vertHough, vertOptions); Bitmap vertHoughPlainImage = PseudoHoughTransform.HoughTransformImage(vertHough); Bitmap vertHoughImage = PseudoHoughTransform.HoughTransformImageWithPeaks(vertHough, vertHoughPeaks); List <RawLine> vertRawLines = PseudoHoughTransform.ExtractRawLines(vertHoughPeaks, vertOptions); this.cyclicPatternsPV.Image = CyclicPatternDetector.CyclicPatternsInLines(vertEdgePoints, vertRawLines, vertOptions); RecognitionOptions vertNoFilterOptions = vertOptions; vertNoFilterOptions.detectCyclicPatterns = false; List <Line> vertUnfilteredLines = LineFilter.FilterLines(vertEdgePoints, vertRawLines, vertNoFilterOptions); List <Line> vertLines = LineFilter.FilterLines(vertEdgePoints, vertRawLines, vertOptions); Bitmap rawLinesImage = DrawLines(bw, horizLines, vertUnfilteredLines, 2); Bitmap filteredLinesImage = DrawLines(bw, horizLines, vertLines, 4); this.filteredLinesPV.Image = filteredLinesImage; this.houghPV.Image = ImageUtil.VerticalConcat(new List <Bitmap> { ImageUtil.HorizontalConcat(new List <Bitmap> { rawLinesImage, horizHoughImage, horizHoughPlainImage }), ImageUtil.RotateClockwise(vertHoughImage), ImageUtil.RotateClockwise(vertHoughPlainImage) }); var lnorm = new LineNormalization(horizLines, vertLines, sourceImage); Bitmap normalizedLinesImage = DrawLines(bw, lnorm.normHorizLines, lnorm.normVertLines, 2); this.normalizedLinesPV.Image = normalizedLinesImage; var tb = TableBuilder.NewBuilder(lnorm, new None <List <double> >()); Bitmap tableRecognitionImage = tb.DebugImage(bw); this.tableRecognitionPV.Image = tableRecognitionImage; Option <Table> recognizedTable = tb.table; recognizedTable.ForEach(table => { Bitmap recognizedTableImage = new Bitmap(bw); Graphics g = Graphics.FromImage(recognizedTableImage); table.DrawTable(g, new Pen(Color.Red, 2)); g.Dispose(); this.recognizedTablePV.Image = recognizedTableImage; }); if (recognizedTable.IsEmpty()) { Console.WriteLine("no table was recognized"); } this.recognizedTablePV.AddDoubleClickListener((pt, e) => { recognizedTable.ForEach(table => { table.GetCellAtPoint(pt.X, pt.Y).ForEach(cell => { table.GetCellImage(bw, cell.X, cell.Y).ForEach(cellImage => { new GradeRecognitionDebugView(cellImage, "<gen>").ShowDialog(); }); }); }); }); }