紧接上篇文章(《Galileo开发板+微信公众平台实现简单的物联网家庭监控》( http://blog.jcix.top/2015-11-27/galileo_wechat/ ) ),
以下功能做了改进:
* 实现了Galileo开发板上用USB摄像头+python版opencv监控并通过微信公众平台进行异常报警的功能。
* 通过connman实现了wifi网络的自动连接和随时修改功能。
* 通过post到服务器,实现了微信控制led灯亮、灭或者光控的功能。
视频监控功能的实现
(完整代码在github: https://github.com/zhangjaycee/galileo_pys/blob/master/cam_wechat.py )
1.图像采集
galileo支持python的opencv库,这给简单的图像处理提供了极大的便利。
图像采集:
1 2 3 4 5 6 |
cap = cv2.VideoCapture(0)#打开摄像头 cap.set(3,320) cap.set(4,240) while True: ret, frame = cap.read() |
2.图像处理
我们要做键控,所以可以记录第一帧,然后通过帧间差别进行报警。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
cap = cv2.VideoCapture(0) <!--more--> cap.set(3,320) cap.set(4,240) avg = None lastUploaded = datetime.datetime.now() motionCounter = 0 normal_count = 0 start_flag = 0 time.sleep(10) while True: timestamp = datetime.datetime.now() text = "ok" ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) if avg is None: print "starting backfground model..." avg = gray.copy().astype("float") continue cv2.accumulateWeighted(gray, avg, 0.5) frameDelta = cv2.absdiff(gray, cv2.convertScaleAbs(avg)) # 对变化图像进行阀值化, 膨胀阀值图像来填补 # 孔洞, 在阀值图像上找到轮廓线 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 = "Attention!" #print "[", text, "]" # 在当前帧上标记文本和时间戳 ts = timestamp.strftime("%A %d %B %Y %I:%M:%S%p") #print ts 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) normal_count += 1 |
3.报警机制和图像上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
if text == "Attention!": # 判断上传时间间隔是否已经达到 if (timestamp - lastUploaded).seconds >= conf["min_upload_seconds"]: # 运动检测计数器递增 motionCounter += 1 # 判断包含连续运动的帧数是否已经 # 足够多 if motionCounter >= conf["min_motion_frames"]: # 判断Dropbox是否被使用 if conf["use_wechat"] and start_flag == 1: cv2.imwrite('/home/root/galileo_dangerous.jpg',frame) os.system("scp /home/root/galileo_dangerous.jpg root@xdjc.date:/root/wechat_galileo/") request = urllib2.Request( url = r'http://galileo.xdjc.date/?signature=1ce507b0abfa4d231b538988c01127c9e03a02ad×tamp=1408377801&nonce=959202980', headers = {'Content-Type' : 'text/xml'}, data = data) print opener.open(request).read() # 更新最近一次上传的时间戳并且重置运动 # 计数器 print "[ Dangerous! ]" lastUploaded = timestamp motionCounter = 0 #否则, 该房间没有“被占领” else: motionCounter = 0 # 判断安保视频是否需要显示在屏幕上 if conf["show_video"]: # 显示安视频 cv2.imshow("Security Feed", frame) key = cv2.waitKey(1) & 0xFF # 如果q被按下,跳出循环 if key == ord("q"): break |
参考:
《用树莓派 + Python + OpenCV 实现家庭监控和移动目标探测(下》( http://python.jobbole.com/81645/ )
connman wifi功能的详细配置
这个过程我写在了下边这篇博客里:
《Intel Galileo开发版PCI-e无线网卡wifi配置》( http://blog.jcix.top/2015-12-10/galileo_connman/ )
实现led灯的亮灭或者光控功能
这个很简单,只要一个post,在服务器端进行相应控制即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#! /usr/bin/env python import sys import urllib2 import time import pyupm_grove as grove led = grove.GroveLed(3) light = grove.GroveLight(2) print "[start....]" time.sleep(20) while True: light_value = light.raw_value() data = '''<xml> <light><![CDATA[%s]]></light> </xml>''' % light_value cookies = urllib2.HTTPCookieProcessor() opener = urllib2.build_opener(cookies) request = urllib2.Request( url = r'http://galileo.xdjc.date/?signature=1ce507b0abfa4d231b538988c01127c9e03a02ad×tamp=1408377801&nonce=959202980', headers = {'Content-Type' : 'text/xml'}, data = data) state = int(opener.open(request).read()) if state == 2: if light_value <= 300: led.on() else: led.off() elif state == 0: led.off() elif state == 1: led.on() time.sleep(1) |
最终功能
只要Intel Galileo开发板自动连接了家中的WiFi,就开始和我们所搭建的云服务器进行通信,进而通过微信公众号和主人进行双向通信,实现智能家庭监控的一系列功能:
1. 在微信中回复“温度”,查询当前室温。
2. 回复“开灯”,自动打开Galileo开发板所控制的灯(本次设计采用LED代替演示);回复关闭,则自动关闭;回复“光控”,则开发板根据光线传感器采集的室内亮度信息自动开或者关灯。
3. 回复“状态”,返回一张实时的家中照片。
4. 回复“打开监控”,开发板通过所连接的USB摄像头开始进行视频监控,若检测到有异常情况发生,自动通过微信向主人报警,并返回一张标记有异常目标和具体时间的监控照片;回复“关闭监控”,会暂停监控和报警。