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

Python Flask无法显示摄像头图像,Web服务浏览器无法连接排查

问题描述

我有一个存放图像识别算法的文件algorithms.py,目前仅作为测试空框架使用,代码如下:

import cv2
camera = cv2.VideoCapture(0)

class algorithms:
    def raw_image(caller):
        while True:
            success, frame = camera.read()
            if not success:
                print("Error reading from camera")
            frame = cv2.flip(frame, 1)  #mirror image vertically
            
            caller.output(frame)

我尝试用Flask搭建Web服务器来展示摄像头图像,但无法正常工作:控制台显示服务器已运行,但浏览器无法连接获取图像,相关代码如下:

from algorithms import algorithms
from flask import Flask, Response
import cv2


class server:
    def output(self, frame):
        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()

        yield (b'--frame\r\n'
                b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')


    def web(self):
        app = Flask(__name__)
        @app.route('/')
        def video_feed():
            return Response(algorithms.raw_image(self), mimetype='multipart/x-mixed-replace; boundary=frame')

        app.run(host='0.0.0.0', port=5000)


server().web()

请问我遗漏了什么配置或代码逻辑?

另外,使用cv2.imshow的方式测试是正常的,代码如下:

from algorithms import algorithms
import cv2

class window:
    def output(self, frame):
            cv2.imshow("Frame", frame)
            #exit
            if cv2.waitKey(1) & 0xFF == ord('q'):
                exit()

    def start(self):
        algorithms.raw_image(self)



window().start()

问题分析与修复

核心问题是**algorithms.raw_image方法没有返回生成器,而Flask的Response必须接收生成器才能实现视频流的持续推送**。

当前代码中,raw_image是一个无限循环的方法,仅调用caller.output(frame),但output方法的yield生成器没有被传递给Response——因为raw_image本身没有返回值,Response实际接收到的是None,自然无法推送图像流。

修复方案(二选一即可)

方案1:修改algorithms.py,让raw_image传递生成器

import cv2
camera = cv2.VideoCapture(0)

class algorithms:
    def raw_image(caller):
        while True:
            success, frame = camera.read()
            if not success:
                print("Error reading from camera")
                continue  # 读取失败时跳过当前循环,避免后续报错
            frame = cv2.flip(frame, 1)  # 垂直镜像
            
            # 将output的生成器内容逐个yield出去
            yield from caller.output(frame)

方案2:重构Flask服务器代码,直接管理生成器

from algorithms import algorithms
from flask import Flask, Response
import cv2

class server:
    def output(self, frame):
        ret, buffer = cv2.imencode('.jpg', frame)
        if not ret:
            return  # 编码失败时跳过,避免流中断
        frame = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

    # 单独定义生成器方法,替代原有的raw_image调用逻辑
    def frame_generator(self):
        camera = cv2.VideoCapture(0)
        while True:
            success, frame = camera.read()
            if not success:
                print("Error reading from camera")
                continue
            frame = cv2.flip(frame, 1)
            yield from self.output(frame)

    def web(self):
        app = Flask(__name__)
        @app.route('/')
        def video_feed():
            return Response(self.frame_generator(), mimetype='multipart/x-mixed-replace; boundary=frame')

        # 开启debug模式方便排查错误,生产环境可关闭
        app.run(host='0.0.0.0', port=5000, debug=True)

server().web()

额外注意事项

  • 必须对cv2.imencode的返回值ret做判断,编码失败时跳过该帧,避免流中断。
  • 若远程访问服务器,需确保服务器的5000端口未被防火墙拦截。
  • Flask的debug=True模式会自动重载代码,调试阶段开启能快速定位问题。

内容的提问来源于stack exchange,提问作者Ey Jo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:35:15