Ejemplo n.º 1
0
 def test_rightmost_coordinate(self):
     # Polygon
     dummy_record = Record([[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]],
                           ('car', ),
                           confidence=0.9)
     geometry = Geometry(record=dummy_record)
     assert geometry.rightmost_coordinate == (1, 0)
     # Point
     dummy_record = Record([0, 1], ('car', ), confidence=0.9)
     geometry = Geometry(record=dummy_record)
     assert geometry.rightmost_coordinate == (0, 1)
Ejemplo n.º 2
0
 def test_coordinates(self):
     # Polygon
     dummy_record = Record([[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]],
                           ('car', ),
                           confidence=0.9)
     geometry = Geometry(record=dummy_record)
     assert geometry.coordinates == geometry._coordinates
     # Point
     dummy_record = Record([0, 1], ('car', ), confidence=0.9)
     geometry = Geometry(record=dummy_record)
     assert geometry.coordinates == geometry._coordinates
Ejemplo n.º 3
0
 def test_min_x(self):
     # Polygon
     dummy_record = Record([[[0, 0], [1, 1], [2, 2], [3, 3], [0, 0]]],
                           ('car', ),
                           confidence=0.9)
     geometry = Geometry(record=dummy_record)
     assert isinstance(geometry.min_x, int)
     assert geometry.min_x == 0
     # Point
     dummy_record = Record([0, 0], ('car', ), confidence=0.9)
     geometry = Geometry(record=dummy_record)
     assert isinstance(geometry.min_x, int)
     assert geometry.min_x == 0
Ejemplo n.º 4
0
 def test_centroid(self):
     # Polygon
     dummy_record = Record([[[0, 0], [2, 0], [2, 2], [0, 2], [0, 0]]],
                           ('car', ),
                           confidence=0.9)
     geometry = Geometry(record=dummy_record)
     centroid = geometry.centroid
     assert isinstance(centroid, tuple)
     assert centroid == (1, 1)
     # Point
     dummy_record = Record([1, 2], ('car', ), confidence=0.9)
     geometry = Geometry(record=dummy_record)
     centroid = geometry.centroid
     assert isinstance(centroid, tuple)
     assert centroid == (1, 2)
Ejemplo n.º 5
0
def data_point_like():
    # Fake records
    records = [
        Record([[[100, 100], [100, 150], [150, 150], [150, 100], [100, 100]]],
               ('ship', ),
               confidence=0.9),
        Record([[[710, 100], [710, 150], [760, 150], [760, 100], [710, 100]]],
               ('boat', ),
               confidence=0.857),
        Record([[[500, 500], [550, 550], [500, 600], [450, 550], [500, 500]]],
               ('boat', ),
               confidence=0.72),
        Record([[[250, 0], [300, 0], [275, 25], [300, 50], [250, 50],
                 [275, 25], [250, 0]]], ('boat', ),
               confidence=0),
        Record([[[300, 300], [320, 280], [420, 380], [400, 400], [300, 300]]],
               ('boat', ),
               confidence=0.3),
        Record([[[650, 300], [670, 280], [770, 380], [750, 400], [650, 300]]],
               ('ship', ),
               confidence=0.1),
        Record([[[-20, 600], [50, 600], [50, 650], [-20, 650], [-20, 600]]],
               ('ship', ),
               confidence=0.927),
        Record([[[700, 600], [800, 600], [800, 650], [700, 650], [700, 600]]],
               ('vessel', ),
               confidence=0.927),
        Record([[[500, -50], [550, -50], [550, 50], [500, 50], [500, -50]]],
               ('boat', ),
               confidence=0.5647),
        Record([[[500, 750], [550, 750], [550, 850], [500, 850], [500, 750]]],
               ('vessel', ),
               confidence=0.1763),
    ]

    # Create collection
    records_collection = RecordCollection(*records)

    # Instantiate a tile
    tile = TileWrapper(np.zeros((768, 768, 3), dtype=np.uint8),
                       filename=Path('84c1b28caecf.png'))

    # Create a data point like
    return tile, records_collection
