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

Python与Flask中VideoCapture调用摄像头异常问题求助

解决Flask+OpenCV摄像头访问报错及帧率问题

你尝试用Flask+OpenCV实现网页摄像头画面展示,初始代码如下:

from flask import Flask, render_template, Response
import cv2

app=Flask(__name__)

cam=cv2.VideoCapture(0)
def gen():
    while True:
            success,frame=cam.read()
            if not success:
                 continue
            success,frame=cv2.imencode(".jpg", frame)
            frame=frame.tobytes()
            yield(b'--frame\r\n'
                    b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
            
@app.route("/")
def index():
    return render_template("test.html")

@app.route("/video")
def video():
    return Response(gen(),mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
     app.run(debug=True,host='0.0.0.0', port=80)

运行时出现设备占用及索引错误:

[ WARN:0@0.088] global cap_gstreamer.cpp:2838 handleMessage OpenCV | GStreamer warning: Embedded video playback halted; module v4l2src0 reported: Device '/dev/video0' is busy
[ WARN:0@0.088] global cap_gstreamer.cpp:1698 open OpenCV | GStreamer warning: unable to start pipeline
[ WARN:0@0.088] global cap_gstreamer.cpp:1173 isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
[ WARN:0@0.088] global cap_v4l.cpp:997 open VIDEOIO(V4L2:/dev/video0): can't open camera by index
[ERROR:0@0.109] global obsensor_uvc_stream_channel.cpp:159 getStreamChannelGroup Camera index out of range

临时通过逐帧打开释放摄像头的方法导致帧率极低,且已尝试重装依赖、更换摄像头仍未解决。以下是可行的解决方案:

1. 强制指定OpenCV使用V4L2后端

GStreamer后端冲突是常见原因,强制使用V4L2可避免该问题,同时设置合理的分辨率与JPEG质量:

from flask import Flask, render_template, Response
import cv2
import atexit

app = Flask(__name__)

# 强制V4L2后端初始化摄像头
cam = cv2.VideoCapture(0, cv2.CAP_V4L2)
# 设置分辨率,匹配你的摄像头参数
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

def gen():
    while True:
        success, frame = cam.read()
        if not success:
            continue
        # 设置JPEG编码质量,平衡画质与传输速度
        success, frame = cv2.imencode(".jpg", frame, [cv2.IMWRITE_JPEG_QUALITY, 80])
        frame = frame.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
            
@app.route("/")
def index():
    return render_template("test.html")

@app.route("/video")
def video():
    return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')

# 程序退出时自动释放摄像头资源
def release_cam():
    if cam.isOpened():
        cam.release()

atexit.register(release_cam)

if __name__ == '__main__':
    # 关闭Debug模式,避免多进程抢占摄像头
    app.run(debug=False, host='0.0.0.0', port=80)

2. 确认摄像头设备索引

执行命令查看系统中的摄像头设备:

ls /dev/video*

如果存在多个设备(如/dev/video1),尝试更换cv2.VideoCapture的索引值,比如cv2.VideoCapture(1, cv2.CAP_V4L2)。

3. 检查摄像头权限

确保当前用户拥有摄像头设备的访问权限,执行以下命令添加权限后重新登录:

sudo usermod -aG video $USER

内容的提问来源于stack exchange,提问作者Adrian Motzer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:16:32