Ejemplo n.º 1
0
class IslandDetector(Detector):

    MAX_SEGMENT_COUNT = 12
    PLAYFIELD_RECT_MASK_SCALE = Vector2(1, 1.1)
    
    def __init__(self, coordinate_factory):
        self._island_factory = IslandFactory(coordinate_factory)
        self._simple_shape_finder = SimpleShapeFinder()
        self._contour_filter = ContourFilter(min_size_scale = 0.75, max_size_scale = 1.5, min_aspect_ratio = 0.8, max_aspect_ratio = 1.2, min_area_scale = 0.5, max_area_scale = 2)

    def detect(self, image, playfield, color_ranges, island_color, robot):
        Logger.get_instance().log(self, "Island Detection", details = "Detection started. Color: {0}.".format(island_color))
        self._contour_filter.target_size = Coordinate.translate_physical_to_game(Island.AVERAGE_PHYSICAL_SIZE_CM, playfield)
        self._contour_filter.target_area = self._contour_filter.target_size.area
        return self._perform_detection(image.clone(), playfield, color_ranges, island_color, robot)

    def _perform_detection(self, image, playfield, color_ranges, island_color, robot):
        island_zone = playfield.rect.clone().scale_centered(self.PLAYFIELD_RECT_MASK_SCALE)
        island_zone_mask = self._create_island_zone_mask(image, island_zone, robot)
        island_zone_image = self._apply_mask(image, island_zone_mask)
        island_mask = self._create_mask(island_zone_image, color_ranges, closure_kernel_size = 7)
        contours = self._find_contours(island_mask, island_zone_image)
        return self._detect_islands_from_contours(contours, island_color)

    def _create_island_zone_mask(self, image, island_zone, robot):
        mask = Image.from_attributes(image.width, image.height, ColorMode.BLACK_AND_WHITE)
        OpenCV.fill_rectangle(mask, island_zone, Color.WHITE)
        self._mask_robot(mask, robot)
        self._log_detection_step("Island Zone Mask", mask)
        return mask

    def _mask_robot(self, mask, robot):
        if robot is not None:
            OpenCV.fill_rotated_rectangle(mask, robot.get_rotated_rect(CoordinateSystem.CAMERA), Color.BLACK)

    def _detect_islands_from_contours(self, contours, island_color):
        islands = []
        filtered_contours = self._contour_filter.filter_contours(contours)
        for contour in filtered_contours:
            islands.append(self._create_island_from_contour(contour, island_color))
        Logger.get_instance().log(self, "Island Detection", details = "Detected islands: {0}.".format(len(islands)))
        return islands

    def _create_island_from_contour(self, contour, island_color):
        simplified_path, enclosing_circle = self._simple_shape_finder.find_shape(contour, self.MAX_SEGMENT_COUNT)
        return self._island_factory.create_island(IslandType.from_segment_count(simplified_path.segment_count), island_color, simplified_path, enclosing_circle)