Rotate image using bilinear interpolation.

The class implements image rotation filter using bilinear interpolation algorithm.

The filter accepts 8 bpp grayscale images and 24 bpp color images for processing.

Sample usage:

// create filter - rotate for 30 degrees keeping original image size RotateBilinear filter = new RotateBilinear( 30, true ); // apply the filter Bitmap newImage = filter.Apply( image );

Initial image:

Result image:

Inheritance: BaseRotateFilter
Exemplo n.º 1
1
        public static Bitmap Apply(Bitmap selectedImage,
            double angle,
            Rectangle rect)
        {
            System.Drawing.Imaging.PixelFormat old_format = selectedImage.PixelFormat;

            RotateBilinear rotationFilter = new RotateBilinear(-angle);
            rotationFilter.FillColor = Color.White;
            rotationFilter.KeepSize = true;
            // 格式必须为其中之一: rotationFilter.FormatTranslations;
            // rotate image applying the filter
            Bitmap temp = selectedImage.Clone(new Rectangle(0, 0, selectedImage.Width, selectedImage.Height),
                System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            Bitmap rotatedImage = rotationFilter.Apply(temp);
#if NO
            return rotatedImage.Clone(rect,
                old_format
                // rotatedImage.PixelFormat
                );
#endif
            return rotatedImage;
        }
Exemplo n.º 2
0
    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);
    }
Exemplo n.º 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();
 }
Exemplo n.º 4
0
    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);
    }
