Skip to content

NimaPourmoradi/CamScanner_OpenCV

Repository files navigation

Step 1 | Import libraries

➡️ At first, import libraries that installed with pip install command.

import cv2                                           # main librarie
import requests                                      # To load image from url
import numpy as np                                   # To works with arrays
from PIL import Image                                # To works with images 
from io import BytesIO                               # To read data from memory
import matplotlib.pyplot as plt                      # To plot images
import ipywidgets                                    # To use load and predict buttons
from IPython.display import display,clear_output     # To use load and predict buttons

Step 2| Read Sample Image From URL

➡️ Using requests and PIL to load an image from an URL and show it.

response = requests.get('https://i.postimg.cc/kGqWpBM3/page2.jpg')
img = Image.open(BytesIO(response.content))

# show imported image
plt.imshow(img)
plt.axis('off')
plt.show()

png

Step 3 | Main Code

➡️ Now, define a function to recive imported images and get cam-scanner like image to output.

def CamScanner(img) :
    # Convert imported image to a numpy array
    img = np.array(img)

    # Change image to GrayScale with 1 color channel
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Using threshold create a mask
    _, mask_page = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)

    # create contours of mask
    countours, _ = cv2.findContours(mask_page, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # define 2 list to store area and P factor
    area_list = []
    p_list = []

    # Loop over contours to store area and arcLength in lists
    for cont in countours :
        area = cv2.contourArea(cont)
        area_list.append(area)

        p = cv2.arcLength(cont, True)
        p_list.append(p)

    # Choose bigest elemnt index
    page_index = np.argmax(area_list)

    # Create closed curve over choosed contours
    RasPoz = cv2.approxPolyDP(curve=countours[page_index], epsilon=0.005*p_list[page_index], closed=True)

    # Create a condition to insure to choose a rectangle(page)
    if len(RasPoz) == 4 :
        RasPoz_reshaped = np.reshape(RasPoz, (4, 2))

        # Image hight and width
        h, w, _ = img.shape

        # Choose point1 of current page edges and point2 of output edges ---> for Prespective
        p1 = np.float32(RasPoz_reshaped)
        p2 = np.float32([ [0, 0], [0, h], [w, h], [w, 0] ])

        # Create a prespective array with p1 & p2 
        arr_pres = cv2.getPerspectiveTransform(p1, p2)

        # Apply prespective on original image
        selected_page = cv2.warpPerspective(img, arr_pres, (w, h))

        # Change color map of selected image to gray
        selected_gray = cv2.cvtColor(selected_page, cv2.COLOR_BGR2GRAY)

        # Apply an adaptive threshold to gray-selected-image to make it more readable
        adaptive_selected = cv2.adaptiveThreshold(selected_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 15, 12)

        # Show original and output image of function
        plt.figure(figsize=(15, 10))
        # Original image
        plt.subplot(1, 2, 1)
        plt.imshow(img)
        plt.title('Original Image')
        plt.axis('off')
        # Converted image
        plt.subplot(1, 2, 2)
        plt.imshow(adaptive_selected, cmap='gray')
        plt.title('Converted Image')
        plt.axis('off')

        plt.show()
# Call the Function
CamScanner(img)

png

Step 4 | Predict

➡️ This part not working in kaggle environment, but if you download and run this notebook on your system, it works !

# Create Upload button by ipywidget

upload = ipywidgets.FileUpload(accept='.jpg', multiple=False)
display(upload)
FileUpload(value=(), accept='.jpg', description='Upload')
button = ipywidgets.Button(description='Predict')
out = ipywidgets.Output()
def on_button_clicked(_):
    with out:
        clear_output()
        try:
            data = BytesIO(upload.value[0]['content'])
            img = Image.open(data)
            CamScanner(img)
            
        except:
            print('No Image Uploaded/Invalid Image File')
button.on_click(on_button_clicked)
ipywidgets.VBox([button,out])
VBox(children=(Button(description='Predict', style=ButtonStyle()), Output()))

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors