基于motion视频捕捉软件的树莓派视频拍照系统(图像变化识别+拍照+邮件)

在果壳看到这篇文章关于树莓派视频拍照系统,就转载过来分享给大家,是很有用的。

本文主要内容摘自本作者的一篇论文,未全部写出,还请见谅。参考文章文末列出。如转载本文,请注明本文出处!


本系统具有无人值守自动监控的功能,即系统监控到视频监控范围内有移动物体时,系统会实时的发送带有视频文件的邮件给用户,以及时的提醒告知用户视频监控的内容。因此需要设计及配置邮件系统,本系统采用功能强大且开源的mutt系统进行设计。
mutt是Linux下的一个email程序。mutt和普通的Windows邮件应用不一样,mutt并不负责直接发出邮件,也不自己编辑邮件,也不会对邮件进行加密和数字签名等。mutt是一个管理email功能的Unix邮件程序。mutt通过管理不同的专门针对某一邮件功能的软件行为进行邮箱的收发等其他功能。比如编辑邮件,可以设置调用vi、pico、Emacs、nano等编辑器;发送邮件时,它将发出的信件放到sendmail的队列里,就不用管了;当需要数字签名时,mutt会把信件交给GnuPG之类的程序处理一下,然后再发出去。mutt邮件系统基本框图如图1.4所示。
基于motion视频捕捉软件的树莓派视频拍照系统(图像变化识别+拍照+邮件)_第1张图片 
图1.4 mutt系统框图
mutt和msmtp安装:
sudo apt-get install mutt
sudo apt-get install msmtp
安装完成后mutt会在/root/目录下生成一个./muttrc的隐藏文件,如果没有,可自己创建一个。编辑~/.muttrc文件如下:
set sendmail=/usr/bin/msmtp
set use_from=yes
set realname=" [email protected] "
set editor="nano"
设置发送邮件工具为msmtp,邮件账户为 [email protected] ,邮件编辑器为nano。
编辑~/.msmtprc文件如下:
defaults
logfile /var/log/msmtp.log
account 126
auth login
host smtp.126.com
from  [email protected]
user myaccount
password mypassword
account default: 126
其中, [email protected] 为邮箱地址,mypassword为邮箱密码,注意这里是明文密码。
以上配置好后就可以使用mutt邮件进行邮件发送了,本系统并不需要接收邮件,所以没有配置邮件接收系统。
二 tmpfs文件系统
因为在实时视频监控的过程中,会产生大量的图片和视频文件,如果图片和视频文件保存在SD卡中(树莓派的存储设备一般为SD卡,硬盘或U盘等存储设备可通过USB口进行扩展),会对SD卡进行大量频繁的写操作,导致SD卡使用寿命极大的降低,然而Linux提供了tmpfs文件系统。为解决这个问题提供了良好的方案。
tmpfs是基于内存的虚拟内存文件系统,并不是快设备,创建时不需要使用mkfs等进行初始化。其最大特点就是存储空间在VM(virtual memory)中。Linux中VM的大小由RM(Real Memory)和swap组成,RM的大小就是物理内存的大小,而swap的大小是由系统决定的。swap是通过硬盘虚拟出来的内存空间,因此它的读写速度比RM(Real Memory)要慢很多,当进程申请一定数量的内存时,如内核的VM子系统发现没有足够的RM时,就会把RM里面的一些不常用的数据交换到swap里面,如需重新使用这些数据再把它们从swap交换到RM里面。如果有足够大的物理内存,可以不划分swap分区。
因此,我们在/mnt/目录下创建一个tmp_motion目录用于保存视频监控过程中产生的图像和视频文件,再将这个目录以tmpfs文件形式挂载到内存空间中,不仅图片和视频文件的保存速度加快了,而且也大大减少了对SD卡的读写操作。
打开/etc/fstab文件,添加如下:
tmpfs /mnt/tmp_motion tmpfs size=80m 0 0
保存退出,重启后,系统开机即会将/mnt/tmp_motion目录以tmpfs文件形式挂载在内存中,同时分配80MB的内存给/mnt/tmp_motion文件目录。
三 Linux crontab定时任务
本文前面已使用过crontab的定时任务功能。crontab是一个Linux下的定时执行工具,可以在无需人工干预的情况下运行作业。crontab是内置程序,基本任何版本的Linux都带有这个程序。

crontab命令选项: 
-u 指定一个用户。
-l 列出某个用户的任务计划。
-r 删除某个用户的任务。
-e 编辑某个用户的任务。

可使用crontab -e编辑定时任务,crontab定时任务格式如下:
Minute Hour Day Month Dayofweek Command

参数范围:
0-59 0-23 1-31 1-12 0-6 Command
30, 8-11 */1 * * ls
上述命令即表示每天的8-11点的第30分钟执行一次ls命令。
四 motion视频软件安装及配置

