|
9 | 9 | import libcamera |
10 | 10 | import picamera2 |
11 | 11 | except ImportError: |
12 | | - pass |
| 12 | + picamera2 = None |
13 | 13 |
|
14 | 14 | from . import base_camera |
15 | 15 |
|
@@ -62,76 +62,93 @@ def to_dict(self) -> dict[str, int | float]: |
62 | 62 | return camera_controls |
63 | 63 |
|
64 | 64 |
|
65 | | -class CameraPiCamera2(base_camera.BaseCameraDevice): |
66 | | - """ |
67 | | - Class for the Picamera2 implementation of the camera. |
68 | | - """ |
69 | | - |
70 | | - __create_key = object() |
| 65 | +if picamera2 is None: |
71 | 66 |
|
72 | | - @classmethod |
73 | | - def create( |
74 | | - cls, width: int, height: int, config: ConfigPiCamera2 |
75 | | - ) -> "tuple[True, CameraPiCamera2] | tuple[False, None]": |
| 67 | + class CameraPiCamera2(base_camera.BaseCameraDevice): |
76 | 68 | """ |
77 | | - Picamera2 Camera. |
78 | | -
|
79 | | - width: Width of the camera. |
80 | | - height: Height of the camera. |
81 | | - config: Configuration for PiCamera2 camera. |
82 | | -
|
83 | | - Return: Success, camera object. |
| 69 | + Class for the Picamera2 import failure. |
84 | 70 | """ |
85 | | - if width <= 0: |
86 | | - return False, None |
87 | | - |
88 | | - if height <= 0: |
89 | | - return False, None |
90 | | - |
91 | | - try: |
92 | | - camera = picamera2.Picamera2() |
93 | | - |
94 | | - camera_config = camera.create_preview_configuration( |
95 | | - {"size": (width, height), "format": "RGB888"} |
96 | | - ) |
97 | | - camera.configure(camera_config) |
98 | | - camera.start() |
99 | | - controls = config.to_dict() |
100 | | - camera.set_controls(controls) |
101 | 71 |
|
102 | | - return True, CameraPiCamera2(cls.__create_key, camera, config) |
103 | | - except RuntimeError: |
| 72 | + @classmethod |
| 73 | + def create(cls, width: int, height: int, config: ConfigPiCamera2) -> "tuple[False, None]": |
104 | 74 | return False, None |
105 | 75 |
|
106 | | - def __init__( |
107 | | - self, |
108 | | - class_private_create_key: object, |
109 | | - camera: picamera2.Picamera2, |
110 | | - config: ConfigPiCamera2, |
111 | | - ) -> None: |
112 | | - """ |
113 | | - Private constructor, use create() method. |
114 | | - """ |
115 | | - assert class_private_create_key is CameraPiCamera2.__create_key, "Use create() method." |
| 76 | + def __init__(self) -> None: |
| 77 | + pass |
116 | 78 |
|
117 | | - self.__camera = camera |
118 | | - self.__config = config |
| 79 | +else: |
119 | 80 |
|
120 | | - def __del__(self) -> None: |
| 81 | + class CameraPiCamera2(base_camera.BaseCameraDevice): |
121 | 82 | """ |
122 | | - Destructor. Release hardware resources. |
| 83 | + Class for the Picamera2 implementation of the camera. |
123 | 84 | """ |
124 | | - self.__camera.close() |
125 | | - |
126 | | - def run(self) -> tuple[True, np.ndarray] | tuple[False, None]: |
127 | | - """ |
128 | | - Takes a picture with Picamera2 camera. |
129 | | -
|
130 | | - Return: Success, image with shape (height, width, channels in BGR). |
131 | | - """ |
132 | | - try: |
133 | | - image_data = self.__camera.capture_array(wait=self.__config.timeout) |
134 | | - except TimeoutError: |
135 | | - return False, None |
136 | 85 |
|
137 | | - return True, image_data |
| 86 | + __create_key = object() |
| 87 | + |
| 88 | + @classmethod |
| 89 | + def create( |
| 90 | + cls, width: int, height: int, config: ConfigPiCamera2 |
| 91 | + ) -> "tuple[True, CameraPiCamera2] | tuple[False, None]": |
| 92 | + """ |
| 93 | + Picamera2 Camera. |
| 94 | +
|
| 95 | + width: Width of the camera. |
| 96 | + height: Height of the camera. |
| 97 | + config: Configuration for PiCamera2 camera. |
| 98 | +
|
| 99 | + Return: Success, camera object. |
| 100 | + """ |
| 101 | + |
| 102 | + if width <= 0: |
| 103 | + return False, None |
| 104 | + |
| 105 | + if height <= 0: |
| 106 | + return False, None |
| 107 | + |
| 108 | + try: |
| 109 | + camera = picamera2.Picamera2() |
| 110 | + |
| 111 | + camera_config = camera.create_preview_configuration( |
| 112 | + {"size": (width, height), "format": "RGB888"} |
| 113 | + ) |
| 114 | + camera.configure(camera_config) |
| 115 | + camera.start() |
| 116 | + controls = config.to_dict() |
| 117 | + camera.set_controls(controls) |
| 118 | + |
| 119 | + return True, CameraPiCamera2(cls.__create_key, camera, config) |
| 120 | + except RuntimeError: |
| 121 | + return False, None |
| 122 | + |
| 123 | + def __init__( |
| 124 | + self, |
| 125 | + class_private_create_key: object, |
| 126 | + camera: picamera2.Picamera2, # type: ignore |
| 127 | + config: ConfigPiCamera2, |
| 128 | + ) -> None: |
| 129 | + """ |
| 130 | + Private constructor, use create() method. |
| 131 | + """ |
| 132 | + assert class_private_create_key is CameraPiCamera2.__create_key, "Use create() method." |
| 133 | + |
| 134 | + self.__camera = camera |
| 135 | + self.__config = config |
| 136 | + |
| 137 | + def __del__(self) -> None: |
| 138 | + """ |
| 139 | + Destructor. Release hardware resources. |
| 140 | + """ |
| 141 | + self.__camera.close() |
| 142 | + |
| 143 | + def run(self) -> tuple[True, np.ndarray] | tuple[False, None]: |
| 144 | + """ |
| 145 | + Takes a picture with Picamera2 camera. |
| 146 | +
|
| 147 | + Return: Success, image with shape (height, width, channels in BGR). |
| 148 | + """ |
| 149 | + try: |
| 150 | + image_data = self.__camera.capture_array(wait=self.__config.timeout) |
| 151 | + except TimeoutError: |
| 152 | + return False, None |
| 153 | + |
| 154 | + return True, image_data |
0 commit comments