Ask Your Question

# Extracting A4 sheet out of troubling backgrounds

So, my challenge is to extract a A4 paper document out of a mobile phone photo. I'm currently doing it using by applying gaussian blur and canny, find the contours and then pick the biggest most rectangle-ish contour. That works great for photos in which the document is having a uniform dark background but if the background is white or containing other shapes then the whole solution goes bananas.

Any suggestion how to get rid of this problem and be less vulnerable to unexpected backgrounds?

Below you can find two troubling images and my current implementation. I'm using python 2.7.9 and opencv 2.4.9.1

    image = cv2.imread(args["image"])
ratio = image.shape[0] / 500.0
orig = image.copy()
image = imutils.resize(image, height = 500)

# convert the image to grayscale, blur it, and find edges
# in the image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 75, 200)

(cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]

# loop over the contours
for c in cnts:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)

# if our approximated contour has four points, then we
# can assume that we have found our screen
if len(approx) == 4:
screenCnt = approx
break

cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 2)

edit retag close merge delete

## 2 answers

Sort by ยป oldest newest most voted

Performing Canny on noisy images will lead to bad results, It is preferable to choose better color space (Lab (*b)) and threshold or use another edge detector for example:

You can find straight lines using hough transform ( eliminate unwanted lines) then find intersections. You can also use generalized hough to detect rectangle but that's not supported in Opencv.

Method 2 :

-Threshold and eliminate unwanted contours . - Use Minimum area rectangle.

more

## Comments

Thank you for the advice, Ziri, it sounds like a good approach! Can I ask what ops/steps did you apply to get to the tow results you provided?

( 2017-09-15 03:12:01 -0500 )edit

Use cvtColor with CV_RGB2Lab (try other color spaces) then split to take single chanel ( b in this case) . Also try color thresholding using inRange

( 2017-09-15 07:44:34 -0500 )edit

You can use : lab = cv2.cvtColor(img, cv2.COLOR_BGR2Lab)

( 2019-04-13 17:10:30 -0500 )edit

I would suggest you follow this tutorial to make a scanner in Python with ease

http://www.pyimagesearch.com/2014/09/...

As for the background problem, I too am stuck in the same problem. But I would suggest you to perform median blur followed by adaptive threshold as preprocessing before using canny on the image. It isolates the page from background quite effectively. Just play around with the threshold values. I used 21 for median blur and 41,7 with adaptive threshold

PS If you do get results, please upload your pre-canny resultant image and post-canny image so that I can debug my problem too ;)

more

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2017-09-14 02:33:12 -0500

Seen: 3,057 times

Last updated: Sep 15 '17