jetson nx跑yolov3_GitHub - gaodechen/webcam_yolov3_jetson_tx_hikvision: 多个网络摄像头进行拉流以及对象检测。平台使用Jetson ...

Introduction

Python多个网络摄像头拉流

拉流后使用PyTorch实现的YOLO v3做对象检测

最后需要运行在ARM架构的Jetson TX 2平台上,并且以海康摄像头作为视频源。

HIKVISION multiple IP cameras: Yonv1943/Python

配合其他模型

同样的拉流代码同样可以复用在EfficientDet、YoloV5等模型上,不过模型需要二次封装。

YoloV5: YoloV5工作对性能的对比缺乏参照,但其实现依旧有启发性。推断前使用DataLoader,故而修改时去掉了拉流取图的进程。

测试环境

Intel CPU + NVIDA GPU

视频源:RTSP/RTMP网络摄像头

使用

多网络摄像头拉流 + YOLO v3对象检测

下载YOLO v3预训练模型yolov3.weights

将本项目文件覆盖放入pytorch-yolo-v3文件夹当中

修改settings.py,加入你的摄像头地址

运行:

python run.py # Default detect and display all cameras in one window

python run.py --single_window=False # OR Detect and display in separate windows

single_window默认为True,表示所有画面合并显示到同一个窗口当中

num_cameras默认值为settings.py中的IP列表大小,表示处理所有给定摄像头

仅多摄像头拉流

去掉predict()进程的调用,并且pop_image()显示raw_q中的原图像。也就是说拉流取得的图像直接取出进行显示。

processes = [

mp.Process(target=push_image, args=(raw_q, cam_addr)),

# display images in raw_q instead

mp.Process(target=pop_image, args=(raw_q, window_name)),

]

帧率

摄像头本身具有帧率,而模型检测也存在帧率。摄像头帧率可以通过cv2属性获取:

fps = cap.get(cv2.CAP_PROP_FPS)

另外此处我们采用的帧率计算方法是,直接使用predict()进程的推断时间来计算帧率,此方法包含的耗时,包含队列取图时阻塞的时间,以及模型推断时间。

文件结构

本程序文件当中主要如下:

settings.py:配置IP camera地址列表,画面大小

yolov3.py:pytorch-yolo-v3模型推断的二次封装,不需要变动

preprocess.py:与pytorch-yolo-v3相比,只是添加了prep_frame函数,将图片输入从文件改为cv2图像

其他细节

OpenCV后端选择

系统默认给出了GStreamer进行后端解码。这里我们改为FFMPEG作为后端:

cap = cv2.VideoCapture(cam_addr, cv2.CAP_FFMPEG)

多个网络摄像头如何拉流?

Yonv1943/Python项目当中已经给出了很棒的解答。我们在此基础上进行修改。

考虑对于一个摄像头,由于H.264编码的问题使用多进程实现,多进程间的同步采用共享队列(multiprocessing.Queue)。

push_image(): 拉流,将图片送入raw_queue(未经推断的图片队列)

predict(): 将raw_queue中的图片取出,经模型推断放进pred_queue()(处理后的图片队列)

pop_image(): 将pred_queue中的图片通过OpenCV显示

总结起来,导致程序崩溃的原因可能有:

推断速度慢,与拉流速度不一致: 即进程同步问题。raw_queue当中累积图片多,延时高,甚至队列溢出程序崩溃

网络原因: 断流导致程序崩溃

机器硬件性能不足: 导致创建某些进程失败

最初代码中,作者通过push_image()进程不断抛弃队首图片解决同步问题。

但是实验过程中,程序还会因为断流的原因产生崩溃,故而这里加入重连,得到最终能够长时间稳定运行的push_image()如下:

def push_image(raw_q, cam_addr):

cap = cv2.VideoCapture(cam_addr, cv2.CAP_FFMPEG)

while True:

is_opened, frame = cap.read()

if is_opened:

raw_q.put(frame)

else:

# reconnect

cap = cv2.VideoCapture(cam_addr, cv2.CAP_FFMPEG)

if raw_q.qsize() > 1:

# drop old images

raw_q.get()

else:

# wait for streaming

time.sleep(0.01)

经过上述修改可以长时间稳定运行,缺点是断流时重连耗时,画面卡顿1s左右。

此外,在NVIDIA Jetson TX2上运行时,出现了程序启动后,无法加载几个摄像头画面的问题,例如分开窗口显示时,有一两个摄像头的窗口一直没有创建。但是程序在本地却正常运行。

最后观察发现,由于Jetson TX2内存不足,导致进程无法创建。解决方法:创建内存交换区。目测4个海康摄像头进行YOLO对象检测时,6G交换区足够。

Jetson TX 2 ARM

运行环境

硬件平台: Jetson TX2 ARM

操作系统:Ubuntu 18.04

视频源: 多个海康网络摄像头(RTSP TCP)

Jetson TX2 ARM PyTorch环境的搭建

git clone --recursive以及compile太耗时了!而且板子上网速也慢,读写也慢。好在最终找到了可以用的whl安装包,直接pip install一次成功。

PyTorch .whl downloading & installation on Jetson TX2: Nvidia Forum

你可能感兴趣的:(jetson,nx跑yolov3)