motion首先初始化设备和创建管理线程,探测并打开视频设备(如果是USB 摄像头,则设备名称是/dev/video0。如果打开设备成功,则需要读取并设置视频设备的一些参数信息,如摄像头类型,帧大小,和图像数据读取方法等。之后是创建图像采集线程Thread0,打开socket等待客户端建立连接,连接成功后创建线程service向客户端传输图像。当图像采集线程退出时,程序结束。

motion软件安装:

sudo apt-get install motion

安装完成后会有一个motion.conf配置文件,位于在/etc/motion/目录下,其关键的部分配置如下:

daemon off

setup_mode off

videodevice /dev/video0

v4l2_palette 2

width 640

height 480

framerate 2

threshold 3500
threshold_tune off
# Noise threshold for the motion detection (default: 32)
noise_level 64
gap 10
quality 50
# Use ffmpeg to encode mpeg movies in realtime (default: off)
ffmpeg_cap_new on
ffmpeg_cap_motion on
ffmpeg_bps 500000
ffmpeg_video_codec msmpeg4
snapshot_interval 1
locate on
target_dir /mnt/flash_8G/motion/snapshots
snapshot_filename %v-%Y%m%d%H%M%S-snapshot
jpeg_filename %v-%Y%m%d%H%M%S-%q
movie_filename %v-%Y%m%d%H%M%S
webcam_port 8081
webcam_quality 60
webcam_motion off
webcam_maxrate 8
webcam_localhost off
# TCP/IP port for the http server to listen on (default: 0 = disabled)
control_port 8080
control_localhost off
control_html_output on
on_event_start /home/pi/motion/on_motion_detected.sh
on_event_end /home/pi/motion/on_motion_end.sh
其中,daemon off:关掉deamon模式。否则运行motion后,会在后台直接运行,需要用top命令查看出motion的进程号,才能kill掉motion进程。
locate on: 设置当探测到图像中有运动时,把运动区域用矩形框起来。
videodevice /dev/video0: 设置加载USB摄像头的设备,一般为video0,当使用network webcam,需要设置netcam_url,此时,videodevice选项自动失效。
v4l2_palette 2:设置图像的编码格式为MJPEG,可选值为0-8,分别对应的不同的图像编码格式。
width和height:设置图像、视频的长度和宽度,值越大,图像越清晰,但所需的网络流量越大,为降低占用的宽带流量,这里设置为640和480。
threshold_tune off: 设置是否使用motion detection阈值自动调节。当设置为on时,下一个设置threshold 4500自动失效。设置off时,可以由threshold指定当探测到多少像素变化时,判断为图像中有运动。
ffmpeg_cap_new on: 指在侦测到运动时,用视频纪录下来。
ffmpeg_video_codec msmpeg4: 设定视频的编码器。
/target_dir /mnt/tmp_motion: 当探测到运动时,图片和视频的保存路径,这里设为保存在U盘下。默认为/var/lib/motion/snapshots。
snapshot_interval 1: 设定自动采集图片的周期,当有运动被检测到时,采集频率会自动变高。
webcam_port 8081:设置视频输出流的访问端口,默认8081端口。当需要外网访问motion监控的过程时,需要设置webcam_localhost为off,即不限制只在局域网内访问motion的监控结果。
control_port 8080:设置motion的网络控制端口,通过该端口可查看和修改motion.conf里的配置,如要外网访问,需设置control_localhost为关闭。
on_event_start /home/pi/motion/on_motion_detected.sh: 设置当探测到运动时,执行指定目录里的文件,这里设定为执行/home/pi/motion/目录下的
on_motion_detected.sh脚本命令。
on_event_end /home/pi/motion/on_motion_end.sh: 当on_event_start事件开始后,即检测到运动之后, 若连续10秒不能再检测到运动时,执行指定目录下的文件,这里设置为执行/home/pi/moiton/目录下的on_motion_end.sh脚本命令。10秒参数由gap 10选项设定。
视频监控的流程
当开启motion视频监控进程时,motion会一定帧速拍摄JPEG的监控图像,当侦测到画面有指定大小的像素变化时,即监控范围内有物体运动。此时motion将触发on_event_start事件,执行用户设置的on_event_start事件的脚本命令。当检测到运动之后,如果有连续10秒钟像素的变化的值小于阈值,即不能再检测到运动时,触发on_event_end事件,执行用户设置的on_event_end事件的脚本命令。
on_motion_detected.sh脚本作用是,记录下探测到运动时的时间,即拍摄的视频文件的文件名的一部分。把这个时间值存到/home/pi/motion/tmp/videotime文件中。该脚本内容如下:
#!/bin/bash
echo "on_motion_detected start!"
DATE=$(date +"%Y%m%d%H%M%S")
ALARM_TIME="/home/pi/motion/tmp/videotime"
echo "$DATE"> $ALARM_TIME
而on_motion_end.sh脚本的作用是用于查找指定的视频文件,并将视频文件以邮件形式发送到用户指定的邮箱,当邮件发送失败时,将视频保存到大容量的存储盘中,减少对SD卡的写操作。
当motion检测到的运动结束后,将拍摄的运动视频文件(.avi文件)发送到指定邮箱里。avi视频的文件名为一个序号+检测到运动的时间+”.avi”,而检测到运动的时间,根据on_motion_detected脚本,保存在/home/pi/motion/tmp/videotime文件里,理论上只要从文件里读出时间,然后补全文件名,该序号由*号替代,便能发出邮件。但是,由于程序运动效率原因,有时会出现记录的时间同开始录制avi视频的时间差1秒的情况,虽然只有一秒,但足以导致脚本找不到avi文件,无法正确发出监控视频。因设置了gap为10,即10秒内最多只有一个视频。所以,可以去查找,以videotime中所记录的时间及其上一秒的时间命名的视频文件。

当在/mnt/tmp_motion文件中找到该视频文件时,通过mutt邮件系统发送邮件主题文件alarm.txt及附件视频文件。邮件发送成功时,并在自定义的邮件发送事件日志current.log文件中记录结果,如果失败,对以tmpfs文件系统形式挂载在内存中的视频文件拷贝到U盘,并将以上操作过程的结果记录到total.log日志中,以备查验。on_motion_end.sh脚本见附录2。
附录2:on_motion_end.sh
#on_motion_end.sh
#!/bin/bash
echo "111111111111111on_motion_end1111111111111111"
DIRC="/mnt/tmp_motion/"
VIDEOTIME="/home/pi/motion/tmp/videotime"
TIME=$(cat $VIDEOTIME)
echo " time = $TIME"

ALARM_EMAIL="/home/pi/motion/tmp/myalarm.txt"
USB_DIR="/mnt/usb/motion/snapshots/"
CURRENT_LOG="/home/pi/motion/sendmail_log/current.log"
TOTAL_LOG="/home/pi/motion/sendmail_log/total.log"
send_succ=1

echo "Subject:Motion detected - $TIME - $DIRC"> $ALARM_EMAIL
echo "">> $ALARM_EMAIL
echo "Motion detected - check $TIME.avi">>$ALARM_EMAIL
MAILBODY=$(cat $ALARM_EMAIL)
echo "" > $CURRENT_LOG

right_time="time.avi=none"
current_date=$(date +"%Y-%m-%d %H:%M:%S")
if [ -e $DIRC*$TIME.avi ];then
echo 'first time exist'
right_time="time.avi=$TIME"
else
TIME=$(expr $TIME - 1)
if [ -e $DIRC*$TIME.avi ];then
echo 'second time exist'
right_time="time.avi=$TIME"
else
echo 'this time not exist'
fi
fi
echo -e "send_date=$current_date" >> $CURRENT_LOG
echo -e "send_date=$current_date" >> $TOTAL_LOG
echo $right_time >> $CURRENT_LOG
echo $right_time >> $TOTAL_LOG
str="?"
(mutt_dotlock -f -u /root/sent ; echo $MAILBODY | mutt -s $TIME  [email protected]  -a $DIRC*$TIME.avi)
if [ $? -eq 0 ];then
echo "send success"
send_succ=0
str="send_succ=0"
else
echo "send fail"
send_succ=1
str="send_succ=1"
fi
echo $str >> $CURRENT_LOG
echo $str >> $TOTAL_LOG

sudo cp $DIRC*$TIME.avi $USB_DIR
if [ $? -eq 0 ];then
echo "copy success"
str="copy=0"
else
echo "copy fail"
str="copy=1"
fi
echo $str >> $CURRENT_LOG
echo $str >> $TOTAL_LOG

if [ $send_succ -eq 0 ];then
sudo rm -r $DIRC*$TIME.avi
if [ $? -eq 0 ];then
echo "delete success"
str="delete=0"
else
echo "delete fail"
str="delete=1"
fi
else
sudo rm -r $DIRC*$TIME.avi
if [ $? -eq 0 ];then
echo "delete sucess after send fail"
str="delete=0"
else
echo "delete fail afte send fail"
str="delete=1"
fi
fi
echo $str >> $CURRENT_LOG
echo $str >> $TOTAL_LOG
其中,/home/pi/motion/tmp/myalarm.txt文件中保存的是发送邮件的主题。邮件系统采用mutt发送。
当系统在视频监控的过程中,会不断的产生图片和视频文件并保存在内存中tmp_motion文件下。视频文件经on_motion_end.sh脚本处理,如果发送成功,那么将删除源文件;如果发送失败,那么将源文件拷贝至外挂的大容量U盘中,再删除源文件。所以tmp_motion文件目录下将不再有视频文件,而图片文件会持续地堆积,如果不对图片文件进行处理,那么tmp_motion将超出限定的80MB的tmpfs文件大小,并导致内存崩溃。
所以在crontab定时任务,加入几个定时任务以保证及时地清除tmp_motion下的文件:
*/3 * * * * rm -r /mnt/tmp_motion/*.jpg
*/5 * * * * rm -r /mnt/tmp_motion/*m.avi
上述命令表示每隔3分钟,系统将删除在/mnt/tmp_motion/目录下的所有.jpg格式的图片文件;每隔5分钟,将删除在/mnt/tmp_motion/目录下的所有文件名末尾的字符串为m.avi的视频文件。

五 系统性能测试及分析
5.1   网络连接及系统功耗分析
本系统自今年2月中旬搭建以来,一直连续不断地开机运行至今,没有出现什么大的系统故障问题,只有2-3次因作者家里的路由器网络断掉导致连不上网,但时间都不长,最多几天而已。即使网络连接中断,视频监控拍摄到的视频文件仍会保存在系统外挂的U盘中,且拍摄的时间,邮件发送及视频复制的情况都会在/home/pi/motion/sendmail/total.log记录,用户可以查看以了解视频监控的历史情况。当路由器网络重新连接之后,系统会通过执行脚本net_restart.sh自动进行网络连接,保证树莓派网络连接通畅。
因花生壳动态域名服务,作者是免费申请的,解析比较不稳定,所以有时解析的了有时解析不了,但通过系统的定时任务每隔一段时间报告ip地址,作者即使用外网访问系统也很方便。
因整个系统的功耗比较低,即使在运行这么多任务的同时,它的散热仍旧良好,图5.1是系统开机几个月以来的CPU温度曲线。
基于motion视频捕捉软件的树莓派视频拍照系统(图像变化识别+拍照+邮件)_第2张图片 
图5.1 系统2月至5月的CPU温度曲线图
从上图可看出,系统自开机以来没有超过60摄氏度以上,最高历史点温度为2014年4月13日和5月19日58摄氏度左右,且与天气环境有关:2014年4月9日10点之前平均温度低于50摄氏度,4月9日10点之后至今平均温度高于50摄氏度低于60摄氏度。
5.2 视频监控功能测试及分析
对系统的视频监控功能进行测试如图5.2可知,在视频画面大小设置为720x576像素,帧速为每秒2帧的情况下,画面较清晰流畅,如需更清晰的画面质量,可设置画面大小为1080p,但不仅占用网络带宽大,而且需摄像头支持,还与摄像头质量有关。本系统所用的摄像头为较廉价的二手UVC USB摄像头,基本满足对于视频监控的画面质量要求。右上角发白部分为远程控制的台灯,可提高摄像头光照度或者模拟移动物体。
基于motion视频捕捉软件的树莓派视频拍照系统(图像变化识别+拍照+邮件)_第3张图片 
图5.2 视频监控实时画面
本文通过对台灯进行亮几秒,灭几秒的方式在晚上大幅度的改变画面像素模拟移动物体的情况,对模拟移动物体侦测的拍摄结果如图5.3所示。
基于motion视频捕捉软件的树莓派视频拍照系统(图像变化识别+拍照+邮件)_第4张图片 
图5.3 模拟移动物体侦测拍摄画面
系统会对监控范围内像素数量变化值大于阈值(这里设置为3500个像素)的情况进行视频拍摄及录制,并用矩形将像素变化的部分框起来提示用户。
视频拍摄完后,系统已把带有视频附件的邮件发给了作者,然而没有发送成功的部分系统将把文件拷贝到外挂的U盘文件目录中了。通过查询自定义的视频文件操作日志/home/pi/motion/sendmail/total.log,也可知道视频文件操作的结果,摘录total.log部分数据如下:
send_date=2014-05-19 23:23:43
time.avi=none
send_succ=1
copy=1
delete=1

send_date=2014-05-19 23:25:46
time.avi=20140519232344
send_succ=1
copy=0
delete=0
数据格式为作者自定义的,当无视频录制时,time.avi=none,且send_date有值表明on_motion_detected.sh脚本记录的时间与视频录制的时间不一致。值为0表示操作成功,1为操作失败。
从以上数据可看出视频录制时间为2014-05-19 23:23:44,邮件发送失败,复制到U盘中成功,删除位于tmp_motion的视频文件成功。
参考文章:
Linux shell脚本编写基础
Linux下的motion detection(最简单的办公室监控系统)
Linux下 mutt和msmtp发送邮件
Crontab的格式
mutt配置转述
百度百科tmpfs文件系统

本文作者来自果壳的:蜗牛R2-D2

你可能感兴趣的:(智能家居)