基于图像识别和文字识别用 Python 提取视频字幕

本文介绍使用 Python 基于图像识别提取视频中的字幕,并使用文字识别将字幕转为纯文本。本文以权力的游戏第一季第一集作为示例。

本文主要使用 OpenCV 读取视频并进行图像处理,需安装以下依赖的库:

pip install opencv-python
pip install Pillow
pip install numpy

1、使用 opencv 读取视频

对于视频文件,可以使用 cv2VideoCapture 类读取:

import cv2video_filename = '/Users/csd/S01E01.mkv'
videoCap = cv2.VideoCapture(video_filename)

调用 get() 方法可以得到视频文件的一些基本信息:

# 帧频
fps = videoCap.get(cv2.CAP_PROP_FPS)
# 视频总帧数
total_frames = int(videoCap.get(cv2.CAP_PROP_FRAME_COUNT))
# 图像尺寸
image_size = (int(videoCap.get(cv2.CAP_PROP_FRAME_HEIGHT)), int(videoCap.get(cv2.CAP_PROP_FRAME_WIDTH)))print(fps)
print(total_frames)
print(image_size)

输出:

23.976023976023978
88644
(576, 1024)

可以看到该视频帧频为 24 fps,共 88644 帧画面,图片尺寸为 (576, 1024)。

调用 read() 方法可以读取一帧的图片

sucess, frame = videoCap.read()

当 sucess 为 True 时,读取成功,此时 frame 是图像像素矩阵,三维 numpy 矩阵。

由于视频开头总会有片头,且字幕不总是在开头就出现,所以选取 1:57 位置的一帧进行演示,使用 PIL 库转为 Image 对象并显示出来,如下图所示:

for i in range(2818):sucess, frame = videoCap.read()from PIL import Image
img = Image.fromarray(frame)
img.show()

2、字幕图片提取与处理

接下来确定字幕的范围

im = frame[:, :, 0]
im = im[495:570, :]     //  确定字幕的范围,注意不同的视频文件剪切的索引值不同
img = Image.fromarray(im)
img.show()

剪切的字幕图片如下所示:

在进行下一步分析前,需对图像做二值化处理。由于字幕的白色的,像素值为 255,将二值化阈值设为 220。

thresh = 220
_, im = cv2.threshold(im, thresh, 255, cv2.THRESH_BINARY)
img = Image.fromarray(im)
img.show()

接下来的一个重要的问题是如何将连续的字幕提取出来,并且不重复。在此使用两张字幕计算平均平方误差的百分比,确定所需提取的字幕。选取如下4帧的字幕进行对比展示:

  • im0: 没有字幕的一帧:
  • im1: 上面演示的一帧;
  • im2: im1 的下一帧,字幕相同;
  • im3: 另一句字幕的一帧:

接着根据下面的公式计算两张图像间每个像素点的平方误差之和的平均值百分比:

计算每张图像与 0 值图像的误差 e(也即上述公式中b为0):

print((im0 ** 2).sum() / im0.size * 100)
print((im1 ** 2).sum() / im1.size * 100)
print((im2 ** 2).sum() / im2.size * 100)
print((im3 ** 2).sum() / im3.size * 100)

得到结果为:

0.0
1.79817708333
1.79817708333
5.66666666667

可以看出,当 e > 1 时,图像才有字幕。

接着计算相同字幕和不同字幕图像直接的误差 e:

print(((im2 - im1) ** 2).sum() / im1.size * 100)
print(((im3 - im1) ** 2).sum() / im1.size * 100)

得到

0.00260416666667
6.64453125

可以看出误差 e > 1 时,字幕发生切换。

3、完整提取一个视频的字幕

为了方便文字识别,将 20 句字幕组合成一张图片。完整的提取字幕的代码如下:

