Files
vision-record/camera.py

125 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
摄像头拍照模块 - 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()