Ejemplo n.º 1
0
 def __init__(self, coordinate_factory, robot_factory):
     self._coordinate_factory = coordinate_factory
     self._playfield_detector = PlayfieldDetector()
     self._robot_detector = RobotDetector(robot_factory)
     self._charging_station_detector = ChargingStationDetector(self._coordinate_factory)
     self._island_detector = IslandDetector(self._coordinate_factory)
     self._treasure_detector = TreasureDetector(self._coordinate_factory)
     self._image_straightening_angle = None
     self._image = None
     self._playfield = None
     self._robot = None
     self._charging_station = None
     self._islands = []
     self._treasures = []
Ejemplo n.º 2
0
class WorldDetector(Detector):
    MAX_IMAGE_SIZE = Vector2(800, 600)
    RED_ISLAND_COLOR_RANGES = [ColorRange(Color.from_hsv(0, 100, 95), Color.from_hsv(20, 255, 255)), ColorRange(Color.from_hsv(340, 100, 100), Color.from_hsv(360, 255, 255))]
    YELLOW_ISLAND_COLOR_RANGE = ColorRange(Color.from_hsv(44, 170, 128), Color.from_hsv(80, 255, 255))
    GREEN_ISLAND_COLOR_RANGE = ColorRange(Color.from_hsv(82, 100, 95), Color.from_hsv(168, 255, 255))
    BLUE_ISLAND_COLOR_RANGE = ColorRange(Color.from_hsv(170, 100, 95), Color.from_hsv(250, 255, 255))

    def __init__(self, coordinate_factory, robot_factory):
        self._coordinate_factory = coordinate_factory
        self._playfield_detector = PlayfieldDetector()
        self._robot_detector = RobotDetector(robot_factory)
        self._charging_station_detector = ChargingStationDetector(self._coordinate_factory)
        self._island_detector = IslandDetector(self._coordinate_factory)
        self._treasure_detector = TreasureDetector(self._coordinate_factory)
        self._image_straightening_angle = None
        self._image = None
        self._playfield = None
        self._robot = None
        self._charging_station = None
        self._islands = []
        self._treasures = []

    def detect_objects(self, image, world_object_types):
        self._image = image.clone()
        self._pre_process_image(self._image, world_object_types)
        if WorldObjectType.PLAYFIELD in world_object_types:
            self._playfield = self._detect_playfield(self._image)
        self._set_image_padding(self._image)
        if WorldObjectType.ROBOT in world_object_types and self._playfield is not None:
            self._robot = self._detect_robot(self._image, self._playfield)
        if WorldObjectType.CHARGING_STATION in world_object_types and self._playfield is not None:
            self._charging_station = self._detect_charging_station(self._image, self._playfield)
        if WorldObjectType.ISLAND in world_object_types and self._playfield is not None:
            self._islands = self._detect_islands(self._image, self._playfield, self._robot)
        if WorldObjectType.TREASURE in world_object_types and self._playfield is not None:
            self._treasures = self._detect_treasures(self._image, self._playfield, self._robot, self._islands)
        return WorldDescriptor(world_object_types, self._image, self._playfield, self._robot, self._charging_station, self._islands, self._treasures)

    def _pre_process_image(self, image, world_object_types):
        self._resize_image(image)
        self._straighten_image(image, world_object_types)
        self._set_image_brightness(image)

    def _resize_image(self, image):
        if image.size > self.MAX_IMAGE_SIZE:
            image.resize(image.size.shrink_to_fit(self.MAX_IMAGE_SIZE))
        self._log_detection_step("Resize", image)

    def _straighten_image(self, image, world_object_types):
        if WorldObjectType.PLAYFIELD in world_object_types:
            self._image_straightening_angle = self._calculate_image_straightening_angle(image)
        image.rotate(-self._image_straightening_angle, ImageRotationMode.FIT_INNER)
        self._log_detection_step("Straighten", image)

    def _calculate_image_straightening_angle(self, image):
        grayscale_image = image.to_grayscale()
        self._log_detection_step("Convert to grayscale", grayscale_image)
        hough_lines = OpenCV.hough_lines(grayscale_image)
        return Segment.average_angle_snap_value(hough_lines)

    def _set_image_brightness(self, image):
        image.set_brightness(target_brightness_level = 150)
        self._log_detection_step("Brightness Adjust", image)

    def _detect_playfield(self, image):
        try:
            playfield = self._playfield_detector.detect(image)
        except DetectionError as e:
            Logger.get_instance().log(self, "Playfield Detection Failed", LogEntryType.DEBUG, error = e, blob_data = image)
            return None
        self._coordinate_factory.set_playfield(playfield)
        self._coordinate_factory.set_image_size(image.size)
        return playfield

    def _set_image_padding(self, image):
        if self._playfield is not None and self._playfield.rect.width > image.width:
            padding_value = (self._playfield.rect.width - image.width) / 2
            image.pad(0, 0, padding_value, padding_value, Color.GRAY)

    def _detect_robot(self, image, playfield):
        try:
            return self._robot_detector.detect(image, playfield)
        except DetectionError as e:
            Logger.get_instance().log(self, "Robot Detection Failed", LogEntryType.DEBUG, error = e, blob_data = image)
            return None

    def _detect_charging_station(self, image, playfield):
        try:
            return self._charging_station_detector.detect(image, playfield)
        except DetectionError as e:
            Logger.get_instance().log(self, "Charging Station Detection Failed", LogEntryType.DEBUG, error = e, blob_data = image)
            return None

    def _detect_islands(self, image, playfield, robot):
        islands = []
        islands.extend(self._island_detector.detect(image, playfield, self.RED_ISLAND_COLOR_RANGES, IslandColor.RED, robot))
        islands.extend(self._island_detector.detect(image, playfield, self.YELLOW_ISLAND_COLOR_RANGE, IslandColor.YELLOW, robot))
        islands.extend(self._island_detector.detect(image, playfield, self.GREEN_ISLAND_COLOR_RANGE, IslandColor.GREEN, robot))
        islands.extend(self._island_detector.detect(image, playfield, self.BLUE_ISLAND_COLOR_RANGE, IslandColor.BLUE, robot))
        return islands

    def _detect_treasures(self, image, playfield, robot, islands):
        return self._treasure_detector.detect(image, playfield, robot, islands)