# camera/opencv_camera.py import cv2 import time from PySide6.QtGui import QImage, QPixmap from .base_camera import BaseCamera class OpenCVCamera(BaseCamera): """Implementacja kamery przy użyciu OpenCV.""" def __init__(self, camera_index=0): self.camera_index = camera_index self.video_capture = None self._is_streaming = False # self._live_view_thread = None # Wewnętrzny wątek do pętli live view def connect(self) -> bool: self.video_capture = cv2.VideoCapture(self.camera_index) if not self.video_capture.isOpened(): # self.error_occurred.emit(f"Nie można otworzyć kamery OpenCV o indeksie {self.camera_index}") self.video_capture = None return False # print("Kamera OpenCV połączona.") return True def disconnect(self): self.stop_stream() if self.video_capture: self.video_capture.release() self.video_capture = None # print("Kamera OpenCV rozłączona.") # self.camera_disconnected.emit() def start_stream(self): if not self.video_capture or not self.video_capture.isOpened(): # self.error_occurred.emit("Próba uruchomienia podglądu na niepodłączonej kamerze.") return if self._is_streaming: return # Już działa self._is_streaming = True # Uruchamiamy pętlę w metodzie, ponieważ cała klasa działa już w dedykowanym wątku # self._live_view_loop() def stop_stream(self): self._is_streaming = False def get_frame(self): if not self.video_capture: return None ret, frame = self.video_capture.read() if not ret: self.stop_stream() return None rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch = rgb_image.shape bytes_per_line = ch * w qt_image = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format.Format_RGB888) return qt_image def capture_photo(self, save_path: str): if not self.video_capture or not self.video_capture.isOpened(): # self.error_occurred.emit("Nie można zrobić zdjęcia, kamera nie jest podłączona.") return ret, frame = self.video_capture.read() if ret: try: cv2.imwrite(save_path, frame) print(f"Zdjęcie zapisane w: {save_path}") # self.photo_captured.emit(save_path) except Exception as e: # self.error_occurred.emit(f"Błąd zapisu zdjęcia: {e}") else: # self.error_occurred.emit("Nie udało się przechwycić klatki do zdjęcia.") def get_available_settings(self) -> dict: # To jest uproszczona implementacja if not self.video_capture: return {} return { "brightness": self.video_capture.get(cv2.CAP_PROP_BRIGHTNESS), "contrast": self.video_capture.get(cv2.CAP_PROP_CONTRAST), "saturation": self.video_capture.get(cv2.CAP_PROP_SATURATION), } def set_setting(self, name: str, value) -> bool: if not self.video_capture: return False prop_map = { "brightness": cv2.CAP_PROP_BRIGHTNESS, "contrast": cv2.CAP_PROP_CONTRAST, "saturation": cv2.CAP_PROP_SATURATION, } if name in prop_map: return self.video_capture.set(prop_map[name], value) return False