前言

前段时间因为各种杂事缠身,一直没时间自己玩玩。今天元旦,打算给自己放个假,所以就寻思着玩玩手边吃了几个月灰的树莓派。花了些时间自己写了点代码,实现了在树莓派端启动服务器,并实时将从连接到树莓派的摄像头读取的数据传输到服务器上,在客户端接收服务器的数据并实时显示图像。功能很简单,代码也很简陋,希望勿喷。
我并没有做完整图像处理的功能,本来打算放yolo上去进行实时目标检测,于是我试着在树莓派上跑了yolo,但是跑一个epoch进行预测花了将近40s,这个速度太感人了,让我完全打消了前面的年头。不过如果在配置稍微好点的服务器上还是可行的,但是对于树莓派也真的别期待有多好的效果了。

依赖库

树莓派(服务器端)

安装系统

关于树莓派的系统如何安装我就不做介绍了,网上很多,也很容易。下面直接给个链接,照着做就是了:
https://www.cnblogs.com/suzhengsheng/p/5044924.html
安装好官方的raspbian系统后,最好先更新一下(不是必须的):

sudo apt-get update
sudo apt-get upgrade

安装opencv

通常安装opencv有两种方式:使用apt-get直接从软件源获取编译好的opencv,或是自己从官网下载源码编译后安装。我个人比较喜欢后者,通常在自己的电脑上都会自己取编译想要用的版本。但是在树莓派上编译着实比较麻烦,各种依赖库的问题,如果不想折腾的话建议还是使用前者的方法。

sudo apt-get install libopencv-dev
sudo apt-get install python-opencv

安装PIL

PIL(python image library)是十分好用的一个可用于python的图像处理库,后面要用到它进行图像的压缩。

sudo apt-get install python-imaging

其他

如果还碰到其他的库没有的情况,请自行使用pip安装。

客户端

我的客户端就是自己的笔记本,环境都是很早就配好的,因为经常用到opencv、numpy等库。考虑到有些人的电脑可能没有安装好,所以还是简要介绍一下。自己配开发环境是最基本的技能了。

numpy

太常用了,不过安装是不要用pip来,可能会报错,我通常是使用如下指令来安装:

sudo apt-get install python-numpy

PIL

指令同树莓派。

sudo apt-get install python-imaging

opencv

可以直接apt-get安装,不过不能指定版本;我个人喜欢用opencv3.0以上的,所以是从源码安装的。相关安装教程请问度娘,花些时间就能搞定。

其他

如果在后面运行程序时碰到了某些库没有,可以考虑用pip安装或是向前面一样使用sudo apt-get install python-(库的名字)

程序实现

使用python在本地读取摄像头并实时显示

在进入正题之前,我们要先实现在本地读取摄像头,测试正常通过后再放到服务器上测试。
创建一个python脚本,名字为:local_camera.py,代码如下:

#coding=utf-8
import cv2# 打开摄像头
capture = cv2.VideoCapture(0)while True:# 从摄像头读取一帧图像;如果读取失败,ret为False,如果成功,ret为true;frame存储了那一帧的数据。ret, frame = capture.read()# print(ret)# 显示图像cv2.imshow("camera", frame)if cv2.waitKey(10) == 27:breakcv2.destroyAllWindows()
capture.release()

程序很简单,不多说了,运行通过后,再往下一步走。

数据源端

创建一个python脚本,名字为:src_camera,py,代码如下:

import cv2
import time
import socket
import Image
import StringIO# 获取摄像头
cap = cv2.VideoCapture(0)
# 调整采集图像大小为640*480
cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480)# 这里的HOST对应树莓派的IP地址(自己输入ifconfig查),端口号自己随便定一个即可,但注意后面的程序中要保持统一
HOST, PORT = '192.168.0.113', 9999
# 连接服务器
sock =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))while True:# 获取一帧图像ret, img = cap.read()# 如果ret为false,表示没有获取到图像,退出循环if ret is False:print("can not get this frame")continue    # 将opencv下的图像转换为PIL支持的格式pi = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))buf = StringIO.StringIO()# 缓存对象pi.save(buf, format='JPEG')# 将PIL下的图像压缩成jpeg格式,存入buf中jpeg = buf.getvalue()# 从buf中读出jpeg格式的图像buf.close()transfer = jpeg.replace('\n', '\-n')# 替换\n为\-n,因为后面传输时,终止的地方会加上\n,可以便于区分print len(transfer), transfer[-1]sock.sendall(transfer + "\n")# 通过socket传到服务器# time.sleep(0.2)sock.close()

