树莓派+电脑 opencv实时网络图像监控
概述
本文实现了一种基于树莓派+python3+opencv3方法实现实时网络视频监控(局域网内)。现将实现过程中才过的坑(对我这个新手来说是坑)与大家分享,我将在代码实现章节进行详细说明。
功能实现
树莓派链接USB摄像头,以树莓派作为服务器,笔记本电脑作为客户端。客户端通过网络实时查看树莓派的摄像头连接的视频图像。
硬件型号
树莓派3B+,USB摄像头,笔记本电脑,路由器。
软件环境版本
python3.6.4 , opencv3.4.0。
特别要注意版本号,参考文章使用的是python2与opencv2及opencv3混合在一起写的程序。对于python3环境下,有一些代码无法使用,尤其是 io.StringIO 与 io.BytesIO的使用方法。python3更加准确的区分了字节串与字符串的关系。对内存操作部分,参考文章1中的StringIO在Python3环境下运行错误,至少我试验的时候是报错的。如果说的不对,请各位见谅。
本文参考了以下文章,感谢各位 :)
1.https://blog.csdn.net/shukebeta008/article/details/79335299#commentBox
2.https://blog.csdn.net/qq_39290394/article/details/84696100
3.https://stackoverflow.com/questions/21018654/strings-in-a-dataframe-but-dtype-is-object
代码组成
代码主要分为三个部分,服务器代码server.py,客户端代码dst.py,视频源代码scr.py。
其中,scr.py负责采集USB摄像头信息,通过网络发送给服务器server.py,然后服务器server.py再发送给scr.py,在scr.py中显示图像。
代码实现
scr.py 源代码如下。
网络套接字的常规使用,视频读取方式没什么可说的,都是基本操作。
这里涉及到一个由 opencv 格式 转 PIL 格式的图像转换,由 BGR 转换为 RGB。
pi = Image.fromarray(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
另外,需要注意的是Image与BytesIO的导入方式,与python2有所不同。并且参考文章中是使用 io.StringsIO 作为图像加载内存的方式,实际在python3中会报错。后改为 io.BtyesIO 方式。可见python3更加准确的区分了字符串与字节串的使用方式。
import cv2
import time
import socket
from PIL import Image
from io import BytesIO
import numpy as np# 获取摄像头
cap = cv2.VideoCapture(0)
# 调整采集图像大小为640*480
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)# 这里的HOST对应树莓派的IP地址(自己输入ifconfig查),端口号自己随便定一个即可,但注意后面的程序中要保持统一
HOST, PORT = '192.168.1.118', 9999
# 连接服务器
sock =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))while True:# 获取一帧图像ret, frame = cap.read()# 如果ret为false,表示没有获取到图像,退出循环if ret is False:print("can not get this frame")continue # 将opencv下的图像转换为PIL支持的格式pi = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))buf = BytesIO()# 缓存对象pi.save(buf, format='JPEG')# 将PIL下的图像压缩成jpeg格式,存入buf中jpeg = buf.getvalue()# 从buf中读出jpeg格式的图像buf.close()sock.send(jpeg)# 通过socket传到服务器# time.sleep(0.2)sock.close()
server.py 源代码如下。都是基本的服务器端常规代码,也没啥好说的。
import socket
import numpy as np
import cv2sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("192.168.1.118", 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_addr)while True:msg = src.recv(1024 *1024)if not msg:breaktry:dst.send(msg)except Exception as ex:dst, dst_addr = sock.accept()print ("Destination Connected Again by", dst_addr)except KeyboardInterrupt:print ("Interrupted")breaksrc.close()
dst.close()
sock.close()
dst.py 源代码如下。
在运行过程中经常出现如下错误。
img = cv2.cvtColor(np.asarray(img_array), cv2.COLOR_RGB2BGR)
TypeError: src data type = 17 is not supported
上网查资料,由于 cv2.cvtColor(np.asarray(img_array), cv2.COLOR_RGB2BGR) 语句中的 img_array.dtype 在运行中偶尔会出现 被定义为 object 的类型,而正确的 img_array.dtype 应该为 uint8,所以就加了一层判断语句,当对象类型为 objec 时,将其转为 uint8 类型。这样就可以顺利运行了。
# -*- coding:utf-8 -*-import cv2
import socket
import time
from PIL import Image
from io import BytesIO
import numpy as np# 注意IP地址和端口号与前面的程序中的保持一致
HOST, PORT = "192.168.1.118", 9999
# 连接到服务器
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))while True:msg = sock.recv(1024*1024)if not msg:breakbuf = BytesIO(msg)buf.seek(0)try:pi = Image.open(buf)# 使用PIL读取jpeg图像数据img_array = np.array(pi)if img_array.dtype == object:img_array = img_array.astype(uint8)print(img_array.dtype)img = cv2.cvtColor(np.asarray(img_array), cv2.COLOR_RGB2BGR)cv2.imshow("camera", img)# 实时显示except(OSError, NameError):print('OSError')if cv2.waitKey(10) == ord('q'):breaksock.close()
cv2.destroyAllWindows()
以上代码的运行次序为 1. server.py 2. scr.py 3. dst.py
运行效果
遗留的问题
我首先将三个代码都放在树莓派上运行,没有丢帧的现象。
但是,当我把 server.py 与 scr.py 放在树莓派上, dst.py 放在笔记本电脑上运行时,电脑采集的视频有时候会丢帧。导致输出 OSError。如下图所示。其中输出 “uint8 dsd” 为正常捕获的视频流。 “OSError” 就为丢帧。我还没有完全解决这个问题。希望有兄弟知道原因的能告知一下。谢谢!
树莓派+电脑 opencv实时网络图像监控相关推荐
- 如何低成本化实时网络摄像头监控直播?
大众直播时代,处处有直播,直播已经在方方面面改变着人们的生活和工作.随着网络直播应用生态的越发完善,你会发现,很多传统监控升级为互联网直播的应用越来越多.那么,如何将常规监控摄像头转为互联网直播?比如 ...
- 树莓派 摄像头 VLC实时监控
这两天在捣鼓树莓派摄像头通过电脑实时监控,有一枚官方鱼眼摄像头,本来是打算实现在任何网络中都可以直接访问,看网上很多教程都是VLC,于是就按照教程来,后来发现VLC只能在局域网中,那就先局域网吧. 网 ...
- 基于Socket、OpenCV和MFC实现的网络实时视频监控
文章目录 1 摘要 2 概述 3 客户端的设计与实现 3.1 OpenCV图像处理 3.1.1 cv::VideoCapture类 3.1.2 图像压缩编码 3.2 Socket 网络通信 4 服务器 ...
- [常用工具] OpenCV获取网络摄像头实时视频流
所需要硬件及软件环境: python 3/OpenCV3.4 or C++11/OpenCV3.4 1 RTSP协议 RTSP (Real Time Streaming Protocol),是一种语法 ...
- python实现流媒体传输_基于OpenCV的网络实时视频流传输的实现
很多小伙伴都不会在家里或者办公室安装网络摄像头或监视摄像头.但是有时,大家又希望能够随时随地观看视频直播. 大多数人会选择使用IP摄像机(Internet协议摄像机)而不是CCTV(闭路电视),因为它 ...
- 通过python调用海康威视工业摄像头并进行图像存储,同时使用opencv实时图像显示(数据流问题已解决)
通过python调用海康威视工业摄像头并进行图像存储,同时使用opencv实时图像显示. 1:图像存储方式 先说情况,本人是做视觉检测的需要高倍率摄像头进行实时检测,也就是需要深度学习进行图片数据处理 ...
- OpenCV获取网络摄像头实时视频流
1.RTSP协议 RTSP (Real Time Streaming Protocol),是一种语法和操作类似 HTTP 协议,专门用于音频和视频的应用层协议. 和 HTTP 类似,RTSP 也使用 ...
- 【树莓派4B深度学习 垃圾分类】Chap.3 树莓派安装opencv并测试视频接口实时视频流的垃圾分类【深度学习 招式篇】
[树莓派4B深度学习 垃圾分类]Chap.3 树莓派安装opencv并测试视频接口实时视频流的垃圾分类[深度学习 招式篇] 后记 1.激活虚拟环境+进入代码+更改测试集路径(这里是安装成功后测试的代码 ...
- 第十四课:树莓派网络视频监控(mjpg-streamer)
目录 一.快速扩容SD卡(raspi-config扩容) (一)查看sd卡容量情况 (内存卡7G) (二)修改树莓派配置 (三)重新查看内存情况(Avail :3.7G 扩容成功) 二.配置树莓派CS ...
最新文章
- fp5139应用电路图_四款l6599d经典应用电路图详解
- Paper:《Spatial Transformer Networks》的翻译与解读
- ewebeditor 图片上传中 请等待_AC米兰客场3-1那不勒斯,博内拉透露:伊布伤势情况需要等待...
- callbackend entry point - iwfndcl_mgw_request_manager~read_entity
- C语言实例:3个数从小到大排序
- shell 判断文件是否存在,没有则创建
- ./wls1036_linux32.bin: /lib/ld-linux.so.2: bad ELF interpreter
- 孙宇晨在线发钱,变身“人间王多鱼”之后,大家突然不讨厌他了?
- linux下自己安装软件做成命令
- ListControl响应右键,弹出菜单
- java----JUnit
- IP签名档HTML版本源码 显示精准定位
- android 关于报错SecurityException revoked permission android.permission.CAMERA
- 对控制台EXE程序的自动运行问题——以6S模型6s.exe为例
- matlab ploty,matlab绘制函数 如何利用matlab的ploty
- 2021秋软工实践第一次结对编程作业
- 《人,绩效和职业道德》及博客读后感
- top SRM526.5
- Access.2007数据库开发全书(奋斗的小鸟)_PDF 电子书
- 二十年目睹之怪状-大学