使用Tesseract OCR提取视频文本出现重复内容,如何获取精准完整文本?
视频OCR重复文本问题解决方案
问题根因
你当前的代码是按固定帧率抽取所有帧进行OCR,视频中静态的文本内容(比如字幕、固定展示的界面文字)会在连续多帧中存在,所以会被重复识别,导致结果出现大量重复内容。
具体解决步骤
- 新增帧相似度校验:只对内容变化超过阈值的帧做OCR,跳过内容几乎没有变化的静态帧,从源头上减少重复识别的可能
- 新增OCR结果相似度校验:新识别出的文本和上一次保留的文本做相似度比对,只有相似度低于阈值才存入结果列表,避免识别误差导致的轻度重复
- 新增OCR图像预处理:提前对帧做灰度化、二值化、去噪处理,提升识别准确率,减少无效内容输出
修改后的可运行代码
import cv2 import os import pytesseract import numpy as np from difflib import SequenceMatcher # 配置参数 pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' FRAME_RATE = 2 # 帧差异阈值,低于该值认为是静态帧,不做OCR FRAME_SIMILARITY_THRESHOLD = 0.95 # 文本相似度阈值,高于该值认为是重复文本,不存入结果 TEXT_SIMILARITY_THRESHOLD = 0.8 # 预处理后的图像保存路径,提前创建目录 IMAGE_SAVE_PATH = './images/' os.makedirs(IMAGE_SAVE_PATH, exist_ok=True) def calculate_frame_similarity(frame1, frame2): # 计算两帧的结构相似性,返回相似度0-1 gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY) gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY) res = cv2.matchTemplate(gray1, gray2, cv2.TM_CCOEFF_NORMED) return res[0][0] def calculate_text_similarity(text1, text2): # 计算两段文本的相似度 return SequenceMatcher(None, text1.strip(), text2.strip()).ratio() def preprocess_image(frame): # OCR前图像预处理:灰度化、二值化、去噪 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 自适应阈值二值化 thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 去噪 denoise = cv2.medianBlur(thresh, 3) return denoise if __name__ == '__main__': video_data = cv2.VideoCapture(r"jonty.mp4") video_length= int(video_data.get(cv2.CAP_PROP_FRAME_COUNT)) - 1 fps=int(video_data.get(cv2.CAP_PROP_FPS)) print(f"总帧数: {video_length}, 视频原始FPS: {fps}, 抽帧帧率: {FRAME_RATE}") text_data=[] frame_time = 0 frame_count = 0 last_frame = None last_text = "" while True: # 原代码的10000是错误的,毫秒换算应该乘以1000 video_data.set(cv2.CAP_PROP_POS_MSEC, frame_time * 1000) frame_time += 1/FRAME_RATE ret, frame = video_data.read() if not ret: break # 第一帧直接处理,后面的帧先做相似度判断 if last_frame is not None: frame_similarity = calculate_frame_similarity(frame, last_frame) if frame_similarity >= FRAME_SIMILARITY_THRESHOLD: # 帧内容变化太小,跳过处理 continue # 更新上一帧 last_frame = frame.copy() # 图像预处理 processed_frame = preprocess_image(frame) # 保存帧 image_path = os.path.join(IMAGE_SAVE_PATH, f'frame{frame_count}.jpg') cv2.imwrite(image_path, processed_frame) # OCR识别 text = pytesseract.image_to_string(processed_frame, lang='eng+deu+fra').strip() # 文本非空且和上一次保留的文本相似度低于阈值才保存 if text and calculate_text_similarity(text, last_text) < TEXT_SIMILARITY_THRESHOLD: text_data.append(text) last_text = text frame_count += 1 # 资源释放 video_data.release() cv2.destroyAllWindows() # 输出最终结果 final_text = "\n".join(text_data) print("最终提取文本:\n", final_text)
参数调整说明
- 如果还是有较多重复,可以适当调低
TEXT_SIMILARITY_THRESHOLD,或者调高FRAME_SIMILARITY_THRESHOLD - 如果出现漏识别的情况,可以适当调高
TEXT_SIMILARITY_THRESHOLD,或者调低FRAME_SIMILARITY_THRESHOLD
内容的提问来源于stack exchange,提问作者Sandesh Chand
相关产品推荐
相关产品推荐

