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)