feat: add rtsp runtime pipeline
This commit is contained in:
72
tests/test_vision.py
Normal file
72
tests/test_vision.py
Normal file
@@ -0,0 +1,72 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from cold_display_guard.vision import (
|
||||
Frame,
|
||||
Region,
|
||||
RuntimeVisionSettings,
|
||||
ZoneOccupancyDetector,
|
||||
point_in_polygon,
|
||||
)
|
||||
|
||||
|
||||
def solid_frame(width: int, height: int, value: int) -> Frame:
|
||||
return Frame(width=width, height=height, rgb=bytes([value, value, value]) * width * height)
|
||||
|
||||
|
||||
def patched_frame(width: int, height: int, base: int, patch: tuple[int, int, int, int, int]) -> Frame:
|
||||
x1, y1, x2, y2, value = patch
|
||||
pixels = bytearray(bytes([base, base, base]) * width * height)
|
||||
for y in range(y1, y2):
|
||||
for x in range(x1, x2):
|
||||
offset = (y * width + x) * 3
|
||||
pixels[offset : offset + 3] = bytes([value, value, value])
|
||||
return Frame(width=width, height=height, rgb=bytes(pixels))
|
||||
|
||||
|
||||
class VisionTests(unittest.TestCase):
|
||||
def test_point_in_polygon(self) -> None:
|
||||
polygon = ((0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0))
|
||||
|
||||
self.assertTrue(point_in_polygon(0.5, 0.5, polygon))
|
||||
self.assertFalse(point_in_polygon(1.5, 0.5, polygon))
|
||||
|
||||
def test_detector_reports_occupied_after_baseline_changes(self) -> None:
|
||||
detector = ZoneOccupancyDetector(
|
||||
[Region("r1c1", ((0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)))],
|
||||
trash_region=None,
|
||||
settings=RuntimeVisionSettings(
|
||||
baseline_frames=1,
|
||||
sample_stride_pixels=4,
|
||||
occupancy_mean_delta=10,
|
||||
occupancy_texture_delta=10,
|
||||
),
|
||||
)
|
||||
now = datetime(2026, 4, 28, 10, 0, tzinfo=timezone.utc)
|
||||
|
||||
baseline_counts, _, _ = detector.observe(solid_frame(32, 32, 30), now)
|
||||
changed_counts, _, _ = detector.observe(patched_frame(32, 32, 30, (0, 0, 32, 32, 90)), now)
|
||||
|
||||
self.assertEqual(baseline_counts, {"r1c1": 0})
|
||||
self.assertEqual(changed_counts, {"r1c1": 1})
|
||||
|
||||
def test_detector_reports_trash_motion(self) -> None:
|
||||
trash = Region("trash", ((0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)))
|
||||
detector = ZoneOccupancyDetector(
|
||||
[],
|
||||
trash_region=trash,
|
||||
settings=RuntimeVisionSettings(sample_stride_pixels=4, trash_motion_delta=10),
|
||||
)
|
||||
now = datetime(2026, 4, 28, 10, 0, tzinfo=timezone.utc)
|
||||
|
||||
_, first_deposit, _ = detector.observe(solid_frame(32, 32, 30), now)
|
||||
_, second_deposit, _ = detector.observe(solid_frame(32, 32, 90), now)
|
||||
|
||||
self.assertEqual(first_deposit, 0)
|
||||
self.assertEqual(second_deposit, 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user