import matplotlib.pyplot as plt import numpy as np import cv2 import easyocr class OCR: def __init__(self, image) -> None: self.image = image self.reader = easyocr.Reader( lang_list=['en'], gpu=False, model_storage_directory='./EasyOCR/model/', download_enabled=False, user_network_directory='./EasyOCR/user_network/' ) def detection(self): img_arr = np.array(self.image, dtype=np.uint8) response = self.reader.readtext(image=img_arr) plot_inputs = [] for box, text, conf in response: plot_inputs.append((text, np.array(box, dtype=np.float32))) fig, ax = plt.subplots(nrows=1, ncols=1) plot = self.drawAnnotations( image=img_arr, predictions=plot_inputs, ax=ax) return fig def drawAnnotations(self, image, predictions, ax=None): """Draw text annotations onto image. Args: image: The image on which to draw predictions: The predictions as provided by `pipeline.recognize`. ax: A matplotlib axis on which to draw. """ if ax is None: _, ax = plt.subplots() ax.imshow(self.drawBoxes(image=image, boxes=predictions, boxes_format="predictions")) predictions = sorted(predictions, key=lambda p: p[1][:, 1].min()) left = [] right = [] for word, box in predictions: if box[:, 0].min() < image.shape[1] / 2: left.append((word, box)) else: right.append((word, box)) ax.set_yticks([]) ax.set_xticks([]) for side, group in zip(["left", "right"], [left, right]): for index, (text, box) in enumerate(group): y = 1 - (index / len(group)) xy = box[0] / np.array([image.shape[1], image.shape[0]]) xy[1] = 1 - xy[1] ax.annotate( text=text, xy=xy, xytext=(-0.05 if side == "left" else 1.05, y), xycoords="axes fraction", arrowprops={"arrowstyle": "->", "color": "r"}, color="r", fontsize=14, horizontalalignment="right" if side == "left" else "left", ) return ax def drawBoxes(self, image, boxes, color=(255, 0, 0), thickness=1, boxes_format="boxes"): """Draw boxes onto an image. Args: image: The image on which to draw the boxes. boxes: The boxes to draw. color: The color for each box. thickness: The thickness for each box. boxes_format: The format used for providing the boxes. Options are "boxes" which indicates an array with shape(N, 4, 2) where N is the number of boxes and each box is a list of four points) as provided by `keras_ocr.detection.Detector.detect`, "lines" (a list of lines where each line itself is a list of (box, character) tuples) as provided by `keras_ocr.data_generation.get_image_generator`, or "predictions" where boxes is by itself a list of (word, box) tuples as provided by `keras_ocr.pipeline.Pipeline.recognize` or `keras_ocr.recognition.Recognizer.recognize_from_boxes`. """ if len(boxes) == 0: return image canvas = image.copy() if boxes_format == "lines": revised_boxes = [] for line in boxes: for box, _ in line: revised_boxes.append(box) boxes = revised_boxes if boxes_format == "predictions": revised_boxes = [] for _, box in boxes: revised_boxes.append(box) boxes = revised_boxes for box in boxes: cv2.polylines( img=canvas, pts=box[np.newaxis].astype("int32"), color=color, thickness=thickness, isClosed=True, ) return canvas