AForge.Imaging.DocumentSkewChecker.GetSkewAngle C# (CSharp) Method

GetSkewAngle() public method

Get skew angle of the provided document image.
Unsupported pixel format of the source image.
public GetSkewAngle ( UnmanagedImage image, Rectangle rect ) : double
image UnmanagedImage Document's unmanaged image to get skew angle of.
rect System.Drawing.Rectangle Image's rectangle to process (used to exclude processing of /// regions, which are not relevant to skew detection).
return double
        public double GetSkewAngle( UnmanagedImage image, Rectangle rect )
        {
            if ( image.PixelFormat != PixelFormat.Format8bppIndexed )
            {
                throw new UnsupportedImageFormatException( "Unsupported pixel format of the source image." );
            }

            // init hough transformation settings
            InitHoughMap( );

            // get source image size
            int width       = image.Width;
            int height      = image.Height;
            int halfWidth   = width / 2;
            int halfHeight  = height / 2;

            // make sure the specified rectangle recides with the source image
            rect.Intersect( new Rectangle( 0, 0, width, height ) );

            int startX = -halfWidth  + rect.Left;
            int startY = -halfHeight + rect.Top;
            int stopX  = width  - halfWidth  - ( width  - rect.Right );
            int stopY  = height - halfHeight - ( height - rect.Bottom ) - 1;

            int offset = image.Stride - rect.Width;

            // calculate Hough map's width
            int halfHoughWidth = (int) Math.Sqrt( halfWidth * halfWidth + halfHeight * halfHeight );
            int houghWidth = halfHoughWidth * 2;

            houghMap = new short[houghHeight, houghWidth];

            // do the job
            unsafe
            {
                byte* src = (byte*) image.ImageData.ToPointer( ) +
                    rect.Top * image.Stride + rect.Left;
                byte* srcBelow = src + image.Stride;

                // for each row
                for ( int y = startY; y < stopY; y++ )
                {
                    // for each pixel
                    for ( int x = startX; x < stopX; x++, src++, srcBelow++ )
                    {
                        // if current pixel is more black
                        // and pixel below is more white
                        if ( ( *src < 128 ) && ( *srcBelow >= 128 ) )
                        {
                            // for each Theta value
                            for ( int theta = 0; theta < houghHeight; theta++ )
                            {
                                int radius = (int) ( cosMap[theta] * x - sinMap[theta] * y ) + halfHoughWidth;

                                if ( ( radius < 0 ) || ( radius >= houghWidth ) )
                                    continue;

                                houghMap[theta, radius]++;
                            }
                        }
                    }
                    src += offset;
                    srcBelow += offset;
                }
            }

            // find max value in Hough map
            maxMapIntensity = 0;
            for ( int i = 0; i < houghHeight; i++ )
            {
                for ( int j = 0; j < houghWidth; j++ )
                {
                    if ( houghMap[i, j] > maxMapIntensity )
                    {
                        maxMapIntensity = houghMap[i, j];
                    }
                }
            }

            CollectLines( (short) ( width / 10 ) );

            // get skew angle
            HoughLine[] hls = this.GetMostIntensiveLines( 5 );

            double skewAngle = 0;
            double sumIntensity = 0;

            foreach ( HoughLine hl in hls )
            {
                if ( hl.RelativeIntensity > 0.5 )
                {
                    skewAngle += ( hl.Theta * hl.RelativeIntensity );
                    sumIntensity += hl.RelativeIntensity;
                }
            }
            if ( hls.Length > 0 ) skewAngle = skewAngle / sumIntensity;

            return skewAngle - 90.0;
        }

Same methods

DocumentSkewChecker::GetSkewAngle ( Bitmap image ) : double
DocumentSkewChecker::GetSkewAngle ( Bitmap image, Rectangle rect ) : double
DocumentSkewChecker::GetSkewAngle ( BitmapData imageData ) : double
DocumentSkewChecker::GetSkewAngle ( BitmapData imageData, Rectangle rect ) : double
DocumentSkewChecker::GetSkewAngle ( UnmanagedImage image ) : double

Usage Example

    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);
    }
All Usage Examples Of AForge.Imaging.DocumentSkewChecker::GetSkewAngle