目标:提取位于视频下方的字幕

机缘:某些要写报告的学习视频太长了orz,弄字幕来参考一下

难点:

  1. 调参(不同视频字幕对应参数会不同,但调整不大)
  2. 图片相似度比较(哈希算法,有更好的算法但我没用心找)

基本策略:

  1. 确定字幕位置
  2. 比较截取的两帧字幕是否相同,若相同,则抛弃其中一帧
  3. 由于调用的是百度平台,有ocr次数限制(1000次/月),所以将某段时间内字幕合成一张图片后再文字识别

具体代码如下:

1. 定义调用百度开放平台OCR的函数

百度官方的ocr可以选择返回带位置和不带位置的文字识别,所以这里定义两个函数,location_ocr 返回位置,baidu_ocr返回识别出的文字

没有用过百度ocr的朋友需要去申请API Key和API Secret,然后飞桨平台上也有很多关于字幕识别的项目

# --coding: utf-8 --import math
import os
from cv2 import cv2
import requests
import base64# 确定字幕位置
def location_ocr(img):'''构建请求url,获取Access Token,必须参数如下:grant_type: 必须参数,固定为client_credentials;client_id: 必须参数,应用的API Key;client_secret: 必须参数,应用的Secret Key;'''host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' \+ 'API Key' + '&client_secret=' + 'Secret Key'headers = {'Content-Type': 'application/json;charset=UTF-8'}# 获取tokenres = requests.get(url=host, headers=headers).json()url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate'data = {}data['access_token'] = res['access_token']'''基于之前获取的token值,再次向请求url发送post请求,完成文字识别'''data['image'] = base64.b64encode(img)# 发送post请求,传入图片信息参数,获取文字识别结果headers = {"Content-Type": "application/x-www-form-urlencoded"}print('文本写入中')res = requests.post(url=url, headers=headers, data=data)result = res.json()# print(result)words_result_num = int(result['words_result_num'])# 文字识别是从上到下的,所以我们取输出的最后一行文字的位置top = result['words_result'][words_result_num-1]['location']['top']height = result['words_result'][words_result_num-1]['location']['height']bottom = top+height# 返回字幕框return top-20, bottom+10def baidu_ocr(img):'''构建请求url,获取Access Token,必须参数如下:grant_type: 必须参数,固定为client_credentials;client_id: 必须参数,应用的API Key;client_secret: 必须参数,应用的Secret Key;'''host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' \+ 'API Key' + '&client_secret=' + 'Secret Key'headers = {'Content-Type': 'application/json;charset=UTF-8'}# 获取tokenres = requests.get(url=host, headers=headers).json()url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic'data = {}data['access_token'] = res['access_token']'''基于之前获取的token值,再次向请求url发送post请求,完成文字识别'''data['image'] = base64.b64encode(img)# 发送post请求,传入图片信息参数,获取文字识别结果headers = {"Content-Type": "application/x-www-form-urlencoded"}print('文本写入中')res = requests.post(url=url, headers=headers, data=data)result = res.json()# print(result)text = result['words_result'][0]['words']# 输出文本结果,保存为txtf = open(r"保存txt的位置", 'a+')print(len(result['words_result']))for i in range(0, len(result['words_result'])):f.write(result['words_result'][i]['words'] + "\n")

2. 定义比较图像相似度的哈希算法

def similarity_hash(title, a, b):# 哈希算法比较图片相似度# 创建类if "AverageHash" == title:hashFun = cv2.img_hash.AverageHash_create()elif "PHash" == title:hashFun = cv2.img_hash.PHash_create()elif "MarrHildrethHash" == title:hashFun = cv2.img_hash.MarrHildrethHash_create()elif "RadialVarianceHash" == title:hashFun = cv2.img_hash.RadialVarianceHash_create()elif "BlockMeanHash" == title:hashFun = cv2.img_hash.BlockMeanHash_create()elif "ColorMomentHash" == title:hashFun = cv2.img_hash.ColorMomentHash_create()hash_a = hashFun.compute(a)hash_b = hashFun.compute(b)compare = hashFun.compare(hash_a, hash_b)return compare

3. 再定义一些有用的函数

def show_img(img):# 显示图片cv2.namedWindow('show_img', cv2.WINDOW_NORMAL)cv2.imshow('show_img', img)cv2.waitKey()cv2.destroyAllWindows()def video_time(video_filename):"""读取视频时长,计算需要切分识别的次数video_filename :所要切分的视频路径times :总切分次数"""total_frames = int(videoCap.get(cv2.CAP_PROP_FRAME_COUNT))# 每 80(图数)*20(帧间隔)=1600 帧,就归结为一张图,计算总图数times = math.ceil(total_frames/1600)return times

4. 开始处理视频

def subtitle_cut(videoCap, i, top, bottom):"""截取videoCap的第i帧的字幕区域并进行预处理"""videoCap.set(cv2.CAP_PROP_POS_FRAMES, i)  # 设置要获取的帧号TorF, frame = videoCap.read()  # read方法返回一个布尔值和一个视频帧subtitle_area = frame[top:bottom, :]# 阈值处理subtitle = cv2.cvtColor(subtitle_area, cv2.COLOR_BGR2GRAY)retVal, bw_img = cv2.threshold(subtitle,220,255,cv2.THRESH_BINARY_INV)return bw_imgvideo_file = '视频位置'
videoCap = cv2.VideoCapture(video_file)# 先在视频中截张图,得出字幕位置
for i in range(10):videoCap.set(cv2.CAP_PROP_POS_FRAMES, 3000+40*i)  # 随机截取,有字就行TorF, frame = videoCap.read()  # read方法返回一个布尔值和一个视频帧r = frame.shape[0]show_img(frame)frame_en = cv2.imencode('.jpg', frame)[1]top, bottom = location_ocr(frame_en)if top > 0.8*r :  # 如果识别的字幕框位于0.8r以下,就判断为字幕show_img(frame[top:bottom, :])break# 对视频截取字幕部分
times = video_time(video_file)
print(times)
os.chdir(r'E:\a_ocr\subtitles cutting\pics')
# 循环:每80张拼接成一张图(提高识别效果)for pic_list in range(5, times+1):  # 视频前面一般没有字幕,于是从5开始np_pic_list = []for i in range(80*pic_list, 80*(pic_list+1)):i = i * 20  # i代表随便抽取的某些帧,每隔20帧就抽取一帧# 比较第i帧前后两张截图,发生字幕切换的i贴入np_pic_listimg1= subtitle_cut(videoCap, i, top, bottom)img2 = subtitle_cut(videoCap, i-20, top, bottom)is_change_word = similarity_hash("PHash", img1, img2)print(is_change_word)if is_change_word>20:  # 判断字幕是否相同的分界点np_pic_list.append(img1)# 垂直拼接并保存成一张图img_splice = cv2.vconcat(np_pic_list)image = cv2.imencode('.jpg', img_splice)[1]show_img(img_splice)baidu_ocr(image)

刚学opencv没多久,写的代码怪乱的,看的朋友见谅

如果传入baidu_ocr中报错,显示图片格式不对,可以尝试image = cv2.imencode('.jpg', image),将image转为一维ndarray.

图片预处理还可以用自适应阈值,形态学处理,高斯滤波等等,对有颜色的字幕可以转为HSV颜色域再处理。

