OpenCV Document Scanner Python.

Published by Abhay Rastogi on

OpenCV Document Scanner Python

Build an OpenCV Document Scanner with just a few lines of code in python. for detecting paper from the image we should know some the Image Processing methods for making an accurate scanner.

OpenCV Image Processing

We should know some of the OpenCV image processing methods needed for building a document scanner in OpenCV.

1) Convert RGB to Gray scale

OpenCV image processing cv2.cvtColor method is used to change the colour of the image. more than 150 colour methods provided to change colour space. in this, we will change RGB to Gray colours space

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

2) Reduce noise and detect edges

The most import part for detecting an image accurately is to remove the unnecessary noise present in it. there are many methods provided in OpenCV .clearing noise of image with (cv2.erode, cv2.morphologyEx) and edges can be found by cv2.Canny method.

kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(gray, kernel, iterations=1)
opening = cv2.morphologyEx(erosion, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
edged = cv2.Canny(closing, 20, 240)

3) Image thresholding and finding contours

Thresholding helps us in archiving better result in finding Contours of image.contours are nothing but the edges region this could be achieved by cv2.adaptiveThreshold and cv2.findContours method in OpenCV.

edged = cv2.Canny(closing, 20, 240)
thresh = cv2.adaptiveThreshold(edged, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) 

4) Find the biggest contour area and approx poly

Next step is to find the biggest contour and crop the image to that contour and display it. for counting the biggest contour out of all counters OpenCV provides cv2.contourArea() method and after getting the main contour we have to find the approx-poly main coordinates the image by (cv2.approxPolyDP, cv2.arcLength).

# Find the biggest contour
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)

# Find the approx poly of the image
epsilon = 0.1 * cv2.arcLength(contours[max_index], True)
approx = cv2.approxPolyDP(contours[max_index], epsilon, True)

5) Crop the image from approxPoly

The final step is to crop the image to approx-poly with ( cv2.getPerspectiveTransform , cv2.warpPerspective) and display it.

pts1 = np.float32(approx)
pts = np.float32([[0, 0], [width, 0], [width, height], [0, height]])
matrix = cv2.getPerspectiveTransform(pts1, pts)
result = cv2.warpPerspective(img, matrix, (width, height))

Full Code

import cv2
import numpy as np   

img = imgread('imageLog.jpg') # Read Image
height, width, channels = img.shape # Find Height And Width Of Image

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # RGB To Gray Scale

kernel = np.ones((5, 5), np.uint8) # Reduce Noise Of Image
erosion = cv2.erode(gray, kernel, iterations=1)
opening = cv2.morphologyEx(erosion, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)

edges = cv2.Canny(closing, 20, 240) # Find Edges

# Get Threshold Of Canny
thresh = cv2.adaptiveThreshold(edges, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)  

# Find Contours In Image
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)  

# Find Biggest Contour
areas = [cv2.contourArea(c) for c in contours]
max_index = np.argmax(areas)
print(max_index)

# Find approxPoly Of Biggest Contour
epsilon = 0.1 * cv2.arcLength(contours[max_index], True)
approx = cv2.approxPolyDP(contours[max_index], epsilon, True)

# Crop The Image To approxPoly
pts1 = np.float32(approx)
pts = np.float32([[0, 0], [width, 0], [width, height], [0, height]])
matrix = cv2.getPerspectiveTransform(pts1, pts)
result = cv2.warpPerspective(img, matrix, (width, height))

flip = cv2.flip(result, 1) # Flip Image
rotate = cv2.rotate(flip, cv2.ROTATE_90_COUNTERCLOCKWISE) # Rotate Image
   
cv2.imshow('Result',rotate)

cv2.waitKey(0)
cv2.destroyAllWindows()

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *