Search code examples
opencvimage-processingedge-detection

How to detect document from a picture in opencv?


I am trying to design an app similar to camscanner. For that, I have to take an image and then find the document in that. I started off with the code described here - http://opencvpython.blogspot.in/2012/06/sudoku-solver-part-2.html

I found the contours and the rectangular contour with max area should be the required document. For every contour, I am finding an approximate closed PolyDP. Of all the polyDP of size 4, the one with max area should be the required document. However, this method is not working.

The input image for the process is this input Image

I tried to print the contour with max area and this resulted in this (Contour inside letter 'C') enter image description here

Code:

img = cv2.imread('bounce.jpeg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(5,5),0) 
thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
_, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

def biggestRectangle(contours):
    biggest = None
    max_area = 0
    indexReturn = -1
    for index in range(len(contours)):
            i = contours[index]
            area = cv2.contourArea(i)
            if area > 100:
                    peri = cv2.arcLength(i,True)
                    approx = cv2.approxPolyDP(i,0.1*peri,True)
                    if area > max_area: #and len(approx)==4:
                            biggest = approx
                            max_area = area
                            indexReturn = index
    return indexReturn

indexReturn = biggestRectangle(contours)
cv2.imwrite('hola.png',cv2.drawContours(img, contours, indexReturn, (0,255,0)))

What is going wrong in this? Is there any other method by which I can capture the document in this picture?


Solution

  • Try this : output image

    import cv2
    import numpy as np
    
    img = cv2.imread('bounce.jpg')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    invGamma = 1.0 / 0.3
    table = np.array([((i / 255.0) ** invGamma) * 255
    for i in np.arange(0, 256)]).astype("uint8")
    
    # apply gamma correction using the lookup table
    gray = cv2.LUT(gray, table)
    
    ret,thresh1 = cv2.threshold(gray,80,255,cv2.THRESH_BINARY)
    
    #thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
    _, contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    def biggestRectangle(contours):
        biggest = None
        max_area = 0
        indexReturn = -1
        for index in range(len(contours)):
                i = contours[index]
                area = cv2.contourArea(i)
                if area > 100:
                    peri = cv2.arcLength(i,True)
                    approx = cv2.approxPolyDP(i,0.1*peri,True)
                    if area > max_area: #and len(approx)==4:
                            biggest = approx
                            max_area = area
                            indexReturn = index
        return indexReturn
    
    indexReturn = biggestRectangle(contours)
    hull = cv2.convexHull(contours[indexReturn])
    cv2.imwrite('hola.png',cv2.drawContours(img, [hull], 0, (0,255,0),3))
    #cv2.imwrite('hola.png',thresh1)