OpenCV无法调用摄像头采集视频,Google Colab运行代码会话崩溃
在Google Colab中调用摄像头采集面部表情的正确方法
你的代码在Colab中运行失败有两个核心原因:
- Colab是云端运行环境,虚拟机没有物理摄像头,直接用
cv.VideoCapture(-1)无法找到可用设备,会触发错误。 cv.imshow()依赖本地图形界面,Colab的云端环境不支持该函数,会导致会话崩溃(即你看到的"Your session is crushed"提示)。
以下是适配Colab环境的实现方案,通过浏览器调用本地摄像头并在Colab中处理帧:
import cv2 import numpy as np from IPython.display import display, Javascript from google.colab.output import eval_js from base64 import b64decode, b64encode # 定义调用摄像头的JavaScript函数 def start_camera(): js = Javascript(''' async function startCamera() { const div = document.createElement('div'); const video = document.createElement('video'); video.style.display = 'block'; const stream = await navigator.mediaDevices.getUserMedia({video: true}); document.body.appendChild(div); div.appendChild(video); video.srcObject = stream; await video.play(); // 创建画布用于捕获帧 const canvas = document.createElement('canvas'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; const ctx = canvas.getContext('2d'); // 定义捕获帧的函数 function captureFrame() { ctx.drawImage(video, 0, 0); return canvas.toDataURL('image/jpeg', 0.8); } return {captureFrame: captureFrame, stream: stream, video: video}; } ''') display(js) return eval_js('startCamera()') # 初始化摄像头 camera = start_camera() try: while True: # 捕获帧 frame_data = camera.captureFrame() # 解码base64数据为OpenCV格式 img_data = b64decode(frame_data.split(',')[1]) np_arr = np.frombuffer(img_data, np.uint8) frame = cv2.imdecode(np_arr, cv2.IMREAD_COLOR) # 转换为灰度图(面部表情处理常用) gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 将处理后的帧转换为可显示的格式 _, encoded_img = cv2.imencode('.jpg', gray_frame) b64_img = b64encode(encoded_img).decode('utf-8') display(Javascript(f''' document.getElementById('output').src = "data:image/jpeg;base64,{b64_img}"; ''')) # 这里可以添加面部表情识别的自定义逻辑 # ... # 通过中断代码执行停止(点击Colab界面的停止按钮即可) except KeyboardInterrupt: # 释放摄像头资源 camera.stream.getTracks()[0].stop() print("摄像头已停止")
代码说明:
- 通过JavaScript调用浏览器的
getUserMediaAPI获取本地摄像头权限,这是Colab访问本地摄像头的可行方式。 - 用画布捕获视频帧并转换为base64格式,再传递给Python端解码为OpenCV可处理的帧格式。
- 避免使用
cv.imshow(),改用IPython.display在Colab界面中展示处理后的帧。 - 最后通过点击Colab界面的停止按钮中断代码执行,终止循环并释放摄像头资源。
内容的提问来源于stack exchange,提问作者Shahriar Shaon
相关产品推荐
相关产品推荐

