家里没人怎么防火防盗?装上这段自动看家程序




假期马上就要到了,不少朋友即将出门旅游或探亲访友。即使没有强迫症的你,也许在锁门离开的一瞬间,心里也会泛起一丝淡淡的担忧:离开家这么长时间,如何才能确保家里一切安好?

长时间家里没人,最主要的威胁来自两个:一个是小偷,另一个是火灾。防盗防火防闺蜜虽然是永恒的主题,但所有措施都是在出门以前做的,究竟效果如何?

最好是能有一个装备,在主人不在家时实时监控家里。一旦有问题,迅速通知主人,同时报警。

 

1.监控系统

1.1市面上的监控系统

针对这个问题,网上有不少现成的监控系统。原理大概是:通过探测器监测家里的情况,一旦发现异常时,报警器通过网络将报警信息推送到主人的手机或电脑。


 探测器的类型主要有两种:

(1)红外探测器


世间万物包括你、我还有小偷的身体,无时无刻都在向外发射着红外线。 

红外线有个规律,就是温度越高的物体,向外发射的红外线强度越大。 

因此,如果把红外线探测器装在门的上面或对面。当有小偷经过的时候,它就能探测到红外线强度异常增大,据此判定有小偷闯入。  

(2)门磁探测器

门磁探测器由两个部分组成,一部分安装在门上,另一部分安装在门框上。如果小偷打开了门,探测器的两部分会被分离开,据此判定有小偷闯入。

这些报警器在一定程度上能监控小偷和火灾,但它们问题在于:

(1) 红外线传感器是利用人体温度和环境温度差值来判断的,因此对温度非常敏感。想想在炎热的夏天,空气的温度几乎都是30几度,已经非常接近人体温度,这对于红外线传感器而言是一个挑战。 

(2) 无论是红外线传感器还是门磁传感器,它们都安装在固定的位置(门和窗户对面或者旁边)。对于有上进心的小偷而言,你觉得他们不会网购这个、拆开仔细研究清楚吗?训练有素的小偷能迅速找到这些监控设备,可能只需要花几秒钟就把警报声消除了。 

因此,我们需要想其他的办法来解决这些问题。 

1.2我们的监控系统

好消息是:这一切都可以通过Matlab编程来实现!而且无需购买上面的传感器,只需要在天桥上的地摊买个摄像头即可。 

工作原理如下:程序通过调用摄像头,对门和窗自动定时拍照。每拍一张照片,就和前一张照片对比,判断门窗是否被打开、家里是否有贼闯入或火情。一旦探测出异常情况,立刻给主人发送报警邮件,并播放警报,赶走小偷。 

如果你买一个针孔摄像头,藏到衣柜边上对着门窗,那么即使是训练有素的小偷进来了,也无法迅速消除摄像头,警报声会一直持续。而且,摄像头对温度并不敏感。 

我们把程序起个名字叫doggydoggy实现监控的流程图如下: 


如果想用Matlab编程实现上面这些功能,至少要解决下面几个难点:

(1)如何调用摄像头自动定时拍照?

(2)如何通过对比两张照片,判断家里是否有贼闯入?

(3)判断出有贼之后,如何给主人发送报警邮件?

(4)如何自动播放警报?

(5)如果小偷对报警声音根本不care,是否有其它办法? 

下面一一解释如何实现,没时间看原理的同学,可以直接跳到第6部分的使用方法。

 

2.定时自动拍照

定时自动拍照由一个主程序doggy.m和一个拍照函数takephotos.m组成。 

其中主程序doggy.m的代码为:

%清除所有变量

clear

clc

 

%建立图片存储文件夹

if exist('doggyphoto','dir')~= 7

   mkdir([cd,'/doggyphoto'])

end

directory=[cd,'/doggyphoto/'];

 

%设置一个监控界面

hf = figure('Units','Normalized','Menubar','None','NumberTitle','off','Name','监控系统');

ha = axes('Parent', hf, 'Units','Normalized','Position', [0.125 0.2 0.75 0.75]);

axisoff

