macOS Sonoma更新后修复Python脚本中的AVCaptureDeviceTypeExternal警告
macOS Sonoma 14.3.1下OpenCV相机访问弃用警告解决指南
问题背景
在MacBook Pro M2(macOS Sonoma 14.3.1)上运行Python面部检测脚本时,访问相机触发以下警告:
python[9050:443412] WARNING: AVCaptureDeviceTypeExternal is deprecated for Continuity Cameras. Please use AVCaptureDeviceTypeContinuityCamera and add NSCameraUseContinuityCameraDeviceType to your Info.plist.
该脚本此前在Windows和未更新的同款MacBook上可正常运行,目前不清楚如何处理该弃用警告,也不知道如何为Python脚本配置Info.plist。
已尝试的解决方法
- 在线搜索同类问题,未找到直接可行的解决方案
- 排查OpenCV与macOS兼容性问题,无法准确定位原因
脚本代码
import serial.tools.list_ports import cv2 import serial import numpy as np # Initialize serial communication with Arduino ports = serial.tools.list_ports.comports() portsList = [] for onePort in ports: portsList.append(str(onePort)) print(str(onePort)) val = "/dev/cu.SLAB_USBtoUART" # Arduino port serialInst = serial.Serial() portVar = None for x in range(0, len(portsList)): if portsList[x].startswith(str(val)): portVar = str(val) if portVar is None: print("Arduino port not found. Exiting.") exit() serialInst.baudrate = 9600 serialInst.port = portVar serialInst.open() # Initialize face detection using Haar Cascade face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') cap = cv2.VideoCapture(0) last_command = "l" while True: # Read a frame from the webcam ret, frame = cap.read() # Convert the frame to grayscale for face detection gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Detect faces in the frame faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5) if len(faces) > 0 and last_command == 'l': print("Face detected. Sending 'h' to Arduino.") serialInst.write('h'.encode('utf-8')) last_command = 'h' elif len(faces) == 0 and last_command == 'h': print("No face detected. Sending 'l' to Arduino.") serialInst.write('l'.encode('utf-8')) last_command = 'l' # Display the frame with face rectangles for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2) cv2.imshow('Face Detection', frame) # Break the loop if 'exit' is entered if cv2.waitKey(1): break # Release resources cap.release() cv2.destroyAllWindows() serialInst.close()
解决方法
方法1:指定OpenCV使用AVFoundation框架
修改相机初始化代码,强制OpenCV使用macOS原生的AVFoundation框架,避免调用已弃用的API:
# 替换原有的cap = cv2.VideoCapture(0) cap = cv2.VideoCapture(0, cv2.CAP_AVFOUNDATION)
AVFoundation会自动适配Continuity Camera的新API规范,直接消除警告。
方法2:打包脚本为macOS应用并配置Info.plist
Python脚本本身没有Info.plist,需将脚本打包成App才能添加权限配置:
- 安装打包工具py2app:
pip install py2app
- 创建
setup.py文件,内容如下:
from setuptools import setup APP = ['你的脚本文件名.py'] DATA_FILES = [] OPTIONS = { 'plist': { 'NSCameraUsageDescription': '需要访问相机进行面部检测', 'NSCameraUseContinuityCameraDeviceType': True } } setup( app=APP, data_files=DATA_FILES, options={'py2app': OPTIONS}, setup_requires=['py2app'], )
- 执行打包命令:
python setup.py py2app
- 在生成的
dist文件夹中找到App,运行即可。
方法3:更新OpenCV到最新版本
旧版本OpenCV对macOS Sonoma的兼容性不佳,更新到最新稳定版可能修复该警告:
pip install --upgrade opencv-python
方法4:使用替代库访问相机
如果上述方法无效,可尝试用pygame替代OpenCV的相机模块,示例代码:
import pygame.camera import cv2 import numpy as np pygame.camera.init() cam_list = pygame.camera.list_cameras() cam = pygame.camera.Camera(cam_list[0], (640, 480)) cam.start() # 读取帧并转换为OpenCV格式 frame = cam.get_image() frame_np = pygame.surfarray.array3d(frame) frame_np = cv2.cvtColor(frame_np, cv2.COLOR_RGB2BGR)
内容的提问来源于stack exchange,提问作者William Lancelot
相关产品推荐
相关产品推荐

