Files
cmbot/tests/test_visibility.py
T

109 lines
4.3 KiB
Python
Raw Normal View History

2026-06-16 11:21:21 +08:00
"""Tests for low-contrast visibility analysis. No GUI dependency."""
import shutil
import sys
import tempfile
import unittest
from pathlib import Path
from PIL import Image
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
from core.models import TransformState, VisibilityStatus
from core.visibility import analyze_visibility
class TestVisibilityAnalysis(unittest.TestCase):
def setUp(self):
self.tmp = Path(tempfile.mkdtemp())
def tearDown(self):
shutil.rmtree(str(self.tmp), ignore_errors=True)
def _save(self, image, name):
path = self.tmp / name
image.save(str(path))
return path
def _rgba(self, w, h, color):
return Image.new("RGBA", (w, h), color)
def test_white_garment_with_light_print_is_unclear_or_low(self):
garment = self._save(self._rgba(100, 100, (245, 245, 245, 255)), "garment.png")
print_img = self._save(self._rgba(20, 20, (250, 250, 250, 255)), "print.png")
state = TransformState(x=30, y=30, width=20, height=20)
result = analyze_visibility(garment, print_img, state)
self.assertIn(result.status, (VisibilityStatus.UNCLEAR, VisibilityStatus.LOW))
self.assertFalse(result.error)
def test_dark_garment_with_dark_print_is_unclear_or_low(self):
garment = self._save(self._rgba(100, 100, (20, 20, 20, 255)), "garment.png")
print_img = self._save(self._rgba(20, 20, (25, 25, 25, 255)), "print.png")
state = TransformState(x=30, y=30, width=20, height=20)
result = analyze_visibility(garment, print_img, state)
self.assertIn(result.status, (VisibilityStatus.UNCLEAR, VisibilityStatus.LOW))
self.assertFalse(result.error)
def test_high_contrast_pair_is_normal(self):
garment = self._save(self._rgba(100, 100, (250, 250, 250, 255)), "garment.png")
print_img = self._save(self._rgba(20, 20, (10, 10, 10, 255)), "print.png")
state = TransformState(x=30, y=30, width=20, height=20)
result = analyze_visibility(garment, print_img, state)
self.assertEqual(result.status, VisibilityStatus.NORMAL)
self.assertGreater(result.rgb_distance, 75)
def test_transparent_pixels_do_not_affect_print_color(self):
garment = self._save(self._rgba(100, 100, (10, 10, 10, 255)), "garment.png")
print_img = Image.new("RGBA", (20, 20), (255, 255, 255, 0))
for x in range(10):
for y in range(20):
print_img.putpixel((x, y), (12, 12, 12, 255))
print_path = self._save(print_img, "print.png")
state = TransformState(x=30, y=30, width=20, height=20)
result = analyze_visibility(garment, print_path, state)
self.assertIn(result.status, (VisibilityStatus.UNCLEAR, VisibilityStatus.LOW))
def test_fully_transparent_print_is_unknown(self):
garment = self._save(self._rgba(100, 100, (10, 10, 10, 255)), "garment.png")
print_img = self._save(self._rgba(20, 20, (10, 10, 10, 0)), "print.png")
state = TransformState(x=30, y=30, width=20, height=20)
result = analyze_visibility(garment, print_img, state)
self.assertEqual(result.status, VisibilityStatus.UNKNOWN)
self.assertTrue(result.error)
def test_uses_target_region_not_whole_garment(self):
garment_img = self._rgba(100, 100, (255, 255, 255, 255))
for x in range(30, 50):
for y in range(30, 50):
garment_img.putpixel((x, y), (10, 10, 10, 255))
garment = self._save(garment_img, "garment.png")
print_img = self._save(self._rgba(20, 20, (12, 12, 12, 255)), "print.png")
state = TransformState(x=30, y=30, width=20, height=20)
result = analyze_visibility(garment, print_img, state)
self.assertIn(result.status, (VisibilityStatus.UNCLEAR, VisibilityStatus.LOW))
def test_target_area_outside_canvas_is_unknown(self):
garment = self._save(self._rgba(100, 100, (255, 255, 255, 255)), "garment.png")
print_img = self._save(self._rgba(20, 20, (255, 255, 255, 255)), "print.png")
state = TransformState(x=200, y=200, width=20, height=20)
result = analyze_visibility(garment, print_img, state)
self.assertEqual(result.status, VisibilityStatus.UNKNOWN)
if __name__ == "__main__":
unittest.main()