axisequal

 

%设置两个按钮

hb1 = uicontrol('Parent', hf, 'Units','Normalized','Position', [0.3 0.05 0.15 0.1], 'String','测试摄像头','Callback', ['imaqhwinfo;'...

   'obj = videoinput(''winvideo'');'...

   'set(obj, ''FramesPerTrigger'', 1);'...

   'set(obj, ''TriggerRepeat'', Inf);'...

   'objRes = get(obj, ''VideoResolution'');'...

   'nBands = get(obj, ''NumberOfBands'');'...

   'hImage = image(zeros(objRes(2), objRes(1), nBands));'...

   'preview(obj, hImage);']);

hb2 = uicontrol('Parent', hf, 'Units','Normalized','Position', [0.6 0.05 0.15 0.1], 'String','开始监控','Callback','takephotos(directory,obj);');

 

 

这段程序分为四个部分: 

第一部分:清除所有变量,避免其它变量影响监控系统的运行;

第二部分:新建一个文件夹doggyphoto用于待会拍照存储照片,如果这个文件夹已存在就不用新建了。 

第三部分:设置一个监控界面; 

第四部分:设置两个按钮,其中一个是按钮是用来测试摄像头的,另一个按钮则是开始监控的。 

在第四部分需要调用一个函数takephotos,源程序是:

function takephotos(directory,obj)

escapetime=30;%从点击开始监控到锁门后离开的时间内,摄像头不监控,单位:秒

daynum=3;   %一共打算出去几天?单位:天

timestep=2; %每隔多少秒拍一次照片?单位:秒

photonum=round(daynum*24*3600/timestep);

i=0;

 

whilephotonum>0

   while escapetime>0

       

       disp(['The monitoring system will start to workin ' num2str(escapetime)' seconds, please leave quickly.']);

       escapetime=escapetime-1;

       pause(1);

       

       ifescapetime==0

           disp(['The monitoring system will start to worknow.']);

       end

   end  

   

   photonum=photonum-1;

    i=i+1;

   filename=[num2str(i)];

   frame = getsnapshot(obj);%抓图

   imwrite(frame,[directory,filename,'.jpg']);%存图

   disp(['Take the ' num2str(i) ' photos.']);  

   

   if(i>1 &&comparephotos(i,i-1)>0)

       sentemail();

       playalarm();

       disp(['Something wrong in the room!']);       

   end    

   pause(timestep);  

 

end

 

   cleari;%清除局部变量

   delete(obj);%关闭摄像头

 

在这个函数中要设置几个参数:

(1) 从主人点击“开始监控”的按钮,到锁门后离开这段时间内,摄像头应该不监控。否则,监控程序把主人也当做小偷了……这段时间可长可短,取决于每个人动作快慢。这里doggy默认给了主人30秒钟,需要更长时间可手动修改。

escapetime=30;%从点击开始监控到锁门后离开的时间内,摄像头不监控,单位:秒

 (2) 主人打算一共出去多少天?doggy需要在这段时间内工作,默认是3天,同样的可手动修改这个参数。

daynum=3;   %一共打算出去几天?单位:天

 (3) 每隔多少秒拍照一次?如果拍的太频繁,照片占用的硬盘空间可能非常大,硬盘会被爆掉的。而如果两次拍照之间间隔时间太久,小偷进来把门又关好了,两次照片一摸一样,监控程序无法判断异常情况。默认是2秒,可手动修改。

timestep=2; %每隔多少秒拍一次照片?单位:秒

 通过Matlab内置函数getsnapshot函数拍照,然后通过内置函数imwrite函数存储,之后调用comparephotos函数判断是否有人闯入或是否有火灾,如果判断有异常情况,通过sentemail函数给主人发邮件,并且通过playalarm播放警报。 

3.判断是否有人闯入或火灾

这项功能是通过comparephotos.m完成的,源代码如下: 

function theif=comparephotos(i,j)

 

name1=[num2str(i)'.jpg'];

name2=[num2str(j)'.jpg'];

img1=imread(name1,'jpg');

