ukrainian-passport-ocr / src /preprocess.py
askakalsky's picture
Upload src/preprocess.py with huggingface_hub
90ec8e7 verified
Raw
History Blame Contribute Delete
1.59 kB
"""
Preprocessing pipeline: raw ROI crop -> clean grayscale binary image.
Steps (tuned for Ukrainian dot-matrix passport series/number strips):
1. Grayscale
2. Non-local means denoising
3. (Optional) CLAHE / top-hat / sharpening
4. (Optional) Gamma correction
5. Otsu binarisation
"""
import cv2
import numpy as np
def preprocess(image: np.ndarray) -> np.ndarray:
"""
Full preprocessing pipeline.
Args:
image: BGR or grayscale crop of the passport ROI.
Returns:
uint8 grayscale image after binarisation (0 = background, 255 = ink).
"""
# 1. Grayscale
if image.ndim == 3:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
else:
gray = image.copy()
# 2. Non-local means denoising
denoised = cv2.fastNlMeansDenoising(gray, h=3, templateWindowSize=9,
searchWindowSize=5)
# 3. Enhancement (all disabled by default — add if needed per scan quality)
enhanced = denoised
# 4. Gamma correction (disabled — gamma=1.0 is identity)
# gamma = 1.8
# lut = np.array([((i / 255.0) ** (1.0 / gamma)) * 255
# for i in range(256)], dtype=np.uint8)
# enhanced = cv2.LUT(enhanced, lut)
# 5. Otsu binarisation
_, binary = cv2.threshold(enhanced, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Invert if background is dark (dots should be white on black,
# matching the original Step_5_Binary preprocessing)
if binary.mean() > 127:
binary = 255 - binary
return binary