import cv2
from PIL import Image
import io
from skimage import filters, measure, morphology
from skimage.filters import threshold_triangle
from skimage.color import rgb2gray
from ..services.google_vision import GoogleVision
[docs]
def detect_rectangles(image, filter_scale):
"""
Automatically detect rectangle within given image.
These can be then used as potential candidates for ROIs.
Args:
image (Image): image object
filter_scale (float): scaling factor to filter out too small rectangles (recommended value between 1 and 3)
Returns:
list: list of discovered rectangles
"""
image_gray = rgb2gray(image)
_, width = image_gray.shape
framebox = extract_framebox(image)
gray_cut = image_gray[framebox[1] : framebox[3] + framebox[1],
framebox[0] : framebox[2] + framebox[0]]
thresh = threshold_triangle(gray_cut)
binary = gray_cut > thresh
image = binary
# Binary image, post-process the binary mask and compute labels
threshold = filters.threshold_otsu(image)
mask = image > threshold
mask = morphology.remove_small_objects(mask, width/filter_scale)
mask = morphology.remove_small_holes(mask, width/(filter_scale*5))
labels = measure.label(mask)
rectangles = []
props = measure.regionprops(labels, image)
for index in range(1, labels.max()):
minr, minc, maxr, maxc = props[index].bbox
rectangles.append((minc + framebox[0], minr + framebox[1], maxc + framebox[0], maxr + framebox[1]))
return rectangles
[docs]
def find_residuals(image, credentials):
"""Detect printed text via Google Vision and convert hits to ``Residual`` objects.
Args:
image: Template page as ``numpy`` array (RGB/BGR).
credentials: Path to Google service-account JSON (passed to ``GoogleVision``).
Returns:
List of ``Residual`` instances for config ``to_ignore`` entries.
"""
google = GoogleVision(credentials)
image_pil = Image.fromarray(image)
image_stream = io.BytesIO()
image_pil.save(image_stream, format='JPEG')
identified = google.annotate_image(image_stream)
identified = google.process_output(identified)
return [rectangle.to_residual() for rectangle in identified]