img2=imread(name2,'jpg');

 

diffvalue=mean(mean(mean(abs(double(img1)-double(img2)))))%计算两张图的差值

Threshold=5;%设置报警的阈值

 

ifdiffvalue>Threshold %如果两张图片差异过大,认为有贼闯入或有火警

   theif=1;

else

   theif=0;

end

 

这个函数首先调用内置函数imread读取两张图片,然后继续对比。 

Matlab中,照片是以数组的形式存储的。因此,通过对比两个数组的差值就能判断两张图片的区别。 

正常情况下,摄像头拍摄的两张相近的图片应该是差别不大;如果差值过大,则说明有异常情况。 

测试结果如下: 

(1) 正常情况下

2秒的图片: 


4秒的图片: 


由于没有人闯入,也没有火情,两张图片应该是一模一样的。

两个数组相减之后,差值为0。如果把这个差值的数组再显示,应该一张全黑的照片:



(2) 如果第二张照片中放了一个异物(记事本,请忽略本人的玉手…)

2秒的照片:



4秒的照片:


 

两个数组相减之后,没有异物的地方差值为0,有异物的地方差值不为0,所以差值的数组再显示就是这样的:

 

 

看,没有异物的地方是全黑的,有异物的地方就被检测出来了。 

(3)由于一天内不同时刻,室外的光线并不一样,所以前后两张照片并不是完全一模一样,即相减后的数组再显示不是全黑的,而是接近于全黑的有一定噪音的图片:

 

所以这里需要有个参数,来调控报警的阈值。

Threshold=5;%设置报警的阈值

这个参数反映了前后两张图片的差异程度。 

如果Threshold设置为0,那么只要两张图片有一丝不同,doggy就会马上报警,真正可以实现连一只蚊子、一只跳蚤都不让飞进来。 

但实际上,我们并不需要doggy这么敏感。否则,由于室外的光线的不同而导致前后两张照片并不是完全一模一样,也会引起误报警。 

这个参数和不同房子的窗户大小、位置相关。一般而言,通过测试后发现设置Threshold5,可以很好的过滤掉误报警。 

 

4.发送邮件

我们不希望外出时,家里有任何情况发生,但一旦有情况,让doggy给我们立刻发一封邮件,源代码文件名叫sentemail.m,代码如下: 

function sentemail()

 

mail ='xxxxxxxxx@qq.com';%可以使用qq邮箱

password ='xxxxxx';      %输入邮箱的密码

setpref('Internet','E_mail',mail);

setpref('Internet','SMTP_Server','smtp.qq.com'); %此处邮箱服务器与上面一致

setpref('Internet','SMTP_Username',mail);

setpref('Internet','SMTP_Password',password);

props = java.lang.System.getProperties;

props.setProperty('mail.smtp.auth','true');

props.setProperty('mail.smtp.socketFactory.class','javax.net.ssl.SSLSocketFactory');

props.setProperty('mail.smtp.socketFactory.port','465');

subject='Alarm'%邮件标题

content='Dear Master, there is something wrong in our house!';%邮件内容

sendmail('xxxxxxxxx@qq.com',subject,content);%需要发送到的邮箱地址

 

在这一块需要注意的是: 

(1) 密码要使用明码,很坑爹是不是?别忘了上个月我们说过可以用pcode给程序加密。 

(2) Matlab可以在邮件里面发送附件。然而,它发送邮件是通过Java接口,速度比较慢,所以不推荐添加太大的附件,以免发送失败。这里为了保险起见,干脆不发附件好了。 

(3) Matlab只能发送不需要authentication的邮箱地址,如果使用出现错误,请把POP3后者SMTP服务打开。以qq邮箱为例,需要在设置里面打开如下权限: 



5.自动播放警报

通知了主人之后,接下来就是该发出声音赶走小偷了,函数文件名是playalarm.m,源代码如下:

function playalarm()

    [y,fs]=wavread('Alarm.wav');%保证wav文件在当前工作目录

   sound(y, fs);                   

 

(1)警报声

最常用的声音是警车的声音。

