GetSkewAngle() public method

Get skew angle of the provided document image.
Unsupported pixel format of the source image.
public GetSkewAngle ( Bitmap image ) : double
image System.Drawing.Bitmap Document's image to get skew angle of.
return double
    protected void fastHarrisRansacBlendStraight(List <Bitmap> imgs)
    {
        List <IntPoint[]> harrisPoints = new List <IntPoint[]>();
        MatrixH           homography;

        //Calculate all the Harris Points
        HarrisCornersDetector harris = new HarrisCornersDetector(0.03f, 10000f);

        for (int i = 0; i < imgs.Count; i++)
        {
            harrisPoints.Add(harris.ProcessImage(imgs[i]).ToArray());
        }

        Bitmap final = imgs[0];

        for (int i = 1; i < imgs.Count; i++)
        {
            //Convert my frames to grayscale so I can find and adjust the normal vectors
            AForge.Imaging.Filters.GrayscaleBT709 grayscale = new AForge.Imaging.Filters.GrayscaleBT709();
            AForge.Imaging.DocumentSkewChecker    skew      = new AForge.Imaging.DocumentSkewChecker();

            double finalAngle = skew.GetSkewAngle(grayscale.Apply(final));
            double imgAngle   = skew.GetSkewAngle(grayscale.Apply(imgs[i]));

            //Less than 5% to account for human error with rotations and wobbles
            if (Math.Abs(finalAngle - imgAngle) < 5)
            {
                AForge.Imaging.Filters.RotateBilinear rotate = new AForge.Imaging.Filters.RotateBilinear(finalAngle - imgAngle);
                rotate.FillColor = Color.FromArgb(0, 255, 255, 255);
                imgs[i]          = rotate.Apply(imgs[i]);

                //Update harris
                harrisPoints[i] = harris.ProcessImage(imgs[i]).ToArray();
            }

            IntPoint[] harrisFinal = harris.ProcessImage(final).ToArray();

            //Correlate the Harris pts between imgs
            CorrelationMatching matcher = new CorrelationMatching(5, final, imgs[i]);
            IntPoint[][]        matches = matcher.Match(harrisFinal, harrisPoints[i]);

            //Create the homography matrix using ransac
            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.025, 0.99);
            homography = ransac.Estimate(matches[0], matches[1]);

            Blend blend = new Blend(homography, final);
            blend.Gradient = true;
            final          = blend.Apply(imgs[i]);
        }

        showImage(final);
    }
    protected void surfRansacBlendStraight(List <Bitmap> imgs)
    {
        MatrixH homography;

        List <SpeededUpRobustFeaturePoint[]> surfPoints = new List <SpeededUpRobustFeaturePoint[]>();
        //Calculate all the Surf Points
        SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector();
        double lastAngle = 0;

        for (int i = 0; i < imgs.Count; i++)
        {
            //Grayscale to find the edges and adjust the normal to point up
            AForge.Imaging.Filters.GrayscaleBT709 grayscale = new AForge.Imaging.Filters.GrayscaleBT709();
            AForge.Imaging.DocumentSkewChecker    skew      = new AForge.Imaging.DocumentSkewChecker();

            double angle = skew.GetSkewAngle(grayscale.Apply(imgs[i]));

            //Less than 5 deg change in angle to account for wobble, ignore big shifts
            if (Math.Abs(angle - lastAngle) < 5)
            {
                AForge.Imaging.Filters.RotateBilinear rotate = new AForge.Imaging.Filters.RotateBilinear(angle);
                rotate.FillColor = Color.FromArgb(0, 255, 255, 255);
                imgs[i]          = rotate.Apply(imgs[i]);
                lastAngle        = angle;
            }
            showImage(imgs[i]);
            surfPoints.Add(surf.ProcessImage(imgs[i]).ToArray());
        }


        Bitmap final = imgs[0];

        for (int i = 1; i < imgs.Count; i++)
        {
            SpeededUpRobustFeaturePoint[] surfFinal = surf.ProcessImage(final).ToArray();

            //Correlate the Harris pts between imgs
            KNearestNeighborMatching matcher = new KNearestNeighborMatching(5);
            matcher.Threshold = 0.05;

            IntPoint[][] matches = matcher.Match(surfFinal, surfPoints[i]);

            //Create the homography matrix using RANSAC
            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.015, 1);
            homography = ransac.Estimate(matches[0], matches[1]);

            Blend blend = new Blend(homography, final);
            blend.Gradient = true;
            final          = blend.Apply(imgs[i]);
        }

        //Smooth/Sharpen if I wanted to
        AForge.Imaging.Filters.Sharpen filter = new AForge.Imaging.Filters.Sharpen();
        //AForge.Imaging.Filters.Gaussian filter = new AForge.Imaging.Filters.Guassian(5);
        //filter.ApplyInPlace(final);

        showImage(final);
    }
