如何用树莓派 智能家居做一个移动设备

【树莓派】把系统安装到U盘或移动硬盘上
TA的更多文章
【树莓派】把系统安装到U盘或移动硬盘上
一般情况下我们都是把树莓派系统Raspberry安装在树莓派上的TF内存卡中,而且官方介绍关于树莓派安装Raspberry也是采用TF内存卡的方式安装。但有的时候我们有特殊的需求,比如需要建立一个树莓派的简单镜像系统,通过移动硬盘扩展系统盘等等愿意。都有可能要求我们把树莓派Raspberry系统安装在USB设备上。那么这次牛人技术就带大家一起在树莓派USB上安装系统!硬件准备Top1)树莓派Raspberry Pi3B,也就是2016年最新版。目前测试树莓派2B,树莓派B+暂时不支持。2)树莓派第一次引导要用的TF内存卡。3)一个电流在2A,电压在5V的直流电源。4)16G的U盘一个,或者2.5英寸的移动USB硬盘一个。5)TF内存卡读卡器一个,用于写系统。6)Win32 Disk Imager软件,用于给TF卡写系统。7)Etcher软件,用于把TF卡系统复制到USB设备上。制作树莓派系统Top首先;去树莓派官方或者牛人技术(www.nrjs.cn)网站上下载树莓派的系统.img文件到自己的Windows系统笔记本电脑中。其次;把内存卡读卡器插入笔记本电脑上,通过Win32 Disk Imager软件把下载的系统写入到TF内存卡中。最后;在笔记本电脑上打开TF卡文件夹并找到cmdline.txt用notepad++编辑,内容如下;program_usb_boot_mode=1
然后保存退出。把写好系统的TF内存卡从电脑上取下来,插入树莓派。把系统转移到U盘或移动硬盘Top首先;把TF内存卡取下来后插入到树莓派的TF内存卡卡槽上,并给树莓派加点开机引导系统。
第一次引导需要毕竟长的时间,等HDMI显示器上显示引导完成后。就可以输入默认用户名pi和密码raspberry登录系统了。登录系统后就执行sudo halt关机命令,让树莓派正常关机。其次;再把TF内存卡插入读卡器并插到电脑上,与此同时也把U盘或移动硬盘也插到电脑上。然后;运行电脑上下载的Etcher软件,把TF卡上的镜像直接复制到U盘或移动硬盘上。最后;把含有Raspberry系统的U盘或移动硬盘插到树莓派上面,即可让树莓派从U盘启动了。注意1;因为树莓派默认优先是从TF卡启动,所以如果用U盘启动时不要插上TF卡。注意2;因为树莓派从USB启动需要采用failsafe boot,所以USB启动大约要比TF卡多花费10秒钟的样子。总结Top完成上面各项操作后,给树莓派加点并启动。然后登录系统,可以输入sudo df -h命令查看到此时的树莓派存储设备只有SDA1这样的USB设备,而且空间也非常的大。&3添加评论分享收藏感谢收起赞同 添加评论分享收藏感谢收起写回答采用树莓派与L298N制作遥控小车全攻略
  本文主要描述使用和L298N制作一个简单的遥控小车,遥控器使用简单的WEB来实现。
  准备工作
  树莓派,(本文使用的是Raspberry
2 B型,即2B)
  8G以上TF卡 树莓派上可用和不可用的SD卡列表
  四驱小车底(含电机,注:本文中的小车底盘佩戴的是高扭矩直流电机)
  母对母、公对母、公对公(可不用)杜邦线
  L298N双HD桥电机驱动板
  无线网卡(最好支持AP的)
  充电电池组(7V以上的,镍氢或者18650充电电池皆可)
  系统安装没什么说的,系统烧到SD就可以了,我使用的Raspbian,这货是基于Debian的,配置命令习惯几乎和ubuntu/debian一样,接上网线开机进入系统配置。
  换上中科大的源,再apt-get upda一次;
  为root用户设置密码;
  配置无线网卡有两中方案,编辑/etc/network/interface,网上教程蛮多的:
  自动连接到路由器,家里有无线路由器,小车在WIFI覆盖的地方;
  树莓派上搭建WIFI热点,信号更好,可以在小区里面开,顺便勾搭妹子,哦哦哦,不对,应该是淘气小孩。唯一需要注意的是网卡芯片。
  底盘组装
  拼装没啥难度,亚克力板上的牛皮纸沾得简直是丧心病狂,马蛋,废了好一会儿功夫才撕干净(⊙﹏⊙)b;
  马达那货就比较坑了,没有带线是裸机的,手中也恰巧没有电烙铁,当时我就懵逼啦。好吧,手中还有多余的公对公杜邦线,拔掉其中一头的接头,打火机烧一下(小时候学会的神技),拔掉一部分把铜线拧紧。最后铜线穿过马达接口的小洞里面,再拧紧。哎丫,没有胶带,最后用透明胶凑合凑合,绑紧。 repeat 4次。
  线路连接
  +12V接口
  +5V~+35V, 如需要板内取电,则供电范围Vs:+7V~+35V
  OUT1、OUT2 为电机A输出;OUT3、OUT4为电机B输出
  IO接口
  ENA和ENA分别为A、B电机的使能端,一开始ENA和ENB各自的上下两个针脚是用跳线帽连接起来的,拔掉就可以接线了。 IN1-IN4 为IO控制输入。
  弄明白L298N之后,连接就方便多了,
  OUT1 OUT2 连接小车左侧前后两个电机(并联),之前电机接出来的杜邦线公头直接往接口里面塞(好羞羞),拧紧螺丝;同理,OUT3 OUT4 连接小车右侧前后两个电机;
  便宜的镍氢电池组电源正负极分别连接12V、GND,电池组的接头是JST母头,比较好连接;
  5V和GND连接到树莓派上的5V和GND用于供电。
  ENA、ENB、IN1-IN4连接到树莓派I/O端口上。
  接好之后是这样子:
  摄像头模块
  摄像头是好几年前台式机用的摄像头,分辨率是奇葩的470x640,而不是480x640,mjpg-streamer下,画面是花的,等到画面调正常之后,画面却如放幻灯片一样。我勒个去!摄像头连接到装了openwrt的wndr3800路由器上流畅的没朋友,在树莓派上调来调去却怎么也不行,认命了,放弃放弃,没有摄像头也能当遥控车开。下面是演示展示:
  小车遥控器
  终于到了编程部分,为了简单,使用的RPI.GPIO模块来操作I/O,不过我发现功能蛮少的,没找到调速的API,文档在这里,代码如下,轮子的参数视接的I/O口而定。
  最后用Flask模块实现Web,这需要在树莓派装Flask模块,在安装的时候发现树莓派的python环境是不完整的。代码仅供参考。