Exemplo n.º 5
0
        public IEnumerable<Bitmap> Apply(Bitmap bitmap)
        {
            // assuming scanned background is white we need to invert for the algo to work
            var copy = new Invert().Apply(bitmap);

            copy = EnsureGrayscale(copy);
            new Threshold { ThresholdValue = 25 }.ApplyInPlace(copy);
            new FillHoles().ApplyInPlace(copy);

            var blobCounter = new BlobCounter
            {
                // set filtering options
                FilterBlobs = true,
                MinWidth = 50,
                MinHeight = 50,
            };

            blobCounter.ProcessImage(copy);
            var blobs = blobCounter.GetObjectsInformation();

            if (blobs.Any())
            {
                var invertedOriginal = new Invert().Apply(bitmap);
                foreach (var blob in blobs)
                {
                    // use inverted source to ensure correct edge colors
                    blobCounter.ExtractBlobsImage(invertedOriginal, blob, false);
                    var blobImage = blob.Image.ToManagedImage();

                    // straighten
                    var angle = new DocumentSkewChecker().GetSkewAngle(EnsureGrayscale(blobImage));
                    var rotationFilter = new RotateBilinear(-angle) { FillColor = Color.Black };
                    blobImage = rotationFilter.Apply(blobImage);

                    // crop
                    blobImage = new ExtractBiggestBlob().Apply(blobImage);

                    new Invert().ApplyInPlace(blobImage);
                    yield return blobImage;
                }
            }
            else
            {
                yield return bitmap;
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Detect hand on a given frame
        /// </summary>
        /// <param name="image">Image to detect the hand palm within</param>
        /// <param name="cycles">Number of snapshot cycles to check against</param>
        /// <param name="similarityRate">The threshold percent of pixels that have to match for a positive result</param>
        /// <param name="trainingPic">A reference to secondary frame field. Temporary.</param>
        /// <returns>IntPoint point at the centre of detected hand palm</returns>
        public IntPoint DetectHand(Bitmap image, int cycles, int similarityRate, PictureBox trainingPic)
        {
            IntPoint dimensions = new IntPoint(image.Width, image.Height);
            BlobCounterBase bc = new BlobCounter();
            Crop cropFilter;

            bc.FilterBlobs = true;
            bc.MinWidth = (int)(avgSize.x * 0.6);
            bc.MinHeight = (int)(avgSize.y * 0.6);
            bc.ObjectsOrder = ObjectsOrder.Size;
            bc.ProcessImage(image);
            Blob[] blobs = bc.GetObjectsInformation();

            int blobWidth = 0;
            int blobHeight = 0;
            float blobAspectRatio;
            double angle;
            RotateBilinear rotate;
            ResizeBilinear resize = new ResizeBilinear((int)avgSize.x, (int)avgSize.y);
            Bitmap bmp;
            List<IntPoint> edges = new List<IntPoint>();

            for (int b = 0; b < blobs.Length; b++)
            {
                Rectangle br = blobs[b].Rectangle;
                cropFilter = new Crop(br);
                image = cropFilter.Apply(image);
                bmp = AForge.Imaging.Image.Clone(image);
                //bc.ExtractBlobsImage(image, blobs[b], false);
                //bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
                edges = bc.GetBlobsEdgePoints(blobs[b]);
                IntPoint circleCenter = FindLargestCircleCenter(edges, blobs[b].Rectangle);
                //bmp = ImageFilters.Draw(bmp, edges);

                //Highlight circle center
                //Graphics gfx = Graphics.FromImage(bmp);
                //gfx.DrawRectangle(new Pen(Color.Red, 3), circleCenter.X - 10, circleCenter.Y - 10, 20, 20);

                blobWidth = blobs[b].Rectangle.Width;
                blobHeight = blobs[b].Rectangle.Height;
                blobAspectRatio = (float)blobWidth / blobHeight;
                if((blobAspectRatio) > avgAspectRatio + 0.08)
                {
                    float test3 = avgSize.y / avgSize.x;
                    if ((blobAspectRatio - avgAspectRatio) <= 1)
                    {
                        angle = ((blobAspectRatio - avgAspectRatio) / (test3 - avgAspectRatio)) * 90 + (1 - (blobAspectRatio - avgAspectRatio)) * 30;
                    }
                    else
                    {
                        angle = ((blobAspectRatio - avgAspectRatio) / (test3 - avgAspectRatio)) * 90;
                    }
                    rotate = new RotateBilinear(angle, false);
                    image = rotate.Apply(image);
                    //bmp = rotate.Apply(bmp);
                }
                image = resize.Apply(image);
                //bmp = resize.Apply(bmp);

                //image = cropFilter.Apply(image);
                //image = maxBlobFilter.Apply(image);
                int scannedPixels = 0;
                int matches = 0;
                float test = 0;
                float threshold = (float)similarityRate / 100;
                int imgHeight, imgWidth;
                
                for (int i = 0; i < cycles; i++)
                {
                    for (int smpl = 0; smpl < 10; smpl++)
                    {
                        if (image.Size.Width < samples[i, smpl].Size.Width)
                            imgWidth = image.Size.Width;
                        else
                            imgWidth = samples[i, smpl].Size.Width;
                        if (image.Size.Height < samples[i, smpl].Size.Height)
                            imgHeight = image.Size.Height;
                        else
                            imgHeight = samples[i, smpl].Size.Height;
                        for (int y = 0; y < imgHeight; y += 3)
                            for (int x = 0; x < imgWidth; x += 3)
                            {
                                scannedPixels++;
                                lock (samples[i, smpl])
                                {
                                    lock (image)
                                    {
                                        if (image.GetPixel(x, y).Equals(samples[i, smpl].GetPixel(x, y)))
                                        {
                                            matches++;
                                        }
                                    }
                                }
                            }
                        test = (float)matches / (float)scannedPixels;
                        if (test >= threshold)
                        {
                            //bc.ExtractBlobsImage(image, blobs[b], false);
                            //bmp.Save("detect" + detectedNum + "o.bmp");
                            //image.Save("detect" + detectedNum + "r.bmp");
                            detectedNum++;
                            return new IntPoint(dimensions.X - circleCenter.X, circleCenter.Y);

                            //return new IntPoint(image.Width - (int)blobs[b].CenterOfGravity.X, (int)blobs[b].CenterOfGravity.Y);
                        }
                        matches = 0;
                        scannedPixels = 0;
                    }
                }
            }
            return new IntPoint();
        }
Exemplo n.º 7
0
 public static Bitmap RotateBilinear(Bitmap bmp, int degree)
 {
     // create filter - rotate for 30 degrees keeping original image size
     RotateBilinear filter = new RotateBilinear(degree, true);
     // apply the filter
     Bitmap newImage = filter.Apply(bmp);
     return newImage;
 }
Exemplo n.º 8
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;
        }
Exemplo n.º 9
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;
        }
