How to auto crop an image?

大城市里の小女人 提交于 2019-11-27 16:16:42

I assume you always have an image with a distinct foreground and background, and you want to do something like a zealous crop of the background.

In this case I would do something similar to region growning. Start at a point where you can be guaranteed a background pixel.

Get another image (or matrix or whatever), initialized to zeros, and set the corresponding pixel value to 1. If any neighboring pixels are within a threshold value in the original image, move to them recursively and set their corresponding pixel values to 0 as well.

That is:

map = 0's, size of image
function f(x,y,image,map)
    if map(x,y) is not  0
        return
    if pixel value at image(x,y)<T
        map(x,y) = 1;
        for all neighbors of x,y
           function([neighbor coordinates],image,map)
    else
        map(x,y) = 2;
 end

Now map should have all background pixels as 1 and forground as 2. You can change this to allow multiple objects and thresholds and so forth. You might want threshold to be a value change rather than an absolute value.

Then simply find the min and max x and y and store the pixels in that range to a new image.

I hope this was along the lines of what you need.

i changed your code to this and works well. thanks

 public static System.Drawing.Image AforgeAutoCrop(Bitmap selectedImage)
        {
            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 = 500;
                //bc.MinHeight = 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);
            }

            return autoCropImage;
        }
Frog Pr1nce

Mostafa HK's code worked for me. I'm using this function to pre-process YouTube thumbnails (to strip the black edges; a common problem), and I did have to make a couple of minor corrections to his code:

1) got rid of the rotation (not sure what that was for)

2) I lowered the threshold from 100 to 25.

3) When cloning the final image, I perform the clone off the original autoCropImage and not the rotatedImage (again, not sure what the rotation was for).

I think the real secret sauce was lowering the threshold. This reduced the number of rectangles the code was finding, and now I am properly cropping all forms of thumbnails (widescreen with black on the top and bottom AND fullscreen with black on the left and right).

    public static System.Drawing.Image AforgeAutoCrop(Bitmap selectedImage)
    {
        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 = 0; // 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(25).ApplyInPlace(rotatedImage);
            BlobCounter bc = new BlobCounter();
            bc.FilterBlobs = true;
            // bc.MinWidth = 500;
            //bc.MinHeight = 500;
            bc.ProcessImage(rotatedImage);
            Rectangle[] rects = bc.GetObjectsRectangles();

            if (rects.Length == 0)
            {
                // CAN'T CROP
            }
            else if (rects.Length == 1)
            {
                autoCropImage = autoCropImage.Clone(rects[0], autoCropImage.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 = autoCropImage.Clone(r2[0], autoCropImage.PixelFormat);
            }
            else
            {
                Console.WriteLine("Huh? on image ");
            }
        }
        catch (Exception ex)
        {
            //MessageBox.Show(ex.Message);
            //CAN'T CROP
        }

        return autoCropImage;
    }

https://stackoverflow.com/search?q=youtube+thumbnail+crop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!