Add camera rotation feature with configurable degrees

This commit is contained in:
2026-05-07 00:39:18 +02:00
parent ec4872a5d6
commit 673cc64169
4 changed files with 19 additions and 0 deletions

View File

@@ -34,6 +34,7 @@ Glowny plik konfiguracji: `app_config.json`.
Istotne ustawienia: Istotne ustawienia:
- `camera.width`, `camera.height`, `camera.fps` - rozdzielczosc i FPS kamery. - `camera.width`, `camera.height`, `camera.fps` - rozdzielczosc i FPS kamery.
- `camera.rotation_degrees` - obrot obrazu z kamery: `0`, `90`, `180` albo `270`.
- `camera.properties` - parametry OpenCV ustawiane na kamerze, np. jasnosc, kontrast, ekspozycja. `null` oznacza brak wymuszania wartosci. - `camera.properties` - parametry OpenCV ustawiane na kamerze, np. jasnosc, kontrast, ekspozycja. `null` oznacza brak wymuszania wartosci.
- `detection.mode` - `best` rysuje najlepsza etykiete, `all` rysuje wszystkie wykrycia. - `detection.mode` - `best` rysuje najlepsza etykiete, `all` rysuje wszystkie wykrycia.
- `detection.frame_stride` - YOLO uruchamiany co N klatek podczas aktywnego wykrywania. - `detection.frame_stride` - YOLO uruchamiany co N klatek podczas aktywnego wykrywania.

View File

@@ -35,6 +35,19 @@ def backend_for_name(name: str) -> int:
return cv2.CAP_ANY return cv2.CAP_ANY
def rotate_frame(frame: np.ndarray, degrees: int) -> np.ndarray:
normalized = degrees % 360
if normalized == 0:
return frame
if normalized == 90:
return cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
if normalized == 180:
return cv2.rotate(frame, cv2.ROTATE_180)
if normalized == 270:
return cv2.rotate(frame, cv2.ROTATE_90_COUNTERCLOCKWISE)
return frame
class CameraWorker(QThread): class CameraWorker(QThread):
frame_ready = Signal(object) frame_ready = Signal(object)
detection_ready = Signal(object) detection_ready = Signal(object)
@@ -98,6 +111,9 @@ class CameraWorker(QThread):
time.sleep(0.2) time.sleep(0.2)
continue continue
with self._lock:
rotation_degrees = int(self.config["camera"].get("rotation_degrees", 0))
frame = rotate_frame(frame, rotation_degrees)
self.frame_ready.emit(frame) self.frame_ready.emit(frame)
self._maybe_detect(frame) self._maybe_detect(frame)
finally: finally:

View File

@@ -17,6 +17,7 @@ DEFAULT_CONFIG: dict[str, Any] = {
"height": 1080, "height": 1080,
"fps": 30, "fps": 30,
"backend": "auto", "backend": "auto",
"rotation_degrees": 0,
"properties": { "properties": {
"brightness": None, "brightness": None,
"contrast": None, "contrast": None,

View File

@@ -5,6 +5,7 @@
"height": 1080, "height": 1080,
"fps": 30, "fps": 30,
"backend": "auto", "backend": "auto",
"rotation_degrees": 0,
"properties": { "properties": {
"brightness": null, "brightness": null,
"contrast": null, "contrast": null,