这部分代码实现的功能是:在树莓派端读取摄像头,使用socket包连接到服务器,并将从摄像头读取的数据发送到服务器上。
注释都在程序中。程序中我们使用socket包来将数据传到服务器,为了减少数据量,所以我们还需要对原始图像进行压缩。而压缩则是通过PIL将图像压缩成jpeg格式,而PIL支持的图像格式与opencv不同,所以在程序中还对其进行了转换。

服务器端

创建一个python脚本,名字为:server_camera,py,代码如下:

import socket
import timesock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("192.168.0.113", 9999))# 注意bind的这里,IP地址和端口号都要与前面的程序中一样
sock.listen(2)# 监听端口# 等待数据源端连接
src, src_addr = sock.accept()
print "Source Connected by", src_addr# 等待目标端连接
dst, dst_addr = sock.accept()
print "Destination Connected by", dst_addrwhile True:msg = src.recv(1024 *1024)if not msg:breaktry:dst.sendall(msg)except Exception as ex:dst, dst_addr = sock.accept()print "Destination Connected Again by", dst_addrexcept KeyboardInterrupt:print "Interrupted"breaksrc.close()
dst.close()
sock.close()

这个服务器端可以说是很简陋了,整体流程是:监听端口–>等待数据端连接–>等待目标端连接–>从数据端接受数据,转发给目标端。

目标端(客户端)

创建一个python脚本,名字为:dst_camera,py,代码如下:

import cv2
import socket
import time
import Image
import StringIO
import numpy as np# 注意IP地址和端口号与前面的程序中的保持一致
HOST, PORT = "192.168.0.113", 9999
# 连接到服务器
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
f = sock.makefile()cv2.namedWindow("camera")while True:# 从服务器读取数据,一行的结尾是'\n',注意我们前面已经将每一帧数据的'\n'替换成'\-n',而结尾就是'\n'msg = f.readline()if not msg:breakprint len(msg), msg[-2]# 将'\-n'换回来成'\n'jpeg = msg.replace("\-n", "\n")buf = StringIO.StringIO(jpeg[0:-1])# 缓存数据buf.seek(0)pi = Image.open(buf)# 使用PIL读取jpeg图像数据# img = np.zeros((640, 480, 3), np.uint8)img = cv2.cvtColor(np.asarray(pi), cv2.COLOR_RGB2BGR)# 从PIL的图像转成opencv支持的图像     buf.close()cv2.imshow("camera", img)# 实时显示if cv2.waitKey(10) == 27:breaksock.close()
cv2.destroyAllWindows()

目标端,也可以说是客户端,这是真正的我们可以看到实际输出的部分了。从服务器读出数据然后显示即可。

运行结果

接下来看下运行结果了。

  1. 先运行服务器端的程序,输入python server_camera.py
  2. 然后运行数据源端的程序,输入python src_camera.py
  3. 最后在自己的客户端上运行程序,输入python dst_camera.py

结果截图:
数据源端和服务器端:

目标端:

我看了下,实时显示的效果还行。如果你想要控制帧率,可以在src_camera.py中更改time.sleep(0.2)这句代码的参数,来控制延时时间。

可能遇到的错误

对号入座:

  • HIGHGUI ERROR: V4L: index 0 is not correct!:http://blog.csdn.net/youhongaa/article/details/55054970
  • socket.error:[errno 99] cannot assign requested address and namespace in python:https://stackoverflow.com/questions/19246103/socket-errorerrno-99-cannot-assign-requested-address-and-namespace-in-python

参考资料:
树莓派+python opencv实现远程监控:写的很不错,但是它用的是老版本的opencv,不保证一定能运行成功。

