Ejemplo n.º 1
0
        protected virtual void CheckCenterLine(Bitmap image)
        {
            var tmpImage = image.Copy(new Rectangle(0, 0, image.Width, image.Height));

            var tmpImageData = tmpImage.LockBits(new Rectangle(new System.Drawing.Point(0, 0), tmpImage.Size),
                                                 ImageLockMode.ReadWrite,
                                                 tmpImage.PixelFormat);

            Drawing.Line(tmpImageData,
                         new IntPoint(0, 0),
                         new IntPoint(0, tmpImageData.Height),
                         Color.White);

            tmpImage.UnlockBits(tmpImageData);

            OCRLessonReport.Imaging.HoughLineTransformation lineTransform = new OCRLessonReport.Imaging.HoughLineTransformation();

            HoughLineRequestSettings vSettings = new HoughLineRequestSettings
            {
                HorizontalLines = false,
                VerticalLines   = true
            };

            var hWidth  = tmpImage.Width / 2;
            var hHeight = tmpImage.Height / 2;

            lineTransform.ProcessImage(tmpImage, vSettings);

            HoughLine[] vLines = lineTransform.GetLinesByRelativeIntensity(0.9);

            var vLineCoordinates = vLines.Select(line => hWidth + line.Radius).Where(x => x > 1).OrderBy(x => x).ToArray();

            if (vLineCoordinates.Length > 0)
            {
                var x0 = vLineCoordinates.FirstOrDefault() - 1;
                var x1 = vLineCoordinates.LastOrDefault() + 2;

                if (x1 - x0 > 10)
                {
                    return;
                }

                var imageData = image.LockBits(new Rectangle(new System.Drawing.Point(0, 0), image.Size),
                                               ImageLockMode.ReadWrite,
                                               image.PixelFormat);

                Drawing.FillRectangle(imageData, new Rectangle(x0, 0, x1 - x0, image.Height), Color.Black);

                image.UnlockBits(imageData);
            }
        }
Ejemplo n.º 2
0
        protected virtual double DetectRotation(Bitmap image)
        {
            //Hough line transformation
            OCRLessonReport.Imaging.HoughLineTransformation lineTransform = new OCRLessonReport.Imaging.HoughLineTransformation();

            HoughLineRequestSettings settings = new HoughLineRequestSettings
            {
                HorizontalLines   = false,
                VerticalLines     = true,
                VerticalDeviation = Settings.SheetEdgeVerticalMaxAngle
            };

            lineTransform.ProcessImage(image, settings);

            HoughLine[] lines = lineTransform.GetLinesByRelativeIntensity(Settings.SheetEdgeSensitivity);

            if (lines.Length < 1)
            {
                throw new Exception("Can't detect left edge");
            }

            Func <HoughLine, double> getAngle = line =>
            {
                double angle = 0;

                if (line.Theta > 90 && line.Radius > 0)
                {
                    angle = 180 - line.Theta;
                }
                else if (line.Theta > 90 && line.Radius < 0)
                {
                    angle = 180 - line.Theta;
                }
                else if (line.Theta < 90 && line.Radius > 0)
                {
                    angle = -line.Theta;
                }
                else if (line.Theta < 90 && line.Radius < 0)
                {
                    angle = -line.Theta;
                }

                return(angle);
            };

            double avgAngle = lines.Select(l => getAngle(l)).Average();

            return(avgAngle);
        }