Ejemplo n.º 6
0
    def test_add_title(self):
        import PIL.Image
        import numpy as np

        # Create data points
        records = [
            Record(
                [[[100, 100], [100, 150], [150, 150], [150, 100], [100, 100]]],
                ['car'],
                confidence=0.9),
        ]
        records_collection = RecordCollection(*records)
        annotation = Annotation(records_collection)
        tile = TileWrapper(np.zeros((100, 100, 3)), filename='test.png')
        data_point = DataPoint(tile, annotation)
        data_points = [data_point]

        # Color engine interface
        simple_categorical_interface = {
            'name': 'Name(Main, Secondary)',
            'type': 'categorical',
            'schema': {
                'Ship': Color(26, 188, 156, ctype='sRGB255'),
                'Car': Color(241, 196, 15, ctype='sRGB255'),
                'Truck': Color(41, 128, 185, ctype='sRGB255'),
                'Wind-turbines': Color(236, 240, 241, ctype='sRGB255')
            }
        }

        # Parameters
        width, height = (300, 300)
        background_color = (0, 0, 0)
        title_size = 25

        # Init compositor
        _compositor = Compositor(
            data_points=data_points,
            color_engine_interface=simple_categorical_interface)

        image = PIL.Image.fromarray(np.zeros((width, height)))

        # Add title
        final_image = _compositor._add_title(mosaic=image,
                                             title='',
                                             background_color=background_color,
                                             title_size=title_size)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.width == width
        assert final_image.height == height + 2 * title_size
Ejemplo n.º 7
0
    def test_compute_label_starting_point(self):
        # Check
        dummy_record = Record([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]],
                              ('car', ),
                              confidence=0.9)
        geometry = Geometry(record=dummy_record)
        starting_point = TagPainter._compute_label_starting_point(
            geometry=geometry, position=Position.RIGHT)

        assert isinstance(starting_point, tuple)
        assert starting_point == (1, 0)

        starting_point = TagPainter._compute_label_starting_point(
            geometry=geometry, position=Position.LEFT)

        assert isinstance(starting_point, tuple)
        assert starting_point == (0, 0)
Ejemplo n.º 8
0
    def test_compute_label_coordinates(self):
        # Parameters
        _painter = TagPainter(Confidence())

        # Check
        dummy_record = Record([[[0, 5], [20, 5], [20, 25], [0, 25], [0, 5]]],
                              ('car', ),
                              confidence=0.9)
        geometry = Geometry(record=dummy_record)
        text = ''
        font = PIL.ImageFont.load_default()  # size = 11
        text_width, text_height = font.getsize(text)
        tile_width = 50

        label_coordinates, text_coordinates = _painter._compute_label_coordinates(
            geometry=geometry, text=text, font=font, tile_width=tile_width)

        assert isinstance(label_coordinates, list)
        assert len(label_coordinates) == 5
        for coordinate in label_coordinates:
            assert isinstance(coordinate, tuple)
            assert len(coordinate) == 2
        assert isinstance(text_coordinates, tuple)
Ejemplo n.º 9
0
def _make_record(*property_pair):
    r = Record([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]], ('dummy', ), 2.0)
    for property_name, value in property_pair:
        if property_name not in ('labels', 'confidence'):
            r.properties[property_name] = value
    return r
