""" 摄像头拍照模块 - Windows 兼容 """ import cv2 import datetime from pathlib import Path from config import config_mgr class CameraCapture: """摄像头拍照管理""" def __init__(self): self.camera_index = config_mgr.get('camera_index', 0) self.cap = None def open(self): """打开摄像头""" if self.cap is None or not self.cap.isOpened(): self.camera_index = config_mgr.get('camera_index', 0) self.cap = cv2.VideoCapture(self.camera_index, cv2.CAP_DSHOW) # Windows DirectShow if not self.cap.isOpened(): raise Exception(f"无法打开摄像头 {self.camera_index}") # 设置分辨率 self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) return self.cap.isOpened() def close(self): """关闭摄像头""" if self.cap is not None: self.cap.release() self.cap = None def capture(self, save_path=None): """拍照并保存(按日期文件夹组织) Returns: dict: {'success': bool, 'path': str, 'timestamp': str, 'date_folder': str, 'error': str} """ try: self.open() # 等待摄像头稳定(Windows 上需要预热) for _ in range(5): self.cap.read() ret, frame = self.cap.read() if not ret: return {'success': False, 'error': '无法捕获图像'} # 获取当前日期 now = datetime.datetime.now() date_str = now.strftime('%Y-%m-%d') timestamp = now.strftime('%Y%m%d_%H%M%S') # 获取按日期的保存目录 date_folder = config_mgr.get_images_dir(date_str) if save_path is None: filename = f"capture_{timestamp}.jpg" save_path = date_folder / filename # 保存图片 cv2.imwrite(str(save_path), frame, [cv2.IMWRITE_JPEG_QUALITY, 90]) return { 'success': True, 'path': str(save_path), 'timestamp': timestamp, 'date_folder': date_str, 'filename': save_path.name } except Exception as e: return {'success': False, 'error': str(e)} def get_camera_info(self): """获取摄像头信息""" try: self.open() width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = int(self.cap.get(cv2.CAP_PROP_FPS)) return { 'index': self.camera_index, 'width': width, 'height': height, 'fps': fps, 'status': 'opened' } except Exception as e: return { 'index': self.camera_index, 'status': 'error', 'error': str(e) } def __del__(self): self.close() def list_available_cameras(max_test=5): """列出可用的摄像头""" available = [] for i in range(max_test): cap = cv2.VideoCapture(i, cv2.CAP_DSHOW) if cap.isOpened(): available.append(i) cap.release() return available if __name__ == "__main__": # 测试摄像头 print("检测可用摄像头...") cams = list_available_cameras() print(f"可用摄像头: {cams}") if cams: print("\n测试拍照...") camera = CameraCapture() result = camera.capture() print(f"结果: {result}") camera.close()