作为越城岭计划的一部分目标,即监测火流星等天体的现象,需要使用自动的摄像设备对夜空进行摄像。
当前的想法是使用树莓派和自带的摄像头(500万像素,可以24帧每秒的速度拍摄)完成这个任务。 然后,可以使用网线将笔记本和树莓派连接起来,然后从笔记本上处理获取的视频。
这样想的出发点是:
- 树莓派自身的运算能力很弱,但是省电是其优点。用一个比较好的充电宝(10000mAh以上),就可以让它工作一整夜。 即使无法让笔记本伴随树莓派在野外工作,但是仍然可能通过网络连接(比如院子里放树莓派,网线扯到屋子里)。 或者可以使用SD卡先记录下摄影的结果,之后处理。
- 树莓派自带的摄像头拍摄夜空是有先例的,起码可以做到延时摄影。对于实时拍摄没有研究,但是仍然有必要测试。
- 树莓派自带的摄像头是500万像素,价格在26-29欧元(人民币200+左右),可以接受。
- 暂时不能考虑在树莓派上进行流星检测和计算,因为其计算能力比较弱。 所以暂时不考虑实时计算,而是在获取其图像之后用性能更好的PC等在白天完成。
- 然而树莓派不是简单的视频采集装置。由于其具有GPIO口,要考虑在树莓派上安装GPS定位和授时,并将这些信息加载在视频中。 如何完成这一点,需要继续研究。
具体的技术实现
实时还是事后采集记录结果?
树莓派上的摄像机,是使用一个raspivid
命令操作的。
抛开这个命令的其他参数,其输出数据有2种方式:
- 将数据保存成文件,储存在SD卡上,以便事后读取;
- 将数据按照字节流的形式,直接输出到
STDOUT
标准输出中,可以实时获取。
选择哪种方式,首先要考虑我们能否具有足够的采集数据的能力。
raspivid
命令可以调节相机模块的输出比特率。输出是以H264编码输出的,比特率一般默认是17Mbps,但是这个数字可以调小。
如果按照17Mbps算,就是一秒钟2.12兆字节。
我们记录数据或者获取数据的速度不能低于这个值,否则长时间录像可能造成树莓派的缓存充满,导致树莓派崩溃。
树莓派的网卡是使用了其USB总线,传送速度是100Mb/s或者12.5MB/s。 实际上后文的实验表明,目前能达到的传送速度只有3MB/s(TCP)或者6MB/s(UDP)。
如果使用SD卡存储,这个记录速度也是可以达到的,但是,SD卡有写入寿命,这是要考虑的。 例如,对于32GB的卡,即使我们能利用全部存储空间,以2MB/s的速度录像,也只能记录4.55小时。
出于对SD卡的吝啬(也是对SD卡的不信任!), 以及对灵活性的偏好(标准输出可以像搭积木一样和各种后处理的程序或者通信程序组合), 还有可以预见到的自动化的可能, 我选择第二种方案。
如何通过网络实时传送数据?
raspivid
命令的-o
选项,就是用来指定输出文件的。
在Linux系统中,输出到文件并不等于写入到磁盘(这里是SD卡)。
我们仍然可能使用RAMDisk这种技术,让输出只是暂时存储在内存中,并稍后读取,然后删除之。
但是,树莓派的可用内存可能只有280MB,这最多只能记录差不多2分钟的视频。
如果我们有文件形式的摄像记录,那么就似乎可以使用文件传输的协议,例如sftp, scp等等登录到树莓派下载文件了。 然而这是不对的。这些协议在传输中使用了加密。
树莓派在向我们的电脑进行数据传送的时候,如果用这些协议,就必须先对发送的数据进行加密。 在互联网上,加密是很好的设计。但是在树莓派和电脑之间只用一根网线连接的时候,就不是了。 树莓派的运算能力是很有限的,使用加密只会让传送速度变慢,所以,不要使用加密!
我们使用最原始而简单的方法:使用netcat
命令,在笔记本电脑这一端监听数据输入。
在树莓派这一端,我们让raspivid
获取一定周期(比如10分钟,也许可以更长)的录像,
将结果设定为直接输出,然后利用Linux的管道机制,直接送进netcat发送。
配置由树莓派和笔记本构成的网络
树莓派和笔记本电脑之间的连接,使用普通网线即可, 因为笔记本和树莓派上的网卡都能自动适应网线,设定正确的模式(正常来说要使用交叉网线)。
重要的一步是,笔记本电脑和树莓派连接后构成的网络中,需要手动为两个设备设定IP地址。 对于笔记本电脑的设定,就比较简单了。 我们将笔记本电脑和树莓派相连的网卡上,将电脑的IP地址设定为192.168.0.1,子网掩码为255.255.255.0,网关不要填。
配置树莓派的方法是,先将树莓派断电,然后取出所用的SD卡,用读卡器插回电脑。
在SD卡的boot分区中,有个cmdline.txt
,这是树莓派开机时所用到的一些参数。
打开这个文件,会发现里面只有一行。这一行中用空格分开了很多设定参数。 我们在这一行的结尾,不添加空行,直接加上空格,然后写上:
ip=192.168.0.100
当然如果这一行里面已经有了ip=
的参数,应该直接修改它。
这样的结果就是,树莓派开机之后,会自己选择这个IP地址作为自己的地址。 这对于下文所说的数据传输是没什么用处的,但是为了控制树莓派,我们需要用SSH登录之。
实现在笔记本上监听输入
netcat
命令,在每收到一个文件的EOF(End Of File,表明文件已经到结尾),就会退出。
我们为了让接收能够连续进行,需要用脚本连续运行这个命令。
这样就会为每个新接收到的视频,在笔记本电脑这一端建立一个文件用来存储。
上文所述的脚本,在笔记本上运行之后,就会在本地开启10401端口,等待树莓派上传送的文件。 传送的会直接写入一个由UUID(全局唯一ID)标识的文件中,可以供以后处理。
在树莓派上摄像并发送摄像结果
在树莓派上命令拍摄的方法是:
$ raspivid -o - -b 16000000 -t 100000 | nc 192.168.0.1 10401
这条指令的意义如下:
-o -
,使用-o
设定输出,-
表示直接输出到标准输出中,不写入文件。-b 16000000
,设定输出比特率为16000000 bit/s。这大约是2兆字节每秒。-t 100000
,设定录像时间为100000毫秒,亦即100秒。| nc 192.168.0.1 10401
,使用管道|
将结果导入到nc中,nc是发送模式,目标是192.168.0.1计算机上的10401端口。
我们前面已经配置了笔记本电脑的IP地址为192.168.0.1,所以,如果防火墙没有拦着的话,我们应该能这样收到树莓派的数据。