2019阿里云双12.12最低价产品入口(新老用户均可),
地址:https://www.aliyun.com/minisite/goods
推荐:py + opencv 打造树莓派监控,场景有变化自动拍照上传到百度云
[大家用树莓派来做监控,文章里面一般都是使用 fswebcam 或 motion。motion 非常强大,可以监测画面变化后保存成 mpeg 或 jpeg,还可以运行成 http 服务器模式。但是树莓派
原文:http://blog.csdn.net/huhumama0/article/details/9164873
近来风闻住宿地不太安全,正好手边有个树莓派,花了些时间用树莓派实现了远程监控,下面和大家分享一下,希望有所帮助。
因为非计算机视觉专业人士,所以使用了python版的opencv,方便快捷。如何在pc上安装python opencv见http://luugiathuy.com/2011/02/setup-opencv-for-python/,曾经见着有中文的桥段找不着在哪里了,对不住了各位不喜英文的童鞋。最后再装上python imaging library。
安装完成后,在opencv/sample/python目录下有一个camera.py文件,先看此源代码:
[python] view plain copy
- <span style="font-size:18px;">import cv2.cv as cv
- import time
- cv.NamedWindow("camera", 1)
- capture = cv.CaptureFromCAM(0)
- while True:
- img = cv.QueryFrame(capture)
- cv.ShowImage("camera", img)
- if cv.WaitKey(10) == 27:
- break
- cv.DestroyAllWindows()
- </span>
一、
数据源端也就是放摄像头的地方。其实,完全可以把电脑开着放在那里然后开着QQ,远端视频聊天即可实现监控。不过这样做略显低端,说出去都有失码农身份。正好手边有一树莓派,正是派上用场的地方。恩,嵌入式开发,听着高端多了。闲话少说,先讲树莓派的配置。首先,用的是Raspbian系统,最好能够先执行sudo apt-get update和sudo apt-get upgrade,保证系统是最新的。系统自带python,不需要再安装;安装python opencv:sudo apt-get install libopencv-dev python-opencv;安装python imaging library:sudo apt-get install python-imaging。大功告成。
传输网络数据就用最基本的socket,那么,树莓派上的代码就如下所示:
[python] view plain copy
- <span style="font-size:18px;">import cv
- import time, socket, Image, StringIO
- capture = cv.CaptureFromCAM(0)
- cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH, 640)
- cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT, 480)
- HOST, PORT = "192.168.0.102", 9999
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.connect((HOST, PORT))
- while True:
- img = cv.QueryFrame(capture)
- pi = Image.fromstring("RGB", cv.GetSize(img), img.tostring())
- buf = StringIO.StringIO()
- pi.save(buf, format = "JPEG")
- jpeg = buf.getvalue()
- buf.close()
- transfer = jpeg.replace("\n", "\-n")
- print len(transfer), transfer[-1]
- sock.sendall(transfer + "\n")
- time.sleep(0.5)
- sock.close()</span>
pi = Image.fromstring(...)
此处用到了python imaging library(PIL),用获取到的帧建立了一个Image实例。这样做的目的在于减少传输的数据量。一幅640x480的RGB图像,原始数据长度为640x480x3=921600Byte,对于2M带宽的小水管来说太多了。这里用PIL来压缩成jpeg格式,能大大减少数据量。opencv本身也提供了保存为jpeg的函数,但可能是由于压缩程度不同。opencv得到的jpeg图像大小为60kb,而PIL得到的jpeg图像仅为19kb。
buf = StringIO.StringIO()
pi.save(buf, ...)
推荐:用树莓派 + Python + OpenCV 实现家庭监控和移动目标探测(下)
[哇,上周那篇关于做一个基本运动检测系统的文章真是赞。写这篇文章很有乐趣,而且从像您一样的读者那里获得反馈,使我的努力变得很值得。对于那些刚看到这篇文章的朋友,
Image提供的save方法,需要将jpeg格式的图像存入一个文件中。但这里显然不需要也最好不要将图像写进硬盘,因此需要一个内存中的“文件”,这就是StringIO。
transfer = jpeg.replace(...)
socket只是一个持续的流,读取时需要能断句,因此将数据中的“\n”替换掉,然后在一帧数据之后手工加上一个“\n”。
time.sleep(0.5)
用来控制fps,0.5相当于是2 fps。
树莓派支持很多种的摄像头,详见http://elinux.org/RPi_VerifiedPeripherals,这里用的是微软的LifeCam VX 800,即插即用。运行上述程序,恩?窗口是黑的?select timeout?楼主坑爹啊!!!别急,这是因为摄像头自带的麦克风不兼容。在/etc/modprobe.d/下新建一个文件camera-blacklist.conf,写上blacklist snd_usb_audio,拔出摄像头,然后rmmod snd_usb_audio,再插上摄像头,即可。若还未解决,属顽固问题,请参考http://www.raspberrypi.org/phpBB3/viewtopic.php?t=35689&p=314596。
二、
服务器端用来中转数据,主旨是提供一个外网ip。上代码:
[python] view plain copy
- <span style="font-size:18px;">import socket, time
- sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- sock.bind(("192.168.0.102", 9999))
- sock.listen(2)
- src, src_addr = sock.accept()
- print "Source Connected by", src_addr
- dst, dst_addr = sock.accept()
- print "Destination Connected by", dst_addr
- while True:
- msg = src.recv(1024 * 1024)
- #print len(msg)
- if not msg:
- break
- try:
- dst.sendall(msg)
- except Exception as ex:
- dst, dst_addr = sock.accept()
- print "Destination Connected Again By", dst_addr
- except KeyboardInterrupt:
- print "Interrupted"
- break
- src.close()
- dst.close()
- sock.close()
- </span>
三、
客户端接受到数据之后还原为图像显示出来即可,相当于是数据源的逆操作。代码如下:
[python] view plain copy
- import cv2.cv as cv
- import socket, time, Image, StringIO
- HOST, PORT = "192.168.0.102", 9999
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.connect((HOST, PORT))
- f = sock.makefile()
- cv.NamedWindow("camera_server")
- while True:
- msg = f.readline()
- if not msg:
- break
- print len(msg), msg[-2]
- jpeg = msg.replace("\-n", "\n")
- buf = StringIO.StringIO(jpeg[0:-1])
- buf.seek(0)
- pi = Image.open(buf)
- img = cv.CreateImageHeader((640, 480), cv.IPL_DEPTH_8U, 3)
- cv.SetData(img, pi.tostring())
- buf.close()
- cv.ShowImage("camera_server", img)
- if cv.WaitKey(10) == 27:
- break
- sock.close()
- cv.DestroyAllWindows()
按照上述方法,就可以实现简单的远程监控。当然,上面的代码远非完善,还有很多可以修改的地方。
无版权,欢迎转载,共勉之。
[硬件:树莓派 B+先安装python-opencv: sudo apt-get install python-opencvPython 2.7 OpenCV3.0# -*- coding: utf-8 -*-import cv2.cv as cv import cv2 import numpy