首页 > 其他分享 >【飞桨AI实战】基于PP-OCR和ErnieBot的智能视频问答

【飞桨AI实战】基于PP-OCR和ErnieBot的智能视频问答

时间:2024-05-25 09:28:24浏览次数:26  
标签:视频 PP gr AI text 飞桨 字幕 video path

前言

        本次分享将带领大家从 0 到 1 完成一个基于 OCR 和 LLM 的视频字幕提取和智能视频问答项目,通过 OCR 实现视频字幕提取,采用 ErnieBot 完成对视频字幕内容的理解,并回答相关问题,最后采用 Gradio 搭建应用。本项目旨在帮助初学者快速搭建入门级 AI 应用,并分享开发过程中遇到的一些坑,希望对感兴趣的同学提供一点帮助。

项目背景和目标

背景:

        光学字符识别(Optical Character Recognition,简称 OCR)是一种将图像中的文字转换为机器编码文本的过程。通常一个 OCR 任务的处理流程如下图所示:

 PP-OCR 是百度面向产业应用提供的 OCR 解决方案,底层采用的是两阶段 OCR 算法,即检测模型+识别模型的组成方式,其处理流程包括如下几个步骤:

而视频字幕提取就是对视频中的每帧图像提取出其中的字幕文字。

        大语言模型(LLM,Large Language Model)是一种先进的自然语言处理技术,当前主流的 LLM 包括 GPTs、百度文心一言、阿里通义千问、字节豆包等,而 ErnieBot 正是基于百度文心一言的智能体框架。基于提取的视频字幕,借助 LLM 强大的语义理解能力,我们可以完成很多有意思的任务,比如让 LLM 帮我们提取视频的关键信息,甚至是基于视频回答我们的问题,减轻当前大模型常见的“幻觉”-胡说八道,比如下面这张图:

目标:

  • 掌握如何用 paddlepaddle 深度学习框架搭建一个文本识别模型;
  • 掌握文本识别模型架构的设计原理以及构建流程;
  • 掌握如何利用已有框架快速搭建应用,满足实际应用需求;

百度 AI Studio 平台

        本次实验将采用 AI Studio 实训平台中的免费 GPU 资源,在平台注册账号后,点击创建项目-选择 NoteBook 任务,然后添加数据集,如下图所示,完成项目创建。启动环境可以自行选择 CPU 资源 or GPU 资源,创建任务每天有 8 点免费算力,推荐大家使用 GPU 资源进行模型训练,这样会大幅减少模型训练时长。

创建项目的方式有两种:

  • 一是在 AI Studio 实训平台参考如下方式,新建项目。

为了快速跑通项目流程,建议直接 fork 源项目。

从零开始实战

        1 基础:动手跑通 CRNN 文本识别任务

核心代码在:core/ 文件夹下

背景:CRNN 是较早被提出也是目前工业界应用较多的文本识别方法。本节将详细介绍如何基于 PaddleOCR 完成 CRNN 文本识别模型的搭建、训练、评估和预测。数据集采用 CaptchaDataset 中文本识别部分的 9453 张图像,其中前 8453 张图像在本案例中作为训练集,后 1000 张则作为测试集。

1.1 数据准备

step 1:解压缩数据

# 打开终端
# 解压子集  -d 指定解压缩的路径,会在data0文件夹下生成
unzip data/data57285/OCR_Dataset.zip -d data0/
# 查看文件夹中文件数量
ls data0/OCR_Dataset/|wc -l

step 2: 准备数据部分代码

# 数据读取类在 reader.py, 可以执行如下脚本查看训练数据
python reader.py

可视化结果如下:

1.2 模型构建

本次实验我们将采用最简单的网络架构来搭建 CRNN 网络 并构建损失函数 CTCLoss

step 1: 搭建 CRNN 网络

# 定义模型类
net.py

step 2: 定义损失函数 CTCLoss

# 定义 loss, 位于 net.py
class CTCLoss(paddle.nn.Layer):
    def __init__(self, batch_size):
        """
        定义CTCLoss
        """
        super().__init__()
        self.batch_size = batch_size

    def forward(self, ipt, label):
        input_lengths = paddle.full(shape=[self.batch_size],fill_value=LABEL_MAX_LEN + 4,dtype= "int64")
        label_lengths = paddle.full(shape=[self.batch_size],fill_value=LABEL_MAX_LEN,dtype= "int64")
        # 按文档要求进行转换dim顺序
        ipt = paddle.tensor.transpose(ipt, [1, 0, 2])
        # 计算loss
        loss = paddle.nn.functional.ctc_loss(ipt, label, input_lengths, label_lengths, blank=10)
        return loss

1.3 模型训练

编写训练脚本 train.py 如下,主要是定义好数据集、模型,配置训练相关参数:

# 运行训练脚本
python train.py

训练过程如下图所示:

1.4 模型预测

编写预测脚本 predict.py

# 运行预测脚本
python predict.py

调用模型预测函数:得到生成图像的可视化结果

2 进阶:基于PP-OCRErnieBot搭建应用

核心代码在:ocr-bot/ 文件夹下

2.1 环境准备

本项目主要用到了以下安装包,可以采用 pip install -r requirements.txt 一键安装。

paddlepaddle
paddleocr==2.7.0
erniebot
moviepy
gradio

2.2 需求分析

本项目主要需要完成两个功能:视频字幕提取 和 智能视频问答

视频字幕提取

  • 中文视频能提取出其中的字幕
  • 英文视频能自动生成中文字幕
  • 生成 SRT 格式的字幕文件
  • 将字幕文件内嵌到视频中去

智能视频问答

  • 提取视频中的关键信息,完成视频摘要
  • 根据字幕信息,回答用户针对视频的提问
  • 根据字幕信息,定位关键信息对应的时间片段

2.2 核心功能实现

2.2.1 基于 PP-OCR 完成字幕提取

采用 opencv 读取视频中的图片,引入 paddleocr 包实现图片中的字幕提取,同时记录时间信息,为了快速完成 demo 展示,这里采用每秒抽取一帧图像,且只用图像底部包含字幕的部分进行文字识别,核心代码如下:

def get_video_ocr(vid_path='/home/aistudio/demo/trim.mp4'):
    ocr = PaddleOCR(use_angle_cls=True, debug=False)
    src_video = cv2.VideoCapture(vid_path)
    fps = int(src_video.get(cv2.CAP_PROP_FPS))
    total_frame = int(src_video.get(cv2.CAP_PROP_FRAME_COUNT)) # 计算视频总帧数
    save_text = []
    for i in tqdm(range(total_frame)):    
        success, frame = src_video.read()
        if i % (fps) == 0 and success:
            result = ocr.ocr(frame[-120:-30, :], cls=True)[0] # 只抽取下半部分图片
            if len(result)> 0: 
                res = result[0][1][0]
                start_time = i//fps
                save_text.append([start_time, res])
    # 将数据转换为字典,合并重复的字幕
    subtitles = {}
    for (time, text) in save_text:
        if text in subtitles:
            subtitles[text].append(time)
        else:
            subtitles[text] = [time]
    subtitle_path = vid_path.replace('.mp4', '.json')
    print(f"字幕提取完成,结果已保存至{subtitle_path}")
    with open(subtitle_path, 'w', encoding='utf-8') as f:
        json.dump(subtitles, f, ensure_ascii=False)
    return '\n'.join(list(subtitles.keys())), subtitle_path
2.2.2 基于 百度翻译API 完成字幕翻译

为了帮助大家对原版英文视频的理解,可以将原始的英文字幕翻译成中文,这里选择直接调用 百度翻译API,开发者每个月都有一定的免费额度。注意将其中的 API_KEY 和 SECRET_KEY 换成你自己的。

def get_access_token():
    API_KEY = "j5HodGgjG2iQ87MenXrw2hot"
    SECRET_KEY = "Ea1AYc1kjzv2MNExEZeMAEwzanDDlsdK"
    url = "https://aip.baidubce.com/oauth/2.0/token"
    params = {"grant_type": "client_credentials", "client_id": API_KEY, "client_secret": SECRET_KEY}
    return str(requests.post(url, params=params).json().get("access_token"))

def translation(content, from_lang="en", to_lang="zh"):
    url = "https://aip.baidubce.com/rpc/2.0/mt/texttrans/v1?access_token=" + get_access_token()
    payload = json.dumps({
        "from": from_lang,
        "to": to_lang,
        "q": content
    })
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }
    response = requests.request("POST", url, headers=headers, data=payload)
    i = response.text.find("dst")+6
    j = response.text.find("src")-3
    return response.text[i:j]
    
def translate_subtitles(subtitle_path, from_lang="en", to_lang="zh"):
    new_subtitles = {}
    subtitles = json.load(open(subtitle_path, 'r'))
    for text, value in subtitles.items():
        trans_text = translation(text, from_lang, to_lang)
        new_subtitles[trans_text] = value
    subtitle_path = subtitle_path.replace('.json', f'_{to_lang}.json')
    print(f"字幕翻译完成,结果已保存至{subtitle_path}")
    with open(subtitle_path, 'w', encoding='utf-8') as f:
        json.dump(new_subtitles, f, ensure_ascii=False)
    return '\n'.join(list(new_subtitles.keys())), subtitle_path
2.2.3 生成 SRT 格式的字幕文件

视频文件中最简单、最常见的外挂字幕格式是SRT(SubRip Text)。SRT字幕通常以srt作为后缀,作为外挂字幕,多数主流播放器都支持直接加载并显示SRT字幕。通常每个字幕段有四部分构成:

  • 字幕序号:从 1 开始(而不是 0)
  • 字幕显示的起始时间
    • 格式为hour:minute:second,millisecond --> hour:minute:second,millisecond
  • 字幕内容(可多行)
  • 空白行(表示本字幕段的结束)

一个简单的例子如下:

1
0:00:00,000 --> 0:00:02,000
可能没有意识到。
2
0:00:02,000 --> 0:00:03,000
他们怎么会知道我们总有一天

让我们编写代码将提取的字幕改写成 SRT 格式的字幕文件:

def generate_subtitles(subtitle_path, save_path='./subtitles.srt'):
    srt_content = ''
    subtitles = json.load(open(subtitle_path, 'r'))
    for index, (text, times) in enumerate(subtitles.items()):
        # SRT文件的索引从1开始
        srt_index = index + 1
        # 格式化时间戳
        start_time = "%s,%03d" % (timedelta(seconds=times[0]), 0 * 100)
        end_time = "%s,%03d" % (timedelta(seconds=times[-1]+1), 0 * 100)
        time_str = f"{start_time} --> {end_time}"
        # 将字幕合并为一个字符串,并用逗号分隔
        # 构建SRT条目
        srt_entry = f"{srt_index}\n{time_str}\n{text}\n"
        srt_content += srt_entry
    # 写入SRT文件
    with open(save_path, 'w', encoding='utf-8') as file:
        file.write(srt_content)
    return srt_content
2.2.4 基于 moviepy 实现视频拼接

注意 moviepy 实现视频拼接需要安装 imagemagick。在 AIStudio 的 Linux 环境中没有 sudo 权限,因此无法安装 imagemagick,如果要实现视频拼接,需要大家移步到自己本地电脑运行。Linux 下一键安装 imagemagick:

sudo apt-get install imagemagick

如果 imagemagick 安装没问题,那么就可以实现将翻译后的中文字幕添加到视频中。这里给出示例代码实现:

def add_subtitles(video_path, subtitle_path, output_path='./video_with_subtitles.mp4'):
    # 加载视频文件
    video = VideoFileClip(video_path)
    width, height = video.w, video.h
    subtitles = json.load(open(subtitle_path, 'r'))
    trans_text = []
    for text, dura in subtitles.items():
        start_time = float(dura[0])
        end_time = float(dura[-1]+1)
        duration = end_time - start_time
        text = TextClip(text, fontsize=20, size=(width-20, 25),
                        align='center', color='white').set_position((10,height-40)).set_duration(duration).set_start(start_time)
        trans_text.append(text)
    video = CompositeVideoClip([video, *trans_text])
    video.write_videofile(output_path)
2.2.5 基于 ErnieBot 实现视频问答

ERNIE Bot 为开发者提供了便捷接口,可以轻松调用文心大模型的文本创作、通用对话、语义向量及AI作图等基础功能。

这里仅使用通用对话接口,你只需要将字幕文件(srt_content)提示词(prompt_content)你的问题(user_content)准备就可以了,示例代码如下:

import erniebot
erniebot.api_type = 'aistudio'
erniebot.access_token = '7d8bcc8494fb95e9059bae34856c3a40daaf8671' # 注意替换成自己的

def chat_with_bot(srt_content, prompt_content, user_content):
    if not srt_content:
        return "请先点击

标签:视频,PP,gr,AI,text,飞桨,字幕,video,path
From: https://blog.csdn.net/class4715/article/details/139189219

