用 yolo 做实时视频检测, 摄像头接入超过 3 路, Python 内存占用就飙高,请问有没有解决办法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
clevertension
V2EX    Python

用 yolo 做实时视频检测, 摄像头接入超过 3 路, Python 内存占用就飙高,请问有没有解决办法?

  •  
  •   clevertension 2024-06-26 16:02:11 +08:00 3476 次点击
    这是一个创建于 538 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问一下做过实时视频检测的大佬,我现在用 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 的数据,就会造成内存占用过高

    17 条回复    2024-06-28 10:30:06 +08:00
    a33291
        1
    a33291  
       2024-06-26 16:07:28 +08:00
    看过海康本身的策略,他们有 2 种方案
    1 是实时检测,也就是实时取流检测,这种的话需要独立的服务器并且同时检测路数不高
    2 是摄像头自己抓拍图片然后传递给超脑,抓拍图片在设备侧做并且不需要每一帧都分析所以极大减少了计算量,从而可以提供更大的吞吐

    基本策略应该类似,比如结合设备本身的移动侦测来做,对移动侦测的图进行分析应该也可以极大减少计算量
    此外,可以考虑分析子码流,对子码流降低码率分辨率(太低可能影响分析结果)
    capric
        2
    capric  
       2024-06-26 16:18:07 +08:00   1
    cv2.VideoCapture 的 read 是调用 ffmpeg 库实现的,涉及到几个耗时操作,解析 rtmp 封装,H.264/H.264 视频解码(最占用 CPU),yuv 颜色空间转换成 rgb24 ,打包成 numpy 数组。如果你是在 pc 在操作,需要自己重新编译 ffmpeg ,启用 nvdec/qsv 硬件加速,这个解码负载就可以移动到 GPU 上来做,CPU 占用就很低了。
    capric
        3
    capric  
       2024-06-26 16:20:07 +08:00
    clevertension
        4
    clevertension  
    OP
       2024-06-26 16:36:20 +08:00
    @capric 谢谢你的建议,ffmpeg 硬解码我试过了,确实速度很快, 确实能降 cpu , 从 300%到 80%,但是内存占用呢,比如 CPU 解码帧率只有 30 左右(和 CPU 性能相关),GPU 解码帧率 7600 多, 那 opencv 一次 read ,读取的 frame 不是很多吗,全部放到内存里了吗,而且,一个 thread 读取的时候,其他 thread 没时间执行, 那是不是会造成 frame 积压,从而内存就飙高了
    murmurkerman
        5
    murmurkerman  
       2024-06-26 17:34:10 +08:00
    搞一个帧队列,丢掉来不及处理的视屏帧。背压肯定会有的,选择丢帧或者提升模型处理性能。
    vicalloy
        6
    vicalloy  
       2024-06-26 17:38:32 +08:00
    处理不过来就是处理不过来,除了增加算力或是减少工作量,没有别的办法。
    最简单的处理就是 yolo 的取样频率不要这么高,比如 5 frame 只取一个 frame 做识别。
    vicalloy
        7
    vicalloy  
       2024-06-26 17:40:52 +08:00
    另外 python 都多线程是用不了多核处理器的。
    可以一个摄像头一个 yolo 处理进程。
    ZnductR0MjHvjRQ3
        8
    ZnductR0MjHvjRQ3  
       2024-06-26 17:50:34 +08:00
    实时视频检测不是耗时操作吗?放线程里不会造成阻塞吗
    paopjian
        9
    paopjian  
       2024-06-26 18:00:57 +08:00
    你这是 yolo 处理不完,queue 堆积图片数据了吧
    clevertension
        10
    clevertension  
    OP
       2024-06-26 19:40:12 +08:00
    @paopjian 我试了一下,好像 yolo 处理还是快的,就是多线程去读取视频流的时候,一路视频读取的时候,另一路就读得不快,堆积了,瓶颈并不在 yolo
    clevertension
        11
    clevertension  
    OP
       2024-06-26 19:40:38 +08:00
    @vicalloy 嗯,准备用 multiprocessing 试一下
    mightybruce
        12
    mightybruce  
       2024-06-26 20:53:39 +08:00   1
    不要用多线程,python 多线程只能利用一个核,有 GIL, 另外视频不需要每一帧都要读的, 可以每隔几帧读一下,然后降低图像的分辨率, 多路摄像头也建议解耦视频读取和图像处理,通过 zeromq 实现一下高速进程通信就可以

    可以看看这个项目
    https://github.com/jeffbass/imagezmq
    vivisidea
        13
    vivisidea  
       2024-06-27 09:29:52 +08:00
    就是多线程获取 camera 的数据,就会造成内存占用过高
    ==
    看下来就是 yolo 处理不过来,frame 都积压在 queue 里面导致的内存过高,这个很容易验证吧,把 queue 长度打印一下就知道了

    一个策略就是采样,不处理每个 frame ,每隔 xx 个 frame 处理一个,根据对实时性的要求来调整,或者把 yolo 剥离出来,多部署几个副本
    capric
        14
    capric  
       2024-06-27 10:54:46 +08:00
    @clevertension 你这个 rtmp 是实时流吗,如果是实时流,一般只有 25/30/60 几种,不会有 7600 那么高,你统计出来 7600 fps ,应该绝大多数 frame 都是 None 。另外可以用 multiprocessing 和 queue 分发。
    clevertension
        15
    clevertension  
    OP
       2024-06-27 11:33:18 +08:00
    @capric 现在 opencv 重新编译好了,cpu 占用降了,处理速度都正常,但是内存偶尔会下降一点,但是还是慢慢地会升高,最终 OOM ,我好像是这个问题 https://github.com/opencv/opencv/issues/21985
    LANB0
        16
    LANB0  
       2024-06-27 15:33:20 +08:00
    @clevertension #4 层主的建议是对的,就是软解和颜色空间转换导致的 CPU 占用,这部分换硬解占用就会下来。至于 frame 积压,耗时操作都在 GPU 的话,单核处理 60 帧一点问题也没有的。
    wh1isper
        17
    wh1isper  
       2024-06-28 10:30:06 +0:00
    每帧都用 CPU 做撞 GIL 了,要么换硬解,要么多进程
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1422 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 16:50 PVG 00:50 LAX 08:50 JFK 11:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86