def test_squares(self): """Test polygon fill for a square polygons""" mask_shape = 4, 4 tests = { # test name: [(row min, row max), (col min, col max)] 'square in': [(1, 3), (1, 3)], 'square out': [(1, 3), (1, 10)], 'square around': [(-1, 5), (-1, 5)], } for test_name, (rows, cols) in tests.items(): with self.subTest(msg=test_name, rows=rows, cols=cols, mask_shape=mask_shape): ref_mask = numpy.zeros(mask_shape, dtype=numpy.uint8) ref_mask[max(0, rows[0]):rows[1], max(0, cols[0]):cols[1]] = True vertices = [(rows[0], cols[0]), (rows[1], cols[0]), (rows[1], cols[1]), (rows[0], cols[1])] mask = shapes.polygon_fill_mask(vertices, ref_mask.shape) is_equal = numpy.all(numpy.equal(ref_mask, mask)) if not is_equal: _logger.debug('%s failed with mask != ref_mask:', test_name) _logger.debug('result:\n%s', str(mask)) _logger.debug('ref:\n%s', str(ref_mask)) self.assertTrue(is_equal)
def test_eight(self): """Tests with eight shape with different rotation and direction""" ref_mask = numpy.array( ((1, 1, 1, 1, 1, 0), (0, 1, 1, 1, 0, 0), (0, 0, 1, 0, 0, 0), (0, 0, 1, 0, 0, 0), (0, 1, 1, 1, 0, 0), (0, 0, 0, 0, 0, 0)), dtype=numpy.uint8) ref_mask_rot = numpy.asarray(numpy.logical_not(ref_mask), dtype=numpy.uint8) ref_mask_rot[:, -1] = 0 ref_mask_rot[-1, :] = 0 tests = { 'dir 1': ([(0, 0), (5, 5), (5, 0), (0, 5)], ref_mask), 'dir 1, rot 90': ([(5, 0), (0, 5), (5, 5), (0, 0)], ref_mask_rot), 'dir 1, rot 180': ([(5, 5), (0, 0), (0, 5), (5, 0)], ref_mask), 'dir 1, rot -90': ([(0, 5), (5, 0), (0, 0), (5, 5)], ref_mask_rot), 'dir 2': ([(0, 0), (0, 5), (5, 0), (5, 5)], ref_mask), 'dir 2, rot 90': ([(5, 0), (0, 0), (5, 5), (0, 5)], ref_mask_rot), 'dir 2, rot 180': ([(5, 5), (5, 0), (0, 5), (0, 0)], ref_mask), 'dir 2, rot -90': ([(0, 5), (5, 5), (0, 0), (5, 0)], ref_mask_rot), } for test_name, (vertices, ref_mask) in tests.items(): with self.subTest(msg=test_name): mask = shapes.polygon_fill_mask(vertices, ref_mask.shape) is_equal = numpy.all(numpy.equal(ref_mask, mask)) if not is_equal: _logger.debug('%s failed with mask != ref_mask:', test_name) _logger.debug('result:\n%s', str(mask)) _logger.debug('ref:\n%s', str(ref_mask)) self.assertTrue(is_equal)
def test_eight(self): """Tests with eight shape with different rotation and direction""" ref_mask = numpy.array(( (1, 1, 1, 1, 1, 0), (0, 1, 1, 1, 0, 0), (0, 0, 1, 0, 0, 0), (0, 0, 1, 0, 0, 0), (0, 1, 1, 1, 0, 0), (0, 0, 0, 0, 0, 0)), dtype=numpy.uint8) ref_mask_rot = numpy.asarray(numpy.logical_not(ref_mask), dtype=numpy.uint8) ref_mask_rot[:, -1] = 0 ref_mask_rot[-1, :] = 0 tests = { 'dir 1': ([(0, 0), (5, 5), (5, 0), (0, 5)], ref_mask), 'dir 1, rot 90': ([(5, 0), (0, 5), (5, 5), (0, 0)], ref_mask_rot), 'dir 1, rot 180': ([(5, 5), (0, 0), (0, 5), (5, 0)], ref_mask), 'dir 1, rot -90': ([(0, 5), (5, 0), (0, 0), (5, 5)], ref_mask_rot), 'dir 2': ([(0, 0), (0, 5), (5, 0), (5, 5)], ref_mask), 'dir 2, rot 90': ([(5, 0), (0, 0), (5, 5), (0, 5)], ref_mask_rot), 'dir 2, rot 180': ([(5, 5), (5, 0), (0, 5), (0, 0)], ref_mask), 'dir 2, rot -90': ([(0, 5), (5, 5), (0, 0), (5, 0)], ref_mask_rot), } for test_name, (vertices, ref_mask) in tests.items(): with self.subTest(msg=test_name): mask = shapes.polygon_fill_mask(vertices, ref_mask.shape) is_equal = numpy.all(numpy.equal(ref_mask, mask)) if not is_equal: _logger.debug('%s failed with mask != ref_mask:', test_name) _logger.debug('result:\n%s', str(mask)) _logger.debug('ref:\n%s', str(ref_mask)) self.assertTrue(is_equal)
def test_shapes(self): """Tests with shapes and reference mask""" tests = { # name: ( # polygon corners as a list of (row, col), # ref_mask) 'concave polygon': ([(1, 1), (4, 3), (1, 5), (2, 3)], numpy.array(((0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 1, 1, 1, 0, 0, 0), (0, 0, 0, 1, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0)), dtype=numpy.uint8)), 'concave polygon partly outside mask': ([(-1, -1), (4, 3), (1, 5), (2, 3)], numpy.array( ((1, 0, 0, 0, 0, 0), (0, 1, 0, 0, 0, 0), (0, 0, 1, 1, 1, 0), (0, 0, 0, 1, 0, 0), (0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0)), dtype=numpy.uint8)), 'polygon surrounding mask': ([(-1, -1), (-1, 7), (7, 7), (7, -1), (0, -1), (8, -2), (8, 8), (-2, 8)], numpy.zeros((6, 6), dtype=numpy.uint8)) } for test_name, (vertices, ref_mask) in tests.items(): with self.subTest(msg=test_name): mask = shapes.polygon_fill_mask(vertices, ref_mask.shape) is_equal = numpy.all(numpy.equal(ref_mask, mask)) if not is_equal: _logger.debug('%s failed with mask != ref_mask:', test_name) _logger.debug('result:\n%s', str(mask)) _logger.debug('ref:\n%s', str(ref_mask)) self.assertTrue(is_equal)
def _handleDraw(self, event): if event['event'] not in ('drawingProgress', 'drawingFinished'): return points = numpy.array((event['ydata'], event['xdata'])).T mask = polygon_fill_mask(points, (self.SIZE, self.SIZE)) self.addImage(mask, legend='mask', colormap=self._mask_colormap, replace=False, resetzoom=False)
def updatePolygon(self, level, vertices, mask=True): """Mask/Unmask a polygon of the given mask level. :param int level: Mask level to update. :param vertices: Nx2 array of polygon corners as (row, col) :param bool mask: True to mask (default), False to unmask. """ fill = shapes.polygon_fill_mask(vertices, self._mask.shape) if mask: self._mask[fill != 0] = level else: self._mask[numpy.logical_and(fill != 0, self._mask == level)] = 0 self._notify()
def test_shapes(self): """Tests with shapes and reference mask""" tests = { # name: ( # polygon corners as a list of (row, col), # ref_mask) 'concave polygon': ( [(1, 1), (4, 3), (1, 5), (2, 3)], numpy.array(( (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 1, 1, 1, 0, 0, 0), (0, 0, 0, 1, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0, 0)), dtype=numpy.uint8)), 'concave polygon partly outside mask': ( [(-1, -1), (4, 3), (1, 5), (2, 3)], numpy.array(( (1, 0, 0, 0, 0, 0), (0, 1, 0, 0, 0, 0), (0, 0, 1, 1, 1, 0), (0, 0, 0, 1, 0, 0), (0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0)), dtype=numpy.uint8)), 'polygon surrounding mask': ( [(-1, -1), (-1, 7), (7, 7), (7, -1), (0, -1), (8, -2), (8, 8), (-2, 8)], numpy.zeros((6, 6), dtype=numpy.uint8)) } for test_name, (vertices, ref_mask) in tests.items(): with self.subTest(msg=test_name): mask = shapes.polygon_fill_mask(vertices, ref_mask.shape) is_equal = numpy.all(numpy.equal(ref_mask, mask)) if not is_equal: _logger.debug('%s failed with mask != ref_mask:', test_name) _logger.debug('result:\n%s', str(mask)) _logger.debug('ref:\n%s', str(ref_mask)) self.assertTrue(is_equal)