Beispiel #3
0
 public BitmapSource Apply(BitmapSource image)
 {
     var filter = new DocumentSkewChecker();
     var bitmap = image.ToBitmap();
     var grayscale = new Grayscale(0.2125, 0.7154, 0.0721).Apply(bitmap);
     var angle = filter.GetSkewAngle(grayscale);
     var rotationFilter = new RotateBilinear(-angle);
     return rotationFilter.Apply(grayscale).ToBitmapImage();
 }
Beispiel #4
0
        private void RotateImage()
        {
            DocumentSkewChecker skewChecker = new DocumentSkewChecker();
            skewChecker.MaxSkewToDetect = 45;
            double angle = skewChecker.GetSkewAngle(_recogimg);

            //Максимальный угол, при котором идет поворот - 45 градусов, после этого изображение не поворачивается
            if (Math.Abs(angle) < 45)
            {
                RotateBilinear rotationFilter = new RotateBilinear(-angle, true);
                rotationFilter.FillColor = Color.Black;
                _recogimg = rotationFilter.Apply(_recogimg);
                _markersimg = rotationFilter.Apply(_markersimg);
            }
        }
Beispiel #5
0
        // 기울어짐 바로잡기
        public static Bitmap skew(Bitmap source)
        {
            // create grayscale filter (BT709)
            Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);       // 8비트 grayscale 로 바꾸고
            // apply the filter
            Bitmap grayImage = filter.Apply(source);

            // create instance of skew checker
            DocumentSkewChecker skewChecker = new DocumentSkewChecker();        // 8비트 grayscale 로 넣어줘야 함
            //    // get documents skew angle
            double angle = skewChecker.GetSkewAngle(grayImage);  // 기울어진 각도를 얻고

            Bitmap tmp = source;
            // convert to 24 bits per pixel
            source = ImageProcess.Clone(tmp, PixelFormat.Format24bppRgb);       // 로테이션 전에 24비트로 바꿔주고
            // delete old image
            tmp.Dispose();

            // create rotation filter
            RotateBilinear rotationFilter = new RotateBilinear(-angle);
            rotationFilter.FillColor = Color.White;
            // rotate image applying the filter
            Bitmap rotatedImage = rotationFilter.Apply(source);  // 원래 이미지를 가져다가 각도만큼 돌리고(원래 이미지는 24비트로 넣어줘야함)

            return rotatedImage;
        }
Beispiel #6
0
        public static System.Drawing.Image AforgeAutoCrop(Bitmap selectedImage,
            DetectBorderParam param)
        {
            // 一些参数的默认值
            if (param.MinObjectWidth == 0)
                param.MinObjectWidth = 500;
            if (param.MinObjectHeight == 0)
                param.MinObjectHeight = 500;

            Bitmap autoCropImage = null;
            try
            {

                autoCropImage = selectedImage;
                // create grayscale filter (BT709)
                Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
                Bitmap grayImage = filter.Apply(autoCropImage);
                // create instance of skew checker
                DocumentSkewChecker skewChecker = new DocumentSkewChecker();
                // get documents skew angle
                double angle = skewChecker.GetSkewAngle(grayImage);
                // create rotation filter
                RotateBilinear rotationFilter = new RotateBilinear(-angle);
                rotationFilter.FillColor = Color.White;
                // rotate image applying the filter
                Bitmap rotatedImage = rotationFilter.Apply(grayImage);
                new ContrastStretch().ApplyInPlace(rotatedImage);
                new Threshold(100).ApplyInPlace(rotatedImage);
                BlobCounter bc = new BlobCounter();
                bc.FilterBlobs = true;
                bc.MinWidth = param.MinObjectWidth; //  500;
                bc.MinHeight = param.MinObjectHeight;   // 500;
                bc.ProcessImage(rotatedImage);
                Rectangle[] rects = bc.GetObjectsRectangles();

                if (rects.Length == 0)
                {
                    System.Windows.Forms.MessageBox.Show("No rectangle found in image ");
                }
                else if (rects.Length == 1)
                {
                    autoCropImage = rotatedImage.Clone(rects[0], rotatedImage.PixelFormat);
                }
                else if (rects.Length > 1)
                {
                    // get largets rect
                    Console.WriteLine("Using largest rectangle found in image ");
                    var r2 = rects.OrderByDescending(r => r.Height * r.Width).ToList();
                    autoCropImage = rotatedImage.Clone(r2[1], rotatedImage.PixelFormat);
                }
                else
                {
                    Console.WriteLine("Huh? on image ");
                }
            }
            catch (Exception ex)
            {
                // MessageBox.Show(ex.Message);
                throw ex;
            }

            return autoCropImage;
        }
