如何将FastAPI上传的视频传入OpenCV的VideoCapture?
解决FastAPI上传视频无法被OpenCV读取的问题
OpenCV的cv2.VideoCapture不直接支持FastAPI的UploadFile对象或原始字节数据,需要将上传的视频数据转换为它能识别的格式,以下是两种可行方案:
方案1:使用临时文件(兼容性好)
将上传的视频保存到临时文件,再通过文件路径让OpenCV读取,这种方法适配所有OpenCV版本:
from fastapi import FastAPI, File, UploadFile from fastapi.responses import PlainTextResponse import cv2 import tempfile import os app = FastAPI() @app.post("/video/test", response_class=PlainTextResponse) async def detect_faces_in_video(video_file: UploadFile): # 创建临时MP4文件,保存上传的视频内容 with tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') as tmp_file: tmp_file.write(await video_file.read()) tmp_path = tmp_file.name # 初始化视频捕获对象 cap = cv2.VideoCapture(tmp_path) if not cap.isOpened(): os.unlink(tmp_path) # 清理临时文件 return "视频文件无法打开" # 逐帧处理视频(示例逻辑) while cap.isOpened(): ret, frame = cap.read() if not ret: break # 在这里添加你的帧处理代码(比如人脸检测) # ... # 释放资源并删除临时文件 cap.release() os.unlink(tmp_path) return "视频处理完成"
方案2:直接读取内存流(需FFMPEG支持)
如果你的OpenCV编译时包含FFMPEG组件,可以直接将字节数据转为numpy数组,让OpenCV从内存读取视频流:
from fastapi import FastAPI, File, UploadFile from fastapi.responses import PlainTextResponse import cv2 import numpy as np import io app = FastAPI() @app.post("/video/test", response_class=PlainTextResponse) async def detect_faces_in_video(video_file: UploadFile): # 读取上传视频的字节内容 video_bytes = await video_file.read() # 将字节转为numpy数组 nparr = np.frombuffer(video_bytes, np.uint8) # 初始化视频捕获对象并读取内存流 cap = cv2.VideoCapture() if not cap.open(nparr, cv2.CAP_FFMPEG): return "无法读取视频流,请检查OpenCV是否支持FFMPEG" # 逐帧处理视频 while cap.isOpened(): ret, frame = cap.read() if not ret: break # 帧处理逻辑 # ... cap.release() return "视频处理完成"
关键说明
cv2.VideoCapture默认仅支持文件路径或设备索引,无法直接接收UploadFile或bytes对象,必须转换格式。- 方案1兼容性更强,无需依赖FFMPEG;方案2避免了磁盘IO,效率更高,但需要确保OpenCV环境带有FFMPEG支持。
内容的提问来源于stack exchange,提问作者alibustami
相关产品推荐
相关产品推荐

