ModelBox
新手入门
【ModelBox OCR实战营】视频字幕识别

发布于27个月以前

  • 0
  • 0
  • 543

发布于27个月以前

视频字幕识别

验证码识别 中,我们介绍了文本行识别算法,但是验证码场景只有单行文本,字符集的数量不多,图片中的字符数也是固定的,本文我们继续提高难度:视频字幕识别,需要先进行文本行的定位,再进行文本行识别,需要识别的字符集数量大大增多,文本行中的文字数量也不固定。

1. 视频字幕识别任务介绍

视频字幕大家比较熟悉,但是视频字幕识别可能不太理解,有些人甚至不能理解这个任务存在的合理性:不是有独立的字幕文件吗?这个任务就是单纯的技术展示吗?

其实,有些视频是内嵌字幕,没有独立的视频文件;或者有些条件下拿不到字幕文件,此时,字幕识别可以有以下用途:视频内容理解场景,字幕识别可以从文字层面提供内容解析;视频推荐场景,识别的字幕中可以提取出关键词;还有字幕自动翻译,也需要先识别原文本才能搭配机器翻译技术。因此,视频字幕识别还是有其应用场景的。

本文要实现的视频字幕识别效果如下:

可以看到,最新的字幕将显示在右侧最下层,前面时刻的字幕会滚动到上层。

2. 模型训练

视频字幕识别应用包括文本行定位与文本行识别两个模型。文本行识别可以继续采用CRNN+CTC模型,与 验证码识别 中一样;文本行定位使用的是DBNet,模型的训练与转换教程已经开放在AI Gallery中,其中包含训练数据、训练代码、模型转换脚本,以及详细的指导文档。开发者如果希望尝试自己训练模型,或者对模板中提供的模型效果不满意,可以进入 【ModelBox】通用文字检测模型训练 页面,点击右上角的Run in ModelArts按钮,跟随教程一步步操作,也可以修改其中的代码、更换新的数据集训练出自己的模型。

3. 资源下载与应用创建

视频字幕识别应用已经做成模板放在华为云OBS中,可以用sdk中的solution.bat工具下载。

1)下载模板

ModelBox sdk目录下执行.\solution.bat -l可看到当前公开的技能模板:

PS ███> .\solution.bat -l
...

Solutions name:
mask_det_yolo3
...
caption_recognition_db_crnn

结果中的 caption_recognition_db_crnn 即为视频字幕识别应用模板,可使用如下命令下载模板:

PS ███> .\solution.bat -s caption_recognition_db_crnn
...

solution.bat工具的参数中,-l 代表list,即列出当前已有的模板名称;-s 代表solution-name,即下载对应名称的模板。下载下来的模板资源,将存放在ModelBox核心库的solution目录下。

2)创建工程

ModelBox sdk目录下使用create.bat创建caption_recognition工程

PS ███> .\create.bat -t server -n caption_recognition -s caption_recognition_db_crnn
sdk version is modelbox-xxx
success: create caption_recognition in ███\modelbox\workspace

create.bat工具的参数中,-t 表示创建事务的类别,包括工程(server)、Python功能单元(Python)、推理功能单元(infer)等;-n 代表name,即创建事务的名称;-s 代表solution-name,表示将使用后面参数值代表的模板创建工程,而不是创建空的工程。

workspace目录下将创建出caption_recognition工程,工程内容如下所示:

caption_recognition
|--bin
│  |--main.bat:应用执行入口
│  |--mock_task.toml:应用在本地执行时的输入输出配置,此应用默认使用本地视频文件为输入源,最终结果输出到另一本地视频文件,可根据需要修改
|--CMake:存放一些自定义CMake函数
|--data:存放应用运行所需要的图片、视频、文本、配置等数据
│  |--character_keys.txt:OCR算法的字符集合
│  |--GB2312.ttf:中文字体文件
│  |--ocr_test.mp4:字幕识别测试用的视频
|--dependence
│  |--modelbox_requirements.txt:应用运行依赖的外部库在此文件定义,本应用依赖pillow等三方库
|--etc
│  |--flowunit:应用所需的功能单元存放在此目录
│  │  |--cpp:存放C++功能单元编译后的动态链接库,此应用没有C++功能单元
│  │  |--collapse_res:合并功能单元,将多个文本行的字幕识别结果合在一起输出
│  │  |--det_post:文本行定位模型的后处理功能单元
│  │  |--draw_res:字幕识别结果画图功能单元
│  │  |--expand_img:展开功能单元,将同一张图的多个文本行检测框展开为多个输出
│  │  |--similarity:文本相似度计算,用于合并相同字幕在多帧的识别结果
|--flowunit_cpp:存放C++功能单元的源代码,此应用没有C++功能单元
|--graph:存放流程图
│  |--caption_recognition.toml:默认流程图,使用data下的测试视频进行推理
│  |--modelbox.conf:modelbox相关配置
|--hilens_data_dir:存放应用输出的结果文件、日志、性能统计信息
|--model:推理功能单元目录
│  |--det:文本行定位推理功能单元
│  │  |--det.toml:文本行定位功能单元的配置文件
│  │  |--det.onnx:文本行定位onnx模型
│  |--ocr:文本行识别推理功能单元
│  │  |--ocr.toml:文本行识别功能单元的配置文件
│  │  |--ocr.onnx:文本行识别onnx模型
|--build_project.sh:应用构建脚本
|--CMakeLists.txt
|--rpm:打包rpm时生成的目录,将存放rpm包所需数据
|--rpm_copyothers.sh:rpm打包时的辅助脚本

4. ModelBox推理

1)查看流程图

mnist工程graph目录下存放流程图,默认的流程图caption_recognition.toml与工程同名,其内容为(以Windows版ModelBox为例):

[driver]
# 功能单元的扫描路径,包含在[]中,多个路径使用,分隔
# ${HILENS_APP_ROOT} 表示当前应用的实际路径
# ${HILENS_MB_SDK_PATH} 表示ModelBox核心库的实际路径
dir = [
    "${HILENS_APP_ROOT}/etc/flowunit",
    "${HILENS_APP_ROOT}/etc/flowunit/cpp",
    "${HILENS_APP_ROOT}/model",
    "${HILENS_MB_SDK_PATH}/flowunit",
]
skip-default = true

[profile]
# 通过配置profile和trace开关启用应用的性能统计
profile = false                       # 是否记录profile信息,每隔60s记录一次统计信息
trace = false                         # 是否记录trace信息,在任务执行过程中和结束时,输出统计信息
dir = "${HILENS_DATA_DIR}/mb_profile" # profile/trace信息的保存位置

[flow]
desc = "caption recognition example with local video" # 应用的简单描述