Beispiel #7
0
        public static bool GetSkewParam(Bitmap selectedImage,
            DetectBorderParam param,
            out double angle,
            out Rectangle rect)
        {
            // 一些参数的默认值
            if (param.MinObjectWidth == 0)
                param.MinObjectWidth = 500;
            if (param.MinObjectHeight == 0)
                param.MinObjectHeight = 500;

            Bitmap autoCropImage = null;
            try
            {

                autoCropImage = selectedImage;

#if NO
                // create grayscale filter (BT709)
                Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
                Bitmap grayImage = filter.Apply(autoCropImage);
#endif
                Bitmap grayImage = selectedImage.Clone(new Rectangle(0, 0, selectedImage.Width, selectedImage.Height),
                System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                // create instance of skew checker
                DocumentSkewChecker skewChecker = new DocumentSkewChecker();
                // get documents skew angle
                angle = skewChecker.GetSkewAngle(grayImage);
                // create rotation filter
                RotateBilinear rotationFilter = new RotateBilinear(-angle);
                rotationFilter.FillColor = Color.Black; // .White;
                rotationFilter.KeepSize = true;
                // rotate image applying the filter
                Bitmap rotatedImage = rotationFilter.Apply(grayImage);
                new ContrastStretch().ApplyInPlace(rotatedImage);
                new Threshold(100).ApplyInPlace(rotatedImage);
                BlobCounter bc = new BlobCounter();
                bc.FilterBlobs = true;
                bc.MinWidth = param.MinObjectWidth; //  500;
                bc.MinHeight = param.MinObjectHeight;   // 500;
#if NO
                bc.MinWidth = 500;// grayImage.Width / 10;  // 500
                bc.MinHeight = 500;// grayImage.Height / 10; // 500
#endif
                bc.ProcessImage(rotatedImage);

                Rectangle[] rects = bc.GetObjectsRectangles();

                if (rects.Length == 0)
                {
                    // System.Windows.Forms.MessageBox.Show("No rectangle found in image ");
                    rect = new Rectangle(0, 0, 0, 0);
                    return false;
                }
                else if (rects.Length == 1)
                {
                    rect = rects[0];
                    // autoCropImage = rotatedImage.Clone(rects[0], rotatedImage.PixelFormat);
                }
                else if (rects.Length > 1)
                {
                    // TODO: 应该把这些矩形合并在一起
                    Rectangle first = new Rectangle(0, 0, 0, 0);
                    int i = 0;
                    foreach (Rectangle one in rects)
                    {
                        Debug.WriteLine("one=" + one.ToString());
                        if (i == 0)
                            first = one;
                        else
                            first = Merge(first, one);
                        i++;
                    }
                    rect = first;
                    Debug.WriteLine("result=" + rect.ToString());
#if NO

                    // get largets rect
                    Console.WriteLine("Using largest rectangle found in image ");
                    var r2 = rects.OrderByDescending(r => r.Height * r.Width).ToList();
                    rect = r2[1];
                    // autoCropImage = rotatedImage.Clone(r2[1], rotatedImage.PixelFormat);
#endif
                }
                else
                {
                    // Console.WriteLine("Huh? on image ");
                    rect = new Rectangle(0, 0, 0, 0);
                    return false;
                }

#if NO
                Blob[] blobs = bc.GetObjectsInformation();
                foreach (var blob in blobs)
                {
                    List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob);
                    List<IntPoint> cornerPoints;

                    // use the shape checker to extract the corner points
                    if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints))
                    {
                        // only do things if the corners form a rectangle
                        if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle)
                        {
                            // here i use the graphics class to draw an overlay, but you
                            // could also just use the cornerPoints list to calculate your
                            // x, y, width, height values.
                            List<Point> Points = new List<Point>();
                            foreach (var point in cornerPoints)
                            {
                                Points.Add(new Point(point.X, point.Y));
                            }

                            Graphics g = Graphics.FromImage(image);
                            g.DrawPolygon(new Pen(Color.Red, 5.0f), Points.ToArray());

                            image.Save("result.png");
                        }
                    }
                }
