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
相关产品推荐
相关产品推荐