发布评论请先
哪种蓝牙耳机最耐用?吃土也要入的四大蓝牙耳机 众所周知,线材的好坏和耐用程度直接关系到运动蓝牙耳机的....
关于深创赛福田区预选赛中国硬件创新创客大赛晋级深创赛半决赛相关安排的通告第十届中国深圳创新创业大赛福....
今天给大家分享一下我家基于树莓派智能车库的应用,可以利用iOS自带的家庭APP,实现Siri语音轻松....
这个夏日,我们看到了豪门出局,新秀崛起的世界杯,看到了怀着一团火创业8年,终在港交所敲钟上市的小米,....
近日2018中国硬件创新大赛与名堂共享空间签署赛事战略合作协议,揭开赛事合作....
近日 2018中国硬件创新大赛与创营万物工场签署赛事战略合作协议,打开赛事合作新篇章。 创营 万物工....
近日2018中国硬件创新大赛与中城康帕斯科技发展(深圳)有限公司签署....
另一方面京东云也重视设备。第三方数据显示,智能硬件设备在中国的渗透率仍然较低,这个市场尚未成熟。刘子....
从产品角度出发,讲解ADC的运用,ADC的电路硬件设计,有源滤波、放大和数字电路等部分与ADC的关系....
市面上的智能家居产品日益增长,人民对于产品的需求也是不断扩大。小米,海尔等知名企业纷纷布局智能家居产....
然而,随着“BAT+TMDJ”等互联网巨头的陆续兴起,各大平台间的流量围墙高筑,获客成本越来越高。小....
童士豪在接受CNBC节目《Squawk Alley》采访时称,小米股价的表现“可能同时反映了中国和美....
日,备受瞩目的第三届中国硬创大赛以助力创业者 改变世界之势迎来了华南分赛区决赛的开....
2018年上半年,全球最强大的电子科技公司苹果公司公布了200大供应商的2018版本, 200家供应....
6月27日傍晚7点,Angelababy、戚薇、潘粤明、李晨nic、尹正、汪东城等等13位娱乐界明星....
机器人细分大致分为三大类,即工业机器人、服务机器人和无人机。而工业机器人根据用途不同,可以分为焊接机....
本文档的主要内容详细介绍的是树莓派B+机械的电路原理图免费下载
目前,工匠社已经推出了两款产品,说到这两款格斗机器人的区别时,招俊健给我打了个比方,他说:“GANK....
我们一起来看看这款具有智能跟随功能的90分智能跟随旅行箱,这款智能硬件对于爱旅游的人来说还是很给力的....
未来行业发展势头势必迅猛,这源于近些年前沿科技领域的井喷式发展,其中人工智能、自动驾驶、VR/AR、....
国内健身热主要是在健身O2O创新的推动下才进入大众视野,而健身O2O创新的鼻祖是由 Payal Ka....
疯壳开源可编程蓝牙心率运动手环众筹项目正在火热进行中,支持者可获得100%开源的蓝牙心率运动手环硬件....
HWTrek智造协作平台从平台2300多智能硬件项目中,精选二十多家海外物联网创新中小企业,在深圳举....
今年年初,高盛对VR/AR800亿美元的市场高估值无疑再次推动了智能硬件的风口,让“虚拟现实”和“增....
激昂的音乐声中,8架无人机自场中缓缓飞起,在空中来回穿梭,却井然有序。这些无人机身材小巧,飞行却异常....
话说睡眠大约占据了人们三分之一的时间,良好的睡眠会让我们一整天都精力充沛,而睡不好很有可能会毁了这一....
虽然攻击手机、电脑已经成为黑客们多年以来的习惯,但随着智能硬件的普及,许多产品跟用户的交互深度已经远....
近日,台湾工业技术研究院研发了一款“智能感应便利贴”的产品,能够在家中老人摔倒后,及时通过手机通知子....
改善人机交互、多样化应用有望助推智能机器人产业爆发,AI将成为图像、语音等识别技术和数据处理的核心推....
家中宝贝如果玩腻了芭比娃娃过家家、对赛车遥控飞机又不太感冒,完全可以自己动手做个玩具出来。
其次就是硬件准备,超频需要一块强大的主板做支撑,特别是主板供电部分,考虑到CPU和内存超频后功耗大增....
如今,众筹平台多种多样,帮助人们实现各种梦想。而Kickstarter则是大众所熟知之一,现在,一起....
大部分消费者对于真正创意十足的产品了解并不算多,在此笔者就搜罗了一些令人意想不到的产品,帮助大家进一....
成功的硬件各有各的成功,但不成功的硬件往往都是相似的。最近就总结了12种最不该做的硬件产品,基本上还....
人类社会的发展,是依赖一次次生产效率提升的变革,软件、硬件都是信息技术的载体,软件已经验证了开放作为....
虽然在树莓派上用户已经可以安装Windows 10 IoT Core系统,不过得益于近期启动的Win....
物联网的三个核心环节在于零部件、整机和内容及运维服务,生态圈的投资机会主要在两类公司:一类是采用硬件....
受万物互联趋势影响,智能家居市场迎来强势发展,权威机构预测,未来五年全球智能家居设备和服务市场将每年....
本文主要详细介绍了树莓派驱动舵机以及它的驱动代码,具体的跟随小编一起来了解一下。
5 月 25 日,菜鸟驿站发布“新物种”——智能科技产品菜鸟小盒,让收寄包裹不仅更方便、智能,还会向....
近日,基于树莓派的世界上最经济计算机的生产商pi-top推出了pi-topPULSE。这款HAT兼容....
5月18日,中国移动宣布在深圳成立智能硬件创新中心,由中国移动终端公司管理,这是国内通信运营商成立的....
如今AI的触角已经伸向了市场各个领域,AI离不开硬件,新一代人工智能硬件相较于之前的硬件有什么不一样....
2015年贴片技术的不断普及,让面包板不再那么有用武之地,经济的发展也让现成的板卡价格降到了一个合理....
物联网从提出到现在仍是碎片化的,即没有标准可言,又无事实规范。要解决这一问题,就需要一个可以兼容各色....
目前智能家居的创新应用中,不排除有部分应用确实能减轻人工负担;但大部分却在实际应用中频繁地被吐槽,新....
使用两个简单的硬件设备和几行代码构建一个空气质量探测器。 我们在东南亚的学校定期测定空气中的颗粒物。....
下面小编就为初学者筛选了10个适合的树莓派开发项目,这10个项目能够很好地帮助初学者对树莓派的硬件和....
本文首先介绍了树莓派的功能,其次介绍了树莓派的用途,最后详细介绍了树莓派新手入门教程。
一、 壁障小车的制作 1、 制作避障小车的准备工作 硬件:Arduino UNO、L298N驱动模块....
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司
电信与信息服务业务经营许可证:粤B2-用树莓派 + Python + OpenCV 实现家庭监控和移动目标探测(下) - Python - 伯乐在线
& 用树莓派 + Python + OpenCV 实现家庭监控和移动目标探测(下)
哇,上周关于做一个基本运动检测系统的文章真是赞。写这篇文章很有乐趣,而且从像您一样的读者那里获得反馈,使我的努力变得很值得。
对于那些刚看到这篇文章的朋友,上周那篇文章是关于使用计算机视觉来建立一个运动检测系统,其动机是因为我的朋友James,他罪恶的双手伸进了我的冰箱,偷走了我最后一罐令人垂涎的啤酒。因为我不能证明是他干的,所以我想看看我是不是能够利用计算机视觉和树莓派,当他再次尝试偷走我的啤酒的时候当场抓获他。
您将在本文的最后看到,我们要建造的家用监控和运动检测系统不仅炫酷又简约,而且针对我们这个特定的目标还非常的强大。
今天我们将要扩展我们的基础运动检测方法,并且:
让我们的运动检测系统变得健壮一些,这样它就可以连续工作一整天,不那么容易受光线变化所影响。
更新我们的代码,让我们的家用监控系统可以在树莓派上运行。
集成 Dropbox API,使得 Python 脚本可以自动把安保图片上传到我们的 Dropbox 账户中。在本文中,我们会看到很多代码,请做好准备。但是我们也会学到很多东西。更重要的是,在本文的最后,你将拥有一个你自己的,可以运行的树莓派家用监控系统。
你可以在下面找到全部的示例视频以及一些其他的例子。
视频地址:
OpenCV and Python 版本 为了运行这个例子,你需要 Python 2.7 和 OpenCV 2.4.X.
在开始前,你需要:
动起来,让我们把必要的东西都搞定。我会假设你已经有了一个和 。
你也已经在 并且可以。我同样还会假设你已经阅读并且熟悉了上周关于这篇文章。
最后,如果你想要上传你的家庭安保图片到个人 Dropbo x账户中,你需要到
注册并获取你的公有和私有API keys,但接入Dropbox API 并不是本教程所必需的,只是一个锦上添花的东西。
除此之外,我们需要用pip-install安装一个额外的包。
如果你没有安装我的 imutils 包,你需要或者通过 pip install imutils 安装
并且如果你有兴趣让你的家用监控系统上传安保图片到 Dropbox,你需要 dropbox 包:pip install dropbox
至此所有的东西都已经安装并且正确配置,我们可以继续前进使用 Python 和 OpenCV 来打造我们的家用监控及运动检测系统了。
这里是我们的安装过程:
,我们家用监控系统的目标是抓住任何尝试溜进我的冰箱并且偷走我的啤酒的人。
为了实现这一目标,我在我的橱柜上安装了树莓派+摄像头:
图1:在橱柜顶部安装的树莓派
这个系统会俯视冰箱和我公寓的正门:
图2:树莓派对准我的冰箱。如果有人尝试偷啤酒的话,运动检测代码就会被触发,上传图片到我的Dropbox中。
如果有人尝试打开冰箱门并取走我的一罐啤酒,运动检测代码会生效,上传当前帧的截图到Dropbox,可以抓他个人赃并获。
DIY:使用树莓派 + Python + OpenCV 打造家用监控及运动检测系统
好啦,让我们开始建造我们的树莓派家用监控系统吧。首先让我们看一下这个工程的目录结构:
|--- pi_surveillance.py
|--- conf.json
|--- pyimagesearch
|--- __init__.py
|--- tempimage.py
|--- pi_surveillance.py|--- conf.json|--- pyimagesearch|&&&&|--- __init__.py|&&&&|--- tempimage.py
我们家用监控系统的主要代码和逻辑会存放在 pi_surveillance.py 中。我们使用一个JSON配置文件conf.json 来代替使用命令行参数或是在pi_surveillance.py中对参数进行硬编码。
针对这样一个工程,我发现放弃使用命令行参数并依赖一个JSON配置文件是很有用的。有时候你有太多的命令行参数,这时利用一个JSON文件会使其变得容易和更加整洁。
最后,为了更好的组织,我们会定义一个pyimagesearch 包,里面包含一个单一的类TempImage,我们会在上传到Dropbox之前使用它临时将图片写入硬盘。
记住我们项目的目录结构,打开一个新的文件,命名为pi_surveillance.py,并且开始导入如下的包:
# 导入必须的包
from pyimagesearch.tempimage import TempImage
from dropbox.client import DropboxOAuth2FlowNoRedirect
from dropbox.client import DropboxClient
from picamera.array import PiRGBArray
from picamera import PiCamera
import argparse
import warnings
import datetime
import imutils
import json
import time
import cv2
# 构建 argument parser 并解析
ap = argparse.ArgumentParser()
ap.add_argument("-c", "--conf", required=True,
help="path to the JSON configuration file")
args = vars(ap.parse_args())
# 过滤警告,加载配置文件并且初始化Dropbox
warnings.filterwarnings("ignore")
conf = json.load(open(args["conf"]))
client = None
1234567891011121314151617181920212223242526
# 导入必须的包from pyimagesearch.tempimage import TempImagefrom dropbox.client import DropboxOAuth2FlowNoRedirectfrom dropbox.client import DropboxClientfrom picamera.array import PiRGBArrayfrom picamera import PiCameraimport argparseimport warningsimport datetimeimport imutilsimport jsonimport timeimport cv2&# 构建 argument parser 并解析参数ap = argparse.ArgumentParser()ap.add_argument("-c", "--conf", required=True,&&&&help="path to the JSON configuration file")args = vars(ap.parse_args())&# 过滤警告,加载配置文件并且初始化Dropbox# 客户端warnings.filterwarnings("ignore")conf = json.load(open(args["conf"]))client = None
哇,真是导入了好多包啊——比我们平常在PyImageSearch博文中使用的要多得多。第一个导入语句从 PyImageSearch导入了我们的 TempImage类。随后在3-4行获取了我们与Dropbox API交互所需的Dropbox函数。5-6行从picamera 导入了一些类,使我们可以获取树莓派摄像头的原始数据流(你可以在读到更多相关内容),剩下导入语句完成了其他我们所需模块的导入。再说一次,如果你还没有安装imutils,你需要在继续本教程之前先完成安装。
16-19行解析我们的命令行参数。我们只需要一个选项 --conf ,它指向我们的JSON配置文件在磁盘上的路径。
23行过滤掉了Python和的警告提示信息,特别是由urllib3和dropbox包产生的那些。最后,我们会在24行从磁盘上加载JSON配置字典并在25行初始化Dropbox客户端。
JSON配置文件
在我们深入的太多之前,让我们先看一眼我们的conf.json文件:
"show_video": true,
"use_dropbox": true,
"dropbox_key": "YOUR_DROPBOX_KEY",
"dropbox_secret": "YOUR_DROPBOX_SECRET",
"dropbox_base_path": "YOUR_DROPBOX_PATH",
"min_upload_seconds": 3.0,
"min_motion_frames": 8,
"camera_warmup_time": 2.5,
"delta_thresh": 5,
"resolution": [640, 480],
"fps": 16,
"min_area": 5000
1234567891011121314
{&&&&"show_video": true,&&&&"use_dropbox": true,&&&&"dropbox_key": "YOUR_DROPBOX_KEY",&&&&"dropbox_secret": "YOUR_DROPBOX_SECRET",&&&&"dropbox_base_path": "YOUR_DROPBOX_PATH",&&&&"min_upload_seconds": 3.0,&&&&"min_motion_frames": 8,&&&&"camera_warmup_time": 2.5,&&&&"delta_thresh": 5,&&&&"resolution": [640, 480],&&&&"fps": 16,&&&&"min_area": 5000}
这个JSON配置文件存放了一系列重要的变量,让我们逐个看看它们:
show_video:一个布尔量,表明来自树莓派的视频流是否要在屏幕上显示。
use_dropbox : 布尔量,表明是否要集成Dropbox API
dropbox_key:你的公有Dropbox API key
dropbox_secret:你的私有 Dropbox API key
dropbox_base_path : 用于存放上传图片的Dropbox 应用程序目录的名字。
min_upload_seconds :两次上传间需要等待的秒数。比如在我们启动脚本后5分33秒有图片被上传至Dropbox,第二张图片只有等到5分36秒时才会被上传。这个参数简单的控制了图片上传的频率。
min_motion_frames : 图片被上传Dropbox之前,包含运动的连续帧帧数的最小值
camera_warmup_time : 允许树莓派摄像头模块“热身”和校准的时间
delta_thresh : 对于一个给定像素,当前帧与平均帧之间被“触发”看做是运动的最小绝对值差。越小的值会导致更多的运动被检测到,更大的值会导致更少的运动被检测到。
resolution : 来自树莓派的视频,其每一帧的宽和高。
fps : 想要从树莓派摄像头每秒获取的帧数
min_area : 图像中需要考虑是否发生运动的最小区域的最小值(像素为单位)。越小的值会导致越多的区域被认为发生了运动,而min_area 的值越大的,则会只会标记更大的区域。
至此我们已经定义了我们conf.json 配置文件中的全部变量,我们可以回头编码了。
集成Dropbox
如果你想要集成Dropbox API,我们首先需要设置我们的客户端:
if conf["use_dropbox"]:
# 连接DropBox并且启动会话授权过程
flow = DropboxOAuth2FlowNoRedirect(conf["dropbox_key"], conf["dropbox_secret"])
print "[INFO] Authorize this application: {}".format(flow.start())
authCode = raw_input("Enter auth code here: ").strip()
# 完成会话授权并获取客户端
(accessToken, userID) = flow.finish(authCode)
client = DropboxClient(accessToken)
print "[SUCCESS] dropbox account linked"
12345678910
if conf["use_dropbox"]:&&&&# 连接DropBox并且启动会话授权过程&&&&flow = DropboxOAuth2FlowNoRedirect(conf["dropbox_key"], conf["dropbox_secret"])&&&&print "[INFO] Authorize this application: {}".format(flow.start())&&&&authCode = raw_input("Enter auth code here: ").strip()&&&&&# 完成会话授权并获取客户端&&&&(accessToken, userID) = flow.finish(authCode)&&&&client = DropboxClient(accessToken)&&&&print "[SUCCESS] dropbox account linked"
在第一行我们查看JSON配置文件,去看一下是否要使用Dropbox,如果是的话,在3-5行开始进行Dropbox的授权过程。
图3:授权Dropbox
请注意它是如何通过提供一个URL给我们来进行授权验证的。把这个URL复制粘贴到你的浏览器中,我们就可以来到 Dropbox 授权页面:
图4:允许我们的脚本访问Dropbox API
在Dropbox集成页面,我们点击“Allow”按钮,这将为我们产生一个授权代码:
图5:从Dropbox获取授权代码
我们随后即可把这段代码复制粘贴回我们的程序:
图 6:与Dropbox的集成现已完成。我们现在可以通过Python代码直接上传图片到Dropbox中了。
得到授权代码之后,我们就可以在10-11行完成Dropbox的集成工作。
树莓派家用监控以运动检测系统
好啦,现在我们终于可以开始执行一些计算机视觉和图像处理工作了。
# 初始化摄像头并且获取一个指向原始数据的引用
camera = PiCamera()
camera.resolution = tuple(conf["resolution"])
camera.framerate = conf["fps"]
rawCapture = PiRGBArray(camera, size=tuple(conf["resolution"]))
# 等待摄像头模块启动, 随后初始化平均帧, 最后
# 上传时间戳, 以及运动帧计数器
print "[INFO] warming up..."
time.sleep(conf["camera_warmup_time"])
avg = None
lastUploaded = datetime.datetime.now()
motionCounter = 0
12345678910111213
# 初始化摄像头并且获取一个指向原始数据的引用camera = PiCamera()camera.resolution = tuple(conf["resolution"])camera.framerate = conf["fps"]rawCapture = PiRGBArray(camera, size=tuple(conf["resolution"]))&# 等待摄像头模块启动, 随后初始化平均帧, 最后# 上传时间戳, 以及运动帧计数器print "[INFO] warming up..."time.sleep(conf["camera_warmup_time"])avg = NonelastUploaded = datetime.datetime.now()motionCounter = 0
在1-3行我们设置从树莓派摄像头获得的数据为捕获的原始数据(更多关于使用树莓派摄像头的内容,你可以。)
我们同时允许树莓派的摄像头“热身”几秒钟,确保传感器有足够的时间进行校准。最后,在11-13行,我们会初始化平均背景帧,以及一些统计用的变量。
# 从摄像头逐帧捕获数据
for f in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
# 抓取原始NumPy数组来表示图像并且初始化
# 时间戳以及occupied/unoccupied文本
frame = f.array
timestamp = datetime.datetime.now()
text = "Unoccupied"
# 调整帧尺寸,转换为灰阶图像并进行模糊
frame = imutils.resize(frame, width=500)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (21, 21), 0)
# 如果平均帧是None,初始化它
if avg is None:
print "[INFO] starting background model..."
avg = gray.copy().astype("float")
rawCapture.truncate(0)
# accumulate the weighted average between the current frame and
# previous frames, then compute the difference between the current
# frame and running average
cv2.accumulateWeighted(gray, avg, 0.5)
frameDelta = cv2.absdiff(gray, cv2.convertScaleAbs(avg))
12345678910111213141516171819202122232425
# 从摄像头逐帧捕获数据for f in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):&&&&# 抓取原始NumPy数组来表示图像并且初始化&&&&# 时间戳以及occupied/unoccupied文本&&&&frame = f.array&&&&timestamp = datetime.datetime.now()&&&&text = "Unoccupied"&&&&&# 调整帧尺寸,转换为灰阶图像并进行模糊&&&&frame = imutils.resize(frame, width=500)&&&&gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)&&&&gray = cv2.GaussianBlur(gray, (21, 21), 0)&&&&&# 如果平均帧是None,初始化它&&&&if avg is None:&&&&&&&&print "[INFO] starting background model..."&&&&&&&&avg = gray.copy().astype("float")&&&&&&&&rawCapture.truncate(0)&&&&&&&&continue&&&&&# accumulate the weighted average between the current frame and&&&&# previous frames, then compute the difference between the current&&&&# frame and running average&&&&cv2.accumulateWeighted(gray, avg, 0.5)&&&&frameDelta = cv2.absdiff(gray, cv2.convertScaleAbs(avg))
这里的代码看上去应该和代码很类似。
我们对当前帧进行一些预处理,调整尺寸为500像素宽,随后将其转换为灰阶图像,并对其使用高斯模糊来移除高频噪点并且让我们的能够专注于这幅图像的“结构”。
在第15行,我们检查一下平均帧是否已经被初始化,如果没有初始化,则用当前帧对其进行初始化。
24,25行非常重要,从这里开始就和上周的实现方式变得不同了。
在我们之前的运动检测脚本中,我们假设了视频数据的第一帧可以很好的代表我们想要建模的背景。对于我们这个特例来说,这个假设可以很好地工作。
但是这个假设同样容易失效。随着时间的变化(已经光线的变化),又因为视线中出现了其他物体,我们的系统会错误地在没有发生运动的区域检测到运动。
为了解决这一问题,我们使用了之前帧的加权平均值配合当前帧工作。这意味着我们的脚本可以动态的调整背景,即使随着时间的推移造成了光线的变化。这个方法仍然很基础,而且不是一个“完美”的背景建模方法,但是和之前相比已经好很多了
基于加权平均的帧数据,我们从当前帧减去加权平均值,得到的结果我们称之为“帧变化量”
delta = |background_model – current_frame|
图7:帧变化量的示意图,平均帧和当前帧的差异
我们随后可以对这个变化量进行阀值处理来找到我们图像中包含与悲剧模型有显著差别的区域——这些区域与视频数据中发生“运动”的区域一致:
# 对变化图像进行阀值化, 膨胀阀值图像来填补
# 孔洞, 在阀值图像上找到轮廓线
thresh = cv2.threshold(frameDelta, conf["delta_thresh"], 255,
cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
(cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
# 遍历轮廓线
for c in cnts:
# if the contour is too small, ignore it
if cv2.contourArea(c) & conf["min_area"]:
# 计算轮廓线的外框, 在当前帧上画出外框,
# 并且更新文本
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = "Occupied"
# 在当前帧上标记文本和时间戳
ts = timestamp.strftime("%A %d %B %Y %I:%M:%S%p")
cv2.putText(frame, "Room Status: {}".format(text), (10, 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.putText(frame, ts, (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX,
0.35, (0, 0, 255), 1)
1234567891011121314151617181920212223242526
&&&&# 对变化图像进行阀值化, 膨胀阀值图像来填补&&&&# 孔洞, 在阀值图像上找到轮廓线&&&&thresh = cv2.threshold(frameDelta, conf["delta_thresh"], 255,&&&&&&&&cv2.THRESH_BINARY)[1]&&&&thresh = cv2.dilate(thresh, None, iterations=2)&&&&(cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,&&&&&&&&cv2.CHAIN_APPROX_SIMPLE)&&&&&# 遍历轮廓线&&&&for c in cnts:&&&&&&&&# if the contour is too small, ignore it&&&&&&&&if cv2.contourArea(c) & conf["min_area"]:&&&&&&&&&&&&continue&&&&&&&&&# 计算轮廓线的外框, 在当前帧上画出外框,&&&&&&&&# 并且更新文本&&&&&&&&(x, y, w, h) = cv2.boundingRect(c)&&&&&&&&cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)&&&&&&&&text = "Occupied"&&&&&# 在当前帧上标记文本和时间戳&&&&ts = timestamp.strftime("%A %d %B %Y %I:%M:%S%p")&&&&cv2.putText(frame, "Room Status: {}".format(text), (10, 20),&&&&&&&&cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)&&&&cv2.putText(frame, ts, (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX,&&&&&&&&0.35, (0, 0, 255), 1)
为了找到图像中通过阀值测试的区域,我们进行简单的轮廓检测。随后遍历这些轮廓,看他们是否大于 min_area 。如果该区域足够大,那么我们可以表明我们已经在当前帧中找到了发生运动的区域。
16-18行计算了轮廓线的外框,将其画在在运动区域,并且更新了我们的text 变量。
最后,21-25行获取了我们当前的时间戳和状态 变量text 并将它们标记在帧数据上。 现在,让我们来编写负责处理Dropbox上传的代码吧:
# 检测该房间是否被“占领”
if text == "Occupied":
# 判断上传时间间隔是否已经达到
if (timestamp - lastUploaded).seconds &= conf["min_upload_seconds"]:
# 运动检测计数器递增
motionCounter += 1
# 判断包含连续运动的帧数是否已经
if motionCounter &= conf["min_motion_frames"]:
# 判断Dropbox是否被使用
if conf["use_dropbox"]:
# write the image to temporary file
t = TempImage()
cv2.imwrite(t.path, frame)
# 将图像上传至Dropbox并删除临时图片
print "[UPLOAD] {}".format(ts)
path = "{base_path}/{timestamp}.jpg".format(
base_path=conf["dropbox_base_path"], timestamp=ts)
client.put_file(path, open(t.path, "rb"))
t.cleanup()
# 更新最近一次上传的时间戳并且重置运动
lastUploaded = timestamp
motionCounter = 0
#否则, 该房间没有“被占领”
motionCounter = 0
12345678910111213141516171819202122232425262728293031
# 检测该房间是否被“占领”&&&&if text == "Occupied":&&&&&&&&# 判断上传时间间隔是否已经达到&&&&&&&&if (timestamp - lastUploaded).seconds &= conf["min_upload_seconds"]:&&&&&&&&&&&&# 运动检测计数器递增&&&&&&&&&&&&motionCounter += 1&&&&&&&&&&&&&# 判断包含连续运动的帧数是否已经&&&&&&&&&&&&# 足够多&&&&&&&&&&&&if motionCounter &= conf["min_motion_frames"]:&&&&&&&&&&&&&&&&# 判断Dropbox是否被使用&&&&&&&&&&&&&&&&if conf["use_dropbox"]:&&&&&&&&&&&&&&&&&&&&# write the image to temporary file&&&&&&&&&&&&&&&&&&&&t = TempImage()&&&&&&&&&&&&&&&&&&&&cv2.imwrite(t.path, frame)&&&&&&&&&&&&&&&&&&&&&# 将图像上传至Dropbox并删除临时图片&&&&&&&&&&&&&&&&&&&&print "[UPLOAD] {}".format(ts)&&&&&&&&&&&&&&&&&&&&path = "{base_path}/{timestamp}.jpg".format(&&&&&&&&&&&&&&&&&&&&&&&&base_path=conf["dropbox_base_path"], timestamp=ts)&&&&&&&&&&&&&&&&&&&&client.put_file(path, open(t.path, "rb"))&&&&&&&&&&&&&&&&&&&&t.cleanup()&&&&&&&&&&&&&&&&&# 更新最近一次上传的时间戳并且重置运动&&&&&&&&&&&&&&&&# 计数器&&&&&&&&&&&&&&&&lastUploaded = timestamp&&&&&&&&&&&&&&&&motionCounter = 0&&&&&#否则, 该房间没有“被占领”&&&&else:&&&&&&&&motionCounter = 0
我们在第二行判断是否确实在当前帧中监测到了运动。如果是的话,我们在第四行做另外一个判断,来确保与上一次上传到Dropbox的时间相比,已经过去了足够长的时间——如果确实经过了足够的时间,我们会将运动计数器递增。
如果我们的运动计数器达到了一定的连续帧数,我们会把使用TempImage类把当前图像写入硬盘,通过Dropbox API将其上传,并且重置我们的运动计数器和最近一次上传的时间戳。
如果并没有在房间中检测到运动,我们就把运动计时器置为0。
最后,让我们来完成这个脚本——判断我们是否希望将安保视频显示在屏幕上:
# 判断安保视频是否需要显示在屏幕上
if conf["show_video"]:
# 显示安视频
cv2.imshow("Security Feed", frame)
key = cv2.waitKey(1) & 0xFF
# 如果q被按下,跳出循环
if key == ord("q"):
# 清理数据流为下一帧做准备
rawCapture.truncate(0)
123456789101112
&&&&# 判断安保视频是否需要显示在屏幕上&&&&if conf["show_video"]:&&&&&&&&# 显示安视频&&&&&&&&cv2.imshow("Security Feed", frame)&&&&&&&&key = cv2.waitKey(1) & 0xFF&&&&&&&&&# 如果q被按下,跳出循环&&&&&&&&if key == ord("q"):&&&&&&&&&&&&break&&&&&# 清理数据流为下一帧做准备&&&&rawCapture.truncate(0)
这段代码同样是不言自明的。我们检查一下是否我们想要把视频显示在屏幕上(依据我们的JSON配置文件),如果是的话就显示,并且监控一个用来终止脚本的按键。
出于完整性考虑,让我们在pyimagesearch/tempimage.py中定义TempImage
# 导入必要的包
import uuid
class TempImage:
def __init__(self, basePath="./", ext=".jpg"):
# 创建文件路径
self.path = "{base_path}/{rand}{ext}".format(base_path=basePath,
rand=str(uuid.uuid4()), ext=ext)
def cleanup(self):
# 删除文件
os.remove(self.path)
12345678910111213
# 导入必要的包import uuidimport os&class TempImage:&&&&def __init__(self, basePath="./", ext=".jpg"):&&&&&&&&# 创建文件路径&&&&&&&&self.path = "{base_path}/{rand}{ext}".format(base_path=basePath,&&&&&&&&&&&&rand=str(uuid.uuid4()), ext=ext)&&&&&def cleanup(self):&&&&&&&&# 删除文件&&&&&&&&os.remove(self.path)
树莓派家用监控系统
我们已经做了很多工作了。让我们看一下树莓派 + Python + OpenCV + Dropbox 家用监控系统的实际表现。 定位到本文的源码目录并且使用下面的命令来执行它:
$ python pi_surveillance.py --conf conf.json
$ python pi_surveillance.py --conf conf.json
根据你的conf.json 的内容,你的输出(可能)与我的大相近庭。快速回顾一下本文之前的内容,我把树莓派和摄像头安装在橱柜的顶部,俯视厨房和冰箱——为了监视并等待任何尝试偷走我啤酒的人。
这里有一个例子,视频从我的树莓派通过X11 forwarding传输至我MacBook,这也是当你设置show_video: true 时会出现的结果:
视频地址:
在这个视频中,我已经禁用了视频流,但通过设置use_dropbox: true启动了Dropbox API集成,我们可以看到在图片中被检测到的运动结果,以及将结果上传到我个人Dropbox 账户的情况。
视频地址:
这里有一些示例帧数据,是家用监控系统工作一整天所记录的内容:
图8:树莓派家用监控系统在视频中检测运动并上传到我个人Dropbox 账户的例子
在这个例子中你可以清楚的看到我拿了冰箱中的啤酒
图9:在这帧被树莓派摄像头捕获的中,你可以清楚的看到我拿了冰箱中的啤酒
鉴于我的咆哮,这个家用监控系统应该能够在James尝试偷窃我啤酒的时候轻易的抓住他——而这一次,我的 Dropbox账户中就有被上传的真凭实据了。
在本文中我们探索了如何使用 Python + OpenCV + Dropbox + 树莓派和一个摄像头模块来建立我们自己的家用监控系统。
我们在上周例子的基础上,扩展了如下几点,(1) 对于背景环境的变化变得更加健壮, (2) 在树莓派上工作,(3) 与Dropbox API 集成,这样我们就可以把家用监控系统的视频图像直接上传到我的账户中,供我们即时查看。
本文源码:
最后,希望你喜欢这篇检测,请考虑把它分享给其他人哦!
打赏支持我翻译更多好文章,谢谢!
打赏支持我翻译更多好文章,谢谢!
任选一种支付方式
关于作者:

我要回帖

更多关于 香橙派和树莓派对比 的文章

 

随机推荐