import cv2
from PIL import Image
import numpy as np
import os
import datetimedef format_time(second):hours = second // 3600minutes = (second - hours * 3600) // 60second = second - hours * 3600 - minutes * 60t = datetime.time(hour=hours, minute=minutes, second=second)return datetime.time.isoformat(t)def cal_stderr(img, imgo=None):if imgo is None:return (img ** 2).sum() / img.size * 100else:return ((img - imgo) ** 2).sum() / img.size * 100def save_image(ex_folder, img: Image, starts: int, ends: int):# 保存字幕图片到文件夹start_time = format_time(starts)end_time = format_time(ends)timeline = '-'.join([start_time, end_time]) + ".png"try:imgname = os.path.join(ex_folder, timeline)img.save(imgname)print('export subtitle at %s' % timeline)except Exception:print('export subtitle at %s error' % timeline)def export_subtitle(video_filename):ex_folder = os.path.splitext(video_filename)[0]if not os.path.exists(ex_folder):os.mkdir(ex_folder)skip_frames = 2818videoCap = cv2.VideoCapture(video_filename)for i in range(skip_frames):videoCap.read()start_frame = skip_framescurr_frame = skip_framesfps = videoCap.get(cv2.CAP_PROP_FPS)success = Truesubtitle_img = Nonelast_img = Noneimg_count = 0while success:for j in range(9):videoCap.read()curr_frame += 1success, frame = videoCap.read()curr_frame += 1if frame is None:print('video: %s finish at %d frame.' % (video_filename, curr_frame))breakimg = frame[:, :, 0]img = img[495:570, :]_, img = cv2.threshold(img, 220, 255, cv2.THRESH_BINARY)if cal_stderr(img) < 1:continueif img_count == 0:subtitle_img = imgprint('video: %s add subtitle at %d frame.' % (video_filename, curr_frame))last_img = imgimg_count += 1elif img_count > 10:img_count = 0subtitle_img = Image.fromarray(subtitle_img)save_image(ex_folder, subtitle_img, int(start_frame/fps), int(curr_frame/fps))start_frame = curr_frame    # 开始时间往后移else:if cal_stderr(img, last_img) > 1:subtitle_img = np.vstack((subtitle_img, img))last_img = imgimg_count += 1print('video: %s add subtitle at %d frame.' % (video_filename, curr_frame))if img_count > 0:subtitle_img = Image.fromarray(subtitle_img)save_image(ex_folder, subtitle_img, int(start_frame / fps), int(curr_frame / fps))print('video: %s export subtitle finish!' % video_filename)if __name__ == '__main__':video_filename = '/Users/csd/S01E01.mkv'export_subtitle(video_filename)

提取的字幕效果如下:

本文的方法对于电影的此类干扰比较大的视频提取效果达不到最佳,而对于公开课类的视频可以达到很好的效果。对不同类别的视频需要根据1、2节调整参数。

4、对字幕进行文字处理

对提取的字幕进行文字处理可以使用百度 AI 开发平台的 OCR 免费接口,具体可参考我的另一篇博文:Python 利用百度文字识别 API 识别并提取图片中文字

基于图像识别和文字识别用 Python 提取视频字幕相关推荐

  1. python提取视频字幕_荐利用Python提取视频中的字幕(文字识别)

    学了好久机器学习的内容有些许枯燥,今天我们来做一个Python的小项目来玩耍吧! 项目背景 通过获取百度API实现视频文字识别. 需求阐述 将.MP4格式视频裁剪成一帧一帧的图片再将图片中的字幕摘取出 ...

  2. python提取视频字幕_利用Python提取视频中的字幕(文字识别)

    我的CSDN博客id:qq_39783601,昵称是糖潮丽子~辣丽 从今天开始我会陆续将数据分析师相关的知识点分享在这里,包括Python.机器学习.数据库等等. 今天来分享一个Python小项目! ...

  3. python提取视频字幕_GitHub - jiulinxiri/video-timeline-and-subtitle-extract: 视频时间轴及字幕提取...

    视频时间轴及字幕提取 能帮助你: 1.识别字幕的时间轴 通过帧差法判断是否相同帧, 进而由相同帧得出字幕时间轴 计算时间轴对应帧的 SSIM , 合并相同的时间轴 2.利用OCR识别字幕 将指定字幕区 ...

  4. 软件测试 给视频添加字幕功能,巧用百度OCR文字识别技术,实现视频字幕识别...

    前言:我们都知道,现在有很多文字识别技术,但是如何合理的应用于生活呢?我当时马上就想到了电影字幕的提取,很多人在看外国新闻的时候,会发现,只有英文字幕呀,怎么办呢,所以这个功能我就研发了出来 一.运用 ...

  5. python提取视频字幕_ffmpeg 提取 视频,音频,字幕 方法

    ffmpeg 提取 视频,音频,字幕 方法 (How to Extract Video, Audio, Subtitle from Original Video?) 1. 提取视频 (Extract ...

  6. python 替换array中的值_利用Python提取视频中的字幕(文字识别)

    我的CSDN博客id:qq_39783601,昵称是糖潮丽子~辣丽 从今天开始我会陆续将数据分析师相关的知识点分享在这里,包括Python.机器学习.数据库等等. 今天来分享一个Python小项目! ...

  7. access数据放到list中_利用Python提取视频中的字幕(文字识别)

    我的CSDN博客id:qq_39783601,昵称是糖潮丽子~辣丽 从今天开始我会陆续将数据分析师相关的知识点分享在这里,包括Python.机器学习.数据库等等. 今天来分享一个Python小项目! ...

  8. 基于百度AI的文字识别(Python语言)

    简 介:百度大脑是百度 AI 核心技术引擎,包括视觉.语音.自然语言处理.知识图谱.深度学习等AI核心技术和AI开放平台.本文介绍百度 AI 核心技术中文字识别功能的使用方法. 关键词:百度AI.文字 ...

  9. 基于模板的文字识别结果结构化处理技术

    原文链接:https://cloud.tencent.com/developer/article/1425800 嘉宾 | 向宇波 编辑 | suiling 来源 | AI科技大本营在线公开课 出品 ...

最新文章

  1. 一篇非常好的transformer年度总结
  2. java interface class_Java中常量定义在interface和class的区别(转)
  3. 《Java疯狂讲义》(第3版)学习笔记 2 - Java语言的运行机制
  4. 天池 在线编程 能否转换
  5. ffmpeg 视频合并
  6. 20190925:(经典算法系列)河内之塔
  7. xp计算机管理窗口,XP系统设备管理器的打开技巧
  8. jQuery Mobile中网格grid样式ui-grid-*
  9. 阻止brew自动更新
  10. 19【推荐系统10】从POLY2、FM到FFM——自动特征交叉的解决方案
  11. 网络操作系统发展历程
  12. 小程序二维码和带参数的二维码生成
  13. 面向开发者稳定、安心的APP内测托管平台
  14. 安卓获取指定目录内所有指定文件类型的文件路径和名字
  15. 2017-910-十一
  16. 医美整形机构业务流程讲解
  17. Mac ubuntu安装无线驱动
  18. android softkeyboard,如何以编程方式关闭Android Soft KeyBoard?
  19. 第三章 PL/SQL数据类型
  20. WebDAV之葫芦儿·派盘 + Strongbox

热门文章

  1. 什么显卡是个人计算机的基本配置和市场主流,现在()显卡已经成为了个人计算机的基本配置和市场主流。 - 问答库...
  2. MarkDown语法详解
  3. 阿里云学生成长计划续费资格考试
  4. Python中的“鸭子形态”,浅谈一下
  5. Drying POJ - 3104 二分
  6. BUU_re_[ACTF新生赛2020]rome
  7. 仿网易云音乐的小程序项目(粗糙版)
  8. mac文件反选_【PS反选键是什么?】Photoshop该如何进行反向选择?
  9. 动态使用element-plus 的图标
  10. [PHP] PHP7.4.2安全和修复版本的更改日志