opencv通过webcam可以获取本地实时视频流,但是如果需要将视频流共享给其他机器调用,就可以将利用flask框架构建一个实时视频流服务器,然后其他机器可以通过向这个服务器发送请求来获取这台机器上的实时视频流。[这篇文章](https://blog.miguelgrinberg.com/post/video-streaming-with-flask)包含非常详细的理论介绍和具体实现,力荐!

首先需要说明的是这里flask提供视频流是通过generator函数进行的,不了解的可以去查下文档这里就不具体讲了。flask通过将一连串独立的jpeg图片输出来实现视频流,这种方法叫做motion JPEG,好处是延迟很低,但是成像质量一般,因为jpeg压缩图片的质量对motion stream不太够用。

multipart 模式

想要将后一次请求得到的图片覆盖到前一次从而达到动画的效果就需要使用在response的时候使用multipart模式。Multipart response由以下几部分组成:包含multipart content类型的header,分界符号分隔的各个part,每个part都具有特定的content类型。multipart视频流的结构如下:

HTTP/1.1 200 OK
Content-Type: multipart/x-mixed-replace; boundary=frame --frame
Content-Type: image/jpeg <jpeg data here>
--frame
Content-Type: image/jpeg <jpeg data here>
...

flask server

具体实现代码main.py

from flask import Flask, render_template, Response
import opencv class VideoCamera(object):
def __init__(self):
# 通过opencv获取实时视频流
self.video = cv2.VideoCapture(0) def __del__(self):
self.video.release() def get_frame(self):
success, image = self.video.read()
# 因为opencv读取的图片并非jpeg格式,因此要用motion JPEG模式需要先将图片转码成jpg格式图片
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes() app = Flask(__name__) @app.route('/') # 主页
def index():
# jinja2模板,具体格式保存在index.html文件中
return render_template('index.html') def gen(camera):
while True:
frame = camera.get_frame()
# 使用generator函数输出视频流, 每次请求输出的content类型是image/jpeg
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n') @app.route('/video_feed') # 这个地址返回视频流响应
def video_feed():
return Response(gen(VideoCamera()),
mimetype='multipart/x-mixed-replace; boundary=frame') if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=5000)

index.html

<html>
<head>
<title>Video Streaming Demonstration</title>
</head>
<body>
<h1>Video Streaming Demonstration</h1>
<img src="{{ url_for('video_feed') }}">
</body>
</html>

注:图片地址由大括号内的字典给出,指向app的第二个地址video_feed,在multipart模式下浏览器会将每次请求得到的地址对大括号进行更新。

局限性

如果视频流一直存在的话,这个app能输出视频流的的客户端的数量和web worker的数量相同,在debug模式下,这个数量是1,也就是说只有一个浏览器上能够看到视频流输出。

如果要克服这种局限的话,使用基于协同网络服务的框架比如gevent,可以用一个worker线程服务多个客户端。

参考

https://blog.miguelgrinberg.com/post/video-streaming-with-flask

https://github.com/mattmakai/video-service-flask

http://www.chioka.in/python-live-video-streaming-example/

利用flask将opencv实时视频流输出到浏览器的更多相关文章

  1. opencv获取IP摄像头(IP-camera)实时视频流

    之前这篇文章讲了如何通过网络摄像头(web camera)获取实时视频流,但是这种方法的缺陷就是摄像头和主机必须连在一起,那这种在室外部署的时候就会非常麻烦并且不安全,所以后来找了下用海康威视或者大华 ...

  2. 人脸检测及识别python实现系列(6)——终篇:从实时视频流识别出“我”

    人脸检测及识别python实现系列(6)——终篇:从实时视频流识别出“我” 终于到了最后一步,激动时刻就要来临了,先平复一下心情,把剩下的代码加上,首先是为Model类增加一个预测函数: #识别人脸 ...

  3. 人脸检测及识别python实现系列(1)——配置、获取实时视频流

    人脸检测及识别python实现系列(1)——配置.获取实时视频流 1. 前言 今天用多半天的时间把QQ空间里的几篇年前的旧文搬到了这里,算是完成了博客搬家.QQ空间里还剩下一些记录自己数学学习路线的学 ...

  4. 在WEB显示实时视频流

    转载自:https://www.jianshu.com/p/7ef5490fbef7 安装摄像头 这里使用的是树莓派的官方摄像头,使用普通的 USB 摄像头也可以,但前提是你能够搞的定它的驱动. 大概 ...

  5. 利用javascript实现文本的自动输出

    主要利用了setTimeout(),递归和String.substring(); 做出的效果就像是有一个打字员在打字. <!doctype html> <html lang=&quo ...

  6. opencv学习_15 (利用cmake查看opencv的源码)

    当我们有时想查看opencv自带的函数的源代码,比如函数cvCreateImage, 此时我们选中cvCreateImage, 点击鼠标右键->转到定义,我们会很惊讶的发现为什么只看到了cvCr ...

  7. 利用sql命令把结果集输出到文件

    利用sql命令把结果集输出到文件 红色部分的三条命令完成把结果集输出到文件!! [root@test root]# psql -hlocalhost -Utest testWelcome to psq ...

  8. Python - 利用flask搭建一个共享服务器

    零.概述 我利用flask搭建了一个简易的共享服务器,分享给大家 一.python代码 import os import time from flask import Flask,render_tem ...

  9. 利用cmake查看opencv的源码

    当我们有时想查看opencv自带的函数的源代码,比如函数cvCreateImage, 此时我们选中cvCreateImage, 点击鼠标右键->转到定义,我们会很惊讶的发现为什么只看到了cvCr ...

随机推荐

  1. java你可能不知道的事(2)--堆和栈<转>

    在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...

  2. FutureTask 源码分析

    FutureTask 源码分析,这个类的原理与我分析android当中的FutureTask类差不多[http://www.cnblogs.com/daxin/p/3802392.html] publ ...

  3. oozie无法识别hadoopHA中的ns1

    [hadoop@dwdev-name1 m_goods_sale_detail]$ oozie job -config job.properties -run Error: E1603 : java. ...

  4. hbase源码系列(三)Client如何找到正确的Region Server

    客户端在进行put.delete.get等操作的时候,它都需要数据到底存在哪个Region Server上面,这个定位的操作是通过HConnection.locateRegion方法来完成的. loc ...

  5. CodeWarrior WarningC12056

    C12056:SP debug info incorrect because of optimization or inline assemble 该warning是代码最优化时(common cod ...

  6. MD5骨骼动画模型加载(一)

    前面我们分析了静态模型OBJ格式,桢动画模型MD2,这篇主要分析骨骼动画MD5的一些概念并且实现. 混合桢动画有计算简单,容易实现等优点,但是在需要比较细致的效果时,则需要更多的关键桢,每桢都添加相同 ...

  7. 怎么用一个ppt介绍一个项目

  8. Eclipse中配置resin 4.x

    开发web项目时,你还困扰在,反复启动web容器的痛苦中么?也许会有人说,用调试模式.但是如果涉及到配置文件或者service类,还是不得不重启web容器吧,而且偶尔会出现抽风情况,没生效的情况(这时 ...

  9. postman-记录cookies信息

    接口:赞我的列表,get请求,要登陆用户信息 http://v80.pcauto.com.cn/xsp/s/auto/info/nocache/club/getPraiseMyDynas.xsp?pa ...

  10. BitSet 是个好东西

    顾名思义,就是位集合(bit set),是从JDK 1.0就出现的东西,后面的版本又慢慢强化. 我们说学习一样东西,最好是场景驱动 - 要考虑它的使用场景,这样才有意义. 那么,BitSet的应用场景 ...