Ejemplo n.º 10
0
    def test_record_collection(self):
        import geojson
        r = Record([0, 1, 2], ('car', 'road vehicle'),
                   some_property='some property',
                   another_property=45)
        r2 = Record([[[0, 0], [0, 1], [1, 1], [0, 0]]],
                    ('car', 'road vehicle'),
                    some_property='some property',
                    another_property=42)
        r3 = Record([[[0, 0], [0, 1], [1, 1], [0, 0]]],
                    ('car', 'road vehicle'),
                    some_property='some properties',
                    another_property=42)

        rc = RecordCollection(r, r2)

        crc_frc = CategoricalRecordCollection.from_record_collection(
            'another_property', rc)
        crc = CategoricalRecordCollection('another_property', r, r2)

        assert len(crc) == 2
        assert len(crc_frc) == 2

        assert crc[1] == r2
        assert crc_frc[1] == r2

        assert crc[1, 0] == r2
        assert crc_frc[1, 0] == r2

        crc[1, 0] = r3
        crc_frc[1, 0] = r3
        assert crc[1, 0] == r3
        assert crc_frc[1, 0] == r3

        assert crc.loc[42, 0] == r3
        assert crc_frc.loc[42, 0] == r3

        crc.loc[42, 0] = r2
        crc_frc.loc[42, 0] = r2
        assert crc.loc[42, 0] == r2
        assert crc_frc.loc[42, 0] == r2

        assert geojson.dumps(crc, sort_keys=True) == '{"features": [' \
                                                     '{"geometry": {"coordinates": [0, 1, 2], "type": "Point"}, ' \
                                                     '"properties": {"another_property": 45, ' \
                                                     '"category": ["car", "road vehicle"], ' \
                                                     '"confidence": null, "some_property": "some property"}, ' \
                                                     '"type": "Feature"}, ' \
                                                     '{"geometry": {"coordinates": ' \
                                                     '[[[0, 0], [0, 1], [1, 1], [0, 0]]], ' \
                                                     '"type": "Polygon"}, ' \
                                                     '"properties": {"another_property": 42, ' \
                                                     '"category": ["car", "road vehicle"], ' \
                                                     '"confidence": null, ' \
                                                     '"some_property": "some property"}, "type": "Feature"}], ' \
                                                     '"type": "FeatureCollection"}'

        assert geojson.dumps(crc_frc, sort_keys=True) == '{"features": [' \
                                                         '{"geometry": {"coordinates": [0, 1, 2], "type": "Point"}, ' \
                                                         '"properties": {"another_property": 45, ' \
                                                         '"category": ["car", "road vehicle"], ' \
                                                         '"confidence": null, "some_property": "some property"}, ' \
                                                         '"type": "Feature"}, ' \
                                                         '{"geometry": {"coordinates": ' \
                                                         '[[[0, 0], [0, 1], [1, 1], [0, 0]]], ' \
                                                         '"type": "Polygon"}, ' \
                                                         '"properties": {"another_property": 42, ' \
                                                         '"category": ["car", "road vehicle"], ' \
                                                         '"confidence": null, ' \
                                                         '"some_property": "some property"}, "type": "Feature"}], ' \
                                                         '"type": "FeatureCollection"}'
Ejemplo n.º 11
0
    def test_constructor(self):
        # Create data points
        records = [
            Record(
                [[[100, 100], [100, 150], [150, 150], [150, 100], [100, 100]]],
                ['car'],
                confidence=0.9),
        ]
        records_collection = RecordCollection(*records)
        annotation = Annotation(records_collection)
        tile = TileWrapper(np.zeros((100, 100, 3)), filename='test.png')
        tile_2 = TileWrapper(np.zeros((200, 200, 3)), filename='test_2.png')
        data_point = DataPoint(tile, annotation)
        data_point_2 = DataPoint(tile_2, annotation)

        # Color engine interface
        simple_categorical_interface = {
            'name': 'Name(Main, Secondary)',
            'type': 'categorical',
            'schema': {
                'Ship': Color(26, 188, 156, ctype='sRGB255'),
                'Car': Color(241, 196, 15, ctype='sRGB255'),
                'Truck': Color(41, 128, 185, ctype='sRGB255'),
                'Wind-turbines': Color(236, 240, 241, ctype='sRGB255')
            }
        }

        # Valid datapoints
        data_points_1 = [data_point]
        data_points_2 = [data_point, data_point_2]
        data_points_3 = (data_point_2, )
        data_points_4 = (data_point, data_point_2)
        data_points_5 = [data_points_1]
        data_points_6 = [data_points_3]
        data_points_7 = (data_points_2, )
        data_points_8 = (data_points_4, )

        # Invalid data points
        inv_data_points_1 = None
        inv_data_points_2 = ['test']
        inv_data_points_3 = ('test', data_point)

        # Checks
        Compositor(data_points=data_points_1,
                   color_engine_interface=simple_categorical_interface)
        Compositor(data_points=data_points_2,
                   color_engine_interface=simple_categorical_interface)
        Compositor(data_points=data_points_3,
                   color_engine_interface=simple_categorical_interface)
        Compositor(data_points=data_points_4,
                   color_engine_interface=simple_categorical_interface)
        Compositor(data_points=data_points_5,
                   color_engine_interface=simple_categorical_interface)
        Compositor(data_points=data_points_6,
                   color_engine_interface=simple_categorical_interface)
        Compositor(data_points=data_points_7,
                   color_engine_interface=simple_categorical_interface)
        Compositor(data_points=data_points_8,
                   color_engine_interface=simple_categorical_interface)

        with pytest.raises(AttributeError):
            Compositor(data_points=inv_data_points_1,
                       color_engine_interface=simple_categorical_interface)

        with pytest.raises(AttributeError):
            Compositor(data_points=inv_data_points_2,
                       color_engine_interface=simple_categorical_interface)

        with pytest.raises(AttributeError):
            Compositor(data_points=inv_data_points_3,
                       color_engine_interface=simple_categorical_interface)
