跳到主要内容

多模态视频分析应用

多模态视频分析应用1. 概念介绍1.1 “视频分析”是什么?1.2 实现原理简述2. 代码解析关键代码1. 工具层入口 (largemodel/utils/tools_manager.py)2. 模型接口层与帧提取 (largemodel/utils/large_model_interface.py)代码解析3. 实践操作3.1 配置在线LLM3.2 启动并测试功能

1. 概念介绍

1.1 “视频分析”是什么?

largemodel项目中,多模态视频分析 功能,指的是让机器人能够处理一段视频,并用自然语言总结视频的核心内容、描述关键事件或回答关于视频的具体问题。这使得机器人从只能理解静态图片,跃升到能够理解动态、有时序关系的世界。

该功能的核心工具是 analyze_video 。当用户提供一个视频文件并提问(例如“总结一下这个视频讲了什么”)时,系统会调用此工具,对视频进行处理和分析,并返回AI的文字回答。

1.2 实现原理简述

离线视频分析的核心挑战在于如何让模型高效地处理包含成百上千帧的视频数据。一种主流的实现原理如下:

  1. 关键帧提取 : 首先,系统不会处理视频的每一帧,而是通过算法(如场景边界检测或固定时间间隔采样)提取出最具代表性的关键帧 (Keyframes)。这极大地减少了需要处理的数据量。
  2. 图像编码 : 提取出的每一帧关键帧,都会像视觉理解应用一样,被送入一个视觉编码器,转换成包含图像信息的数字向量。
  3. 时序信息融合 : 这是与单图理解最大的不同。模型需要理解这些关键帧之间的时间顺序。通常会使用一种循环神经网络(RNN)或Transformer模型来融合所有关键帧的向量,形成一个能代表整个视频动态内容的“记忆”向量。
  4. 问答与生成 : 用户的文本问题被编码后,与这个“记忆”向量进行跨模态融合。最后,语言模型部分会基于这些融合后的信息,生成对整个视频的总结或特定问题的答案。

简单来说,就是把一段视频“浓缩”成几张关键图片和它们的顺序,然后像看连环画一样理解整个故事,并回答相关问题

2. 代码解析

关键代码

1. 工具层入口 (largemodel/utils/tools_manager.py)

此文件中的analyze_video函数定义了该工具的执行流程。

# From largemodel/utils/tools_manager.py class ToolsManager : # ... def analyze_video ( self , args ): """ Analyze video file and provide content description. 分析视频文件并提供内容描述。 :param args: Arguments containing video path. :return: Dictionary with video description and path. """ self . node . get_logger (). info ( f"Executing analyze_video() tool with args: {args}" ) try : video_path = args . get ( "video_path" ) # ... (智能路径回退机制) if video_path and os . path . exists ( video_path ): # ... (构建Prompt) # Use a fully isolated, one-time context for video analysis to ensure a plain text description. / 使用完全隔离的一次性上下文进行视频分析,以确保获得纯文本描述。 simple_context = [{ "role" : "system" , "content" : "You are a video description assistant. ..." }] result = self . node . model_client . infer_with_video ( video_path , prompt , message = simple_context ) # ... (处理结果) return { "description" : description , "video_path" : video_path } # ... (错误处理)

2. 模型接口层与帧提取 (largemodel/utils/large_model_interface.py)

此文件中的函数负责处理视频文件,并将其传递给底层模型。

​ x # From largemodel/utils/large_model_interface.py ​ class model_interface : # ... def infer_with_video ( self , video_path , text = None , message = None ): """Unified video inference interface. / 统一的视频推理接口。""" # ... (准备消息) try : # 根据 self.llm_platform 决定调用哪个具体实现 if self . llm_platform == 'ollama' : response_content = self . ollama_infer ( self . messages , video_path = video_path ) # ... (其他在线平台的逻辑) # ... return { 'response' : response_content , 'messages' : self . messages . copy ()} ​ def _extract_video_frames ( self , video_path , max_frames = 5 ): """Extract keyframes from a video for analysis. / 从视频中提取关键帧用于分析。""" try : import cv2 # ... (视频读取和帧间隔计算) while extracted_count < max_frames : # ... (循环读取视频帧) if frame_count % frame_interval == 0 : # ... (将帧保存为临时图片) frame_base64 = self . encode_file_to_base64 ( temp_path ) frame_images . append ( frame_base64 ) # ... return frame_images # ... (异常处理)

