【多模态大模型】AI对视频内容解析问答

慈云数据 2024-05-01 技术支持 84 0

文章目录

  • 1. 项目背景
  • 2. 直接对视频进行解析进行AI问答:MiniGPT4-Video
    • 2.1 MiniGPT4-Video效果
    • 3. 对视频抽帧为图片再进行AI问答
      • 3.1 视频抽帧
      • 3.2 图片AI问答
        • 3.2.1 阿里通义千问大模型 Qwen-vl-plus
        • 3.2.2 Moonshot

          1. 项目背景

          最近在做一个项目,需要使用AI技术对视频内容进行解析。实现这个功能,我们有两种可行的思路:

          1. 直接对视频进行解析进行AI问答:
          • 这种方法可以充分利用视频中包含的动态信息,如物体运动、声音等,从而得到更丰富的理解结果。
          • 需要使用专门的视频处理和理解模型,例如视频分类、目标检测、字幕生成等深度学习技术。
          • 这种方式计算量较大,对硬件性能要求较高,适合部署在服务器端环境中。
            1. 对视频抽帧为图片再进行AI问答:
            • 这种方法相对更加简单和高效,可以直接利用成熟的图像理解模型。
            • 可以根据需求灵活选择合适的帧率,提取关键帧进行分析。
            • 这种方法计算量较小,更适合部署在移动设备或边缘计算环境中。

              2. 直接对视频进行解析进行AI问答:MiniGPT4-Video

              MiniGPT4-video是一个视频理解的多模态大模型,可以直接对视频内容向AI进行提问。

              官网:https://vision-cair.github.io/MiniGPT4-video/

              论文链接:https://arxiv.org/abs/2404.03413

              2.1 MiniGPT4-Video效果

              官网中可以传本地视频和链接视频测试效果。我们只要在 Your Question 输入对AI提出的问题,AI就会在 MiniGPT4-video Answer 中给出这个问题的答案。

              笔者做了多次尝试,能够直接对视频内容进行解析,快速得到想要的答案,效果还不错。

              3. 对视频抽帧为图片再进行AI问答

              3.1 视频抽帧

              笔者测试了两款常用的视频抽帧工具:opencv 和 ffmpeg。这两款工具实现的效果都相同,笔者更倾向于使用 opencv,因为它是python的第三方库,可以直接调用python代码,使用起来更方便。详细的介绍,可以查看笔者的另一篇文章:

              视频抽帧转图片,opencv和ffmpeg效果测评

              在这里补充一下视频处理的几个重要概念:

              • 帧(Frame):在视频或动画中,帧指的是单个静态图像。视频或动画由大量连续的帧组成。
              • 帧数(Frame Count):视频或动画中总共包含的帧的数量。帧数决定了视频或动画的长度。
              • 帧率(Frame Rate):每秒显示的帧数,也称为FPS(Frames Per Second)。帧率决定了视频或动画的流畅度和质量。常见的帧率有24FPS、30FPS、60FPS等。
              • FPS(Frames Per Second):每秒显示的帧数,即帧率。这是视频或动画的一个重要参数,决定了画面的流畅性。较高的帧率(如60FPS)可以提供更流畅的视觉体验,而较低的帧率(如24FPS)可能会出现卡顿或闪烁的问题。

                举例来说假如我有一个视频,他的视频长度是42s,fps是25,每隔15秒抽取一张图,那么抽取的图片数是: 25*42/15 = 70张。

                如果使用的是 opencv,可以使用以下代码,通过调整 timef,可以得到截取到不同数目的视频图片数。

                import cv2
                from PIL import Image
                import numpy as np
                cap = cv2.VideoCapture("D:/Download/ANMR0005.mp4")  # 获取视频对象
                isOpened = cap.isOpened  # 判断是否打开
                # 视频信息获取
                fps = cap.get(cv2.CAP_PROP_FPS)
                imageNum = 0
                sum=0
                timef=15  #隔15帧保存一张图片
                while (isOpened):
                    sum+=1
                    (frameState, frame) = cap.read()  # 记录每帧及获取状态
                    if frameState == True and (sum % timef==0):
                        # 格式转变,BGRtoRGB
                        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                        # 转变成Image
                        frame = Image.fromarray(np.uint8(frame))
                        frame = np.array(frame)
                        # RGBtoBGR满足opencv显示格式
                        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
                        imageNum = imageNum + 1
                        fileName = 'D:/Download/video_image/image' + str(imageNum) + '.jpg'  # 存储路径
                        cv2.imwrite(fileName, frame, [cv2.IMWRITE_JPEG_QUALITY, 100])
                        print(fileName + " successfully write in")  # 输出存储状态
                    elif frameState == False:
                        break
                print('finish!')
                cap.release()
                

                3.2 图片AI问答

                接下来,让我们来测试阿里通义千问大模型 Qwen-vl-plus 和 Moonshot。

                我们准备了一张从海飞丝洗发水的广告视频中抽帧出来的图片,要让AI回答:请你判断图中是否包含洗发水?,请你回答“是”或“否”,并解释原因。

                在这里插入图片描述

                3.2.1 阿里通义千问大模型 Qwen-vl-plus

                在使用 Qwen-vl-plus 大模型需要在官网创建一个API-KEY,才能调用接口。API官方文档用详细介绍这个模型要怎么调用,参数如何设置等详细说明。

                • API官方说明文档:

                  https://help.aliyun.com/zh/dashscope/developer-reference/qwen-vl-plus/?spm=a2c4g.11186623.0.0.1e9d7794QqfJS4

                  • API-KEY的创建:

                    https://help.aliyun.com/zh/dashscope/developer-reference/activate-dashscope-and-create-an-api-key?spm=a2c4g.11186623.0.0.21477794cgawYi

                    调用 Qwen-vl-plus 大模型,与AI问答的代码,如下:

                    from dashscope import MultiModalConversation
                    import dashscope
                    import json
                    import time
                    def invokeQween_vl_plus(api_key, prompt, file_path):
                        '''
                        API官方说明文档:https://help.aliyun.com/zh/dashscope/developer-reference/qwen-vl-plus/?spm=a2c4g.11186623.0.0.1e9d7794QqfJS4
                        @param
                        api_key (str): 阿里云 用户中心-API Key管理获取:https://help.aliyun.com/zh/dashscope/developer-reference/activate-dashscope-and-create-an-api-key?spm=a2c4g.11186623.0.0.36347794rx7gaK
                        prompt (str): 对文件分析的指令
                        file_path (str):需要解析的文件路径。示例:"./A.png"
                        
                        @return
                        text (str):模型输出
                        input_tokens(int):输入Token
                        output_tokens(int):输出Token
                        image_tokens (int):输入图片Token
                        time_consuming(int):耗时
                        '''
                        messages = [{
                            'role': 'user',
                            'content': [
                                {
                                    'image': file_path
                                },
                                {
                                    'text': prompt
                                },
                            ]
                        }]
                        start_time = time.time()
                        response = MultiModalConversation.call(model='qwen-vl-plus', messages=messages)
                        time_consuming = time.time() - start_time
                        
                        text = response.output.choices[0].message.content[0]["text"]
                        input_tokens = response.usage["input_tokens"]
                        output_tokens = response.usage["output_tokens"]
                        image_tokens = response.usage["image_tokens"]
                        print(f"input_tokens:{input_tokens}")
                        print(f"output_tokens:{output_tokens}")
                        print(f"image_tokens:{image_tokens}")
                        print(f"运行时间:{time_consuming}")
                        return text, input_tokens, output_tokens, image_tokens, time_consuming
                        
                    #=========================================== 调用示例 ============================================
                    # 调用示例
                    dashscope.api_key = "Your-KEY"
                    prompt = '请你判断图中是否包含洗发水的实物图?请你回答“是”或“否”,并解释原因'
                    file_path = "C:\\Users\video\\open_cv_images\\test3\\image42.jpg"
                    text, input_tokens, output_tokens, image_tokens, time_consuming = invokeQween_vl_plus(dashscope.api_key, prompt, file_path)
                    print(text)
                    

                    输出的结果是:

                    input_tokens:1248

                    output_tokens:46

                    image_tokens:1196

                    运行时间:8.08695936203003

                    是。图片中的女子手中拿着一瓶带有蓝色泵头和白色瓶身,上面印有品牌名称"海飞丝"以及产品信息的洗发水瓶子,这是一张该产品的实物展示照片。

                    3.2.2 Moonshot

                    Moonshot 也需要申请 API-KEY

                    API官方说明文档:

                    https://platform.moonshot.cn/docs/api-reference#%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF

                    用户中心-API Key管理获取:

                    https://platform.moonshot.cn/console/api-keys

                    对应的代码如下;

                    import requests
                    from pathlib import Path
                    from openai import OpenAI
                    def invokeMoonshot_FileAnalysis(api_key, prompt, file_path):
                        '''
                        Moonshot 文件解析:上传文件 → OCR提取文件信息 → Moonshot 大模型分析 → 结论
                        API官方说明文档:https://platform.moonshot.cn/docs/api-reference#%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF
                        @param
                        api_key (str): Moonshot 用户中心-API Key管理获取:https://platform.moonshot.cn/console/api-keys
                        prompt (str): 对文件分析的指令
                        file_path (str):需要解析的文件路径。示例:"./A.png"
                        
                        @return
                        output (str):模型输出
                        input_tokens (int): 输入Token
                        output_tokens (int): 输出Token
                        time_consuming (int): 耗时
                        '''
                        client = OpenAI(api_key=api_key, base_url="https://api.moonshot.cn/v1")                  # 账号信息 & 文件上传 URL
                        file_object = client.files.create(file=Path(file_path), purpose="file-extract")          # 上传需要解析的文件,得到文件id
                        file_content = client.files.content(file_id=file_object.id).text                         # 获取上传文件被OCR提取的文本信息
                        token_count_url = 'https://api.moonshot.cn/v1/tokenizers/estimate-token-count'           # 计算Token的请求地址 
                        # 拼装模型输入
                        messages=[ 
                                {"role": "system", "content": "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。",},
                                {"role":"system","content":file_content},
                                {"role": "user", "content":prompt}
                            ]      
                        
                        # 调用大模型API
                        start_time = time.time()
                        completion = client.chat.completions.create(
                            model="moonshot-v1-8k",   # moonshot-v1-8k, moonshot-v1-32k, moonshot-v1-128k
                            messages=messages,
                            temperature=0.01,
                            top_p=0.01,
                            max_tokens=4096,
                            n=1,
                            presence_penalty=0,
                            frequency_penalty=0,
                        )
                        output = completion.choices[0].message.content
                        #print(completion.choices)
                        time_consuming = time.time() - start_time
                        # 计算输入token
                        headers = {
                            "Content-Type": "application/json",
                            "Authorization": f"Bearer {api_key}"
                        }
                        data_input = {
                            "model": "moonshot-v1-8k",
                            "messages":  messages
                        }
                        response_input = requests.post(token_count_url, json=data_input, headers=headers)
                        # 解析JSON响应并获取total_tokens的值
                        input_tokens = response_input.json()['data']['total_tokens']
                        print(f"input_tokens:{input_tokens}")
                        # 计算输出token
                        data_output = {
                           "model": "moonshot-v1-8k",
                            "messages": [
                        {"role": "system","content": "你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。"},
                        { "role": "assistant", "content": output}
                                        ]
                        }
                        response_output = requests.post(token_count_url, json=data_output, headers=headers)
                        # 解析JSON响应并获取total_tokens的值
                        output_tokens = response_output.json()['data']['total_tokens']
                        print(f"output_tokens:{output_tokens}")
                        return output,input_tokens,output_tokens,time_consuming
                    #=========================================== 调用示例 ============================================
                    api_key = 'Your-KEY'
                    file_name = 'image42.jpg'
                    prompt =  '请你判断{}的信息中是否包含洗发水?,请你回答“是”或“否”,并解释原因'.format(file_name)
                    file_path = "C:\\Users\\video\\open_cv_images\\test3\\image42.jpg"
                    start_time = time.time()
                    output,input_tokens,output_tokens,time_consuming = invokeMoonshot_FileAnalysis(api_key, prompt, file_path)
                    print(output,input_tokens,output_tokens,time_consuming)
                    

                    输出结果:

                    是。

                    原因:在提供的信息中,“海飞丝”是一个知名的洗发水品牌,因此可以判断信息中包含了洗发水的提及。 155 103 0.939953088760376

                    从两个模型的结果来看,Qwen-vl-plus 直接根据图片做AI问答,而 Moonshot 是将图片信息转为文本信息,然后再做AI问答,上述代码中 Qwen-vl-plus 的参数会比 Moonshot 多一个 image_tokens。

                    总的来说,对于我们的测试数据,两个模型都能给出比较准确的答案。

微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon