def find(self, image: Image) -> Tuple[Rectangle, Angle]: play_area = self._play_area_finder.find(image) image.crop(play_area).process(self._process) self._goal = Rectangle( self._goal.top_left_corner.x + play_area.top_left_corner.x, self._goal.top_left_corner.y + play_area.top_left_corner.y, self._goal.width, self._goal.height) return self._goal, self._orientation
def take_picture(self) -> Image: count = self._buffer_size while count > 0: self._video_capture.grab() count -= 1 has_captured, cv_image = self._video_capture.read() if not has_captured: raise AcquisitionError() return Image(cv_image)
def draw(self, image: Image, path: Path) -> Image: image_content = image.content for movement in path.movements: start_relative_coords = self._get_coord_relative_to_table( image, movement.start) end_relative_coords = self._get_coord_relative_to_table( image, movement.end) start_coords = (start_relative_coords.x, start_relative_coords.y) end_coords = (end_relative_coords.x, end_relative_coords.y) cv2.line(image_content, start_coords, end_coords, (255, 0, 0), 5) return Image(image_content)
def take_picture(self) -> Image: blank_image = np.zeros((self._height, self._width, 3), np.uint8) blank_image[:, 0:self._width // 6] = (255, 0, 0) blank_image[:, 1 * self._width // 6:2 * self._width // 6] = (255, 255, 0) blank_image[:, 2 * self._width // 6:3 * self._width // 6] = (0, 255, 0) blank_image[:, 3 * self._width // 6:4 * self._width // 6] = (0, 255, 255) blank_image[:, 4 * self._width // 6:5 * self._width // 6] = (0, 0, 255) blank_image[:, 5 * self._width // 6:self._width] = (255, 0, 255) return Image(blank_image)
def take_picture(self) -> Image: count = self._buffer_size while count > 0: self._video_capture.grab() count -= 1 has_captured, cv_image = self._video_capture.read() if not has_captured: raise AcquisitionError() self.image_display.display_debug_image('[OpenCvCamera] take_picture', cv_image) return Image(cv_image)
def main(): camera = OpenCvCamera(0) image = Image(cv2.imread('my_photo-4.jpg')) item_finder = HSVItemFinder() should_continue = True while should_continue: items = item_finder.find_items(image) for item in items.items: print('Color: {}, Shape: {}, Position: ({}, {})'.format(item.item.color, item.item.shape, item.camera_coordinate.x, item.camera_coordinate.y)) key = cv2.waitKey(0) if key == ord('q'): should_continue = False cv2.destroyAllWindows()
def draw_robot(self, image: Image, position: Position) -> Image: image_content = image.content self._old_points.append(position) for i in range(len(self._old_points)): try: relative_position_start = self._get_coord_relative_to_table( image, self._old_points[i].coordinate) relative_position_end = self._get_coord_relative_to_table( image, self._old_points[i + 1].coordinate) except IndexError: continue cv2.line(image_content, (relative_position_start.x, relative_position_start.y), (relative_position_end.x, relative_position_end.y), (100, 100, 100), 1) start_relative_coords = self._get_coord_relative_to_table( image, position.coordinate) start_coords = (start_relative_coords.x, start_relative_coords.y) calculated_coords = self._calculate_coords_with_orientation(position) end_relative_coords = self._get_coord_relative_to_table( image, calculated_coords) end_coords = (end_relative_coords.x, end_relative_coords.y) cv2.line(image_content, start_coords, end_coords, (255, 0, 255), 4) return Image(image_content)
def find(self, image: Image) -> Tuple[Coord, Angle]: image.process(self._process) return self._robot, self._orientation
def find_items(self, image: Image) -> ItemRelativePositions: image.process(self._process) return self._items_relative_positions
def rectify_image(self, image: Image) -> Image: rectified_image = image.process(self._process_rectify) self._image_display.display_debug_image( '[OpenCvCameraCalibration] rectified_image', rectified_image.content) return rectified_image
def take_picture(self) -> Image: data = cv2.imread(self._path) return Image(data)
def find(self, image: Image) -> Tuple[Rectangle, Angle]: image.process(self._process) return self._source, self._orientation
class TestVisionService(TestCase): valid_camera_ids_int = [0, 2] valid_camera_ids_str = ['0', '2'] invalid_camera_id_int = 1 invalid_camera_id_str = '1' calibration_file_path = 'path' image = Image(np.zeros((50, 50, 3))) def setUp(self) -> None: self.camera_factory = Mock() self.play_area_finder = Mock() self.goal_finder = Mock() self.source_finder = Mock() self.obstacle_finder = Mock() self.robot_finder = Mock() self.camera_calibration_factory = Mock() self.camera_calibration = Mock() self.camera_drawer = Mock() self.vision_service = VisionService( self.camera_factory, self.camera_calibration_factory, self.camera_drawer, self.play_area_finder, self.goal_finder, self.source_finder, self.obstacle_finder, self.robot_finder) def initialiseService(self) -> None: self.camera = Mock() self.camera_factory.create_camera = Mock(return_value=self.camera) self.camera.take_picture = Mock(return_value=self.image) self.camera_calibration_factory.load_calibration_from_file = Mock( return_value=self.camera_calibration) self.camera_calibration.rectify_image = Mock(return_value=self.image) self.vision_service.set_camera(self.valid_camera_ids_str[0], self.calibration_file_path) def test_when_service_first_created_then_it_is_not_initialized( self) -> None: self.assertFalse(self.vision_service._initialized.is_set()) def test_when_camera_ids_requested_then_ids_from_camera_factory_returned_as_string( self) -> None: self.camera_factory.get_cameras = Mock( return_value=self.valid_camera_ids_int) expected_values = self.valid_camera_ids_str actual_values = self.vision_service.get_camera_ids() self.assertListEqual(expected_values, actual_values) def test_when_camera_set_with_valid_id_then_service_is_initialized( self) -> None: self.initialiseService() self.camera_factory.create_camera.assert_called_with( self.valid_camera_ids_int[0]) self.camera.take_picture.assert_called_once() self.camera_calibration_factory.load_calibration_from_file.assert_called_with( self.calibration_file_path, self.image) self.camera_calibration.rectify_image.assert_called_once() self.assertTrue(self.vision_service._initialized.is_set()) def test_when_camera_set_with_invalid_id_then_CameraDoesNotExistError_is_raised( self) -> None: self.camera_factory.create_camera = Mock( side_effect=CameraDoesNotExistError(self.invalid_camera_id_int)) self.assertRaises(CameraDoesNotExistError, self.vision_service.set_camera, self.invalid_camera_id_str, self.calibration_file_path) def test_when_updated_then_attached_observers_are_notified(self) -> None: self.initialiseService() observer = Mock() self.vision_service.attach(observer) self.vision_service.update() observer.update.assert_called_once() def test_when_get_goal_then_center_of_goal_and_orientation_are_returned_as_real_coordinate( self) -> None: self.initialiseService() expected_coord = Coord(0, 0) expected_angle = Angle(0) self.goal_finder.find = Mock(return_value=(Rectangle(0, 0, 10, 8), expected_angle)) self.camera_calibration.convert_table_pixel_to_real = Mock( return_value=Coord(0, 0)) position = self.vision_service.get_goal() actual_coord = position.coordinate actual_angle = position.orientation self.camera_calibration.convert_table_pixel_to_real.assert_called_with( Coord(5, 4)) self.assertEqual(expected_coord, actual_coord) self.assertEqual(expected_angle, actual_angle) def test_when_get_source_then_center_of_source_and_orientation_are_returned_as_real_coordinate( self) -> None: self.initialiseService() expected_coord = Coord(0, 0) expected_angle = Angle(0) self.source_finder.find = Mock(return_value=(Rectangle(0, 0, 10, 8), expected_angle)) self.camera_calibration.convert_table_pixel_to_real = Mock( return_value=Coord(0, 0)) position = self.vision_service.get_source() actual_coord = position.coordinate actual_angle = position.orientation self.camera_calibration.convert_table_pixel_to_real.assert_called_with( Coord(5, 4)) self.assertEqual(expected_coord, actual_coord) self.assertEqual(expected_angle, actual_angle)
def find_destination(self, image: Image, destination: int) -> CameraCoordinate: self._destination_to_find = destination image.process(self._process) return self._destination_coordinate
def draw_source(self, image: Image, source: Rectangle) -> Image: if source is not None: self._color = (0, 255, 0) self._rectangle = source image = image.process(self._draw_rectangle) return image
def draw_obstacles(self, image: Image, obstacles: List[Rectangle]) -> Image: for obstacle in obstacles: self._color = (0, 0, 255) self._rectangle = obstacle image = image.process(self._draw_rectangle) return image
def draw_goal(self, image: Image, goal: Rectangle) -> Image: if goal is not None: self._color = (255, 0, 0) self._rectangle = goal image = image.process(self._draw_rectangle) return image
def find(self, image: Image) -> List[Rectangle]: image.process(self._process) return self._obstacles
def rectify_image(self, image: Image) -> Image: return image.process(self._process_rectify)
def read_qr_code(self, image: Image) -> str: image.process(self._process) return self._code
def find(self, image: Image) -> Rectangle: image.process(self._process) return self._play_area
def to_image(image_string: str) -> Image: with io.StringIO(image_string) as file_stream: encoded_image = numpy.loadtxt(file_stream, dtype='uint8') decoded_image = cv2.imdecode(encoded_image, cv2.IMREAD_COLOR) return Image(decoded_image)
def get_image(self) -> Image: return Image(self._image.content)