报警器的声音会让一些有贼心没贼胆的人退散,而且能够引起周边邻居注意。

  

(2)恐怖片

对于等级比较高的小偷而言,这种报警声音或许早已经被免疫了。 

这时不如换成恐怖片的声音,比警车的声音更有效果。

友情提醒:此恐怖片声音非常惊悚,切勿在深夜一个人点开。

对于盗贼而言,其实是需要很强的心理素质的。 

尤其是进屋的前几秒种,是最紧张和防御状态最充分的时候。 

他会仔细检查看有没有情况,一旦发现这个房间里面没有威胁,他会稍微放松一点。 

所以这段惊悚的声音,最前面7秒没有声音,是为了给盗贼充分的时间放松。 

等他开始放松的时候,再突然听到惊悚的声音才能达到最好的效果。

  

(3)声音飘忽的感觉

光播放恐怖片的音乐,也许对于胆大的盗贼来说根本无所谓,甚至只能当做他们饭后的茶资。 

那我们就加点立体效果,即声音飘忽不定的感觉。 

原理是这样的:人可以判断声源的位置,是因为声源到两只耳朵的距离一般不同,声音传到两只耳朵的时刻、强弱及其他特征也就不同。 

那么,如果我们通过左声道和右声道放出来的恐怖片声音强度或时刻不一样,盗贼就会感觉恐怖声的发出位置是在飘忽不定的,更具有惊悚效果。

 

下面,我们改变两个声道声音的强度:

function playalarm2()

    [y,fs]=wavread('kb.wav');

   left=y(:,1);  %左声道

   right=y(:,2); %右声道

  

   x=1:length(left);

 

   y(:,1)=left.*sin(2*pi().*x/length(left)*5)';

   y(:,2)=left.*(1-sin(2*pi().*x/length(left)*5))';

   wavwrite(y,fs,'kb2');

 

比起上面的那个,能明显感觉到这次声源在左右移动。(每篇推送只能插入一段音频,所以这段飘忽的音频无法插入,需要试听的给后台留言) 

然而,这个声音仍然只在盗贼的正前方,能不能有办法让盗贼认为声源在左右上下移动,甚至跳到他背后呢? 

答案当然是可以的了啦!当两个波形具有180°相位差且分别位于两个声道时,只要两个声道不被融合在一起,我们可以明显感觉到声源跑到后面去了。 

不过限于时间和篇幅,这里无法继续展开讨论,下次找机会专门做个Matlab处理立体声的专题吧。

 

(4)增加次声波

只有恐怖片声音的刺激,也许还是不能完全克制住盗贼的贪欲。 

能否让听到立体声恐怖片的盗贼,除了在心理上不舒服之外,身体也产生不舒服的感觉呢? 

接下来,隆重推出另一个大杀器——次声波。 

什么是次声波?人耳朵能听到的声音的频率是202万赫兹。频率小于20赫兹的声波叫做次声波。

 



某些频率的次声波由于和人体器官的振动频率相近甚至相同,容易和人体器官产生共振,对人体有很强的伤害性,危险时可致人死亡。 

当然,通过matlab程序生成的次声波,经过音响播放出来其实功率很小,并不足以伤害到盗贼。但是至少会让盗贼感觉到有点不舒服。 

更重要的是,这个声音盗贼是听不到的。 

也就是说,站在盗贼的角度,他无法听到声音,只能感受到难受。再配上恐怖片的惊悚的立体音效,效果达到了。 

生成次声波的源代码如下:

function createisound()

    f=10;%频率10赫兹

    w=2*pi()*f;

    t=[0:0.0001:30];%步进0.0001

    y=sin(w*t);


这样,就得到了一个频率为10赫兹,时间为30秒的次声波。

 

(5)高分贝DJ 

如果盗贼油盐不进,对警车声和恐怖片声音都免疫。 

我们还有最后一招,但也是最没有办法的办法:把音量调到最大,播放下面高分贝DJ,把邻居们都吵醒吧。 

他们会怒气冲冲找你算账,然后在无意中把小偷逼走。 

