Path: blob/master/Model-3/ocr/page.py
426 views
# -*- coding: utf-8 -*-1"""2Crop background and transform perspective from the photo of page3"""4import numpy as np5import cv26from .helpers import *78def detection(image):9""" Finding Page """10# Edge detection11imageEdges = edgesDet(image, 200, 250)1213# Close gaps between edges (double page clouse => rectangle kernel)14closedEdges = cv2.morphologyEx(imageEdges,15cv2.MORPH_CLOSE,16np.ones((5, 11)))17# Countours18pageContour = findPageContours(closedEdges, resize(image))19# Recalculate to original scale20pageContour = pageContour.dot(ratio(image))21# Transform prespective22newImage = perspImageTransform(image, pageContour)23return newImage242526def edgesDet(img, minVal, maxVal):27""" Preprocessing (gray, thresh, filter, border) + Canny edge detection """28img = cv2.cvtColor(resize(img), cv2.COLOR_BGR2GRAY)2930img = cv2.bilateralFilter(img, 9, 75, 75)31img = cv2.adaptiveThreshold(img, 255,32cv2.ADAPTIVE_THRESH_GAUSSIAN_C,33cv2.THRESH_BINARY, 115, 4)3435# Median blur replace center pixel by median of pixels under kelner36# => removes thin details37img = cv2.medianBlur(img, 11)3839# Add black border - detection of border touching pages40img = cv2.copyMakeBorder(img, 5, 5, 5, 5,41cv2.BORDER_CONSTANT,42value=[0, 0, 0])43return cv2.Canny(img, minVal, maxVal)444546def fourCornersSort(pts):47""" Sort corners: top-left, bot-left, bot-right, top-right"""48diff = np.diff(pts, axis=1)49summ = pts.sum(axis=1)50return np.array([pts[np.argmin(summ)],51pts[np.argmax(diff)],52pts[np.argmax(summ)],53pts[np.argmin(diff)]])545556def contourOffset(cnt, offset):57""" Offset contour because of 5px border """58cnt += offset59cnt[cnt < 0] = 060return cnt616263def findPageContours(edges, img):64""" Finding corner points of page contour """65# Getting contours66im2, contours, hierarchy = cv2.findContours(edges,67cv2.RETR_TREE,68cv2.CHAIN_APPROX_SIMPLE)6970# Finding biggest rectangle otherwise return original corners71height = edges.shape[0]72width = edges.shape[1]73MIN_COUNTOUR_AREA = height * width * 0.574MAX_COUNTOUR_AREA = (width - 10) * (height - 10)7576maxArea = MIN_COUNTOUR_AREA77pageContour = np.array([[0, 0],78[0, height],79[width, height],80[width, 0]])8182for cnt in contours:83perimeter = cv2.arcLength(cnt, True)84approx = cv2.approxPolyDP(cnt, 0.03 * perimeter, True)8586# Page has 4 corners and it is convex87if (len(approx) == 4 and88cv2.isContourConvex(approx) and89maxArea < cv2.contourArea(approx) < MAX_COUNTOUR_AREA):9091maxArea = cv2.contourArea(approx)92pageContour = approx9394# Sort corners and offset them95pageContour = fourCornersSort(pageContour[:, 0])96return contourOffset(pageContour, (-5, -5))979899def perspImageTransform(img, sPoints):100""" Transform perspective from start points to target points """101# Euclidean distance - calculate maximum height and width102height = max(np.linalg.norm(sPoints[0] - sPoints[1]),103np.linalg.norm(sPoints[2] - sPoints[3]))104width = max(np.linalg.norm(sPoints[1] - sPoints[2]),105np.linalg.norm(sPoints[3] - sPoints[0]))106107# Create target points108tPoints = np.array([[0, 0],109[0, height],110[width, height],111[width, 0]], np.float32)112113# getPerspectiveTransform() needs float32114if sPoints.dtype != np.float32:115sPoints = sPoints.astype(np.float32)116117M = cv2.getPerspectiveTransform(sPoints, tPoints)118return cv2.warpPerspective(img, M, (int(width), int(height)))119120