Ejemplo n.º 3
0
        protected virtual Bitmap ProcessCell(Bitmap cellImg, bool check = false)
        {
            //Build horizontal hough lines
            OCRLessonReport.Imaging.HoughLineTransformation lineTransform = new OCRLessonReport.Imaging.HoughLineTransformation();

            HoughLineRequestSettings vSettings = new HoughLineRequestSettings
            {
                HorizontalLines = false,
                VerticalLines   = true
            };

            HoughLineRequestSettings hSettings = new HoughLineRequestSettings
            {
                HorizontalLines = true,
                VerticalLines   = false
            };

            lineTransform.ProcessImage(cellImg, vSettings);

            HoughLine[] vLines = lineTransform.GetLinesByRelativeIntensity(Settings.CellSensitivity);

            lineTransform.ProcessImage(cellImg, hSettings);

            HoughLine[] hLines = lineTransform.GetLinesByRelativeIntensity(Settings.CellSensitivity);

            var hWidth  = cellImg.Width / 2;
            var hHeight = cellImg.Height / 2;

            var vLineCoordinates = vLines.Select(line => hWidth + line.Radius);
            var hLineCoordinates = hLines.Select(line => hHeight - line.Radius);

            var xEdges = GetCellEdges(vLineCoordinates, cellImg.Width, Settings.CellXEdgeWith, Settings.CellEdgeCutting);
            var yEdges = GetCellEdges(hLineCoordinates, cellImg.Height, Settings.CellYEdgeWith, Settings.CellEdgeCutting);

            cellImg = cellImg.Copy(new Rectangle(xEdges.Item1, yEdges.Item1, xEdges.Item2 - xEdges.Item1, yEdges.Item2 - yEdges.Item1));

            //Check central line
            if (check)
            {
                CheckCenterLine(cellImg);
            }

            return(cellImg);
        }