6.使用方法

好了,原理以及讲清楚,下面讲如何使用这个监控系统。 

6.1搭建监控系统

(1)材料准备

材料只需要:

一台装有Matlab的电脑

一个摄像头

一个音响(最好有低音炮,效果更佳) 

把电脑、摄像头和音响都藏在隐蔽的位置。音响最好对称的放在房间的两个角落。

  

(2)参数设置 

将所有代码拷到电脑上,一共有六个文件

doggy.m,

takephotos.m, 

comparephotos.m, 

sentemail.m, 

playalarm.m

playalarm2.m

每个文件对应的功能见下图:

  

 

通过doggy.m调用takephotos.m进行拍照,然后调用comparephotos.m判断是否有人闯入或是否有火灾,如果判断有异常情况,通过sentemail.m函数给主人发邮件,并且通过playalarm.mplayalarm2.m播放警报。  

需要设置的参数有:

(1) takephotos.mescapetime参数:从主人点击“开始监控”的按钮,到锁门后离开这段时间内,摄像头应该不监控。 

(2) takephotos.mdaynum参数:主人打算一共出去多少天? 

(3) takephotos.mtimestep=2参数:每隔多少秒拍照一次? 

(4) comparephotos.mThreshold=5:设置报警的阈值。 

(3)开始监控

参数设置好以后,在主程序里运行doggy回车,弹出如下界面:

 

 点左下方的“测试摄像头”,看摄像头是否正常工作。 

然后点右下方的“开始监控”之后,程序开始倒计时: 

 


主人在这个时间内,离开锁门准备去外面度假咯。 

接下来,是程序每隔几秒钟给门和窗照相,




然后对比前后两张照片判定是否有人闯入。

 

6.2盗贼的体验

 

我们希望报警程序永远不要被激活。但是万一被激活,它是这样防御盗贼的: 

首先,盗贼进了门,开始判断家里是否有报警器或者其它威胁什么的。 

等待了几秒钟,发现没什么不对劲,开始准备搜东西。 

正在他准备开始搜的时候,天上传来一道惊悚的声音 

冷静了几秒,他马上识别这是房子的主人在播放恐怖片呢,心里想:小样,给我玩这套。 

但接下来,他惊喜的发现这个惊悚的声音开始飘忽移动,慢慢移动到他背后 

这时候,他已经萌生了退意。 

再接下来,次声波开始发射,他感觉到除了心里不舒服之外,身体也有些不太舒服。 

算了吧,放弃吧。大部分盗贼决定放弃了。 

然而,还有少部分盗贼是盗墓出身,根本不care 

好吧,这个时候开始播放超大音量DJ

邻居们,请你们快怒气冲冲到我房子里吧!赶走盗贼就靠你们了。 

恩,请提醒我现在不是在写恶搞的剧本,而是在认真严肃的写推送。

 

7.写在最后

7.1改进方案

 其实这个程序还有很多地方可以改进,比如:

(1) 自动定时拍摄的照片的分辨率其实可以调整的更高一些,这样可以更准确的进行判断是否有人闯入。 

(2) 报警或者恐怖片的立体声还可以做的更逼真,当然这要考虑到左右两个声道声音的延迟以及相位差。 

(3) 可以调用多个摄像头,从多角度对门进行防御。

 

7.2防盗意识

相比于在家安装监控系统,更重要的是平时要加强安全意识。 

比如在外面吃饭时财别外漏,在公共场合聊天时别说自己家有多少家财。 

不怕贼偷,就怕贼惦记。监控系统永远只是防御的最后一环。 

就像足球比赛一样,监控系统只是守门员而已。足球最好控制在前场队员手里,才能远离失败。如果老是让自己的足球守门员抵御对方的前锋,不停的扑球,迟早是会被进球。

 

(END)



科学计算编点程3M君,酷爱MatlabPython编程,擅长图像识别和多媒体处理。不定时po一些自己在科学、工程计算编程中总结的经验教训、小技巧、实用工具和好玩的东西,欢迎关注~



  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值