#endif

            }
            catch (Exception ex)
            {
                // MessageBox.Show(ex.Message);
                throw ex;
            }
            finally
            {
                if (autoCropImage != null)
                    autoCropImage.Dispose();
            }
            return true;
        }
Beispiel #8
0
        // 기울기 보정
        private void button51_Click(object sender, EventArgs e)
        {
            ///////////// ini 객체 생성 시작 /////////////////////////////////////////////////////
            //현재 프로그램이 실행되고 있는정보 가져오기: 디버깅 모드라면 bin/debug/프로그램명.exe
            FileInfo exefileinfo = new FileInfo(@"C:\Program Files\PLOCR\PLOCR.exe");
            string pathini = exefileinfo.Directory.FullName.ToString();  //프로그램 실행되고 있는데 path 가져오기
            string fileName = @"\PLOCRconfig.ini";  // 환경설정 파일명
            string filePath = pathini + fileName;   //ini 파일 경로
            DocumentAnalysis.IniUtil ini = new DocumentAnalysis.IniUtil(filePath);   // 만들어 놓았던 iniUtil 객체 생성(생성자 인자로 파일경로 정보 넘겨줌)
            //////////// ini 객체 생성 끝 /////////////////////////////////////////////////////////

            Bitmap source = Global.source;

            // create grayscale filter (BT709)
            Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);       // 8비트 grayscale 로 바꾸고
            // apply the filter
            Bitmap grayImage = filter.Apply(source);

            grayImage.Save(@"C:\\Program Files\\PLOCR\\그레이스케일.png");

            // create instance of skew checker
            DocumentSkewChecker skewChecker = new DocumentSkewChecker();        // 8비트 grayscale 로 넣어줘야 함
            //    // get documents skew angle
            double angle = skewChecker.GetSkewAngle(grayImage);  // 기울어진 각도를 얻고

            Bitmap tmp = source;
            // convert to 24 bits per pixel
            source = imageProcess.Clone(tmp, PixelFormat.Format24bppRgb);       // 로테이션 전에 24비트로 바꿔주고
            // delete old image
            tmp.Dispose();

            // create rotation filter
            RotateBilinear rotationFilter = new RotateBilinear(-angle);
            rotationFilter.FillColor = Color.White;
            // rotate image applying the filter
            Bitmap rotatedImage = rotationFilter.Apply(source);  // 원래 이미지를 가져다가 각도만큼 돌리고(원래 이미지는 24비트로 넣어줘야함)

            Global.source = rotatedImage;
            pictureBox1.Image = Global.source;
            pictureBox1.Invalidate();

            ini.SetIniValue("기울어짐 바로잡기", "바로잡기 예/아니오", "예");
        }
Beispiel #9
0
 public static Bitmap Orient_Hough(Bitmap blob)
 {
     GC.Collect();
     Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
     Bitmap documentImage = filter.Apply(blob);
     //Bitmap documentImage =  AForge.Imaging.Image.Clone(blob, PixelFormat.Format16bppGrayScale); //force the jpgs
     // create instance of skew checker
     DocumentSkewChecker skewChecker = new DocumentSkewChecker();
     // get documents skew angle
     double angle = skewChecker.GetSkewAngle(documentImage);
     // rotate image applying the filter
     return RotateImg(blob, (int)-angle, Color.Transparent);
 }
Beispiel #10
0
        // Align scanned document
        private void documentAligningMenuItem_Click( object sender, EventArgs e )
        {
            try
            {
                // get grayscale image from current image
                Bitmap grayImage = ( image.PixelFormat == PixelFormat.Format8bppIndexed ) ?
                    AForge.Imaging.Image.Clone( image ) :
                    AForge.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply( image );
                // threshold it using adaptive Otsu thresholding
                OtsuThreshold threshold = new OtsuThreshold( );
                threshold.ApplyInPlace( grayImage );
                // get skew angle
                DocumentSkewChecker skewChecker = new DocumentSkewChecker( );
                double angle = skewChecker.GetSkewAngle( grayImage );

                if ( ( angle < -skewChecker.MaxSkewToDetect ) ||
                     ( angle > skewChecker.MaxSkewToDetect ) )
                {
                    throw new ApplicationException( );
                }

                // create rotation filter
                RotateBilinear rotationFilter = new RotateBilinear( -angle );
                rotationFilter.FillColor = Color.White;
                // rotate image applying the filter
                ApplyFilter( rotationFilter );
            }
            catch
            {
                MessageBox.Show( "Failed determining skew angle. Is it reallly a scanned document?", "Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
        }