在 Windows 下用 Python 和 OpenCV 做视频分析程序,如何加速?
从视频中提取数据,开启视频窗口的话每秒处理 5-6 帧,一小时视频要 5-6 小时处理完,我想慢点也没关系,但是 cpu 占用率只有 2%。这就不让我淡定了,明显是偷懒了,安排了多线程,好像也是不能提升速度,请问 windows 就是不会给 python 太多资源么?我开了几路脚本一起做,cpu 仍然占用率也很低。这是怎么回事?
在 Windows 下用 Python 和 OpenCV 做视频分析程序,如何加速?
用的是 GPU?
在Windows下用Python和OpenCV加速视频分析,核心是减少CPU解码负担并利用硬件加速。最直接有效的方法是使用OpenCV的cv2.VideoCapture时指定后端为支持硬解的CAP_MSMF(Media Foundation)或CAP_DSHOW(DirectShow),并设置cv2.CAP_PROP_HW_ACCELERATION。如果硬件支持,这能显著降低CPU占用。
不过,OpenCV的硬解支持有时不太稳定。更可靠的方案是使用ffmpeg-python或PyAV库,它们对硬件解码(如NVIDIA的NVDEC、Intel的QSV)支持更好。你可以先用ffmpeg硬解,再把帧传给OpenCV处理。
这里给你个用ffmpeg-python硬解结合OpenCV的完整例子:
import cv2
import ffmpeg
import numpy as np
def decode_hw(video_path, hw_device='cuda'): # 也可用 'dxva2' 或 'qsv'
# 使用ffmpeg硬件解码,输出原始BGR帧
probe = ffmpeg.probe(video_path)
video_info = next(s for s in probe['streams'] if s['codec_type'] == 'video')
width = video_info['width']
height = video_info['height']
process = (
ffmpeg
.input(video_path, hwaccel=hw_device, hwaccel_output_format='cuda') # 硬解到GPU
.output('pipe:', format='rawvideo', pix_fmt='bgr24', vcodec='rawvideo')
.run_async(pipe_stdout=True, pipe_stderr=True)
)
while True:
in_bytes = process.stdout.read(width * height * 3)
if not in_bytes:
break
# 将字节数据转为numpy数组(仍在CPU内存)
frame = np.frombuffer(in_bytes, np.uint8).reshape([height, width, 3])
# 这里进行你的OpenCV处理,例如:
# gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# ... 你的分析逻辑
yield frame
process.wait()
# 使用示例
for frame in decode_hw('your_video.mp4', hw_device='dxva2'): # Windows常用dxva2
cv2.imshow('Frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
另外,如果分析算法不复杂,可以试试用OpenCV的cv2.cuda模块把处理也放到GPU上,但注意这需要额外编译支持CUDA的OpenCV。
简单说,优先用ffmpeg硬解,比折腾OpenCV后端更靠谱。
放代码
不敢放,太丑了,流程比较简单,识别轮廓,拟和椭圆和质点,记录 csv,甚至没有定义函数。
没有就是 cpu。
用的是机械硬盘?或者内存比较小?
多线程改为多进程
计算密集的任务试试多进程
是不是时间消耗在 IO 操作上了
试着多将几帧一次性读入内存看看行不行?运行的时候看下资源占用率是不是硬盘开销比较大,如果你 CPU 相当牛叉有十几个核可以试试用 MATLAB 并行。
5/6 帧一秒,视频好歹也 25 帧一秒最少
我说的是处理速度,不是播放速度,一小时视频 5 个小时处理完没毛病
建议用 go 或者 rust
- 可以只处理部分帧(关键帧?); 2. 每帧太大的话,降采样变小点;
是处理速度
如果只是线、椭圆检测啥的,OpenCV 好像提供跟踪,应该快点吧。
应该是 io 没跟上,导致 cpu 工作不饱和
换 c++
OpenCV 的 Python 绑定,调的也是 C++。
我觉得可能是,其实硬盘没有跟忙。
初级菜鸟,还不会那些语言。我也不会多进程,就是在系统下一次运行了 9 个脚本分别处理 9 个视频。发现内存占用多了一些,cpu 仍然是 2-10%。关闭 imshow 函数会快一点,大概是 3 个小时能处理一个小时视频。 采样量已经非常小了 288:100。我觉得可能是 io 的问题
请问具体是哪个函数呢?
把事情分解开来做
比如一段视频,2000 帧,提取出 100 帧出来,把这个时间算一下,花了多长时间
然后分析其中 1 帧,看多长时间,
这样来找出瓶颈在哪里,
如果 cpu 利用率不高,可以开 50 个进程,同时分析 50 帧嘛
给自己一个入 1080 的理由
谢谢,我试下
CPU 不高肯定是非 CPU 瓶颈,你得先找出瓶颈再分析。。。
上 tbb 直接让你的 cpu 100%
放代码出来看看。。如果处理是可并行的,可以考虑多线程,or 用 gpu 来加速,但做这些可能都还是用 C++来做方便些
There are at least 5 types of tracker algorithms that can be used:
- MIL
- BOOSTING
- MEDIANFLOW
- TLD
- KCF
[OpenCV: Introduction to OpenCV Tracker]( http://docs.opencv.org/3.1.0/d2/d0a/tutorial_introduction_to_tracker.html )
多线程换多进程。。
加时延统计 慢慢分析


