-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4bd1103
commit 00bd4d7
Showing
12 changed files
with
711 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.idea | ||
config.txt | ||
test | ||
tmp_imgs | ||
test | ||
__pycache__ | ||
build | ||
dist | ||
*.spec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,72 @@ | ||
# SubExtractor-OCR | ||
|
||
> 字幕提取器-OCR版-1.0 | ||
## 简介 | ||
|
||
SubExtractor-OCR 是一款基于 OCR(Optical Character Recognition 光学字符识别)技术的视频字幕提取器。它利用 PyQT6 构建,旨在帮助用户从视频中提取视频文本字幕,从而获取视频文案。 | ||
|
||
这是一款开源自制软件,专为解决提取视频文案的烦恼而生。不再需要手动暂停视频抄录文案,字幕提取器为你助力! | ||
|
||
## 功能亮点 | ||
|
||
- **OCR 提取**: 使用光学字符识别技术从视频中提取字幕文本。 | ||
- **用户友好的界面**: 基于 PyQT6 构建,提供直观、易用的用户界面。 | ||
|
||
- **支持自定义高度区间**:设置字幕高度区间,提高适应性。 | ||
|
||
## 注意事项 | ||
|
||
好了,现在揭晓一些坏消息。由于这是字幕提取器1.0版本,一些功能尚未支持,比如批量化视频处理和自动一键完成。但是,我们已经有了改进的计划,期待未来更完美的版本。 | ||
|
||
### 为什么没有实现批量化? | ||
|
||
批量化处理涉及到复杂的业务场景,视频尺寸不一致可能导致字幕高度区间的错误。 | ||
|
||
我正在思考是否可以添加为每个视频设置字幕高度区间的功能,欢迎在评论区一起探讨。 | ||
|
||
### 开发者的心路历程 | ||
|
||
虽然功能是无限的,但我们的完美主义者一直在思考更好的方案,想为大家呈现最佳版本。当前版本虽不完美,但每个流程和函数都已实现,只是用户操作流程还需要梳理。有代码基础的同学可以尝试使用并提出建议。 | ||
|
||
### 使用方法 | ||
|
||
1. 选择视频文件。 | ||
2. 点击“视频抽帧”按钮,耐心等待抽帧完成。 | ||
3. 量取字幕的高度区间。 | ||
4. 点击后续按钮,完成后续处理。 | ||
5. 复制文案,享受提取字幕的乐趣! | ||
|
||
### 效果展示 | ||
|
||
在软件运行界面中,选择一个视频文件,点击视频抽帧按钮,即可开始操作。后续处理速度快,最终效果可在文案中查看。 | ||
|
||
### 待改进实现的方面 | ||
|
||
- 批量化自动化处理 | ||
- 单独线程处理任务而不是单线程 | ||
- 预设功能,无需每次输入高度区间 | ||
|
||
### 最后的话 | ||
|
||
感谢您使用字幕提取器-OCR版-1.0!我们将不断改进和更新,为用户提供更好的体验。有任何问题或建议,请在评论区与我们分享。希望您喜欢这个小工具,让视频文案提取更轻松愉快! | ||
|
||
字幕一般不会换行吧 | ||
|
||
就截取一行得了,不纠结那么多了 | ||
|
||
## 打包命令 | ||
|
||
`pyinstaller -w 视频字幕提取-OCR版-1.0.py -i ./logo.png` | ||
|
||
## 贡献 | ||
|
||
如果您发现任何问题或有改进建议,请提出 issue 或创建 pull 请求。我们欢迎您的贡献! | ||
|
||
## 许可证 | ||
|
||
SubExtractor-OCR 使用 [MIT 许可证](LICENSE)。 | ||
|
||
--- | ||
|
||
请注意,上述 README 只是一个示例,具体内容可能需要根据你的项目的实际情况进行修改。你可以添加更多的详细信息,例如支持的字幕格式、示例截图等。希望这个示例对你有帮助! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# -*- coding: utf-8 -*- | ||
# @Time : 2023/12/6 23:17 | ||
# @QQ : 2942581284 | ||
# @File : 01.视频抽帧.py | ||
import cv2 | ||
import os | ||
|
||
def get_video_frames(video_path=r"D:\program\剪映\导出\如何给我们的PyQt6程序制作一个炫酷的充值按钮.mp4", | ||
tmp_imgs_path='tmp_imgs'): | ||
tmp_folder_path, file_extension = os.path.splitext(os.path.basename(video_path)) | ||
folder_path=os.path.join(tmp_imgs_path, tmp_folder_path) | ||
if not os.path.exists(folder_path): | ||
os.makedirs(folder_path) | ||
# 打开视频文件 | ||
cap = cv2.VideoCapture(video_path) | ||
# 检查视频是否成功打开 | ||
if not cap.isOpened(): | ||
print("无法打开视频文件") | ||
else: | ||
# 获取视频帧数 | ||
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) | ||
print(f"视频总帧数: {total_frames}") | ||
frame_rate = int(cap.get(cv2.CAP_PROP_FPS)) | ||
print(f"视频帧率: {frame_rate} fps") | ||
# 设置帧间隔,每秒抽取一帧,1秒抽取1帧 | ||
frame_interval = frame_rate // 1 | ||
# 循环遍历视频的每一帧并保存为图像 | ||
frame_count = 0 | ||
while True: | ||
ret, frame = cap.read() | ||
if not ret: | ||
break | ||
if frame_count % frame_interval == 0: | ||
image_filename = f"frame_{frame_count:06d}.png" | ||
image_save_path=os.path.join(folder_path,image_filename) | ||
cv2.imencode(".png", frame)[1].tofile(image_save_path) | ||
print(f"保存图像:{image_filename},视频抽帧进度:{frame_count//frame_interval}/{total_frames//frame_interval}:{frame_count}/{total_frames}") | ||
frame_count += 1 | ||
cap.release() | ||
|
||
get_video_frames() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# -*- coding: utf-8 -*- | ||
# @Time : 2023/12/6 23:17 | ||
# @QQ : 2942581284 | ||
# @File : 02.裁剪图像.py | ||
import os | ||
import cv2 | ||
import numpy as np | ||
|
||
|
||
def cv_imread(file_path): | ||
cv_img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1) | ||
return cv_img | ||
|
||
|
||
# imgurl='测试.jpg' | ||
# img1 = cv_imread(imgurl) | ||
# cv2.imencode('.jpg', img1 )[1].tofile(imgurl) | ||
|
||
def cut_zimu_from_img( | ||
imgs_path=r'D:\文件夹\github_\myshare_github\Python-Project-Pro\视频文案提取-OCR字幕识别\tmp_imgs\【PyQtPySide界面美化】qt-material极简上手!'): | ||
zimu_folder_name = os.path.basename(imgs_path) + '-字幕' | ||
zimu_path = os.path.join(os.path.dirname(imgs_path), zimu_folder_name) | ||
if not os.path.exists(zimu_path): | ||
os.makedirs(zimu_path) | ||
# 获取文件夹中的所有图片文件 | ||
image_files = [f for f in os.listdir(imgs_path)] | ||
# 定义裁剪区域的坐标 (x, y, width, height) | ||
height_min = 1800 | ||
height_max = 1950 | ||
width = 3800 | ||
crop_area = (0, height_min, width, height_max - height_min) | ||
# 循环处理每个图片文件 | ||
for image_file in image_files: | ||
# 拼接图片文件的完整路径 | ||
image_path = os.path.normpath(os.path.join(imgs_path, image_file)) | ||
|
||
print(image_path) | ||
# 读取图片 | ||
image = cv_imread(image_path) | ||
# image = cv2.imread(image_path) | ||
if image is not None: | ||
# 裁剪图片 | ||
x, y, w, h = crop_area | ||
cropped_image = image[y:y + h, x:x + w] | ||
# 保存裁剪后的图片 | ||
output_file = os.path.join(zimu_path, f"cropped_{image_file}") | ||
cv2.imencode(".png", cropped_image)[1].tofile(output_file) | ||
print(f"已保存裁剪后的图片:{output_file}") | ||
else: | ||
print(f"无法读取图片:{image_path}") | ||
|
||
cut_zimu_from_img() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import os | ||
import json | ||
import time | ||
from wechat_ocr.ocr_manager import OcrManager, OCR_MAX_TASK_ID | ||
|
||
wechat_ocr_dir = r"C:\Users\86159\AppData\Roaming\Tencent\WeChat\XPlugin\Plugins\WeChatOCR\7061\extracted\WeChatOCR.exe" | ||
# wechat_ocr_dir = "C:\\Users\\Administrator\\AppData\\Roaming\\Tencent\\WeChat\\XPlugin\\Plugins\\WeChatOCR\\7057\\extracted\\WeChatOCR.exe" | ||
wechat_dir = r"D:\微信\WeChat\[3.9.8.15]" | ||
# wechat_dir = "D:\\GreenSoftware\\WeChat\\3.9.6.32" | ||
|
||
def ocr_result_callback(img_path: str, results: dict): | ||
zimu_imgs_path=os.path.dirname(img_path).replace('-字幕','-识别结果') | ||
zimu_imgs_name=os.path.basename(img_path) | ||
result_file = os.path.join(zimu_imgs_path,zimu_imgs_name)+".json" | ||
# result_file = os.path.basename(img_path) + ".json" | ||
print(f"识别成功,img_path: {img_path}, result_file: {result_file}") | ||
with open(result_file, 'w', encoding='utf-8') as f: | ||
f.write(json.dumps(results, ensure_ascii=False, indent=2)) | ||
|
||
def ocr_zimu(file_name=r'D:\文件夹\github_\myshare_github\Python-Project-Pro\视频文案提取-OCR字幕识别\tmp_imgs\如何给我们的PyQt6程序制作一个炫酷的充值按钮'): | ||
zimu_path=file_name+'-字幕' | ||
output_path=file_name+'-识别结果' | ||
if not os.path.exists(output_path): | ||
os.makedirs(output_path) | ||
ocr_manager = OcrManager(wechat_dir) | ||
# 设置WeChatOcr目录 | ||
ocr_manager.SetExePath(wechat_ocr_dir) | ||
# 设置微信所在路径 | ||
ocr_manager.SetUsrLibDir(wechat_dir) | ||
# 设置ocr识别结果的回调函数 | ||
ocr_manager.SetOcrResultCallback(ocr_result_callback) | ||
# 启动ocr服务 | ||
ocr_manager.StartWeChatOCR() | ||
# 开始识别图片 | ||
image_files = [f'{f}' for f in os.listdir(zimu_path)] | ||
for image_name in image_files: | ||
image_path=os.path.join(zimu_path,image_name) | ||
ocr_manager.DoOCRTask(image_path) | ||
# time.sleep(1) | ||
while ocr_manager.m_task_id.qsize() != OCR_MAX_TASK_ID: | ||
pass | ||
# 识别输出结果 | ||
ocr_manager.KillWeChatOCR() | ||
|
||
|
||
if __name__ == "__main__": | ||
ocr_zimu() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# -*- coding: utf-8 -*- | ||
# @Time : 2023/12/6 20:25 | ||
# @QQ : 2942581284 | ||
# @File : 提取中间字幕.py | ||
import os | ||
import json | ||
|
||
def extract_zimu_from_file(file): | ||
with open(file, 'r', encoding='utf-8') as file: | ||
data = json.load(file) | ||
zimu_width = 3800 | ||
if data: | ||
# print(data) | ||
ocrResult=data['ocrResult'] | ||
if ocrResult: | ||
ocrResult.sort(key=lambda x:-1*(x['location']['right']-x['location']['left'])) | ||
center=ocrResult[0]['location']['left']+ocrResult[0]['location']['right'] | ||
if abs(center - zimu_width) < 100: | ||
print(ocrResult[0]['text']) | ||
return ocrResult[0]['text'] | ||
else: | ||
return False | ||
|
||
def connect_center_result(file_path=r'D:\文件夹\github_\myshare_github\Python-Project-Pro\视频文案提取-OCR字幕识别\tmp_imgs\如何给我们的PyQt6程序制作一个炫酷的充值按钮'): | ||
res_list=[] | ||
zimu_path=file_path+'-识别结果' | ||
zimu_files=os.listdir(zimu_path) | ||
zimu_files.sort(key=lambda x:int(x[14:20])) | ||
for file in zimu_files: | ||
zimu_file_path=os.path.join(zimu_path,file) | ||
result=extract_zimu_from_file(zimu_file_path) | ||
if result: | ||
res_list.append(result) | ||
res_list=list(dict.fromkeys(res_list)) | ||
# res_list=handke_repeat_list(res_list) | ||
print(','.join(res_list)) | ||
|
||
connect_center_result() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
很喜欢的一段话,总有一天,你会静下心来,像个局外人一样回首自己的故事,然后笑着摇摇头,浮生不过梦一场,这个世界没有不带伤的人,无论什么时候你都要相信,真正能治愈你自己的只有自己,不去抱怨,不怕孤单,努力沉淀,世间皆苦,唯有自渡,人生很多痛苦其实都是自找的,打败我们的不是情绪,而是无法控制的想象力,想开看开,让一切顺其自然的发生 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
如何给我们的拍QT程序,加上不同的主颗,加上不同的主题,我们可以点击按钮,直接切换啊暗色或者是亮安,以及它的主题色,”界面的这些样式,微因为我们是程序员而不是心1设计师啊,微因为我们是程序员而不是心设计师啊,做出来二个四不像,”就样式不怎么好看,程序最后也没做好,发现了一个样式表,是叫做QTmaterial调,就是这里,发现一个QTmaterial,发现个QTmaterial,亡是一个我们程序的样式表,就像它这里演示明一样,就像亡这里演示的一样,可以直接切换主题的颜色什么的,还可以切换暗量,使用起来的话北常的简单,“就是首先我们安装这个三方库,就叫这个QT啊material,然后我们使用的话,扶取到APP对象,我们直接使用亡,我们直接嗯,输入一个主题的名字就可]以了,然后如何查看主题的名字呢,我们就直接嗯,他有个类似的sims方法,我们直接就可以输出这些,那比如说我们这里也亏了啊,直接运行运就会输出这此啊,但它输出,已还可以给一些类,这还可以给一些类,流加一些类名什么的,比如说这此,按钮我们可能有警告按钮,成功的按钮这些,我们只需要在这里,嗯直接选择我们的失的对象,嗯直接选择我们的类的对家,lnset property,然后将它类名添加上,然后将运类名流加上,就可]以设置不同的按钮的颜色什么的,就可以设置不同的按钮的颜色什么的,然后我这个程序呢,今号山副话¥,这个方法,就可了,当然我们也可]以就是使用运,来扶取运所有名字,我们这里一个主题按钮,也会有显示他成有时名子,然后我们点击之后就可]以切换,黄色这此,这此果的就是黑色主题,亮的就是客色主题,还是挺有趣的,用起来也是挺简单的,当然你也可以在网上,搜一些其他的主题使用 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
大家好这一期我们来看一下pyinstaller,这个工具该如何使用啊,成为一个可]执行程序的,打包之后呢,我们在没有python环境中的电脑,也可人应用我们时python脚本,协可人应用我们时python脚本,嗯他打包的话就直接使用命令行,辆八我们的的 pyinstaller,输八我们的的 pyinstaller,然后输八几个套数,这几个参数分别代表什么的,比如说我们可]以-C,就是命令行运行,不使用GUI,就是我们输入-c啊,如果我们要使用GUI程序的话,就是不使用这个控制行,我们使用-W,也就说这两个选项,-C利-w我们选一,然后剩下的呢,你可以-F,就是打包之后,我们只有一个软件,而不是多个,就是多个脚本啊,一股不建议这种,因为这种可能他运行速度比较慢,因为他是单程序啊,然后-p这些一股都用不到,我也没用到过,然后·呢,然后后面跟一个文图标文件,就可]以将我们打包后的程序的图标,改成那个图标,然后这里呢,我们有两亏了两种,两个脚本,这个呢没有使用GUI程,没有用到GUI,我们直接就是直接从命令行输入啊,我们的输八长度小于2的时候,我们可以直接会直接输出他的你好,然后可以试看打爆他,我们直接点开我们的终端,在终端中输厂,我们这个已经与好了,这个就是无命令行的和有命令行,我们的第一种没有GUI,只能使用命令行,所以我们使用,c 就是使用命令行,那么就直接复制亡,然后一个回车键,运就开始打包程序了,我们这个文件夹它会多出两个,两个文件夹一个是build和一个dist,两午文件来一个是build利一个dist,build是我们打包过程中,产生的中间文件,密存储在这个里面,运存储在这个里面,我们要看的是dist,采在打包成功之后呢,等二天我们等运打包成功之忙,等一我们等之打包成功之片,我们点开,发现民多了一个hello的文件夹,我们发现,指定个图标,我们程序的图标就变成了这个图标,然后我们双击亡,二就会快速的运行,然后消失掉,其实这个使用方法是不正确的,我们正确的使用方法是,在这里命令行输CMD,在这里命令行输入CMD,三然后我们输入我们版本的名字,苏后可以直接按佳tb建补全,再拉回车啊,然后宣就会输出我们时的,输出我们的程序,当然因为为我们是仅有那种接口,就可以自定义输入的,XM毒风以鲜,那是不是就说唉,hello WX,首先这一种昵是没有GU,哎首先这一种呢是没有GU,盛哎首先这一种呢是没有GUI,二的界面然后我们来看一下有GUI的,我们运行之先看一下效果,黑发现运是有个这样的资口对吧,那我们现在将亡打包一下哎,那我们现往将亡打包一下哎,二无有GUI时我们是使用无命令行的,然后呢直接在这里命令行,然后他就开始了,给我们这下GUlhello的打包,然后打包之后呢,勋是我们的GUIhello文件夹,不后我们就发现生成了这样的文件,我们就可以直接双击这个exe文件,然后运就会运行程序,*但是我们发现哎,这里的图标运不是我们的图标,因为我们的,之使用的是相对路径,但是我们打包的时候,没有将这个图标打包进来,所以说昵,我们需要将这个图标,给运复制进那个文件夹,这个时候我们再运行程序收,翼图标是不是就变成我们的图标了呀,这就是GUI,我们如果你可能有一些静态文件夹,他没有打包进来,蒸你将那些静态文件夹给他拖进来,然后使用的话,命名成你想要的名字,然后别人在没有拍摄环境的计算机上,直接运行这个程序 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
怠有二天你会明白,任何关系到最后只是相识一场,大家也都是阶段性的陪伴,那些你放不下的人和事,到最后岁月都会替你去轻描淡写,这个世界上从来没有盛同身受,你可以消沉、也可以抱怨,甚至可以崩渍,但一定要懂得自愈,好起来的从来不是生活,而是你自己,当你的内心足够坚定的时候,谁都没有办法影响你的心,经历越多越明白,善良有度,付出有底线,不在烂人、烂事上纠维,不滑耗自己,也绝不会委曲求全,但凡让我累点的关系,我都不会去维持,一、是没必要,就没必要互相说服,别去焦虚,鼓励自己过好今天就好,这世间有太多的猝不及防,有些东西根本不配占用你的情绪,人生匆匆,一定要过好自己的人生 |
Oops, something went wrong.