[graph]
format = "graphviz" # 流程图的格式,当前仅支持graphviz
graphconf = """digraph caption_recognition {
    node [shape=Mrecord]
    queue_size = 1
    batch_size = 1

    # 定义节点,即功能单元及其属性
    input1[type=input,flowunit=input,device=cpu,deviceid=0]
    data_source_parser[type=flowunit, flowunit=data_source_parser, device=cpu, deviceid=0]
    video_demuxer[type=flowunit, flowunit=video_demuxer, device=cpu, deviceid=0]
    video_decoder[type=flowunit, flowunit=video_decoder, device=cpu, deviceid=0, pix_fmt="rgb"]

    det_resize[type=flowunit flowunit=resize device=cpu deviceid="0" image_width=640, image_height=640]
    det_color_transpose[type=flowunit flowunit=packed_planar_transpose device=cpu deviceid="0"]
    det_mean[type=flowunit flowunit=mean device=cpu deviceid="0" mean="123.68,103.53,116.28"]
    det_normalize[type=flowunit flowunit=normalize device=cpu deviceid=0 standard_deviation_inverse="0.01712475,0.01742919,0.0175070"]
    det[type=flowunit flowunit=det device=cpu deviceid="0"]
    det_post[type=flowunit, flowunit=det_post, device=cpu, deviceid=0]

    expand_img[type=flowunit, flowunit=expand_img, device=cpu, deviceid=0 img_w=320, img_h=32]
    ocr_color_transpose[type=flowunit flowunit=packed_planar_transpose device=cpu deviceid="0"]
    ocr_mean[type=flowunit flowunit=mean device=cpu deviceid="0" mean="127.5,127.5,127.5"]
    ocr_normalize[type=flowunit flowunit=normalize device=cpu deviceid=0 standard_deviation_inverse="0.007843,0.007843,0.007843"]
    ocr[type=flowunit flowunit=ocr device=cpu deviceid="0"]

    collapse_res[type=flowunit flowunit=collapse_res device=cpu deviceid="0"]
    similarity[type=flowunit flowunit=similarity device=cpu deviceid="0"]
    draw_res[type=flowunit flowunit=draw_res device=cpu deviceid="0"]
    video_out[type=flowunit, flowunit=video_out, device=cpu, deviceid=0]

    # 定义边,即功能间的数据传递关系
    input1:input -> data_source_parser:in_data
    data_source_parser:out_video_url -> video_demuxer:in_video_url
    video_demuxer:out_video_packet -> video_decoder:in_video_packet
    video_decoder:out_video_frame -> det_resize:in_image
    det_resize:out_image -> det_color_transpose:in_image
    det_color_transpose:out_image -> det_mean:in_data
    det_mean:out_data -> det_normalize:in_data
    det_normalize:out_data -> det:input
    det:output -> det_post:in_feat
    video_decoder:out_video_frame -> det_post:in_image
    det_post:has_box -> expand_img:in_image
    expand_img:out_image -> ocr_color_transpose:in_image
    ocr_color_transpose:out_image -> ocr_mean:in_data
    ocr_mean:out_data -> ocr_normalize:in_data
    ocr_normalize:out_data -> ocr:input
    ocr:output -> collapse_res:in_feat
    collapse_res:out_feat -> similarity:in_feat
    det_post:has_box -> similarity:in_image
    similarity:out_image -> draw_res: in_image
    det_post:no_box -> draw_res: in_image
    draw_res:out_image-> video_out:in_video_frame
}"""

这是个视频推理流程图,首先进行文本行定位,再截取文本区域图片进行文本行识别,最后展示结果。因为一句字幕会持续一段时间,应用中增加了文本相似度计算模块,用于对多帧的相同字幕进行合并。

2)用启动脚本执行应用

启动应用前执行.\build_project.sh进行工程构建,该脚本将编译自定义的C++功能单元(本应用不涉及)、将应用运行时会用到的配置文件转码为Unix格式(防止执行过程中的格式错误)、安装第三方依赖库:

PS ███> .\build_project.sh
...
PS ███>

然后执行.\bin\main.bat运行应用:

PS ███> .\bin\main.bat
...

运行结束后在hilens_data_dir目录下生成了result.mp4文件,可以打开查看,效果与文章开头的图类似。

5. 小结

本教程我们再次增加了难度,使用视频字幕识别这一场景学习了文本行定位+识别算法,这是很多OCR任务的标准流程。前几年OCR领域的很多创新都是在提出更优的文本行定位算法、文本行识别算法,很多新的模型结构被提出。万变不离其宗,我们把握了这一基础流程,已经可以应付很多OCR任务了。

LLM初学者

作者相关内容

【2022 ModelBox实战营】第一个应用
发布于30个月以前
【2022 ModelBox实战营】通用Python功能单元
发布于30个月以前
【ModelBox客流分析实战营】ModelBox端云协同AI开发套件(Windows)SDK安装篇
发布于28个月以前
【2022 ModelBox实战营】推理功能单元
发布于30个月以前
ModelBox开发案例 - 使用YOLO v3做口罩检测
发布于34个月以前

暂无数据

热门内容推荐

ModelArts JupyterLab常见问题解决办法
ModelArts开发者 发布于45个月以前
为医生打造专属数字分身!华为云联合万木健康打造医疗医学科普和患者教育数字人引擎
HWCloudAI 发布于20个月以前
图数据库 | 聊聊超级快的图上多跳过滤查询
弓役是也 发布于23个月以前
ModelArts准备工作_简易版
ModelArts开发者 发布于46个月以前
”智蔗见智·向新而生”广西第二届人工智能大赛baseline使用教程
追乐小王子 发布于31个月以前

暂无数据