1.背景
我手里的是基础开发套件(EDK开发板)可以接两路FPC软排线的摄像头,但貌似购买适配的摄像头特别贵,一款3280¥,一款需要1500¥;买两个摄像头的价钱都赶上买一块开发板的价钱了,所有咱们小户人家怎么办呢?那就只能通过网络视频数据回灌来学习验证我们的神经网络算法了。下面为官方推荐的摄像头:
2.视频数据回灌链路概述
上面这个图片来源于Horizon开发者社区的视频教程:第6节 视频通路概要
我们可以看到sensor也就是我们的摄像头模组,摄像头通过MIPI协议通道进入到CIM或者CIM DMA;这是视频通路的VIN部分,我们没有摄像头那么VIN部分这里就不去管它。总线AXI我们可以理解为DDR缓存,大黑箭头表示CV处理模块和DDR通信。那么我们使用网路数据回灌的时候通过PC端经过网线把视频数据灌入到DDR缓存中,上图中VPS部分的CV处理器(ISP,PYM,GDC,STITCH,LKOF)读取灌入DDR中的视频数据进行处理,在模型部署的前处理阶段去读取CV处理器处理后的视频图像输出作为模型的输入。我这里就基于Horizon的AI工具链OE包中的例子来进行演示,例子用到了VPS部分的PYM0金字塔处理器。
3.代码实现介绍
我这里把OE包中的例子copy出来,把工程文件改为network_data_view_sample把不需要的部分删掉,精简大小,工程目录介绍如下:
.
├── CMakeLists.txt
├── README.md
├── build_and_deploy.sh
├── configs
│ ├── codec #编码配置,主要用于web显示
│ ├── model #存放模型和后处理配置文件
│ └── vio #主要是通路配置文件,包括配置PYM的输入输出
├── deploy #这个文件夹是编译生成的文件夹,运行时把整个文件夹copy到板子
│ ├── J5_Sample
│ ├── configs
│ ├── lib
│ ├── run_sample.sh
│ ├── start_nginx.sh
│ └── webservice
├── deps #这个是包含库文件
│ └── aarch64
├── run_sample.sh #这个是运行的脚本
├── src #这下面是源代码
│ ├── common
│ ├── main.cc
│ ├── message
│ ├── modules
│ ├── utils
│ └── uws_server
└── tools #这里面是网路回灌工具和web显示工具
├── network_send
└── webservice
该例子用的是生产者和消费者的方式把视频回灌的效果在浏览器上web端显示查看效果。代码中其他部分都没有修改,主要修改的地方为把原来例子中图片回灌改成了视频回灌,在tools下面的pc_send.py脚本中加入如下函数即可:
def send_void(ip, input_file_path, is_loop):
end_point = "tcp://" + ip + ":6680"
bpu_board = BPUBoard(end_point)
# 打开视频文件
video = cv2.VideoCapture(input_file_path)
# 定义计数器
frame_count = 0
loop = 1
if is_loop == "true":
loop_flag = 0
else:
loop_flag = 1
circle = 0
while loop:
# 读取视频的下一帧
ret, frame = video.read()
height1, width1 = frame.shape[:2]
print(f"Get_Frame {frame_count}: Height = {height1}, Width = {width1}")
#cv2.imwrite(f"car_{frame_count}.jpg", frame)
# 检查是否成功读取帧
if not ret:
break
# 将帧调整为1920x1080大小
resized_frame = cv2.resize(frame, (1920, 1080), interpolation=cv2.INTER_LANCZOS4)
# cv2.imwrite(f"car_1080P_{frame_count}.jpg", resized_frame)
# 获取帧的高度和宽度
height, width = resized_frame.shape[:2]
# 打印帧的高度和宽度
print(f"Send_Frame {frame_count}: Height = {height}, Width = {width}")
# 增加计数器
frame_count += 1
frame_count_str = str(frame_count)
# 将BGR颜色空间转换为NV12颜色空间
# 先将帧从BGR转换为RGB,然后再从RGB转换为NV12
#rgb_frame = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2RGB)
#y_frame, u_frame, v_frame = cv2.split(rgb_frame)
#nv12_frame = cv2.merge([y_frame, u_frame, v_frame])
nv12_frame = rgb2nv12_calc(resized_frame)
bpu_board.send_msg(nv12_frame,height, width, height, width, frame_count_str)
print("Send %d Frame!!!" % (frame_count))
#time.sleep(0.1)
loop = loop - loop_flag
print("Send over!!!")
4.验证效果展示
由于视频数据回灌的脚本依赖于docker环境,有的时候比较麻烦,我这里给它打个包,打包后在无docker的linux环境中都可以进行视频数据回灌,打包后的执行文集和依赖放在network_send_video文件夹介绍下:
.
├── READ.ME
├── __pycache__
│ └── test_pb2.cpython-38.pyc
├── build
│ └── pc_send
├── dist
│ └── pc_send
├── pc_send.spec
├── run_pc_send #运行脚本,./run_pc_send +板子IP 运行
└── video #放回灌视频的文件夹,视频文件名称格式为video.mp4
└── video.mp4
板端运行:
#把编译出来的deploy文件夹copy到userdata下,进入到该目录,记得给权限
root@j5dvb:/userdata/deploy_net_runtime# ls
J5_Sample lib start_nginx.sh
configs run_sample.sh webservice
root@j5dvb:/userdata/deploy_net_runtime# ./run_sample.sh 1 #这个命令启动运行
PC端运行:
cd /network_send_video #进入到该目录下
./run_pc_send 192.168.1.10 #运行脚本后面加板子IP
效果如下:
打开浏览器 输入http://192.168.1.10 (这里的IP是板子的IP) 前提是板子和PC在同一网段下
5.获取代码
我把编译出来的可执行软件包放在network_data_recharge文件夹下:
.
├── deploy_net_runtime #编译出来在板端运行的软件包
├── network_send_images #图片视频数据回灌工具包
└── network_send_video #视频数据回灌工具包
3 directories, 0 files
上链接:
编译出来的运行软件包以及工具:
https://download.csdn.net/download/weixin_41896321/89267268
https://download.csdn.net/download/weixin_41896321/89267308
/************************************************************
公元2024年5月
/***********************************************************