算法链路从读取视频帧开始,再进行采样、推理、跟踪和事件判断。先把“读到帧”和“判断出事件”分清,避免将进程在线当作算法正常。
做一个解码与采样实验
使用 Python 3 和 OpenCV,先创建虚拟环境并安装依赖:
python -m venv .venv.\.venv\Scripts\python.exe -m pip install opencv-python==4.12.0.88安装 FFmpeg 后生成一段测试文件:
ffmpeg -f lavfi -i "testsrc2=size=640x360:rate=25:duration=5" -an -c:v libx264 -pix_fmt yuv420p input.mp4保存 sample_frames.py:
from pathlib import Pathimport sysimport cv2
source = sys.argv[1] if len(sys.argv) > 1 else 'input.mp4'output = Path('frames')output.mkdir(exist_ok=True)capture = cv2.VideoCapture(source, cv2.CAP_FFMPEG, [ cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, 5000, cv2.CAP_PROP_READ_TIMEOUT_MSEC, 5000,])if not capture.isOpened(): capture.release() raise RuntimeError('无法打开视频,请检查路径、地址和 FFmpeg 后端支持')
read_count = 0saved_count = 0try: while read_count < 250 and saved_count < 10: ok, frame = capture.read() if not ok: break if read_count % 25 == 0: filename = output / f'frame_{read_count:06d}.jpg' if not cv2.imwrite(str(filename), frame): raise RuntimeError(f'图片保存失败:{filename}') saved_count += 1 read_count += 1finally: capture.release()print(f'read={read_count}, saved={saved_count}')if read_count == 0: raise RuntimeError('打开成功但没有读到帧').\.venv\Scripts\python.exe .\sample_frames.py .\input.mp4对 5 秒、25 FPS 的测试素材,应读取 125 帧并保存 5 张图片。换成 RTSP URI 时,编码、账号和网络也会影响读取;URI 中凭据不应公开在日志里。
这个例子每 25 帧取一帧。只有固定 25 FPS 素材才可近似理解为每秒一帧;实时或可变帧率来源应按时间戳设计采样。循环有帧数和保存数量限制,没有无限重连。
接入自己的算法
flowchart LR V[视频流] --> D[解码] D --> S[按策略采样] S --> P[模型预处理与推理] P --> T[目标跟踪] T --> E[事件规则] E --> F[图片与录像证据] F --> U[上传与通知]模型的输入尺寸、颜色顺序、归一化、类别与输出坐标必须按实际模型检查。OpenCV 常用 BGR,其他模型可能要求 RGB;一段能读取 JPEG 的代码不代表已经实现目标检测。
结果应带摄像头/任务标识、帧编号或时间戳、模型版本和坐标约定。异步结果迟到时,要回到对应的帧,不能随便画到最新画面。
从检测到告警
单帧检测是候选结果,告警通常还需要持续时间、区域、阈值、去重和恢复条件。例如“对象连续在区域内”要记录状态转换,而不是每帧发送一条通知。
先准备正常、触发、临界和恢复样本,检查事件与证据时间能否对应。模型分数不是统一可信概率,不同场景的阈值需依据实际样本确定。
下一篇:运维与容量规划。参考:OpenCV 视频读取、超时属性。
评论