Ejemplo n.º 4
0
        public virtual void ProccessImage(BackgroundWorker worker)
        {
            this.worker = worker;

            UpdateProgress(3);

            //Brightness and sharpen filters
            BrightnessCorrection cfilter = new BrightnessCorrection(Settings.Brightness);
            GaussianSharpen      filter  = new GaussianSharpen(4, 11);

            //Apply filters
            cfilter.ApplyInPlace(sourceBitmap);
            UpdateProgress(15);
            filter.ApplyInPlace(sourceBitmap);
            UpdateProgress(30);

            //Convert to gray
            var tmpImage = ConvertToGrayScale(sourceBitmap);

            UpdateProgress(35);

            //Cut edges
            tmpImage = CutEdgesAndInvert(tmpImage);
            UpdateProgress(40);

            //Get angle for rotating image
            var rotateAngle = DetectRotation(tmpImage);

            UpdateProgress(45);

            if (rotateAngle != 0)
            {
                RotateBilinear rotate = new RotateBilinear(rotateAngle, true);
                tmpImage = rotate.Apply(tmpImage);
            }

            //Build horizontal hough lines
            OCRLessonReport.Imaging.HoughLineTransformation lineTransform = new OCRLessonReport.Imaging.HoughLineTransformation();

            HoughLineRequestSettings settings = new HoughLineRequestSettings
            {
                HorizontalLines     = true,
                VerticalLines       = false,
                HorizontalDeviation = 2
            };

            lineTransform.ProcessImage(tmpImage, settings);

            //Get horizontal line
            HoughLine[] lines = lineTransform.GetLinesByRelativeIntensity(Settings.HorizontalSensitivity);

            //Get half width and height for future calculations
            int hWidth  = tmpImage.Width / 2;
            int hHeight = tmpImage.Height / 2;
            //Get line coordinates (Y axis only - horizontal lines)
            var lineCoordinates = lines.Select(line => hHeight - line.Radius);
            //Grouping coords by delta
            var groupedCoordinates = ImagingHelper.GroupingCoordinates(lineCoordinates, Settings.LineGroupingDelta);

            if (groupedCoordinates.Count <= Settings.HeaderStartLine)
            {
                throw new Exception("Invalid source. Can't be recognized");
            }

            int headerLineY0 = groupedCoordinates[Settings.HeaderStartLine];
            int headerLineY1 = groupedCoordinates[Settings.HeaderStartLine + 1];
            //Copy header to new image
            var headerImage = tmpImage.Copy(new Rectangle(0, headerLineY0, tmpImage.Width, headerLineY1 - headerLineY0));
            //Parse header to get header lines
            HoughLineRequestSettings headerSettings = new HoughLineRequestSettings
            {
                HorizontalLines   = false,
                VerticalLines     = true,
                VerticalDeviation = 1
            };

            lineTransform.ProcessImage(headerImage, headerSettings);

            Func <HoughLine, int, int> getRadius = (l, w) =>
            {
                if (l.Theta > 90 && l.Theta < 180)
                {
                    return(w - l.Radius);
                }
                else
                {
                    return(w + l.Radius);
                }
            };

            HoughLine[] headerLines = lineTransform.GetLinesByRelativeIntensity(Settings.VerticalSensitivity);
            //Get header vertical lines
            var headerLineCoordinates = headerLines.Select(line => getRadius(line, hWidth));
            //Grouped lines
            var groupedheaderLineCoordinates = ImagingHelper.GroupingCoordinates(headerLineCoordinates, Settings.LineGroupingDelta);
            //Build cell map
            List <TableCell> cellMap = new List <TableCell>();

            UpdateProgress(50);

            //Use tess engine for ocr
            using (TesseractEngine engine = new TesseractEngine(Settings.TessdataPath, Settings.TessdataLanguage))
            {
                //Parse top header
                var x0 = groupedheaderLineCoordinates.FirstOrDefault();
                var x1 = groupedheaderLineCoordinates.LastOrDefault();
                var y0 = groupedCoordinates[0];
                var y1 = groupedCoordinates[1];

                int fullProgress = (groupedheaderLineCoordinates.Count - 1) * (groupedCoordinates.Count - Settings.BottomStartLine - 1 - Settings.HeaderStartLine);
                int curProgress  = 0;

                var hImage = tmpImage.Copy(new Rectangle(x0, y0, x1 - x0, y1 - y0));
                hImage = ProcessCell(hImage);

                using (var page = engine.Process(hImage, PageSegMode.SingleBlock))
                {
                    cellMap.Add(new TableCell(0, 0, TableCellType.MainHeader, hImage, page.GetText(), false));
                }

                //Parse table
                for (int i = 0; i < groupedheaderLineCoordinates.Count - 1; i++)
                {
                    int subjectArea = (i < Settings.ColumnSubjectStart - 1) ? 0 : 1;

                    for (int j = Settings.HeaderStartLine; j < groupedCoordinates.Count - Settings.BottomStartLine - 1; j++)
                    {
                        int headerArea = (j == Settings.HeaderStartLine) ? 2 : 0;

                        TableCellType cellType = (TableCellType)(subjectArea + headerArea);

                        var cellImg = tmpImage.Copy(new Rectangle(groupedheaderLineCoordinates[i], groupedCoordinates[j],
                                                                  groupedheaderLineCoordinates[i + 1] - groupedheaderLineCoordinates[i],
                                                                  groupedCoordinates[j + 1] - groupedCoordinates[j]));

                        if (cellType == TableCellType.Text || cellType == TableCellType.Header || cellType == TableCellType.HeaderRotated)
                        {
                            cellImg = ProcessCell(cellImg, i == Settings.NameStartLine);

                            string text = String.Empty;

                            if (cellType == TableCellType.HeaderRotated)
                            {
                                cellImg.RotateFlip(RotateFlipType.Rotate90FlipNone);
                            }

                            using (var page = engine.Process(cellImg, PageSegMode.SingleBlock))
                            {
                                text = page.GetText();
                            }


                            cellMap.Add(new TableCell(i, j, cellType, cellImg, text, false));
                        }
                        else
                        {
                            cellImg = ProcessCell(cellImg);

                            BilateralSmoothing bfilter = new BilateralSmoothing();
                            bfilter.KernelSize    = 7;
                            bfilter.SpatialFactor = 10;
                            bfilter.ColorFactor   = 60;
                            bfilter.ColorPower    = 0.5;
                            bfilter.ApplyInPlace(cellImg);

                            cellImg = FilterColors(cellImg, Settings.FilteringColor, ByteColor.Black, ByteColor.White);

                            BlobCounter bcounter = new BlobCounter();
                            bcounter.ProcessImage(cellImg);

                            var blobs = bcounter.GetObjects(cellImg, false);

                            if (blobs.Length < 1)
                            {
                                continue;
                            }

                            var biggestBlob       = blobs.OrderBy(b => b.Area).LastOrDefault();
                            var biggestBlobsImage = biggestBlob.Image.ToManagedImage();

                            cellMap.Add(new TableCell(i, j, cellType, biggestBlobsImage, GetMask(biggestBlobsImage).ToString(), GetMask(biggestBlobsImage)));
                        }

                        curProgress++;
                        double reportProgress = (double)curProgress / (double)fullProgress * 50 + 50;
                        UpdateProgress((int)reportProgress);
                    }
                }
            }

            this.Cells = cellMap;

            UpdateProgress(100);
        }