树莓派摄像头实时视频流传输至主机的技术方案
本文介绍如何利用树莓派自带摄像头实现实时视频流传输至主机。通过配置raspivid命令输出比特率,结合netcat进行无加密数据转发,并手动设定树莓派与主机的静态IP,构建低延迟局域网视频传输环境。方案涵盖网络配置、接收脚本编写及发送指令详解,适用于需要连续录像且对传输效率有要求的场景。
树莓派简介与特点
树莓派(Raspberry Pi)是嵌入式开发领域广为人知的硬件平台,由英国“Raspberry Pi基金会”注册开发,项目由埃本·阿普顿(Eben Epton)领导。2012年3月,首款树莓派发布,其外形仅信用卡大小,却具备完整电脑功能,中文译名为“树莓派”。
凭借轻便迷你的特性,树莓派作为终端设备深受大众喜爱。
树莓派的核心特点在于其强大的处理能力与灵活性。
相较于51单片机或STM32等嵌入式微控制器,树莓派不仅能控制IO引脚,还能运行操作系统,执行复杂任务管理与调度,支持上层应用开发。开发者可选择多种编程语言,连接底层硬件与上层应用,实现物联网云控制与管理,或搭建小型网络服务器进行测试开发与服务提供。
与普通PC相比,树莓派提供的IO引脚可直接控制底层硬件,这是PC难以做到的。同时,树莓派体积小、成本低,仍能完成部分PC任务与应用。
摄像头硬件与采集方式
树莓派自带摄像头已用于夜空延时摄影,实时拍摄虽未深入研究,但值得测试。该摄像头为500万像素,价格约26-29欧元(折合人民币200+)。
关于实时采集还是事后记录结果的问题,树莓派摄像机通过raspivid命令操作。该命令的输出数据主要有两种方式:
- 将数据保存为文件,存储于SD卡以便事后读取;
- 将数据以字节流形式直接输出至STDOUT标准输出,实现实时获取。
选择方式需首先评估数据采集能力是否充足。
raspivid命令可调节相机模块输出比特率,默认采用H264编码,比特率通常为17Mbps,即每秒2.12兆字节。若记录或获取数据速度低于此值,长时间录像可能导致树莓派缓存满溢,进而引发系统崩溃。
树莓派网卡通过USB总线传输,理论速度为100Mb/s(即12.5MB/s)。实际实验表明,当前能达到的传送速度仅为3MB/s(TCP)或6MB/s(UDP)。
若使用SD卡存储,该记录速度可达,但需考虑SD卡的写入寿命。例如,对于32GB卡,即使利用全部空间,以2MB/s速度录像,仅能记录4.55小时。
实时数据传输方案
如何通过网络实时传送数据?
raspivid命令的-o选项用于指定输出文件。在Linux系统中,输出到文件不等于写入磁盘(SD卡)。可使用RAMDisk技术,使输出暂存于内存中,稍后读取并删除。但树莓派可用内存仅约280MB,最多只能记录约2分钟视频。
若有文件形式的摄像记录,似乎可使用sftp、scp等协议登录树莓派下载文件。然而,这些协议在传输中使用了加密。
树莓派向电脑传送数据时,若使用加密协议,需先对发送数据加密。在互联网上加密是良好设计,但在树莓派与电脑仅用一根网线连接时则不然。树莓派运算能力有限,使用加密会减慢传送速度,因此应避免使用加密。
采用最原始简单的方法:使用netcat命令,在笔记本电脑端监听数据输入。在树莓派端,让raspivid获取一定周期(如10分钟,或更长)录像,设定为直接输出,利用Linux管道机制直接送入netcat发送。
网络环境配置
配置由树莓派和笔记本构成的网络。
树莓派与笔记本电脑间使用普通网线连接,因两者网卡均能自动适应网线,设定正确模式(通常需交叉网线)。
关键步骤是,笔记本电脑与树莓派连接后构成的网络中,需手动为两设备设定IP地址。笔记本电脑设定较简单,将相连网卡IP地址设为xxx.xxx.x.xxx,子网掩码为255.255.255.0,网关不填。
配置树莓派需先断电,取出SD卡,用读卡器插回电脑。在SD卡的boot分区中,有cmdline.txt文件,包含树莓派开机参数。
打开该文件,发现仅有一行,用空格分隔多个设定参数。在该行结尾不添加空行,直接加空格后写上:ip=xxx.xxx.x.xxx
若该行已有ip=参数,应直接修改它。
如此设置后,树莓派开机将自动选择该IP地址作为自身地址。
主机端接收脚本
实现在笔记本上监听输入。
netcat命令在每收到一个文件EOF(End Of File,表明文件结尾)时退出。为使接收连续进行,需用脚本连续运行该命令。这样,每个新接收视频将在笔记本端建立文件存储。
# -*- coding: utf-8 -*-
import os
import signal
import subprocess
import sys
import uuid
# 获取程序运行的本地目录,和用来存储接收结果的recv文件夹目录
BASEPATH = os.path.realpath(os.path.dirname(sys.argv[0]))
RECV = os.path.join(BASEPATH, 'recv')
# 如果接收目录不存在,就自动新建
print " *** Received files are put into: %s" % RECV
if not os.path.isdir(RECV):
os.system('mkdir -p %s' % RECV)
# 下面的部分用来记录正在等待接收的文件。这个文件会以一个UUID.tmp的格式命名。
# 在接收成功后,就会被重命名为UUID。(UUID是一个特定格式的唯一字符串,不会重复)。
# 如果在接收过程中按下Ctrl+C,就会发送一个终止命令给程序,这样程序会退出,
# 并删除没有接收完整的那个文件。
working = False
fullname = False
def sigint_handler(signum, frame):
global fullname, working
print "\n"
print " *** SIGINT detected. End the program."
if working and fullname != False:
print " *** Unfinished recording deleted."
os.system('rm -f %s.tmp' % fullname)
exit()
signal.signal(signal.SIGINT, sigint_handler)
# 使用一个死循环来不断运行netcat(nc)命令。
n = 1
while True:
recname = str(uuid.uuid1())
print " [%8d] Listening for file [%s]. Use Ctrl+C to stop this script." % (n, recname)
fullname = os.path.join(RECV, recname)
working = True # 标记接收开始
# 使用 nc -lp 10401 命令接收数据,表明端口为10401。
subprocess.call('nc -lp 10401 > %s.tmp' % fullname, shell=True)
os.system('mv %s.tmp %s' % (fullname, fullname))
working = False # 标记接收完毕
n += 1
上文所述脚本在笔记本运行后,将在本地开启10401端口,等待树莓派上传文件。传送数据直接写入由UUID(全局唯一ID)标识的文件中,供后续处理。
树莓派发送指令详解
在树莓派上摄像并发送摄像结果。
在树莓派上拍摄命令如下:
$ raspivid -o - -b 16000000 -t 100000 | nc xxx.xxx.x.xxx 10401
该指令意义如下:
- -o -,使用-o设定输出,-表示直接输出至标准输出,不写入文件。
- -b 16000000,设定输出比特率为16000000 bit/s,约2兆字节每秒。
- -t 100000,设定录像时间为100000毫秒,即100秒。
- | nc xxx.xxx.x.xxx 10401,使用管道|将结果导入nc,nc为发送模式,目标为xxx.xxx.x.xxx计算机上的10401端口。
以上为Python实现树莓派摄像头持续录像并传送到主机的步骤详细内容,更多关于python 树莓派的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









