refactor: update detect method in camera classes to return dictionaries instead of lists

This commit is contained in:
2025-10-01 18:26:02 +02:00
parent 324ab2e016
commit dea17b8b26
3 changed files with 38 additions and 15 deletions

View File

@@ -5,6 +5,11 @@ class BaseCamera(ABC):
def __init__(self) -> None:
self.error_msg = None
@staticmethod
@abstractmethod
def detect() -> dict:
raise NotImplementedError
@abstractmethod
def connect(self, index: int | None = None) -> bool:
raise NotImplementedError

View File

@@ -24,20 +24,21 @@ class GPhotoCamera(BaseCamera):
super().__init__()
self.camera = None
self.configs: List[dict] = []
self.camera_list = []
self.camera_index = 0
def detect(self) -> list:
self.camera_list.clear()
@staticmethod
def detect() -> dict:
cameras = gp.check_result(gp.gp_camera_autodetect()) # type: ignore
# cameras = gp.Camera().autodetect()
if not cameras or cameras.count() == 0: # type: ignore
return []
return {}
camera_list = {}
for i in range(cameras.count()): # type: ignore
name = cameras.get_name(i) # type: ignore
port = cameras.get_value(i) # type: ignore
self.camera_list.append({"name": name, "port": port})
return self.camera_list
camera_list[i] = {"name": name, "port": port}
return camera_list
def connect(self, index: int | None = None) -> bool:
self.error_msg = None
@@ -45,10 +46,12 @@ class GPhotoCamera(BaseCamera):
try:
if index:
self.camera_index = index
camera_list = GPhotoCamera.detect()
port_info_list = gp.PortInfoList()
port_info_list.load()
port_address = self.camera_list[index]["port"]
port_address = camera_list[index]["port"]
port_index = port_info_list.lookup_path(port_address)
self.camera.set_port_info(port_info_list[port_index])

View File

@@ -5,7 +5,7 @@ from typing import List
from .base_camera import BaseCamera
class CvCamera(BaseCamera):
class OpenCvCamera(BaseCamera):
"""Kamera oparta na cv2.VideoCapture"""
config_map = {
@@ -24,13 +24,28 @@ class CvCamera(BaseCamera):
self.camera_list = []
self.camera_index = 0
def detect(self) -> list:
self.camera_list.clear()
self.camera_list = enumerate_cameras(cv2.CAP_ANY)
@staticmethod
def detect():
camera_list = enumerate_cameras(cv2.CAP_ANY)
result = {}
seen_ports = set()
result = []
for camera in self.camera_list:
result.append({"name": camera.name, "port": camera.path})
for camera in camera_list:
# unikamy duplikatów tego samego /dev/videoX albo tej samej ścieżki na Windows/macOS
if camera.path in seen_ports:
continue
cap = cv2.VideoCapture(camera.index, camera.backend) # próbujemy otworzyć
ret, frame = cap.read()
cap.release()
if ret and frame is not None and frame.size > 0:
result[camera.index] = {
"name": camera.name,
"port": camera.path,
"backend": camera.backend,
}
seen_ports.add(camera.path)
return result
@@ -38,7 +53,7 @@ class CvCamera(BaseCamera):
self.error_msg = None
try:
if index:
self.camera_index = self.camera_list[index].index
self.camera_index = index
self.cap = cv2.VideoCapture(self.camera_index)