问一下做过实时视频检测的大佬,我现在用 opencv 获取摄像头的数据,如果超过 3 路以后, python 的内存占用就飙上去了,基本的实现逻辑如下:
vid = cv2.VideoCapture('rtmp_url')
while(True):
# Capture the video frame
# by frame
ret, frame = vid.read()
queue.put(frame)
上面代码跑在 python 的 thread 里,3 路视频就 3 个 thread, 感觉这里线程之前有竞争导致一个摄像头数据取完了,另一个没有取,就堆积下来了,然后内存占用就上去了, 我感觉好像还没到 yolo 的 predict , 就是多线程获取 camera 的数据,就会造成内存占用过高
1
a33291 135 天前
看过海康本身的策略,他们有 2 种方案
1 是实时检测,也就是实时取流检测,这种的话需要独立的服务器并且同时检测路数不高 2 是摄像头自己抓拍图片然后传递给超脑,抓拍图片在设备侧做并且不需要每一帧都分析所以极大减少了计算量,从而可以提供更大的吞吐 基本策略应该类似,比如结合设备本身的移动侦测来做,对移动侦测的图进行分析应该也可以极大减少计算量 此外,可以考虑分析子码流,对子码流降低码率分辨率(太低可能影响分析结果) |
2
capric 135 天前 1
cv2.VideoCapture 的 read 是调用 ffmpeg 库实现的,涉及到几个耗时操作,解析 rtmp 封装,H.264/H.264 视频解码(最占用 CPU),yuv 颜色空间转换成 rgb24 ,打包成 numpy 数组。如果你是在 pc 在操作,需要自己重新编译 ffmpeg ,启用 nvdec/qsv 硬件加速,这个解码负载就可以移动到 GPU 上来做,CPU 占用就很低了。
|
3
capric 135 天前
@capric 还需要重新编译 opencv ,https://blog.csdn.net/jiexijihe945/article/details/125084488
|
4
clevertension OP @capric 谢谢你的建议,ffmpeg 硬解码我试过了,确实速度很快, 确实能降 cpu , 从 300%到 80%,但是内存占用呢,比如 CPU 解码帧率只有 30 左右(和 CPU 性能相关),GPU 解码帧率 7600 多, 那 opencv 一次 read ,读取的 frame 不是很多吗,全部放到内存里了吗,而且,一个 thread 读取的时候,其他 thread 没时间执行, 那是不是会造成 frame 积压,从而内存就飙高了
|
5
murmurkerman 135 天前
搞一个帧队列,丢掉来不及处理的视屏帧。背压肯定会有的,选择丢帧或者提升模型处理性能。
|
6
vicalloy 135 天前
处理不过来就是处理不过来,除了增加算力或是减少工作量,没有别的办法。
最简单的处理就是 yolo 的取样频率不要这么高,比如 5 frame 只取一个 frame 做识别。 |
7
vicalloy 135 天前
另外 python 都多线程是用不了多核处理器的。
可以一个摄像头一个 yolo 处理进程。 |
8
ZnductR0MjHvjRQ3 135 天前
实时视频检测不是耗时操作吗?放线程里不会造成阻塞吗
|
9
paopjian 135 天前
你这是 yolo 处理不完,queue 堆积图片数据了吧
|
10
clevertension OP @paopjian 我试了一下,好像 yolo 处理还是快的,就是多线程去读取视频流的时候,一路视频读取的时候,另一路就读得不快,堆积了,瓶颈并不在 yolo
|
11
clevertension OP @vicalloy 嗯,准备用 multiprocessing 试一下
|
12
mightybruce 135 天前 1
不要用多线程,python 多线程只能利用一个核,有 GIL, 另外视频不需要每一帧都要读的, 可以每隔几帧读一下,然后降低图像的分辨率, 多路摄像头也建议解耦视频读取和图像处理,通过 zeromq 实现一下高速进程通信就可以
可以看看这个项目 https://github.com/jeffbass/imagezmq |
13
vivisidea 134 天前
就是多线程获取 camera 的数据,就会造成内存占用过高
== 看下来就是 yolo 处理不过来,frame 都积压在 queue 里面导致的内存过高,这个很容易验证吧,把 queue 长度打印一下就知道了 一个策略就是采样,不处理每个 frame ,每隔 xx 个 frame 处理一个,根据对实时性的要求来调整,或者把 yolo 剥离出来,多部署几个副本 |
14
capric 134 天前
@clevertension 你这个 rtmp 是实时流吗,如果是实时流,一般只有 25/30/60 几种,不会有 7600 那么高,你统计出来 7600 fps ,应该绝大多数 frame 都是 None 。另外可以用 multiprocessing 和 queue 分发。
|
15
clevertension OP @capric 现在 opencv 重新编译好了,cpu 占用降了,处理速度都正常,但是内存偶尔会下降一点,但是还是慢慢地会升高,最终 OOM ,我好像是这个问题 https://github.com/opencv/opencv/issues/21985
|
16
LANB0 134 天前
@clevertension #4 层主的建议是对的,就是软解和颜色空间转换导致的 CPU 占用,这部分换硬解占用就会下来。至于 frame 积压,耗时操作都在 GPU 的话,单核处理 60 帧一点问题也没有的。
|
17
wh1isper 133 天前
每帧都用 CPU 做撞 GIL 了,要么换硬解,要么多进程
|