Ejemplo n.º 12
0
    def test_plot(self):
        import PIL.Image
        import numpy as np

        # Create data points
        records = [
            Record(
                [[[100, 100], [100, 150], [150, 150], [150, 100], [100, 100]]],
                ['car'],
                confidence=0.9,
                confidence_confidence=0.9,
                color=Color(26, 188, 156)),
        ]
        records_collection = RecordCollection(*records)
        annotation = Annotation(records_collection)
        tile = TileWrapper(np.zeros((100, 100, 3), dtype=np.uint8),
                           filename='test.png')
        data_point = DataPoint(tile, annotation)
        data_points = []

        # Legend
        simple_categorical_interface = {
            'name': 'Name(Main, Secondary)',
            'type': 'categorical',
            'schema': {
                'Ship': Color(26, 188, 156, ctype='sRGB255'),
                'Car': Color(241, 196, 15, ctype='sRGB255'),
                'Truck': Color(41, 128, 185, ctype='sRGB255'),
                'Wind-turbines': Color(236, 240, 241, ctype='sRGB255')
            }
        }

        kwargs = {
            'plot_centers': False,
            'plot_confidences': True,
            'zoom': 1,
            'alpha': 128,
            'scale': 1,
            'axis': 0,
            'background_color': (48, 56, 68, 255),
            'item_margins': (10, 10),
            'main_axis_align': 'start',
            'minor_axis_align': 'start'
        }

        # Accumulates datapoints (flattened)
        nb_datapoints = 15
        for _ in range(nb_datapoints):
            data_points.append(data_point)

        # Parameters
        _compositor = Compositor(
            data_points=data_points,
            color_engine_interface=simple_categorical_interface)
        n_cols = 10
        margins = (5, 5)

        # Test with neither title nor legend (use AdaptiveImagePositionGenerator)
        final_image = _compositor.plot(n_cols=n_cols,
                                       margins=margins,
                                       title=None,
                                       center=True,
                                       **kwargs)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.width > n_cols * (100 + 2 * margins[0])
        assert final_image.height > 2 * (100 + 2 * margins[1])  # 2 rows
        assert final_image.height < 3 * (100 + 2 * margins[1]
                                         )  # but less than 3 rows

        # Test with neither title nor legend (use SimpleImagePositionGenerator)
        final_image = _compositor.plot(n_cols=n_cols,
                                       margins=margins,
                                       title=None,
                                       center=False,
                                       **kwargs)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.width > n_cols * (100 + 2 * margins[0])
        assert final_image.height > 2 * (100 + 2 * margins[1])  # 2 rows
        assert final_image.height < 3 * (100 + 2 * margins[1]
                                         )  # but less than 3 rows

        # Nested datapoints
        nested_data_points = [[data_point, data_point, data_point, data_point],
                              [data_point, data_point, data_point],
                              [data_point, data_point, data_point, data_point],
                              [
                                  data_point, data_point, data_point,
                                  data_point, data_point
                              ], [data_point, data_point]]

        _compositor = Compositor(
            data_points=nested_data_points,
            color_engine_interface=simple_categorical_interface)

        final_image = _compositor.plot(n_cols=n_cols,
                                       margins=margins,
                                       title=None,
                                       center=True,
                                       **kwargs)

        # Check 5 cols and 5 rows (plus each tile title)
        painter_title_height = 70
        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.width > 5 * (100 + 2 * margins[0])
        assert final_image.height > 5 * (100 + 2 * margins[1])
        assert final_image.height < 5 * (100 + painter_title_height +
                                         2 * margins[1])

        # Add title
        final_image_with_title = _compositor.plot(n_cols=n_cols,
                                                  margins=margins,
                                                  title='Test',
                                                  center=True,
                                                  **kwargs)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image_with_title.width == final_image.width
        assert final_image_with_title.height > final_image.height

        # Add legend and title
        final_image_with_legend = _compositor.plot(n_cols=n_cols,
                                                   margins=margins,
                                                   title='Test',
                                                   center=True,
                                                   **kwargs)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image_with_legend.width == final_image_with_title.width
        assert final_image_with_legend.height == final_image_with_title.height
