14

徐珂靖 · 2020年09月07日

云芯一号测评2:实时捕获并存储网络IP摄像头图像

测试背景简介

大家好,我是徐珂靖,是个骨灰级工科男。最近,我机缘巧合地申请得到了一块云芯一号ARM微服务器开发板。填报申请表时,我的试用计划是设计一个用于家庭IoT设备的局域网计算系统,将会用到多种技术,包括视频编码、网络视频流采集、AI物体检测、UDP协议通信、MySQL数据库读写、网页动态数据显示等。

我将会主要用C、C++、PHP等语言来编程,以实现以上功能,并尽量使用现成的开源项目的API接口以减小工作量。另外,为了表达对极术社区的感谢,我会把所有代码都开源。

当然,在做复杂的服务器应用前,我们最好是先把各个子模块的接口给调通了。第一步是实现个最简单的视频监控存储服务器的功能。在这个应用里,我们将把捕获网络RTSP视频流与图像保存的代码调通。

笔者业余时间也是个极客,自制了不少有趣的设备,比如通过Arduino自动控制的鱼缸,那个鱼缸还带个IP摄像头可以远程监控。那么,今天就来给这个IP摄像头做个网络监控存储服务器吧。

实现思路

我们将用云芯一号采集来自IP摄像头的RTSP视频流,然后一边显示,一边按编号保存成一系列jpg图片文件。

我计划把这个功能将通过C++语言编程实现。其中视频流捕获、图像显示、图像保存的函数,不需要自己再重复实现一次了。这里可以偷个懒,我们将使用OpenCV的API接口。

源代码编写

已知IP摄像头的视频流地址是:rtsp://192.168.3.33:8554/live

用户名admin,密码123456

在OpenCV中,可以通过VideoCapture类来打开RTSP视频流,代码写法如下

VideoCapture cap("rtsp://admin:12345@192.168.3.33:8554/live");

从cap捕获视频流中的一帧图像放入Mat类型的frame变量中的写法如下

cap>>frame

然后,为了把照片按顺序保存,我们要给个顺序的编号设置一下文件名,并且希望文件存到一个合适的路径里。

这里我推荐一个方法,先定义一个char类型的filename数组,然后用sprintf函数把文件编号格式化输出到filename数组中。

举个例子,比如j变量每循环加1代表文件编号,格式化输出文件名,最后用imwrite函数保存图片,代码可以这样写:

j++;

sprintf(filename, "/home/dat/test/img/%06d.jpg", j);

imwrite(filename, frame);

最后,通过imshow函数实现图像显示,循环时候要加上waitKey(1),不然黑屏,这个BUG从很久以前的版本就存在,大家也习以为常了。

代码开源

代码中的i%30==0是个求余数并与0比较的判断,目的是每隔30帧进入括号内的语句然后保存图片。你可以按需求设置。举例,如果想要节省存储空间,可以设置i%1000,这样就每隔1000帧保存一张了。

源代码如下:

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main(int argc, char**argv)
{

`Mat frame;`
`int i=0,j=0;`
`VideoCapture cap("rtsp://admin:12345@192.168.3.33:8554/live");`
`char filename[256];`
`while (1)`
`{`
    `i++;`
    `cap >> frame;`
    `if(i%30==0)`
    `{`
        `j++;`
        `sprintf(filename, "/home/dat/test/img/%06d.jpg", j);`
        `imwrite(filename, frame);`
    `}`
    `imshow("test",frame);`
    `waitKey(1);`
`}`
`return 0;`

}

编译与运行

把上一小节代码保存为mycvtest.cpp,编译然候运行的命令如下

g++ -ggdb mycvtest.cpp -o aaaaa pkg-config --cflags --libs opencv

./aaaaa

以下是运行时候的屏幕截图。
Screenshot_2020-09-06_18-08-59.png

多运行一会儿,可以发现/home/dat/test/img目录里保存的照片更多了。
2.png

下一步工作

我们已成功把RTSP视频流的图像帧存入Mat frame变量,下一步可以把该变量接入到OpenCV的DNN模块以实现目标检测。

在实现目标检测功能时,我们也可以评估一下Open AI Lab的Tengine推理框架,相信能获得更好的运行效能。

检测结果的存储将会使用MySQL客户端的C语言API接口,这样就不用单独开发数据存储及用户安全管理的服务了。

最后,多个进程一起调试时,程序是否还能保持实时和高效也需要测试。如果一台云芯一号无法胜任,我们还要考虑往局域网里再添加一台GPU服务器以同时跑多个神经网络。

更多云芯一号的技术教程及评测报告请关注Arm微服务器专栏
推荐阅读
关注数
4271
内容数
71
低成本Arm微服务器开发平台“云芯1号”教程及应用,欢迎关注
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息