File size: 4,039 Bytes
28dbedc
8e0d79f
28dbedc
52f0700
28dbedc
 
 
8e0d79f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52f0700
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28dbedc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import unittest
from PIL import Image, ImageDraw
from grounding_demo.protocol import Primitive
from grounding_demo.render import draw_primitives, layout_box_labels, _font, PURPLE


class RenderRegression(unittest.TestCase):
    def test_chinese_and_mixed_text_have_real_glyphs(self):
        font = _font(24, "中文 OCR:姓名,日期(2026年)")
        missing = bytes(font.getmask("\u0378"))
        masks = []
        for char in "姓名出生日期地址簡體繁體,:()":
            with self.subTest(char=char):
                mask = bytes(font.getmask(char))
                self.assertNotEqual(mask, missing)
                self.assertTrue(any(mask))
                masks.append(mask)
        self.assertEqual(len(set(masks[:6])), 6)

    def test_chinese_badges_measure_and_draw_with_the_same_font(self):
        text = "中文 OCR:测试标签 2026年(示例)"
        primitives = [Primitive(text, (100, 300, 800, 500))]
        badge = layout_box_labels(primitives, 1000, 700, _font(20))[0]
        self.assertEqual(badge["text"], text)
        expected = ImageDraw.Draw(Image.new("RGB", (1, 1))).textbbox(
            (0, 0), text, font=_font(20, text)
        )
        self.assertEqual(badge["text_bounds"], expected)
        x1, y1, x2, y2 = badge["box"]
        self.assertEqual(x2-x1, expected[2]-expected[0]+8)
        self.assertEqual(y2-y1, expected[3]-expected[1]+8)
        rendered = draw_primitives(Image.new("RGB", (1000, 700), "white"), primitives)
        self.assertEqual(rendered.size, (1000, 700))

    def test_long_chinese_badges_stay_inside_canvas_without_changing_text_data(self):
        text = "这是一段很长的中文识别结果,包含标点和 English 2026。"*4
        primitive = Primitive(text, (900, 0, 999, 999))
        badges = layout_box_labels([primitive], 140, 120, _font(18))
        self.assertEqual(len(badges), 1)
        badge = badges[0]
        self.assertEqual(badge["label"], text)
        self.assertTrue(badge["text"].endswith("…"))
        x1,y1,x2,y2 = badge["box"]
        self.assertTrue(0<=x1<x2<=140 and 0<=y1<y2<=120)

    def test_dense_labels_are_unique_visible_and_do_not_overlap(self):
        boxes = [Primitive(f"category {i}", (50+(i%5)*180, 50+(i//5)*210,
                                           150+(i%5)*180, 190+(i//5)*210)) for i in range(20)]
        boxes += [Primitive("category 0", (700, 800, 850, 950))]
        original = list(boxes)
        labels = layout_box_labels(boxes, 1000, 1000, _font(16))
        self.assertEqual(len(labels), 20)
        self.assertEqual(len({row["label"] for row in labels}), 20)
        for i, row in enumerate(labels):
            x1,y1,x2,y2=row["box"]
            self.assertTrue(0<=x1<x2<=1000 and 0<=y1<y2<=1000)
            for other in labels[i+1:]:
                a,b,c,d=other["box"]
                self.assertFalse(x1<c and a<x2 and y1<d and b<y2)
        self.assertEqual(boxes, original)

    def test_large_late_region_does_not_erase_small_target(self):
        image = Image.new("RGB", (1000, 1000), "white")
        small = Primitive("boat", (300, 400, 350, 450))
        large = Primitive("lake", (0, 300, 999, 999))
        rendered = draw_primitives(image, [small, large])
        self.assertEqual(rendered.getpixel((300, 425)), PURPLE)
        self.assertEqual(rendered.getpixel((500, 700)), (255, 255, 255))

    def test_nested_geometry_is_not_filtered(self):
        image = Image.new("RGB", (1000, 1000), "white")
        boxes = [Primitive("target", (i, i, 999-i, 999-i)) for i in range(100, 401, 100)]
        rendered = draw_primitives(image, boxes)
        for i in range(100, 401, 100):
            self.assertEqual(rendered.getpixel((i, 500)), PURPLE)

    def test_small_and_edge_label_canvas_is_safe(self):
        image = Image.new("RGB", (32, 32), "white")
        result = draw_primitives(image, [Primitive("long OCR text "*10, (970, 0, 999, 999))])
        self.assertEqual(result.size, image.size)


if __name__ == "__main__":
    unittest.main()