python - Python Flask 仅在浏览器中显示从 OpenCV 流式传输的实时视频中的一帧
问题描述
我遇到了一个奇怪的问题,因为这是昨晚工作的,据我所知,我没有进行任何更改。因此,我通过与远程机器的套接字连接从我的树莓派获得了 opencv 流。然后,我计划将其传递到烧瓶中,以将其显示在用户可以查看实时提要的网页上。
客户端.py
import cv2
import io
import socket
import struct
import time
import pickle
import zlib
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('ec2 instance id', 8089))
connection = client_socket.makefile('wb')
cam = cv2.VideoCapture(0)
cam.set(3, 320);
cam.set(4, 240);
img_counter = 0
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
while True:
ret, frame = cam.read()
result, frame = cv2.imencode('.jpg', frame, encode_param)
# data = zlib.compress(pickle.dumps(frame, 0))
data = pickle.dumps(frame, 0)
size = len(data)
print("{}: {}".format(img_counter, size))
client_socket.sendall(struct.pack(">L", size) + data)
img_counter += 1
cam.release()
现在这是我的代码变得有点混乱的地方,当谈到 python 时,我并不是最好的。我知道下面的这个套接字代码可以分成不同的类和东西。
服务器.py
from flask import Flask, render_template, Response
from flask import make_response
import cv2
import socket
import sys
import cv2
import pickle
import numpy as np
import struct ## new
import zlib
app = Flask(__name__)
@app.route('/')
def index():
"""Video streaming home page."""
return render_template('index.html')
def gen():
"""Video streaming generator function."""
HOST=''
PORT=8089
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print('Socket created')
s.bind((HOST,PORT))
print('Socket bind complete')
s.listen(10)
print('Socket now listening')
conn,addr=s.accept()
data = b""
payload_size = struct.calcsize(">L")
print("payload_size: {}".format(payload_size))
while True:
while len(data) < payload_size:
print("Recv: {}".format(len(data)))
data += conn.recv(4096)
print("Done Recv: {}".format(len(data)))
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack(">L", packed_msg_size)[0]
print("msg_size: {}".format(msg_size))
while len(data) < msg_size:
data += conn.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
frame=pickle.loads(frame_data, fix_imports=True, encoding="bytes")
frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
#vc = cv2.VideoCapture(frame)
#below I am looping through frame and converting them back to byptes
so I can display them in the browser as an image
for data1 in frame:
data1 = cv2.imencode('.jpg', frame)[1].tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' +data1+ b'\r\n\r\n')
@app.route('/video_viewer')
def video_feed():
return Response(gen(),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, threaded=True)
现在,当我运行这些时,只会向我显示一个图像,而不是不断地输入图像。就像我说的这种方法昨晚确实有效。我的猜测是我的循环有问题?for data1 in the frame:
. 为写得不好的套接字代码道歉。任何正确方向的帮助将不胜感激。
收到第一个图像帧后,烧瓶的输出会创建一个新的获取请求,该请求会停止实时提要
解决方案
推荐阅读
- api - 如何在 MAC 中设置 NODE_TLS_REJECT_UNAUTHORIZED =0 的值
- python - 使用 web3.py 获取待处理交易的详细信息
- java - 基于 Spring Boot 中 bean 的当前状态动态不运行 @Scheduled 作业
- excel - 目标.地址 = 范围
- css - 从 TreeView 散焦时如何删除白色边框?
- python - 尝试在 heroku 上运行 gecko 驱动程序并获取 WebDriverExceptio;状态 255
- angular - formControlName 的有效字符串
- woocommerce - 当一个类别只有 1 个产品时,Woocommerce 重定向到单个产品页面
- javascript - 使用 BrowserRouter 的对象作为 React 子项无效
- html - 1密码扩展显示在某些输入字段上以及如何禁用它