import sys import unittest from pathlib import Path import cv2 import numpy as np sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "scripts")) from scan_background import whiten_background class ScanBackgroundTest(unittest.TestCase): def receipt(self, background=45, paper=245): image = np.full((1600, 1200, 3), background, dtype=np.uint8) image[120:1440, 360:820] = paper for y in range(220, 1350, 70): cv2.putText(image, "BON 12,34 EUR", (375, y), cv2.FONT_HERSHEY_SIMPLEX, .7, (20, 20, 20), 2) cv2.rectangle(image, (400, 140), (780, 180), (40, 80, 210), -1) return image def test_receipt_on_dark_or_gray_backing_keeps_canvas_text_and_colored_logo(self): for background in (35, 140): image = self.receipt(background) result = whiten_background(image) self.assertEqual(result.shape, image.shape) self.assertTrue(np.all(result[:80] == 255)) self.assertTrue(np.all(result[:, :250] == 255)) self.assertTrue(np.array_equal(result[120:1440, 360:820], image[120:1440, 360:820])) def test_slanted_receipt_is_whitened_without_rotating_or_cropping(self): image = np.full((1600, 1200, 3), 55, dtype=np.uint8) polygon = np.array([[450, 100], [890, 155], [720, 1450], [280, 1390]]) cv2.fillPoly(image, [polygon], (245, 245, 245)) cv2.putText(image, "FEDEO", (470, 700), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 0), 3) result = whiten_background(image) self.assertEqual(result.shape, image.shape) inside = np.zeros(image.shape[:2], dtype=np.uint8) cv2.fillPoly(inside, [polygon], 255) self.assertTrue(np.array_equal(result[inside > 0], image[inside > 0])) self.assertTrue(np.all(result[:50] == 255)) def test_white_full_page_is_not_replaced_by_its_largest_text_box(self): image = np.full((1600, 1200, 3), 255, dtype=np.uint8) cv2.rectangle(image, (300, 400), (800, 1200), (30, 30, 30), 4) cv2.putText(image, "Footer", (20, 1550), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2) self.assertTrue(np.array_equal(whiten_background(image), image)) def test_slanted_receipt_retains_every_paper_edge_pixel_at_300_dpi(self): image = np.full((3508, 2480, 3), 45, dtype=np.uint8) polygon = np.array([[820, 200], [1700, 340], [1250, 3300], [380, 3160]]) cv2.fillPoly(image, [polygon], (245, 245, 245)) inside = np.zeros(image.shape[:2], dtype=np.uint8) cv2.fillPoly(inside, [polygon], 255) result = whiten_background(image) self.assertTrue(np.array_equal(result[inside > 0], image[inside > 0])) self.assertTrue(np.all(result[:50] == 255)) def test_blank_and_ambiguous_low_contrast_pages_remain_unchanged(self): for image in [np.full((300, 200, 3), 245, dtype=np.uint8), self.receipt(215, 230)]: self.assertTrue(np.array_equal(whiten_background(image), image)) if __name__ == "__main__": unittest.main()