cv2.VideoCapture运行时相机切换,如何固定读取外接相机并获取相机信息?
问题解决:固定外接相机与获取相机信息
一、固定读取外接相机
MacOS下OpenCV默认的相机枚举顺序不稳定,每次启动程序可能重新排列内置/外接相机的索引,导致你遇到的切换问题。可以通过以下方式固定外接相机:
方法1:遍历相机并按名称筛选
通过遍历所有可能的相机索引,检查设备名称来定位外接相机(比如外接相机名称通常包含"USB"、"External"等关键词):
import cv2 def get_external_camera_index(): # 遍历常见的相机索引范围 for index in range(5): cap = cv2.VideoCapture(index, cv2.CAP_AVFOUNDATION) if cap.isOpened(): # 获取设备名称(AVFoundation后端支持此属性) device_name = cap.get(cv2.CAP_PROP_DEVICE_NAME).decode('utf-8') # 根据名称判断是否为外接相机,关键词可根据实际情况调整 if "USB" in device_name or "External" in device_name: cap.release() return index cap.release() return -1 # 未找到外接相机 # 获取外接相机索引 external_cam_index = get_external_camera_index() if external_cam_index == -1: print("未检测到外接相机") else: cameraCapture = cv2.VideoCapture(external_cam_index, cv2.CAP_AVFOUNDATION) success, frame = cameraCapture.read() while success and cv2.waitKey(1) == -1: cv2.imshow("Mine", frame) success, frame = cameraCapture.read() cameraCapture.release() cv2.destroyAllWindows()
方法2:强制指定AVFoundation后端并锁定索引
如果外接相机的索引在系统中相对固定(重启后不变),可以显式指定使用AVFoundation后端,避免后端切换导致的索引变化:
import cv2 # 显式使用AVFoundation后端,确保相机枚举逻辑一致 cameraCapture = cv2.VideoCapture(1, cv2.CAP_AVFOUNDATION) # 后续代码不变 success, frame = cameraCapture.read() while success and cv2.waitKey(1) == -1: cv2.imshow("Mine", frame) success, frame = cameraCapture.read() cameraCapture.release() cv2.destroyAllWindows()
二、获取指定相机的信息
1. 获取分辨率等基础参数
使用OpenCV的get()方法可以直接读取相机的分辨率、帧率等参数:
import cv2 cap = cv2.VideoCapture(1, cv2.CAP_AVFOUNDATION) if cap.isOpened(): # 获取分辨率 width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # 获取帧率 fps = cap.get(cv2.CAP_PROP_FPS) print(f"分辨率: {int(width)}x{int(height)}") print(f"帧率: {fps}") cap.release()
2. 获取相机设备名称
在MacOS的AVFoundation后端下,可以通过cv2.CAP_PROP_DEVICE_NAME获取设备名称:
import cv2 cap = cv2.VideoCapture(1, cv2.CAP_AVFOUNDATION) if cap.isOpened(): device_name = cap.get(cv2.CAP_PROP_DEVICE_NAME).decode('utf-8') print(f"相机名称: {device_name}") cap.release()
如果需要更详细的设备信息(比如制造商、型号),可以使用pyobjc调用MacOS的AVFoundation框架:
import objc from Foundation import NSBundle # 加载AVFoundation框架 AVFoundation = NSBundle.bundleWithIdentifier_("com.apple.AVFoundation") objc.loadBundleFunctions(AVFoundation, globals(), [("AVCaptureDevice", "devices")]) # 遍历所有相机设备 for device in AVCaptureDevice.devices(): if device.hasMediaType_("vide"): # 筛选视频设备 print(f"设备名称: {device.localizedName()}") print(f"设备型号: {device.modelID()}") print(f"制造商: {device.manufacturer()}") print("---")
注意:需要先安装pyobjc库:pip install pyobjc
内容的提问来源于stack exchange,提问作者fjybiocs
相关产品推荐
相关产品推荐

