Spaces:
Running on Zero
Running on Zero
| from __future__ import annotations | |
| from PIL import Image | |
| from ocr_studio.config import DESKEW_MAX_ANGLE | |
| def _rotate(image: Image.Image, angle: float) -> Image.Image: | |
| if abs(angle) < 0.25: | |
| return image | |
| fill = (255, 255, 255) | |
| return image.convert("RGB").rotate(angle, expand=True, fillcolor=fill, resample=Image.Resampling.BICUBIC) | |
| def enhance_scan(image: Image.Image) -> Image.Image: | |
| try: | |
| import cv2 | |
| import numpy as np | |
| except Exception: | |
| return image.convert("RGB") | |
| rgb = np.array(image.convert("RGB")) | |
| lab = cv2.cvtColor(rgb, cv2.COLOR_RGB2LAB) | |
| lightness, axis_a, axis_b = cv2.split(lab) | |
| clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) | |
| lightness = clahe.apply(lightness) | |
| merged = cv2.merge((lightness, axis_a, axis_b)) | |
| enhanced = cv2.cvtColor(merged, cv2.COLOR_LAB2RGB) | |
| return Image.fromarray(enhanced) | |
| def estimate_deskew_angle(image: Image.Image) -> float: | |
| try: | |
| import cv2 | |
| import numpy as np | |
| except Exception: | |
| return 0.0 | |
| gray = np.array(image.convert("L")) | |
| if gray.size < 400: | |
| return 0.0 | |
| inverted = cv2.bitwise_not(gray) | |
| _, binary = cv2.threshold(inverted, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) | |
| coords = np.column_stack(np.where(binary > 0)) | |
| if coords.shape[0] < 80: | |
| return 0.0 | |
| _rect, _size, raw_angle = cv2.minAreaRect(coords) | |
| angle = raw_angle | |
| if angle < -45: | |
| angle = 90.0 + angle | |
| if abs(angle) > DESKEW_MAX_ANGLE: | |
| return 0.0 | |
| return float(-angle) | |
| def deskew_image(image: Image.Image) -> tuple[Image.Image, float]: | |
| rgb = image.convert("RGB") | |
| angle = estimate_deskew_angle(rgb) | |
| straightened = _rotate(rgb, angle) | |
| return enhance_scan(straightened), angle | |
| def prepare_page(image: Image.Image, deskew: bool) -> tuple[Image.Image, float]: | |
| if not deskew: | |
| return enhance_scan(image.convert("RGB")), 0.0 | |
| return deskew_image(image) | |