blob: 35b65fe855f8613fadc976ef2b6aa3614bb3b0a7 [file] [log] [blame] [edit]
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Abstract base class for all detector tests."""
from unittest import TestCase
import numpy as np
from optofidelity.detection._calibrated_frame import CalibratedFrame
from optofidelity.detection._detector import DetectorDebugger
from optofidelity.detection.screen_calibration import ScreenCalibration
from optofidelity.videoproc import Canvas, ImageMatches
from . import test_data
class DetectorTest(TestCase):
@property
def calibration(self):
return ScreenCalibration(test_data.CalibrationBlackImage(),
test_data.CalibrationWhiteImage())
def calibratedFrame(self, image_name, prev_image_name=None, calibration=None):
image = test_data.LoadImage(image_name)
prev_image = None
if prev_image_name:
prev_image = test_data.LoadImage(prev_image_name)
calibration = calibration or self.calibration
return CalibratedFrame(image, prev_image, calibration, 0)
def uncalibratedFrame(self, image_name, prev_image_name=None):
image = test_data.LoadImage(image_name)
prev_image = None
if prev_image_name:
prev_image = test_data.LoadImage(prev_image_name)
return CalibratedFrame(image, prev_image, None, 0)
def assertExpectedEventsGenerated(self, detector, data_sequence,
expected_events, print_only=False,
ignore=None):
events = list(detector.GenerateEvents(data_sequence))
if ignore is not None:
events = [e for e in events if not isinstance(e, ignore)]
if print_only:
print events
return
self.assertEqual(len(events), len(expected_events))
for event in events:
expected = next((e for e in expected_events
if e.time == event.time), None)
if expected is None:
self.fail("Did not expect event: %s" % event)
self.assertAlmostEqual(event.location, expected.location)
self.assertEqual(event.time, expected.time)
self.assertEqual(event.start_time, expected.start_time)
self.assertEqual(event.state, expected.state)
class DebuggerTests(DetectorTest):
def composeExampleDebugView(self, debug_flags):
debugger = DetectorDebugger(self.calibration, debug_flags)
frame = self.calibratedFrame("finger.png")
mask = (frame.screen_space_normalized < 0.5)
debugger.screen_space_canvas.DrawMask(Canvas.GREEN, mask)
half_height = frame.camera_space_shape[0] / 2
half_width = frame.camera_space_shape[1] / 2
debugger.camera_space_canvas.DrawHLine(Canvas.BLUE, half_height)
debugger.camera_space_canvas.DrawVLine(Canvas.BLUE, half_width)
profile = np.mean(frame.screen_space_normalized, 0)
debugger.screen_space_canvas.PlotProfile(Canvas.RED, profile)
return debugger.ComposeDebugFrame(frame)
def testDebuggerNormalizedCompose(self):
expected_image_path = test_data.Path("debugger_normalized.png")
actual = self.composeExampleDebugView(["normalized"])
self.assertTrue(ImageMatches(actual, expected_image_path))
def testDebuggerCameraSpaceCompose(self):
expected_image_path = test_data.Path("debugger_camera_space.png")
actual = self.composeExampleDebugView([])
self.assertTrue(ImageMatches(actual, expected_image_path))