Cropping investigation
This commit is contained in:
1 parent
48602c24f1
commit
bd1964ffcd
10 files changed
+814
-24
No files matched your search
@@ -0,0 +1,87 @@
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from copienator.ink_detection import detect_bounds
|
||||
|
||||
|
||||
class PaperRulingTests(unittest.TestCase):
|
||||
def scan(self, colour, *, warp=False):
|
||||
image = np.full((1200, 850, 3), 255, np.uint8)
|
||||
for y in range(20, 1200, 20):
|
||||
cv2.line(image, (0, y), (849, y), colour, 1)
|
||||
for x in range(10, 850, 20):
|
||||
cv2.line(image, (x, 0), (x, 1199), colour, 1)
|
||||
cv2.line(image, (80, 0), (80, 1199), (210, 70, 80), 2)
|
||||
cv2.putText(image, 'answer', (120, 410), cv2.FONT_HERSHEY_SIMPLEX,
|
||||
1, (20, 60, 180), 2)
|
||||
cv2.putText(image, 'more', (120, 710), cv2.FONT_HERSHEY_SIMPLEX,
|
||||
1, (20, 60, 180), 2)
|
||||
if warp:
|
||||
yy, xx = np.indices(image.shape[:2], dtype=np.float32)
|
||||
image = cv2.remap(image, xx+2*np.sin(yy/95), yy,
|
||||
cv2.INTER_LINEAR, borderValue=(255,255,255))
|
||||
return image
|
||||
|
||||
def test_default_path_does_not_run_experimental_colour_model(self):
|
||||
image = self.scan((70, 110, 225))
|
||||
with patch('copienator.ink_detection.ruling_suppression',
|
||||
side_effect=AssertionError('Expensive colour model invoked')):
|
||||
result = detect_bounds(image, dpi=150)
|
||||
self.assertLess(result['top_px'], 410)
|
||||
self.assertGreater(result['bottom_px'], 710)
|
||||
self.assertFalse(result.get('ruling_cleanup', False))
|
||||
|
||||
def test_saturated_coloured_grid_and_margin_do_not_seed_blank_edges(self):
|
||||
for colour in [(65, 65, 65), (70, 110, 225), (155, 170, 240)]:
|
||||
for warp in [False, True]:
|
||||
with self.subTest(colour=colour, warp=warp):
|
||||
image = self.scan(colour, warp=warp)
|
||||
debug = {}
|
||||
result = detect_bounds(image, dpi=150, colour_cleanup=True, diagnostics=debug)
|
||||
self.assertGreater(result['top_px'], 280)
|
||||
self.assertLess(result['bottom_px'], 810)
|
||||
self.assertTrue(result['ruling_cleanup'])
|
||||
self.assertTrue(debug['masks']['paper_suppressed'].any())
|
||||
self.assertFalse(debug['masks']['foreground'][:250].any())
|
||||
|
||||
def test_writing_crossing_ruling_keeps_both_outer_bounds(self):
|
||||
image = self.scan((70, 110, 225))
|
||||
cv2.putText(image, 'top', (120, 200), cv2.FONT_HERSHEY_SIMPLEX,
|
||||
.7, (190, 20, 20), 2)
|
||||
cv2.putText(image, 'bottom', (120, 1000), cv2.FONT_HERSHEY_SIMPLEX,
|
||||
.7, (20, 20, 20), 2)
|
||||
result = detect_bounds(image, dpi=150, colour_cleanup=True)
|
||||
self.assertLess(result['top_px'], 180)
|
||||
self.assertGreater(result['bottom_px'], 1000)
|
||||
|
||||
def test_isolated_bars_and_axes_are_not_a_ruling_colour_family(self):
|
||||
for colour in [(190, 20, 20), (20, 20, 20), (20, 90, 190)]:
|
||||
with self.subTest(colour=colour):
|
||||
image = self.scan((70, 110, 225))
|
||||
cv2.line(image, (100, 1020), (700, 1020), colour, 3)
|
||||
cv2.line(image, (425, 980), (425, 1120), colour, 3)
|
||||
result = detect_bounds(image, dpi=150, colour_cleanup=True)
|
||||
self.assertGreater(result['bottom_px'], 1120)
|
||||
|
||||
def test_grid_colour_with_a_thicker_answer_bar_is_preserved(self):
|
||||
colour = (70, 110, 225)
|
||||
image = self.scan(colour)
|
||||
cv2.line(image, (150, 1020), (650, 1020), colour, 5)
|
||||
self.assertGreater(detect_bounds(image, dpi=150, colour_cleanup=True)['bottom_px'], 1020)
|
||||
|
||||
def test_regular_fraction_bars_inside_an_answer_are_not_paper(self):
|
||||
image = np.full((1200,850,3),255,np.uint8)
|
||||
cv2.putText(image,'answer',(120,300),cv2.FONT_HERSHEY_SIMPLEX,
|
||||
1,(20,60,180),2)
|
||||
for y in (400,550,700,850,1000):
|
||||
cv2.line(image,(130,y),(700,y),(20,20,20),3)
|
||||
result = detect_bounds(image,dpi=150, colour_cleanup=True)
|
||||
self.assertGreater(result['bottom_px'],1000)
|
||||
self.assertFalse(result.get('ruling_cleanup',False))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user