视频字幕识别(百度AI开放平台OCR | python | opencv)相关推荐

  1. java 百度账号注册界面_基于百度AI开放平台的人脸识别的注册登录(1)

    百度ai开放平台首页 2.选择产品服务,人脸与人体识别,人脸识别选项.打开后如图所示 人脸识别 3.点击立即使用 3.jpg 4.点击创捷应用 创建应用 这一页大家按自己需求填写即可 5.创建完成后点 ...

  2. 票据识别android代码,Android 百度AI开放平台-文字识别-财务票据文字识别

    简单记录一下今天关于百度AI开放平台-文字识别-财务票据文字识别的实现过程 文字识别有对应的Android SDK集成及相关Demo,文档地址如下图: SDK目录图.png 但是SDK中的返回数据字段 ...

  3. 基于百度AI开放平台的人脸识别

    文章目录 前言 人脸识别流程图 一.注册账号 二.创建应用 三.下载SDK文件 四.创建工具类 五.创建用于人脸识别的网页 1.引入css文件 2.创建注册按钮 3.创建模态框,用于捕捉人脸 4.引入 ...

  4. 百度AI人脸识别与检测一:学生人脸识别签到系统简介及百度AI开放平台账号注册和人脸实例应用创建

    <百度AI人脸识别与检测>专栏为项目专栏,从零到一,从无到有开发一个学生人脸识别签到系统:主要用到的技术有百度开放平台中的人脸检测.人脸识别.Python图形界面开发PyQt5.线程的管理 ...

  5. 百度AI开放平台集成人脸识别,离线采集有动作活体版本sdk

    前言 Android项目Android studio环境: 1.工程build.gradle版本号:3.2.1 2.app目录下的build.gradle配置:compileSdkVersion 28 ...

  6. 史上最简单的图像识别-百度AI开放平台

    提到图像识别,一般都会想到人工智能.虽然现在人工智能还在发展阶段,但是有些技术已经成熟,比如图像识别.语音识别.百度早在2015年之前就已经推出了AI开放平台,涵盖了语音识别.图像处理.视频技术等等. ...

  7. 百度ai开放平台使用方法(附带例子详细步骤)

    百度ai开放平台 1.百度ai开放平台内有众多功能,如文字识别,语音技术等等内容,本文章以身份证识别为例子,教大家怎么使用它啦 链接走起:https://cloud.baidu.com/?from=c ...

  8. 将文字变成语音的GUI程序(基于百度AI开放平台)【面向过程的写法】

    尝试了用Python中tkinter写了第一个GUI程序后,便想着把原来只在控制台上玩过语音合成的程序变成可以有窗口交互的GUI程序.因为有过用VB写应用系统的经验,对窗体还是有一定的认识,所以用着老 ...

  9. 百度AI开放平台和高德开放平台的使用

    目录 1.百度AI开放平台 1.1语音合成 1.2语音识别 1.3人脸识别 1.4文字识别 1.4.1手写文字识别 1.4.2 身份证识别 1.5人体检测 2.高德开放平台 2.1天气查询 2.2地理 ...

最新文章

  1. 2019年北航OO第四单元(UML任务)及学期总结
  2. unittest单元测试框架之unittest案例(二)
  3. Flutter 中获取地理位置[Flutter专题61]
  4. vue实现时间选择器,精确到秒
  5. eslint 禁用命令
  6. Spring集成:轻量级集成方法
  7. LeetCode 2064. 分配给商店的最多商品的最小值(二分查找)
  8. 设置loadrunner中每个mdrv.exe进程中包含的vuser个数
  9. 如何做一个“千里马”
  10. Git 与 Github 的使用 —— 下载单个图像或单个文件夹
  11. Fundamentals of Power Electronics 第1版第2版 pdf 资源
  12. 关闭或更改Windows自带输入法繁体简体切换(Ctrl+Shift+F)的快捷键
  13. 失意的企业家,排队和俞敏洪做直播
  14. 先吃奶油还是先吃蛋糕--推迟满足感
  15. 86u 网页服务器,路由器怎么设置DMZ_华硕RT-AC86U路由器开启DMZ方法
  16. js实现图片虚化_Web前端之高斯模糊图片记
  17. Kali linux 2016.2(Rolling)里安装OpenVAS
  18. struts2 项目构建规划 (6)
  19. 红黑树的历史和由来。
  20. ImGUI 1.87 绘制D3D外部菜单

热门文章

  1. 常见物联网无线组网方式
  2. 给我写信 wyz831201王玉镇
  3. 浅谈一下“敏捷开发”
  4. 内网渗透建立代理通道(如何攻击目标内网机器?)-Socks代理(゚益゚メ) 渗透测试
  5. Kaggle Top1% 是如何炼成的!
  6. ppurl 下载电子书
  7. 瀑布模型、迭代模型和敏捷开发
  8. 前端裁图-如何使用ps软件将矩形图片裁剪成圆角矩形
  9. iphone live photo没有声音
  10. metasploit中用shodan模块进行网络摄像头查找