Exemplo n.º 10
0
        private void RotateImageButtonPress(object sender, EventArgs e)
        {
            int angle = 0;

            if(!int.TryParse(angleForRotationTextBox.Text, out angle)) {
                MessageBox.Show("Check input data and try again  !");
                return;
            }

            image.RotateAngle = angle % 360;

            RotateBilinear filter = new RotateBilinear(image.RotateAngle, true);
            Bitmap newImage = filter.Apply(image.SourceImage);

            ClearCurrentImage();
            pictureBox1.Image = newImage;
        }
 //private void RotateImage(Bitmap srcimg, int angle)
 //{
 //    if (srcimg == null)
 //        throw new ArgumentNullException("image");
 //    if (!_rotatedimg_table.ContainsKey(angle))
 //    {
 //        const double pi2 = Math.PI / 2.0;
 //        // Why can't C# allow these to be const, or at least readonly
 //        // *sigh*  I'm starting to talk like Christian Graus :omg:
 //        double oldWidth = _width;
 //        double oldHeight = _height;
 //        // Convert degrees to radians
 //        double theta = ((double)angle) * Math.PI / 180.0;
 //        double locked_theta = theta;
 //        // Ensure theta is now [0, 2pi)
 //        while (locked_theta < 0.0)
 //            locked_theta += 2 * Math.PI;
 //        double newWidth, newHeight;
 //        int nWidth, nHeight; // The newWidth/newHeight expressed as ints
 //        #region Explaination of the calculations
 //        #endregion
 //        double adjacentTop, oppositeTop;
 //        double adjacentBottom, oppositeBottom;
 //        // We need to calculate the sides of the triangles based
 //        // on how much rotation is being done to the bitmap.
 //        //   Refer to the first paragraph in the explaination above for
 //        //   reasons why.
 //        if ((locked_theta >= 0.0 && locked_theta < pi2) ||
 //            (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2)))
 //        {
 //            adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
 //            oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth;
 //            adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight;
 //            oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
 //        }
 //        else
 //        {
 //            adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
 //            oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight;
 //            adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth;
 //            oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
 //        }
 //        newWidth = adjacentTop + oppositeBottom;
 //        newHeight = adjacentBottom + oppositeTop;
 //        nWidth = (int)Math.Ceiling(newWidth);
 //        nHeight = (int)Math.Ceiling(newHeight);
 //        Bitmap rotatedBmp = new Bitmap(nWidth, nHeight);
 //        using (Graphics g = Graphics.FromImage(rotatedBmp))
 //        {
 //            g.Clear(Color.White);
 //            // This array will be used to pass in the three points that
 //            // make up the rotated srcimg
 //            Point[] points;
 //            if (locked_theta >= 0.0 && locked_theta < pi2)
 //            {
 //                points = new Point[] {
 //                                     new Point( (int) oppositeBottom, 0 ),
 //                                     new Point( nWidth, (int) oppositeTop ),
 //                                     new Point( 0, (int) adjacentBottom )
 //                                 };
 //            }
 //            else if (locked_theta >= pi2 && locked_theta < Math.PI)
 //            {
 //                points = new Point[] {
 //                                     new Point( nWidth, (int) oppositeTop ),
 //                                     new Point( (int) adjacentTop, nHeight ),
 //                                     new Point( (int) oppositeBottom, 0 )
 //                                 };
 //            }
 //            else if (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2))
 //            {
 //                points = new Point[] {
 //                                     new Point( (int) adjacentTop, nHeight ),
 //                                     new Point( 0, (int) adjacentBottom ),
 //                                     new Point( nWidth, (int) oppositeTop )
 //                                 };
 //            }
 //            else
 //            {
 //                points = new Point[] {
 //                                     new Point( 0, (int) adjacentBottom ),
 //                                     new Point( (int) oppositeBottom, 0 ),
 //                                     new Point( (int) adjacentTop, nHeight )
 //                                 };
 //            }
 //            g.DrawImage(srcimg, points);
 //            g.Dispose();
 //        }
 //        //Console.WriteLine((int)angle);
 //        _rotatedimg_table.Add(angle, rotatedBmp);
 //        Rectangle bbx = BBX(rotatedBmp);
 //        if (_max_width < bbx.Width)
 //        {
 //            _max_width = bbx.Width;
 //            _max_width_idx = angle;
 //        }
 //    }
 //}
 //private void RotateImage(string path, int angle)
 //{
 //    Bitmap srcimg = new Bitmap(path);
 //    if (srcimg == null)
 //        throw new ArgumentNullException("image");
 //    if (!_rotatedimg_table.ContainsKey(angle))
 //    {
 //        const double pi2 = Math.PI / 2.0;
 //        // Why can't C# allow these to be const, or at least readonly
 //        // *sigh*  I'm starting to talk like Christian Graus :omg:
 //        double oldWidth = _width;
 //        double oldHeight = _height;
 //        // Convert degrees to radians
 //        double theta = ((double)angle) * Math.PI / 180.0;
 //        double locked_theta = theta;
 //        // Ensure theta is now [0, 2pi)
 //        while (locked_theta < 0.0)
 //            locked_theta += 2 * Math.PI;
 //        double newWidth, newHeight;
 //        int nWidth, nHeight; // The newWidth/newHeight expressed as ints
 //        #region Explaination of the calculations
 //        #endregion
 //        double adjacentTop, oppositeTop;
 //        double adjacentBottom, oppositeBottom;
 //        // We need to calculate the sides of the triangles based
 //        // on how much rotation is being done to the bitmap.
 //        //   Refer to the first paragraph in the explaination above for
 //        //   reasons why.
 //        if ((locked_theta >= 0.0 && locked_theta < pi2) ||
 //            (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2)))
 //        {
 //            adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
 //            oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth;
 //            adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight;
 //            oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
 //        }
 //        else
 //        {
 //            adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight;
 //            oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight;
 //            adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth;
 //            oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth;
 //        }
 //        newWidth = adjacentTop + oppositeBottom;
 //        newHeight = adjacentBottom + oppositeTop;
 //        nWidth = (int)Math.Ceiling(newWidth);
 //        nHeight = (int)Math.Ceiling(newHeight);
 //        Bitmap rotatedBmp = new Bitmap(nWidth, nHeight);
 //        using (Graphics g = Graphics.FromImage(rotatedBmp))
 //        {
 //            g.Clear(Color.White);
 //            // This array will be used to pass in the three points that
 //            // make up the rotated srcimg
 //            Point[] points;
 //            if (locked_theta >= 0.0 && locked_theta < pi2)
 //            {
 //                points = new Point[] {
 //                                     new Point( (int) oppositeBottom, 0 ),
 //                                     new Point( nWidth, (int) oppositeTop ),
 //                                     new Point( 0, (int) adjacentBottom )
 //                                 };
 //            }
 //            else if (locked_theta >= pi2 && locked_theta < Math.PI)
 //            {
 //                points = new Point[] {
 //                                     new Point( nWidth, (int) oppositeTop ),
 //                                     new Point( (int) adjacentTop, nHeight ),
 //                                     new Point( (int) oppositeBottom, 0 )
 //                                 };
 //            }
 //            else if (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2))
 //            {
 //                points = new Point[] {
 //                                     new Point( (int) adjacentTop, nHeight ),
 //                                     new Point( 0, (int) adjacentBottom ),
 //                                     new Point( nWidth, (int) oppositeTop )
 //                                 };
 //            }
 //            else
 //            {
 //                points = new Point[] {
 //                                     new Point( 0, (int) adjacentBottom ),
 //                                     new Point( (int) oppositeBottom, 0 ),
 //                                     new Point( (int) adjacentTop, nHeight )
 //                                 };
 //            }
 //            g.DrawImage(srcimg, points);
 //            g.Dispose();
 //        }
 //        //Console.WriteLine((int)angle);
 //        _rotatedimg_table.Add(angle, rotatedBmp);
 //        Rectangle bbx = BBX(rotatedBmp);
 //        if (_max_width < bbx.Width)
 //        {
 //            _max_width = bbx.Width;
 //            _max_width_idx = angle;
 //        }
 //    }
 //}
 private void RotateImage(Bitmap srcimg, int angle)
 {
     if (!_rotatedimg_table.ContainsKey(angle))
     {
         RotateBilinear filter = new RotateBilinear(angle);
         Bitmap rotateimg = ImageUtils.InvertColors(filter.Apply(ImageUtils.InvertColors(srcimg)));
         _rotatedimg_table.Add(angle, rotateimg);
     }
 }
        public void Apply(string input_dir, string output_dir, string fn, int char_size, double size_ratio, bool preprocessing, int tnum, string lang)
        {
            MergeTextStrings mts = new MergeTextStrings();

            ImageSlicer imgslicer = new ImageSlicer();
            List<TextString> text_string_list = new List<TextString>();
            List<string> imgpath_list = imgslicer.Apply(1, 1, 100, input_dir + fn, output_dir);

            Log.WriteLine("Grouping text strings...");
            for (int s = 0; s < imgpath_list.Count; s++)
            {
                Bitmap srcimg = null;

                if (lang == "eng")
                {
                    using (Bitmap tileimg = new Bitmap(imgpath_list[s]))
                    {
                        RemoveBoarderAndNoiseCC removeBoarderAndNoiseCC = new RemoveBoarderAndNoiseCC();
                        srcimg = removeBoarderAndNoiseCC.Apply(tileimg, char_size, 0.18);
                        Log.WriteBitmap2FolderExactFileName(output_dir, srcimg, "CDAInput.png");
                    }
                }
                else
                {
                    using (Bitmap tileimg = new Bitmap(imgpath_list[s]))
                    {
                        RemoveBoarderCC removeBoarderCC = new RemoveBoarderCC();
                        srcimg = removeBoarderCC.Apply(tileimg);
                        Log.WriteBitmap2FolderExactFileName(output_dir, srcimg, "CDAInput.png");
                    }
                }
                ConditionalDilationAutomatic cda = new ConditionalDilationAutomatic();
                cda.ang_threshold = angle_ratio;
                string outputImagePath = output_dir + s + ".png";
                cda.Apply(tnum, srcimg, size_ratio, angle_ratio, preprocessing, outputImagePath);

                using (Bitmap dilatedimg = new Bitmap(outputImagePath))
                {
                    DetectTextStrings detectTS = new DetectTextStrings();
                    List<TextString> string_list = detectTS.Apply(srcimg, dilatedimg);
                    List<Bitmap> string_img_list = new List<Bitmap>();
                    for (int i = 0; i < string_list.Count; i++)
                        string_img_list.Add(string_list[i].srcimg);

                    int[] offset = imgslicer.xy_offset_list[s];

                    for (int i = 0; i < string_list.Count; i++)
                    {
                        string_list[i].x_offset = offset[0];
                        string_list[i].y_offset = offset[1];
                        mts.AddTextString(string_list[i]);
                    }
                }
                using (Bitmap CDAInputwithLabel=new Bitmap (outputImagePath))
                {
                    Graphics g = Graphics.FromImage(CDAInputwithLabel);
                    for (int i = 0; i < mts.text_string_list.Count; i++)
                    {
                        Font font = new Font("Arial", 20);
                        g.DrawString(i.ToString(), font, Brushes.Red, mts.text_string_list[i].bbx.X, mts.text_string_list[i].bbx.Y);

                        g.DrawRectangle(new Pen(Color.Green, 4), mts.text_string_list[i].bbx);

                    }
                    Log.WriteBitmap2FolderExactFileName(output_dir, CDAInputwithLabel, "CDAInputwithLabel.png");
                    g.Dispose();
                    g=null;
                }
                srcimg.Dispose();
                srcimg = null;
            }

            Log.WriteLine("Detecting long string orientation...");
            DetectTextOrientation detectTextOrientation = new DetectTextOrientation();
            detectTextOrientation.Apply(mts, tnum);

            Log.WriteLine("Detecting short string orientation...");
            for (int i = 0; i < mts.text_string_list.Count; i++)
            {
                if (mts.text_string_list[i].char_list.Count <= 3)
                {
                    List<int> nearest_string_list = detectTextOrientation.findNearestSrings(i, mts.text_string_list);
                    int initial_orientation_count = mts.text_string_list[i].orientation_list.Count;
                    for (int j = 0; j < nearest_string_list.Count; j++)
                        mts.text_string_list[i].orientation_list.AddRange(mts.text_string_list[nearest_string_list[j]].orientation_list);
                    for (int j = initial_orientation_count; j < mts.text_string_list[i].orientation_list.Count; j++)
                    {
                        RotateBilinear filter = new RotateBilinear(mts.text_string_list[i].orientation_list[j]);
                        Bitmap rotateimg = ImageUtils.InvertColors(filter.Apply(ImageUtils.InvertColors(mts.text_string_list[i].srcimg)));
                        mts.text_string_list[i].rotated_img_list.Add(rotateimg);
                    }
                }
            }

            Log.WriteLine("Writing string results...");
            mts.WriteBMP(output_dir);
        }