Ejemplo n.º 13
0
    def test_add_legend(self):
        import PIL.Image
        import numpy as np

        # Create data points
        records = [
            Record(
                [[[100, 100], [100, 150], [150, 150], [150, 100], [100, 100]]],
                ['car'],
                confidence=0.9),
        ]
        records_collection = RecordCollection(*records)
        annotation = Annotation(records_collection)
        tile = TileWrapper(np.zeros((100, 100, 3)), filename='test.png')
        data_point = DataPoint(tile, annotation)
        data_points = [data_point]

        # Legend
        simple_categorical_interface = {
            'name': 'Name(Main, Secondary)',
            'type': 'categorical',
            'schema': {
                'Ship': Color(26, 188, 156, ctype='sRGB255'),
                'Car': Color(241, 196, 15, ctype='sRGB255'),
                'Truck': Color(41, 128, 185, ctype='sRGB255'),
                'Wind-turbines': Color(236, 240, 241, ctype='sRGB255')
            }
        }

        legend_config = {
            'scale': 1,
            'axis': 0,
            'item_margins': (10, 10),
            'main_axis_align': 'start',
            'minor_axis_align': 'start'
        }

        # Parameters
        width, height = (300, 300)
        background_color = (0, 0, 0)

        # Init compositor
        _compositor = Compositor(
            data_points=data_points,
            color_engine_interface=simple_categorical_interface)

        image = PIL.Image.fromarray(np.zeros((width, height)))

        # Add legend
        final_image = _compositor._add_legend(
            mosaic=image, background_color=background_color, **legend_config)

        # Checks (vertical mode)
        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.height == height
        assert final_image.width > width

        # Checks horizontal mode
        legend_config['axis'] = 1
        final_image = _compositor._add_legend(
            mosaic=image, background_color=background_color, **legend_config)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.width == width
        assert final_image.height > height
Ejemplo n.º 14
0
    def test_draw(self):
        # Fake records
        invalid_records = [
            Record(
                [[[100, 100], [100, 150], [150, 150], [150, 100], [100, 100]]],
                ('car', ),
                confidence=0.9),
            Record([[[100, 100], [110, 110], [100, 100]]], ('car', ),
                   confidence=0.9),
        ]
        records = [
            Record(
                [[[100, 100], [100, 150], [150, 150], [150, 100], [100, 100]]],
                ('car', ),
                confidence=0.9,
                color=Color(255, 128, 128)),
            Record([[[100, 100], [100, 150], [100, 100]]], ('car', ),
                   confidence=0.9,
                   color=Color(128, 255, 255)),
            Record([100, 100], ('ship', ),
                   confidence=0.3,
                   color=Color(128, 255, 255)),
        ]

        # Create collection
        invalid_records_collection = RecordCollection(*invalid_records)
        records_collection = RecordCollection(*records)

        # Finally, the annotation
        invalid_annotation = Annotation(invalid_records_collection)
        annotation = Annotation(records_collection)

        # Instantiate a tile
        tile = TileWrapper(np.zeros((300, 300, 4), dtype=np.uint8),
                           filename='test.png')

        # Create a datapoint
        invalid_datapoint = DataPoint(tile, invalid_annotation)
        datapoint = DataPoint(tile, annotation)

        # Parameters
        _painter = Painter(fill=True)

        # Sanity check
        with pytest.raises(AttributeError):
            _painter.draw(invalid_datapoint)

        # Draw datapoint
        final_image = _painter.draw(datapoint)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.width == 300
        assert final_image.height == 300 + _painter.TITLE_HEIGHT

        # With centers
        _painter = Painter(plot_centers=True)

        # Sanity check
        with pytest.raises(AttributeError):
            _painter.draw(invalid_datapoint)

        # Draw datapoint
        final_image = _painter.draw(datapoint)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.width == 300
        assert final_image.height == 300 + _painter.TITLE_HEIGHT

        # Test zoom
        zoom = 2.5
        _painter = Painter(zoom=zoom)

        final_image = _painter.draw(datapoint)

        assert isinstance(final_image, PIL.Image.Image)
        assert final_image.width == 300 * zoom
        assert final_image.height == (300 + _painter.TITLE_HEIGHT) * zoom

        # Check invalid geometry
        class InvalidRecord(object):
            def __init__(self, type, coordinates):
                self.id = '1'
                self.type = type
                self.coordinates = coordinates
                self.labels = Label('test'),
                self.color = Color(255, 128, 128, ctype='sRGB255')

        records = [
            Record(
                [[[100, 100], [100, 150], [150, 150], [150, 100], [100, 100]]],
                ('car', ),
                confidence=0.9,
                color=Color(255, 128, 128)),
            Record([[[100, 100], [100, 150], [100, 100]]], ('car', ),
                   confidence=0.9,
                   color=Color(128, 255, 255)),
            InvalidRecord(type='Test', coordinates=[])
        ]

        # Create data point
        records_collection = RecordCollection(*records)
        annotation = Annotation(records_collection)
        tile = TileWrapper(np.zeros((300, 300, 4), dtype=np.uint8),
                           filename='test.png')
        data_point = DataPoint(tile, annotation)

        _painter = Painter(fill=True)

        with pytest.raises(ValueError):
            _painter.draw(data_point)