相关文章

  • 在 Azure AI Studio 中创建项目并使用聊天演练场
    在AzureAIStudio中创建项目并使用聊天演练场See:CreateaprojectandusethechatplaygroundinAzureAIStudio-AzureAIStudio|MicrosoftLearn在本动手实验中,你将创建项目,部署聊天模型,然后在AzureAIStudio中的演练场中使用它。本动手实验包括:在AzureA......
  • uni-app 微信 支付宝 小程序 使用 longpress 实现长按删除功能,非常简单 只需两步
    1、先看效果2、直接上代码ui结构<viewclass="bind"@longpress="deleteImage":data-index="index"><viewclass="bind_left">绑定设备</view><viewclass="bind_right"><viewc......
  • uniapp快速分享知识点,请求简单封装 登陆 ,支付 , 分享 , 短信,
    第一部份requrety请求封装 备注:关于环境配置ui选择插件安装在我的另一个帐号中前几天也经写了,这个博客就不用在写一遍了另一博客地址:https://www.cnblogs.com/ZzwWan/p/18202502module.exports=(vm)=>{//初始化请求配置uni.$u.http.setConfig((config)=>{......
  • 玩赚Ai 智图师 Midjourney版:利用Midjourney实现AI创作及变现(10节课)
    欢迎来到本期玩赚AI智图师Midjourney版课程!在这里,我们将带领大家深入学习如何利用Midjourney这款强大的Ai创作工具,实现ai创作及变现。首先,我们将简要介绍Midjourney的功能和特点,然后通过10节课程,逐步带领大家掌握如何利用Midjourney制作各种精彩的AI作品,包括头像、插画、海报......
  • 【AI学习】对LLM训练中数据处理的再认识
    最近读了几篇文章,对于LLM模型中的数据处理,有了一些再认识。这几篇文章分别是《世界顶级风投a16z创始人对谈AI与创业》、《BenThompson对NatFriedman和DanielGross的采访》、《AI教父Hinton最新万字精彩访谈:直觉,AI创新的洞见和思考,未来》有一些观点:1、训练模型的数......
  • The configuration for MySQL Server 8.0.27 has failed You can find more informati
    遇见这种情况,作者当时也是痛苦万分,网上找了许许多多的方法试了好多次都不行。分析问题出现这种问题是因为我们之前安装过但是没有安装完全就取消了,电脑里面已经存储了。重新安装的时候把安装位置和数据存放的位置路径全部使用英文,例如:之前我的安装路径:D:\用户\app\mysql......
  • [自动驾驶技术]-7 Tesla自动驾驶方案之算法(AI Day 2022)
    特斯拉在2022年AIDay上更新了感知规控算法模型,核心引入了Occupancy技术。下图是特斯拉活动日展示的主题内容,本文主要解读Planning和NeuralNetwork部分。1规划决策Interactionsearch-交互搜索特斯拉在自动驾驶规划中使用了一种高度复杂和优化的搜索算法,结合了多种先进的......
  • 【源码翻译之交互式对象包 AIS-AIS_ColoredShape.hxx文件 多颜色交互式对象
    类AIS_ColoredShape形状的呈现具有可自定义的子形状属性。此类可以将topods的子拓扑分别设置不同的颜色然后作为一个整体显示成员类型定义文档◆DataMapOfDrawerCompdtypedefNCollection_IndexedDataMap<Handle<AIS_ColoredDrawer>,TopoDS_Compound,TColStd_MapT......
  • P10298 [CCC 2024 S4] Painting Roads
    原题链接题解由易到难,先不考虑交替的事情,既然要尽量少的涂色,那么我最少要涂几条颜色的边?(由于图不一定联通,这里先考虑连通图的情况)如果一条边处于一个环内,那么这个边就可以不涂色。所以只要有环我就可以选择一条边不涂色,那么到最后,涂色的边构成一棵树接下来考虑这颗树能否实现......
  • 5款超好用的AI换脸软件,一键视频直播换脸(附下载链接)
    随着AIGC的火爆,AI换脸技术也被广泛应用于娱乐、广告、电影制作等领域,本期文章系统介绍了市面上超火的5款AI软件换脸整合包收录了全部5款AI工具,请按照需要选择下载:百度网盘:https://pan.baidu.com/s/1-LeEVYHv0tra-AJlK9seJQ?pwd=j4at 1.Roop作为AI换脸领域的鼻祖,Roop的人气一......