Path: blob/master/Model-3/ocr/words.py
426 views
# -*- coding: utf-8 -*-1"""2Detect words on the page3return array of words' bounding boxes4"""5import numpy as np6import matplotlib.pyplot as plt7import cv28from .helpers import *910def detection(image):11""" Detecting the words bounding boxes """12# Preprocess image for word detection13blurred = cv2.GaussianBlur(image, (5, 5), 10)14edgeImg = edgeDetect(blurred)15ret, edgeImg = cv2.threshold(edgeImg, 50, 255, cv2.THRESH_BINARY)16bwImage = cv2.morphologyEx(edgeImg, cv2.MORPH_CLOSE,17np.ones((15,15), np.uint8))18# Return detected bounding boxes19return textDetect(bwImage, image)202122def edgeDetect(im):23"""24Edge detection25Sobel operator is applied for each image layer (RGB)26"""27return np.max(np.array([sobelDetect(im[:,:, 0]),28sobelDetect(im[:,:, 1]),29sobelDetect(im[:,:, 2])]), axis=0)303132def sobelDetect(channel):33""" Sobel operator """34sobelX = cv2.Sobel(channel, cv2.CV_16S, 1, 0)35sobelY = cv2.Sobel(channel, cv2.CV_16S, 0, 1)36sobel = np.hypot(sobelX, sobelY)37sobel[sobel > 255] = 25538return np.uint8(sobel)394041def textDetect(img, image):42""" Text detection using contours """43small_2 = resize(image,2000)44small = resize(img, 2000)4546# Finding contours47mask = np.zeros(small.shape, np.uint8)48im2, cnt, hierarchy = cv2.findContours(np.copy(small), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)49index = 050boundingBoxes = np.array([0,0,0,0])5152# image for drawing bounding boxes53small = cv2.cvtColor(small, cv2.COLOR_GRAY2RGB)54small_copy = small.copy()55implt(small_copy , t='All contours')56cv2.drawContours(small_copy, cnt, -1, (0,255,0), 3)57implt(small_copy, t='check')58cv2.imwrite('check.jpg',small_copy)59# Go through all contours in top level60while (index >= 0 and index<40):61x,y,w,h = cv2.boundingRect(cnt[index])62cv2.drawContours(mask, cnt, index, (255, 255, 255), cv2.FILLED)63maskROI = mask[y:y+h, x:x+w]64# Ratio of white pixels to area of bounding rectangle65r = float(cv2.countNonZero(maskROI)) / (w * h)6667# Limits for text68#if r > 0.1 and 1600 > w > 10 and 1600 > h > 10 and (60 // h) * w < 1000:69if r > 0.1 and 2000 > w > 15 and 1500 > h > 15:70cv2.rectangle(small, (x, y),(x+w,y+h), (0, 255, 0), 2)71crop_img = small_2[y:y+h,x:x+w]72implt(crop_img, t='contours %s' % (index))73cv2.imwrite('check%s.jpg' % (index),crop_img)74boundingBoxes = np.vstack((boundingBoxes,np.array([x, y, x+w, y+h])))7576index+=17778implt(small, t='Bounding rectangles')79cv2.imwrite('check2.jpg',small)8081bBoxes = boundingBoxes.dot(ratio(image, 2000)).astype(np.int64)82return bBoxes[1:]838485def textDetectWatershed(thresh):86""" Text detection using watershed algorithm - NOT IN USE """87# According to: http://docs.opencv.org/trunk/d3/db4/tutorial_py_watershed.html88img = cv2.cvtColor(cv2.imread("data/textdet/%s.jpg" % IMG),89cv2.COLOR_BGR2RGB)90img = resize(img, 3000)91thresh = resize(thresh, 3000)92# noise removal93kernel = np.ones((3,3),np.uint8)94opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 3)9596# sure background area97sure_bg = cv2.dilate(opening,kernel,iterations=3)9899# Finding sure foreground area100dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)101ret, sure_fg = cv2.threshold(dist_transform,1020.01*dist_transform.max(), 255, 0)103104# Finding unknown region105sure_fg = np.uint8(sure_fg)106unknown = cv2.subtract(sure_bg,sure_fg)107108# Marker labelling109ret, markers = cv2.connectedComponents(sure_fg)110111# Add one to all labels so that sure background is not 0, but 1112markers += 1113114# Now, mark the region of unknown with zero115markers[unknown == 255] = 0116117markers = cv2.watershed(img, markers)118implt(markers, t='Markers')119image = img.copy()120gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)121122for mark in np.unique(markers):123# mark == 0 --> background124if mark == 0:125continue126127# Draw it on mask and detect biggest contour128mask = np.zeros(gray.shape, dtype="uint8")129mask[markers == mark] = 255130131cnts = cv2.findContours(mask.copy(),132cv2.RETR_EXTERNAL,133cv2.CHAIN_APPROX_SIMPLE)[-2]134c = max(cnts, key=cv2.contourArea)135136# Draw a bounding rectangle if it contains text137x,y,w,h = cv2.boundingRect(c)138cv2.drawContours(mask, c, 0, (255, 255, 255), cv2.FILLED)139maskROI = mask[y:y+h, x:x+w]140# Ratio of white pixels to area of bounding rectangle141r = float(cv2.countNonZero(maskROI)) / (w * h)142143# Limits for text144if r > 0.2 and 2000 > w > 15 and 1500 > h > 15:145cv2.rectangle(image, (x, y),(x+w,y+h), (0, 255, 0), 2)146147implt(image)148149150