使用python和树莓派实现远程监控相关推荐

  1. 毕业设计 树莓派视觉远程监控遥控小车设计与实现 - 嵌入式 物联网

    文章目录 0 前言 1 简介 2 实现效果 3 树莓派视觉环境搭建 3.1 树莓派安装系统 3.2 设置静态网络 3.3 更换镜像源 3.4 安装中文输入法 3.5 电脑控制树莓派 3.6 OpenC ...

  2. 基于python的远程监控_python远程监控

    最近用python写了一个远程监控的程序,主要功能有:1.获取系统信息 2.对屏幕进行截图,屏幕截图发送到邮箱 3.可以用摄像头获取图片,这些图片上传到七牛 4.开机自启动 # #coding by ...

  3. 树莓派(四):使用摄像头实现拍照和远程监控功能

    配置好树莓派的基本环境之后,就可以使用树莓派的摄像头模块了,接下来我会教你一些关于树莓派摄像头的基本操作:摄像头拍照,并实现摄像头的远程监控. 配置摄像头 首先将树莓派与摄像头模块插好: 插法是将蓝色 ...

  4. Python:通过远程监控用户输入来获取淘宝账号和密码的实验(二)

    从今天早上产生了写个获取淘宝账号及密码的想法后,到现在,全天都在看书.调试程序,12小时内写了三篇相关博客,如下: <Python:通过获取淘宝账号和密码的实验,来看登陆方式选择的重要性> ...

  5. 树莓派4B+cpolar+MJPG-Streamer+Xshenll实现远程监控

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 树莓派4B+cpolar+MJPG-Streamer+Xshenll实现远程监控 前言 具体流程 1.系统安装 2.配置环境 3.下载 ...

  6. 基于手机app的树莓派远程监控(非常全)

    基于手机app的树莓派远程监控(非常全) 一.准备器件:树莓派系统板,树莓派自带摄像头 二. 树莓派系统环境:Raspberry Debian 9 手机app运行环境:android studio 三 ...

  7. 从零搭建树莓派远程监控小车,udp视频传输,qt上位机

    目录 前言 一.材料准备 二.连线方式 三.软件编程 软件编程主要有一下几个方面 (1)树莓派视频传输 (2)esp8266代码 (3)上位机编程 四.总结 前言 最近刚准备完期末机器人驱动的课设,本 ...

  8. 树莓派实现远程网络监控

    写在前面 我这里用的是树莓派zero w,外加500万像素摄像头,其他型号类似.本教程共分为两部分: 树莓派摄像头配置,实现内网监控功能 网络穿透,实现远程跨网络监控 所需准备 树莓派+摄像头.系统以 ...

  9. python实现一个简单的远程监控,看看你老婆微信都在聊啥。

    python实现一个简单的远程监控,看看你老婆微信都在聊啥. 1.pywin32模块检测活动窗口 2.PIL模块截图 3.http.server.socketserver开启一个临时web服务. 4. ...

最新文章

  1. 关于 HTML5 的 11 个让人难以接受的事实
  2. C语言指出下列程序的错误,2012年计算机二级C语言精编教程第二章(8)
  3. 北京计算机在职研究生双证学校,北京在职研究生目前有哪些学校开设了双证专业?...
  4. 基础层区块链Harmony发布主网新版本v4.0.0
  5. Continuous Laplacian, Functional Map, Spectral CNN
  6. linux diff 补丁,Linux中diff、补丁的用法及介绍
  7. 计算机中丢失inetcomm,模块inetcomm.dll已加载,但找不到入口点DllRegisterServer
  8. 哈理工OJ 1029 Function Run Fun(记忆思想)
  9. 标准串口定义-9转25的串口线接法图
  10. 人工智能、机器学习、神经网络及深度学习关系
  11. 【杂谈】什么文章可以给有三AI投稿?你能得到什么
  12. EasyUi 手机号码,邮箱,remote验证
  13. UR机器人C语言和Python编程控制
  14. 计算机与信息技术基础第一章总结,第一章信息与计算机《计算机应用基础》.ppt...
  15. Etix公司和NRB公司在比利时合作建设一个数据中心
  16. php读取蓝牙电子秤,使用ionic/cordova读取小米蓝牙体重秤数据
  17. c语言日期计算器程序代码,旧计算器(C语言代码)
  18. Linux性能观测——dstat命令详解
  19. JAVA进入公司试用期多久_一般企业的试用期为多长时间
  20. 求职简历应该怎么填写受HR喜爱?HR喜欢邮箱格式应该怎么写?

热门文章

  1. python 列表 随机采样_Python 随机抽样
  2. pythonfor循环加2_python-for循环
  3. 改善程序的55个具体做法
  4. Caffe:solver及其配置
  5. 老手是这样教新手编程的
  6. 【Hisi音频】Hi3520D音频输出调试
  7. 给自己看的flex布局方法
  8. Linux 编程--三种常用的定时器
  9. 50个Android开发技巧(09 避免用EditText对日期进行验证)
  10. Masonry自动布局详解一:基本用法