在本教程中,您将进修怎么经过Flask和Python哄骗OpenCV将视频从网络摄像头流式传输到网页阅读器/HTML页面。
您的车被偷过吗?
我的车在周末就被偷了。让我通告您,我很生机。
我不能暴露太多的细节,由于这个案件还在视察中,但如下是我能够通告您的:
约莫六个月前,我和老婆从康涅狄格州的诺沃克搬到了宾夕法尼亚州的费城。我有一辆车,我不屡屡开,但仍然留着它以备时常之需。
咱们小区很难找到泊车的处所,是以我须要一个车库。
我传闻有个车库,就报名了,起头把车停在何处。
直到上个礼拜天。
我和老婆到达车库取车。咱们企图开车到马里兰去拜谒我的父母,吃一些螃蟹(马里兰的螃蟹很着名)。
我走到我的车旁,取下车衣。
我立马就蒙圈了——这不是我的车。
我的车#$
去何处了?几分钟后我就意识到一个事实——我的车被偷了。
在曩昔的一周中,我为行将出书的《树莓派电脑视觉》一书正在做的劳动被打断了——我连续在与泊车场的主人、费城巡捕局和我车上的GPS跟踪效劳打交道,想弄明白究竟产生了甚么。
在工做处理以前,我不能公然暴露任何细节,不过让我通告您,我正一心处理巡捕汇报、讼师文牍、尚有保障索赔等一大堆的文献。
我期望下个月这个题目能赢得处理——我厌烦分神,尤为是让我阔别我最喜爱做的工做——教推算机视觉和深度进修。
我胜利地行使我的波折警示了一篇新的平安相干的推算机视觉博客帖子。
在这篇文章中,咱们将进修怎么哄骗Flask和OpenCV将视频流式传输到网页阅读器中。
您能够在不到5分钟的时候内将此系统布置到树莓派上:
容易地安设所需的包/软件并启动足本
尔后翻开您的推算机/智高手机阅读器,并导航到URL/IP地方,就可以够看到传输过来的视频了(并且保证您的任何东西没有被偷)。
没甚么比一个小看频凭据更能捉住扒手了。
当我延续与巡捕、保障等处理布告劳动时,您就可以够起头用树莓派相机武装本人,不论您在何处生涯和劳动,均能够捉住恶人。
要进修怎么哄骗OpenCV和Flask将视频流式传输到一个网页阅读器的HTML页面,请延续阅读!
OpenCV——将视频流式传输到网页阅读器/HTML页面在本教程中,咱们将首先商议Flask,它是一个用于Python编程谈话的微型web框架。
咱们将进修活动探测的原形学识,以便咱们能够将它运用到咱们的项目中。咱们将经过一个后台减法器来实行活动探测。
在此原形上,咱们将Flask与OpenCV聚集,如此咱们就可以够:
走访来自树莓派相机模块或USB网络摄像头的帧。
处理帧并运用一个恣意的算法(这边咱们将哄骗后台去除/活动探测,但您也能够运用图象分类,目标探测等)。
将结局流式传输到一个网页页面/网页阅读器。
别的,咱们将波及的代码将能够帮助多个客户端(即,不只一私人/网页阅读器/标签页能同时走访流媒体),这是您在网上看到的绝大多半例子都无奈处理的。
把全部这些进程块放在一同,咱们就会赢得一个能够施行活动探测的家庭监控系统,尔后它会将视频结局流式传输到您的网页阅读器中。
让咱们起头吧!
Flaskweb框架图1:Flask是Python的一个微型web框架(imagesource)。
在本节中,咱们将扼要商议Flaskweb框架以及如安在您的系统中安设它。
Flask是一个特别大方的用Python编程谈话编写的微型web框架。
与Django同样,Flask是哄骗Python建设web运用程序时最罕见的web框架之一。
不过,与Django不同的是,Flask特别轻量,这使得哄骗它建设原形的web运用程序特别轻易。
正如咱们将在本节中看到的,咱们只要要一小部份代码就可以够哄骗Flask实行时刻流式传输视频——别的的代码包罗(1)OpenCV和走访咱们的视频流,也许()保证咱们的代码是线程平安的,并且能够处理多个客户端。
若是您须要在一个机械上安设Flask,您只要要容易地按如下夂箢举行职掌:
安设了它以后,您能够延续安设NumPy、OpenCV和imutils:
注视:若是您想要完备安设包罗“非免费”(专利)算法的OpenCV,那您肯定要从源代码来编译OpenCV。
项目构造在咱们延续以前,让咱们看看咱们项方针目录构造:
为了施行后台去除和活动探测,咱们将实行一个名为SingleMotionDetector的类——该类将位于singlemotiondetector.py文献中pyimagesearch的motion_detection子模块中。
webstreaming.py文献将哄骗OpenCV走访咱们的网络摄像头,经过SingleMotionDetector施行活动探测,尔后经过Flaskweb框架将输出帧提供给咱们的网络阅读器。
为了让咱们网络阅读器能有东西显示,咱们须要哄骗HTML填充index.html的实质来供给接纳到的视频。咱们只要要插入一些原形的HTML记号——Flask将事实处理将视频流发送到咱们的阅读器的工做。
实行一个原形的活动探测器图:哄骗RaspberryPi、OpenCV、Flask和网络流媒体举行视频监控。
经过哄骗后台去除举行活动探测,咱们能够探测到我在椅子上的活动。
咱们的活动探测算法将经过后台减除的形势来探测活动。
大多半后台去除算法的劳动道理是:
积累相加前N帧的加权匀称值
取目下帧并从帧的加权匀称值中减去它
对去除的输出举行阈值处理,以赶上像素值不同较大的地区(“白色”示意前程,“黑色”示意后台)
运用原形的图象处理手艺如腐化和膨胀来消除噪声
行使表面探测索取活动地区
咱们的活动探测实行将位于SingleMotionDetector类中,该类能够在SingleMotionDetector.py中找到。
咱们称之为一个“容易活动探测器”,由于其算法自身只对寻觅容易的、最大的活动地区感兴致。
本日签到口令:
咱们也能够很轻易地增添这个法子来处理多个活动地区。
让咱们来实行该活动探测器。
翻开singlemotiondetector.py文献,并插入如下代码:
第-4行处理所需的导入。
全部这些都是相当准则的,包罗用于数字处理的NumPy、用于为咱们供给方私函数的imutils和用于OpenCV绑定的cv。
尔后咱们在第6行界说SingleMotionDetector类。这个类承受一个可选的参数accumWeight,它是用于积累加权匀称值的因数。
accumWeight越大,在积累加权匀称值时,后台(bg)被思虑的越少。
相悖地,accumWeight越小,在推算匀称值时思虑后台(bg)就会越多。
配置accumWeight=0.5会匀称地加权后台和前程——我屡屡意见哄骗这个配置做为起头值(尔后您能够依据本人的尝试调换它)。
接下来,让咱们界说update法子,它将承受一个输入帧并推算加权匀称值:
为了防范咱们的bg帧为None(这象征着update从未被移用),咱们只要要保存bg帧(第15-18行)。
不然,咱们管帐算输入帧、现有后台bg和响应的accumWeight因子之间的加权匀称值。
鉴于咱们的后台bg,咱们目前能够经过detect法子运用活动探测:
detect法子须要一个参数和一个可选参数:
image:将要被运用活动探测的输入帧/图象。
tVal:用于将一个特定像素记号为“活动”或非活动的阈值。
给定咱们的输入image,咱们推算该image和bg之间的绝对过错(第7行)。
任何不同tVal的像素场所都被配置为55(白色;前程),不然配置为0(黑色;后台)(8行)。
经过一系列的腐化和膨胀来消除噪声和小的部分活动地区,不然这些地区会被以为是假阳性的(或许是由于反射或光线的倏地改变)。
下一步是运用表面探测索取任何活动地区:
第7-9行对咱们的thresh图象施行表面探测。
尔后,咱们初始化两组记账变量,以跟踪包罗任何活动的场所(第40行和第41行)。这些变量将孕育“畛域框”,它将通告咱们活动产生的场所。
着末一步是填充这些变量(假使活动存在于帧中,固然是如此):
在4-45行中,咱们搜检咱们的表面列表能否为空。
若是是这类境况,那末在帧中就找不到活动,咱们就可以够安心肠忽视它。
不然,在帧中确凿存在活动,是以咱们就须要起头在表面线赶上行轮回(第48行)。
关于每个表面,咱们推算其畛域框,尔后革新咱们的记账变量(第47-5行),找到全部活动产生的最小和最大(x,y)坐标。
着末,咱们将畛域框场所返回给移用函数。
聚集OpenCV和Flask图:OpenCV和Flask(一个Python微型网络框架)是波及RaspberryPi和相同硬件的网络流媒体和视频监控项方针完好伙伴。
让咱们延续,将OpenCV和Flask聚集起来,从一个视频流(运转在树莓派上)向一个网络阅读器供给帧。
翻开您项目构造中的webstreaming.py文献,并插入如下代码:
第-1行处理咱们须要的导入:
第行导入咱们上边实行的SingleMotionDetector类
VideoStream类(第行)将理睬咱们走访咱们的RaspberryPi相机模块或USB网络摄像头.
第4到6行处理导入咱们须要的Flask包——咱们将哄骗这些包显露咱们的index.html模板,并将其提供给客户端。
第7行导入threading库,保证咱们能够帮助并发(譬如,同时哄骗多个客户端、网络阅读器和选项卡)。
让咱们延续施行一些初始化:
首先,咱们在第17行初始化咱们的outputFrame——这将是将提供给客户端的帧(送达活动探测)。
尔后,咱们在第18行创立一个lock,它将在革新ouputFrame时被用来保证线程平安做为(即保证某个帧在革新时不被任何线程试验读取)。
第1行初始化咱们的Flaskapp自身,而第5-7行走访咱们的视频流:
若是您正在哄骗一个USB网络摄像头,您能够维持代码稳定。
不然,若是您正在哄骗一个RPi相机模块,那您应当废除掉第5行的诠释,并将第6行诠释掉。
下一个函数index将会衬托咱们的index.html模板并供给输出视频流:
这个函数特别容易—它所做的便是在咱们的HTML文献中移用Flaskrender_template。
咱们将鄙人一章观察该index.html文献,因而,咱们将推延对此文献实质的进一步商议直到阿谁时刻。
咱们的下一个函数的性能是:
对咱们视频流中的帧举行轮回
运用活动探测
在outputFrame上绘制任何结局
并且,这个函数肯定以线程平安的方法来施行全部这些职掌,以保证帮助并发。
目前让咱们看看这个函数:
咱们的detection_motion函数承受单个参数frameCount,它是在SingleMotionDetector类中建设咱们的后台bg所需的最小帧数:
若是咱们没有最少frameCount帧,咱们将会延续推算累计加权匀称值
一旦frameCount到达了,咱们将施行后台去除。
第7行猎取对三个变量的全面引用:
vs:咱们实例化的VideoStream目标
outputFrame:将提供给客户端的输出帧
lock:在革新outputFrame以前咱们肯定赢得的线程锁。
第41行哄骗一个accumWeight=0.1值来初始化咱们的SingleMotionDetector类,这象征着在推算加权匀称值时,bg值的权重会更高。
第4行初始化到当今为止读取的帧的total数——咱们须要保证曾经读取了充满多的帧来建设咱们的后台模子。
从何处,咱们将能够施行后台去除。
这些初始化告竣后,咱们目前能够起头对来自相机的帧举行轮回:
第48行读取来自咱们相机的frame帧,而第49-51行施行预处理职掌,包罗:
调换宽度为px(咱们的输入帧越小,数据量就越小,因而,咱们的算法运转的就越快)。
更动成灰阶图。
高斯朦胧(来增加噪声)。
尔后,咱们猎取目下时候戳并将其绘制在frame上(第54-57行)。
在举行一次最后搜检以后,咱们就可以够施行活动探测:
在第6行中,咱们保证咱们最少读取了frameCount帧来建设咱们的后台去除模子。
若是是如此,咱们将运用咱们活动探测器的.detect活动,它将返回单个变量motion。
若是motion是None,那末咱们就懂得目下frame中没有产生涯动。不然,若是motion不是None(第67行),那末咱们须要在frame上绘制活动地区的畛域框坐标。
第76行革新咱们的活动探测后台模子,而第77行添加了迄今为止从摄像机读取的帧的total数。
着末,第81行赢得帮助线程并发所需的lock,而第8行配置outputFrame。
咱们须要猎取锁,以保证咱们在试图革新outputFrame变量时客户机不会不料读取它。
咱们的下一个函数,generate,是一个Python生成器,用于将咱们的outputFrame编码为JPEG数据——目前让咱们来看看它:
第86行猎取对outputFrame和lock的全面引用,相同于detect_motion函数。
尔后generate在第89行启动一个无穷轮回,这个轮回将连续赓续到咱们收场足本。
在轮回内部,咱们:
首先猎取lock(第91行).
保证outputFrame非空(第94行),若是一个帧被从摄像机传感器中丢弃,那末这类境况就有或许产生。
在第98行将frame编码为一个JPEG图象——在这边施行JPEG收缩以增加网络负载,并且保证帧的倏地传输。
搜检胜利flag能否失利(第行和10行),这象征着若是此JPEG收缩进程失利,咱们就应当忽视该帧。
着末,将编码的JPEG以一个字节数组提供给一个能够分析它的网络阅读器。
在这么短的代码中做了这么多劳动,是以肯定要搜检这个函数再三,以保证您相识它是怎么劳动的。
下一个函数video_feed会移用咱们的generate函数:
注视这个app.route函数签字,就像上头的index函数同样。
这个app.route签字通告Flask这个函数是一个URL端点,数据是从