Blue Eye
Blue Eye

Reputation: 49

Detecting Paper Edge and Crop it

I am using C# to write a program to detect the paper edges and crop out the square edges of the paper from the images.

Below is the image I wish to crop. The paper will always appear at the bottom of the pages.

enter image description here

I had read through these links but I still have no idea how to do it.

OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection

Edit: I am using EMGU for this OCR project

Upvotes: 0

Views: 3542

Answers (2)

Temak
Temak

Reputation: 3009

You can also:

  1. Convert your image to grayscale
  2. Apply ThresholdBinary by the pixel intensity
  3. Find contours.
    To see examples on finding contours you can look on this post.
    FundContours method doesn't care about the contours size. The only thing to be done here before finding contours is emphasizing them by binarizing the image (and we do this in step 2).
    For more info also look at OpenCV docs: findContours, example.

  4. Find proper contour by the size and position of its bounding box.
    (In this step we iterate over all found on contours and try to figure out, which one the contour of the paper sheet, using known paper dimensions, proportions of them and the relative positon - left bottom corner of the image ).

  5. Crop the image using bounding box of the sheet of paper.

    Image<Gray, byte> grayImage = new Image<Gray, byte>(colorImage);
    Image<Bgr, byte> color = new Image<Bgr, byte>(colorImage);
    
    grayImage = grayImage.ThresholdBinary(new Gray(thresholdValue), new Gray(255));
    
    using (MemStorage store = new MemStorage())
    for (Contour<Point> contours= grayImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, store); contours != null; contours = contours.HNext)
    {
        Rectangle r = CvInvoke.cvBoundingRect(contours, 1);
    
        // filter contours by position and size of the box
    }
    
    // crop the image using found bounding box
    

UPD: I have added more details.

Upvotes: 3

TaW
TaW

Reputation: 54433

  • Decide on the Paper color
  • Decide on a delta to allow the color to vary
  • Decide on points along the bottom to do vertical tests
  • Do the vertical tests going up, collecting the minimum y where the color stops appearing
  • Do at least 10-20 such tests

The resulting y should be 1 more than what you want to keep. You may need to insert a limit to avoid cropping everything if the image is too bright. Either refine the algorithm or mark such an the image as an exception for manual treatment!

To crop you use the DrawImage overload with source and dest rectangles!

Here are a few more hints:

  • To find the paper color you can go up right from the left bottom edge diagonally until you hit a pixel with a Color.GetBrightness of > 0.8; then go further for 2 pixels to get clear of any antialiased pixels.

  • A reasonable delta will depend on your images; start with 10%

  • Use a random walk along the bottom; when you are done maybe add one extra pass in the close vicinity of the minimum found in pass one.

  • The vertical test can use GetPixel to get at the colors or if that is too slow you may want to look into LockBits. But get the search algorithm right first, only then think about optimizing!

If you run into trouble with your code, expand your question!

Upvotes: 0

Related Questions