You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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才能添加权限配置:

  1. 安装打包工具py2app:
pip install py2app
  1. 创建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'],
)
  1. 执行打包命令:
python setup.py py2app
  1. 在生成的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 15:45:41