refactor: update set_config methods to specify return type as None

feat: implement CvCamera class for OpenCV camera handling
This commit is contained in:
2025-09-27 12:26:43 +02:00
parent 373e01310e
commit 1ff5091250
3 changed files with 100 additions and 9 deletions

View File

@@ -26,11 +26,11 @@ class BaseCamera(ABC):
raise NotImplementedError
@abstractmethod
def set_config_by_id(self, id: int, value: str):
def set_config_by_id(self, id: int, value) -> None:
raise NotImplementedError
@abstractmethod
def set_config_by_name(self, name: str, value: str):
def set_config_by_name(self, name: str, value) -> None:
raise NotImplementedError
def get_error_msg(self):

View File

@@ -32,13 +32,6 @@ class GPhotoCamera(BaseCamera):
self.camera.init()
config = self.camera.get_config()
self.read_config(config)
for config in self.configs:
print(config)
config_iso = self.get_config_by_name("iso")
self.set_config_by_id(config_iso['id'], "400")
self.set_config_by_id(config_iso['id'], "100")
self.set_config_by_id(config_iso['id'], "1600")
return True
except Exception as e:
self.error_msg = f"[GPHOTO2] {e}"

View File

@@ -0,0 +1,98 @@
import cv2
from typing import List
from .base_camera import BaseCamera
class CvCamera(BaseCamera):
"""Kamera oparta na cv2.VideoCapture"""
config_map = {
0: {"name": "frame_width", "cv_prop": cv2.CAP_PROP_FRAME_WIDTH, "default": 640},
1: {"name": "frame_height", "cv_prop": cv2.CAP_PROP_FRAME_HEIGHT, "default": 480},
2: {"name": "fps", "cv_prop": cv2.CAP_PROP_FPS, "default": 30},
3: {"name": "brightness", "cv_prop": cv2.CAP_PROP_BRIGHTNESS, "default": 0.5},
4: {"name": "contrast", "cv_prop": cv2.CAP_PROP_CONTRAST, "default": 0.5},
5: {"name": "saturation", "cv_prop": cv2.CAP_PROP_SATURATION, "default": 0.5},
}
def __init__(self, device_index: int = 0) -> None:
super().__init__()
self.device_index = device_index
self.cap = None
self.configs: List[dict] = []
def connect(self) -> bool:
self.error_msg = None
try:
self.cap = cv2.VideoCapture(self.device_index)
if not self.cap.isOpened():
self.error_msg = f"[CV2] Could not open camera {self.device_index}"
return False
self.configs.clear()
for id, conf in self.config_map.items():
value = self.cap.get(conf["cv_prop"])
self.configs.append(
{
"id": id,
"name": conf["name"],
"label": conf["name"].capitalize(),
"value": value,
"choices": None, # brak predefiniowanych wyborów
"cv_prop": conf["cv_prop"],
}
)
return True
except Exception as e:
self.error_msg = f"[CV2] {e}"
self.cap = None
return False
def disconnect(self) -> None:
if self.cap:
self.cap.release()
self.cap = None
self.configs.clear()
def get_frame(self):
self.error_msg = None
if self.cap is None or not self.cap.isOpened():
self.error_msg = "[CV2] Camera is not initialized."
return (False, None)
try:
ret, frame = self.cap.read()
if not ret:
self.error_msg = "[CV2] Failed to read frame."
return (False, None)
return (True, frame)
except Exception as e:
self.error_msg = f"[CV2] {e}"
return (False, None)
def get_config_by_id(self, id: int):
return next(w for w in self.configs if w["id"] == id)
def get_config_by_name(self, name: str):
return next(w for w in self.configs if w["name"] == name)
def set_config(self, config, value: float):
if not self.cap:
return
try:
self.cap.set(config["cv_prop"], value)
config["value"] = self.cap.get(config["cv_prop"]) # sprawdz co ustawiło
except Exception as e:
self.error_msg = f"[CV2] {e}"
def set_config_by_id(self, id: int, value: float):
config = self.get_config_by_id(id)
self.set_config(config, value)
def set_config_by_name(self, name: str, value: float):
config = self.get_config_by_name(name)
self.set_config(config, value)