本文简述了利用OpenCV库以及PaddleOCR库对视频预定位置进行字幕提取并整合识别,在实际工程中,可以调用OCR的识别输出接口进行识别内容的批量保存。
后续改进方向参考:
1.PaddleNLP进行识别文本纠错。
2.选取合适的方式做到字幕截取不重不漏:
简便思路可以采用高密度切图的方式,重复识别的文字内容在后续进行去重。而实际应用中应当采用识别前预处理的方式,从而减少重复识别带来的时间消耗。
切图后文字识别前的去重方式,可以参考我的另一篇图像相似度判别的小文章,主要原理是采用图像HASH值判别相似度的方式。
3.针对不同视频可以自动选择不同的字幕位置。
4.当字幕质量较低,如没有浅灰色背景条衬托时,简单二值化处理是否能继续适用的探讨。
一、参考内容
1:PaddleOCR
二、部分代码及思路
1:本demo所需的库
import os
from cv2 import cv2
from PIL import Image
from paddleocr import PaddleOCR, draw_ocr
2:视频字幕示例
可以看到字幕部分存在部分其他文字干扰,不建议整帧识别。本demo不涉及字幕位置判断的相应功能,而是直接截取字幕位置进行处理,效果如下。
但是实际OCR识别时,会被背景文字所干扰,我们还需要调用CV库中二值化函数进行筛选处理,效果如下:
此时肉眼观察效果较好,但是直接进行OCR识别会出现“拆字”的问题,原因可能为图片过于细长,不适合预训练好的图片参数,而且考虑到每行字幕均会参与识别,OCR调用频率过高的问题,尝试将字幕进行上下拼接
for i in range(3, 10):
i = i * 700 # i代表随便抽取的某些帧
videoCap.set(cv2.CAP_PROP_POS_FRAMES, i) # 设置要获取的帧号
TorF, frame = videoCap.read()
# 直接截取字幕所在位置,效果如上图
np_img = frame[870:955, :]
# 将字幕段进行颜色处理,未达到阈值的颜色将会变为白色背景
retVal, bw_img = cv2.threshold(np_img, 245, 245, cv2.THRESH_BINARY_INV)
np_pic_list.append(bw_img)
拼接效果如下,经过拼接的图片调用识别函数,可以达到事半功倍的效果。
识别效果如下,准确率较高。测试句子中“干旱”变为“干早”,其实paddleNLP库中也有文本纠错功能,可以尝试后续添加相应预训练集以及相关功能函数进行识别错误纠正。
三、demo源码
import os
from cv2 import cv2
from PIL import Image
from paddleocr import PaddleOCR, draw_ocr
# 读入视频
video_filename = r'F:\pycharm_project\OCR\video\demo.mp4'
videoCap = cv2.VideoCapture(video_filename)
# 切换图片保存目录
os.chdir(r'F:\pycharm_project\OCR\pics')
np_pic_list = []
for i in range(3, 10):
i = i * 700 # i代表随便抽取的某些帧
videoCap.set(cv2.CAP_PROP_POS_FRAMES, i) # 设置要获取的帧号
TorF, frame = videoCap.read() # read方法返回一个布尔值和一个视频帧
# im = frame[:, :, 0] # 显示全图
# 确定字幕的范围,这里仅针对该视频作展示实际情况需要更改
np_img = frame[870:955, :]
# 实现array到image的转换
# oir_pic = Image.fromarray(np_img)
# 这里颜色会出现改变,问题应该是RGB与BGR编码格式变化引起的
# oir_pic.save('pic_' + str(i) + '.jpg')
# 将字幕段进行颜色处理,未达到阈值的颜色将会变为白色背景
retVal, bw_img = cv2.threshold(np_img, 245, 245, cv2.THRESH_BINARY_INV)
# 逐段追加
np_pic_list.append(bw_img)
# 垂直拼接并保存成一张图
Image.fromarray(cv2.vconcat(np_pic_list)).save('result_1.jpg')
# 调用paddleOCR接口
ocr = PaddleOCR(use_angle_cls=True, lang="ch")
img_path = r'F:\pycharm_project\OCR\pics\result_1.jpg'
result = ocr.ocr(img_path, cls=True)
for line in result:
print(line)
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]
im_show = draw_ocr(image, boxes, txts, scores, font_path='/path/to/PaddleOCR/doc/simfang.ttf')
im_show = Image.fromarray(im_show)
im_show.save('result_2.jpg')