Ejemplo n.º 15
0
    def test_constructor(self):
        dummy_record_list = Record([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]],
                                   ('car', ),
                                   confidence=0.9)
        dummy_record_tuple = Record(((
            (0, 0),
            (0, 1),
            (1, 1),
            (1, 0),
            (0, 0),
        ), ), ('car', ),
                                    confidence=0.9)

        geometry_list = Geometry(record=dummy_record_list)
        geometry_tuple = Geometry(record=dummy_record_tuple)

        # Check coordinates format
        assert isinstance(geometry_list.coordinates, list)
        for i, coordinate in enumerate(geometry_list.coordinates):
            assert isinstance(coordinate, tuple)
            assert coordinate == tuple(dummy_record_list.coordinates[0][i])

        assert isinstance(geometry_tuple.coordinates, list)
        for i, coordinate in enumerate(geometry_tuple.coordinates):
            assert isinstance(coordinate, tuple)
            assert coordinate == tuple(dummy_record_tuple.coordinates[0][i])

        # Check exceptions
        class InvalidRecord(object):
            def __init__(self, type, coordinates):
                self.type = type
                self.coordinates = coordinates

        with pytest.raises(ValueError):
            Geometry(record=object())
        with pytest.raises(ValueError):
            Geometry(record=InvalidRecord(type='Point', coordinates=[1]))
        with pytest.raises(ValueError):
            Geometry(record=InvalidRecord(type='Point', coordinates=[1, 2, 3]))
        with pytest.raises(ValueError):
            Geometry(record=InvalidRecord(type='Polygon', coordinates=[[]]))
        with pytest.raises(ValueError):
            Geometry(record=InvalidRecord(
                type='Polygon', coordinates=[[[0, 0], [1, 0], [1, 1]]]))
        with pytest.raises(ValueError):
            Geometry(record=InvalidRecord(
                type='Test', coordinates=[[[0, 0], [1, 0], [1, 1]]]))
        with pytest.raises(TypeError):
            Geometry(record=InvalidRecord(type='Point', coordinates='Test'))
        with pytest.raises(TypeError):
            Geometry(
                record=InvalidRecord(type='Polygon', coordinates=['Hello']))

        # Test zoom = 2
        dummy_record = Record([[[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]],
                              ('car', ),
                              confidence=0.9)
        expected_coordinates = [(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]
        geometry_list = Geometry(record=dummy_record, zoom=2)

        assert isinstance(geometry_list.coordinates, list)
        for i, coordinate in enumerate(geometry_list.coordinates):
            assert isinstance(coordinate, tuple)
            assert coordinate == expected_coordinates[i]

        # Test zoom = 0.6
        dummy_record = Record([[[0, 0], [0, 10], [10, 10], [10, 0], [0, 0]]],
                              ('car', ),
                              confidence=0.9)
        expected_coordinates = [(0, 0), (0, 6), (6, 6), (6, 0), (0, 0)]
        geometry_list = Geometry(record=dummy_record, zoom=0.6)

        assert isinstance(geometry_list.coordinates, list)
        for i, coordinate in enumerate(geometry_list.coordinates):
            assert isinstance(coordinate, tuple)
            assert coordinate == expected_coordinates[i]
Ejemplo n.º 16
0
    def draw(self):
        """Draw the legend, along the given axis.

        The generated legend is a grid with each cell having the dimensions of the biggest item to draw.
        The grid is then filled along the main axis first. The size of the legend along the
        main axis is fixed while the size along the minor one is variable.

        Returns:
            :class:`~PIL.Image.Image`: The output legend.

        """
        # Init legend item drawer
        drawer = LegendItemDrawer(background_color=self._background_color,
                                  scale=self._scale,
                                  margins=self._item_margins)

        margin = int(drawer.TEXT_SIZE * self._scale)
        # Draw all items
        items = self._draw_items(drawer)

        # No items to draw means empty legend
        if not items:
            return PIL.Image.new(mode='RGBA', size=(0, 0))

        # Compute position for each item
        position_generator = LegendItemPositionGenerator(
            items_sizes=[item.size for item in items],
            axis=self._axis,
            max_size_along_axis=self._max_size_along_axis - 2 * margin,
            main_axis_align=self._main_axis_align,
            minor_axis_align=self._minor_axis_align)
        items_with_position = [
            (items[i], position)
            for i, position in enumerate(list(position_generator))
        ]

        # Prepare tag if needed
        upper_margin = 0
        draw = None
        if self._plot_tag:
            upper_margin = int(
                (2 * 2 + 0.75 * drawer.TEXT_SIZE + 2 * 4) * self._scale)
            # Prepare record and descriptor
            tag_descriptor = CategoricalDescriptor(name='name')
            tag_record = Record(
                coordinates=[[[0.5 * margin,
                               int(upper_margin / 2)],
                              [0.5 * margin,
                               int(upper_margin / 2) + 1],
                              [0.5 * margin + 1,
                               int(upper_margin / 2) + 1],
                              [0.5 * margin + 1,
                               int(upper_margin / 2)],
                              [0.5 * margin,
                               int(upper_margin / 2)]]],
                labels=['Dummy'],
                name=self._tag_descriptor.__descriptor__['name'],
                categorical_descriptor_name=0.5,
                color=Color(*get_outline_color(self._background_color),
                            ctype='sRGB255'))
            tag_descriptor.update(RecordCollection(tag_record))
            # Prepare TagPainter and Draw
            tag_painter = TagPainter(tag_descriptor,
                                     text_margin=2 * self._scale,
                                     text_size=0.75 * drawer.TEXT_SIZE *
                                     self._scale)
            draw = Draw(size=(int(position_generator.legend_size[0] +
                                  2 * margin), upper_margin),
                        zoom=1,
                        mode='RGBA',
                        background_color=self._background_color)
            # Draw legend tag
            tag_painter.draw(tag_record, draw=draw)

        # Create legend
        legend = PIL.Image.new(
            mode='RGBA',
            size=(position_generator.legend_size[0] + 2 * margin,
                  position_generator.legend_size[1] + 2 * margin +
                  upper_margin),
            color=self._background_color)

        for item, position in items_with_position:
            legend.alpha_composite(im=item,
                                   dest=(position[0] + margin,
                                         position[1] + margin + upper_margin))

        if draw is not None:
            legend.alpha_composite(im=draw.overlay, dest=(0, 4))

        if self._color_engine_interface['type'] == 'categorical':
            bottom_margin = position_generator.legend_size[
                1] - position_generator.true_legend_size[1]
            drawer.draw_outline_with_title(self._primary_descriptor_name,
                                           legend,
                                           margins=(0, upper_margin, 0,
                                                    bottom_margin))

        return legend