Exemplo n.º 13
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("기울어짐 바로잡기", "바로잡기 예/아니오", "예");
        }
Exemplo n.º 14
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 );
            }
        }
Exemplo n.º 15
0
        private void CheckUp()
        {
            List<double> disttohight = new List<double>();
            AForge.Point hightpoint = new AForge.Point((float)_markersimg.Width / 2.0f, 0);

            for (int iteration = 0; iteration < 4; iteration++)
            {
                FindCenterMarker();
               // RotateBicubic rbf = new RotateBicubic(-90);
                RotateBilinear rbf = new RotateBilinear(-90);
                _markersimg = rbf.Apply(_markersimg);
                disttohight.Add(Geometry.EuclidianDistance(_tcmarker.Blob.CenterOfGravity, hightpoint));
            }

            double mindist = disttohight.Min();
            double angle = disttohight.IndexOf(mindist) * -90;
            RotateBilinear _recogimgrotator = new RotateBilinear(angle);
            _recogimg = _recogimgrotator.Apply(_recogimg);
            _markersimg = _recogimgrotator.Apply(_markersimg);
        }
Exemplo n.º 16
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;
        }
Exemplo n.º 17
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);
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Crop the blob from the image
        /// </summary>
        private Bitmap CropBlob(BlobPanel blob, System.Drawing.Image source, int rotationAngel = 0)
        {
            // Create the target image, this is a squared image.
            int size = Math.Max(blob.Height, blob.Width);
            Bitmap newImage = new Bitmap(size, size, PixelFormat.Format24bppRgb);

            // Get the graphics object of the image.
            Graphics g = Graphics.FromImage(newImage);

            // Create the background color to use (the image we create is larger than the blob (as we squared it)
            // so this would be the color of the excess areas.
            Color bColor = Color.FromArgb((int)txtExtractedBackColor.Value, (int)txtExtractedBackColor.Value, (int)txtExtractedBackColor.Value);

            // Fill back color.
            g.FillRectangle(new SolidBrush(bColor), 0, 0, size, size);

            // Now we clip the blob from the PictureBox image.
            g.DrawImage(source, new Rectangle(0, 0, blob.Width, blob.Height), blob.Left, blob.Top, blob.Width, blob.Height, GraphicsUnit.Pixel);
            g.Dispose();

            if (rotationAngel != 0)
            {
                RotateBilinear filter = new RotateBilinear(rotationAngel, true);
                filter.FillColor = bColor;
                // apply the filter
                newImage = filter.Apply(newImage);
            }

            // Resize the image.
            ResizeBilinear resizefilter = new ResizeBilinear((int)txtExportSize.Value, (int)txtExportSize.Value);
            newImage = resizefilter.Apply(newImage);

            return newImage;
        }