代码解析

视频分析功能的实现比图像分析更复杂一步,它需要在模型接口层进行一次关键的预处理:帧提取。

  1. 工具层 (tools_manager.py):

    • analyze_video函数是视频分析的业务入口。它的职责很明确:接收一个视频文件路径,构建一个用于请求视频内容描述的指令(Prompt)。
    • 它通过调用self.node.model_client.infer_with_video方法来启动分析流程。与视觉理解工具一样,它完全不关心底层的模型细节,只负责传递“视频文件”和“分析指令”。
  2. 模型接口层 (large_model_interface.py):

    • infer_with_video函数是连接上层工具和底层模型的调度器。它根据平台配置(self.llm_platform)将任务分发给相应的具体实现函数。
    • 与处理单张图片不同,处理视频需要一个额外的步骤。_extract_video_frames方法展示了实现这一步的通用逻辑:它使用cv2库来读取视频,并从中提取出若干个(默认为5个)关键帧。
    • 每个提取出的帧都被视为一张独立的图片,并通常被编码为Base64字符串。
    • 最终,包含多张帧图像数据和分析指令的请求被发送给大模型。模型会对这些连续的图像进行综合分析,从而生成对整个视频内容的描述。
    • 这个“视频转多图”的预处理过程被完全封装在模型接口层,对工具层是透明的。

总结来说,视频分析的通用流程是:ToolsManager发起分析请求 -> model_interface拦截请求,并调用_extract_video_frames将视频文件分解为多张关键帧图片 -> model_interface将这些图片连同分析指令一起,根据配置发送给相应的模型平台 -> 模型返回对视频的综合描述 -> 结果最终交还给ToolsManager。这个设计确保了上层应用的稳定性和通用性。

3. 实践操作

3.1 配置在线LLM

  1. 先从前面教程的任意一个平台中获取API Key之后获取API Key

  2. 然后需要更新配置文件中的key,打开模型接口配置文件large_model_interface.yaml:

xxxxxxxxxx vim ~/yahboom_ws/src/largemodel/config/large_model_interface.yaml 3. 填入你的API Key : 找到对应的部分,将你刚刚复制的API Key粘贴进去。这里以通义千问配置为例

xxxxxxxxxx # large_model_interface.yaml ​ ## 通义千问 qianwen_api_key : "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 粘贴你的Key qianwen_model : "qwen-vl-max-latest" # 可以根据需要选择模型, 如qwen-turbo, qwen-plus 4. 打开主配置文件yahboom.yaml:

xxxxxxxxxx vim ~/yahboom_ws/src/largemodel/config/yahboom.yaml 5. 选择要使用的在线平台 : 修改llm_platform参数为你想要使用的平台名称

xxxxxxxxxx # yahboom.yaml ​ model_service : ros__parameters : # ... llm_platform : 'tongyi' #可选平台: 'ollama', 'tongyi', 'spark', 'qianfan', 'openrouter'

3.2 启动并测试功能

  1. 准备视频文件 :

将一个要测试的视频文件放置到以下的路径: /home/jetson/yahboom_ws/src/largemodel/resources_file/analyze_video

然后将视频命名为 test_video.mp4

  1. 启动largemodel 主程序:

打开一个终端,然后运行下面的指令:

xxxxxxxxxx ros2 launch largemodel largemodel_control.launch.py 3. 测试 :

* **唤醒** : 对着麦克风说:“你好,小亚。”

* **对话** : 扬声器回应之后,就可以说:`分析一下视频内容`

* **观察日志** : 在运行`launch`文件的终端中,你应该能看到:

1. ASR节点识别出你的问题并打印出来。
2. `model_service`节点收到文本,调用LLM,并打印出LLM的回复。
* **听回答** : 稍后,你应该能从扬声器听到回答。