服务热线

13879170742
网站导航
主营产品:
其它
当前位置:主页 > 技术文章 > 其它 >

行车记录仪图片OCR识别

时间:2026-05-11 09:00 点击次数:
 
import os
import re
import threading
import time
from tkinter import (
    Tk, Frame, Button, Label, Entry, Text, Scrollbar,
    filedialog, StringVar, END, DISABLED, NORMAL
)
from PIL import Image
import pytesseract
 
# 【Windows 必须改成你自己的 tesseract.exe 路径】
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
 
class ImageRenameTool:
    def __init__(self, root):
        self.root = root
        self.root.title("照片时间提取批量重命名工具")
        self.root.geometry("850x650")
        
        # 状态控制
        self.folder_path = StringVar()
        self.is_running = False
        self.is_paused = False
        self.task_thread = None
        self.file_list = []
        self.current_index = 0
 
        self._init_ui()
 
    def _init_ui(self):
        # 文件夹选择
        frame_path = Frame(self.root)
        frame_path.pack(pady=10, fill="x", padx=20)
        
        Label(frame_path, text="图片文件夹:").pack(side="left")
        Entry(frame_path, textvariable=self.folder_path, width=65).pack(side="left", padx=5)
        Button(frame_path, text="选择文件夹", command=self._select_folder).pack(side="left")
 
        # 控制按钮
        frame_ctrl = Frame(self.root)
        frame_ctrl.pack(pady=10, fill="x", padx=20)
        
        self.btn_start = Button(frame_ctrl, text="开始处理", command=self._start_task, width=12)
        self.btn_start.pack(side="left", padx=5)
        
        self.btn_pause = Button(frame_ctrl, text="暂停", command=self._pause_task, width=12, state=DISABLED)
        self.btn_pause.pack(side="left", padx=5)
        
        self.btn_stop = Button(frame_ctrl, text="停止", command=self._stop_task, width=12, state=DISABLED)
        self.btn_stop.pack(side="left", padx=5)
 
        # 日志框
        frame_log = Frame(self.root)
        frame_log.pack(pady=10, fill="both", expand=True, padx=20)
        
        Label(frame_log, text="运行日志:").pack(anchor="w")
        self.log_text = Text(frame_log, height=22)
        scroll = Scrollbar(frame_log, command=self.log_text.yview)
        self.log_text.config(yscrollcommand=scroll.set)
        self.log_text.pack(side="left", fill="both", expand=True)
        scroll.pack(side="right", fill="y")
 
    def _select_folder(self):
        folder = filedialog.askdirectory()
        if folder:
            self.folder_path.set(folder)
            self._log(f"已选择:{folder}")
            exts = ('.jpg', '.jpeg', '.png', '.bmp', '.tif')
            self.file_list = [os.path.join(folder, f) for f in os.listdir(folder) if f.lower().endswith(exts)]
            self._log(f"找到 {len(self.file_list)} 张图片")
 
    def _log(self, msg):
        t = time.strftime("%Y-%m-%d %H:%M:%S")
        self.log_text.insert(END, f"[{t}] {msg}\n")
        self.log_text.see(END)
        self.root.update_idletasks()
 
    def _extract_time(self, path):
        try:
            img = Image.open(path).convert('L')
            text = pytesseract.image_to_string(img, lang='eng')
            # 匹配日期时间:2025-01-01 12:34:56 / 2025/01/01 12:34:56
            match = re.search(r'(\d{4}[-/]\d{1,2}[-/]\d{1,2}[\sT]\d{1,2}:\d{1,2}:\d{1,2})', text)
            if match:
                raw = match.group(1)
                clean = re.sub(r'[^0-9]', '', raw)
                if len(clean) >= 14:
                    return clean[:14]
                return clean
            return None
        except:
            return None
 
    def _rename(self, old_path, time_str):
        try:
            dirname = os.path.dirname(old_path)
            ext = os.path.splitext(old_path)[1]
            new_name = f"{time_str}{ext}"
            new_path = os.path.join(dirname, new_name)
            i = 1
            while os.path.exists(new_path):
                new_name = f"{time_str}_{i}{ext}"
                new_path = os.path.join(dirname, new_name)
                i += 1
            os.rename(old_path, new_path)
            return True, new_name
        except Exception as e:
            return False, str(e)
 
    def _worker(self):
        total = len(self.file_list)
        self._log(f"开始处理,共 {total} 个文件")
        while self.current_index < total and self.is_running:
            if self.is_paused:
                time.sleep(0.3)
                continue
            path = self.file_list[self.current_index]
            self._log(f"处理:{os.path.basename(path)}")
            t = self._extract_time(path)
            if t:
                ok, name = self._rename(path, t)
                if ok:
                    self._log(f"→ 重命名为:{name}")
                else:
                    self._log(f"→ 重命名失败:{name}")
            else:
                self._log("→ 未识别到时间,跳过")
            self.current_index += 1
            time.sleep(0.1)
        if self.is_running:
            self._log("✅ 全部处理完成")
        else:
            self._log("⏹️  任务已停止")
        self.is_running = False
        self.btn_start.config(state=NORMAL)
        self.btn_pause.config(state=DISABLED)
        self.btn_stop.config(state=DISABLED)
 
    def _start_task(self):
        if not self.folder_path.get():
            self._log("⚠️ 请先选择文件夹")
            return
        self.is_running = True
        self.is_paused = False
        self.current_index = 0
        self.btn_start.config(state=DISABLED)
        self.btn_pause.config(state=NORMAL)
        self.btn_stop.config(state=NORMAL)
        self.task_thread = threading.Thread(target=self._worker, daemon=True)
        self.task_thread.start()
 
    def _pause_task(self):
        if not self.is_running:
            return
        self.is_paused = not self.is_paused
        self.btn_pause.config(text="恢复" if self.is_paused else "暂停")
        self._log("⏸️ 已暂停" if self.is_paused else "▶️ 已恢复")
 
    def _stop_task(self):
        self.is_running = False
        self.is_paused = False
        self.btn_start.config(state=NORMAL)
        self.btn_pause.config(state=DISABLED)
        self.btn_stop.config(state=DISABLED)
        self._log("⏹️  正在停止...")
 
if __name__ == "__main__":
    root = Tk()
    app = ImageRenameTool(root)
    root.mainloop()



运行:pip install pillow pytesseract
安装 Tesseract-OCR
把上面代码复制运行
完美使用:窗口界面 + 批量提取时间 + 重命名 + 暂停 + 停止 + 日志






import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import threading
import win32file
import win32api
import os
import time
 
# JPG 固定特征码
JPG_START = b'\xff\xd8\xff'
JPG_END = b'\xff\xd9'
# 保存路径
SAVE_PATH = r"D:\11"
 
class JpgRecoveryTool:
    def __init__(self, root):
        self.root = root
        self.root.title("磁盘底层JPG恢复工具 - 管理员运行")
        self.root.geometry("750x550")
        self.root.resizable(False, False)
 
        # 运行控制变量
        self.running = False
        self.paused = False
        self.stop_flag = False
        self.scan_thread = None
 
        # 创建界面
        self.create_widgets()
        # 自动扫描物理磁盘
        self.scan_physical_disks()
 
    def create_widgets(self):
        # 顶部:磁盘选择区域
        frame_disk = tk.Frame(self.root, pady=10)
        frame_disk.pack(fill=tk.X, padx=10)
 
        tk.Label(frame_disk, text="选择物理磁盘:", font=("微软雅黑", 10)).pack(side=tk.LEFT, padx=5)
        self.disk_var = tk.StringVar()
        self.disk_combo = ttk.Combobox(frame_disk, textvariable=self.disk_var, width=50, state="readonly")
        self.disk_combo.pack(side=tk.LEFT, padx=5)
 
        # 中间:按钮控制区
        frame_btn = tk.Frame(self.root, pady=5)
        frame_btn.pack(fill=tk.X, padx=10)
 
        self.start_btn = tk.Button(frame_btn, text="开始扫描", width=12, command=self.start_scan, bg="#4CAF50", fg="white")
        self.start_btn.pack(side=tk.LEFT, padx=5)
 
        self.pause_btn = tk.Button(frame_btn, text="暂停", width=12, command=self.pause_scan, bg="#FFC107", state=tk.DISABLED)
        self.pause_btn.pack(side=tk.LEFT, padx=5)
 
        self.stop_btn = tk.Button(frame_btn, text="停止", width=12, command=self.stop_scan, bg="#F44336", fg="white", state=tk.DISABLED)
        self.stop_btn.pack(side=tk.LEFT, padx=5)
 
        # 日志显示区域
        tk.Label(self.root, text="运行日志:", font=("微软雅黑", 10), anchor="w").pack(fill=tk.X, padx=10, pady=(5, 0))
        self.log_text = scrolledtext.ScrolledText(self.root, width=90, height=28, font=("Consolas", 9))
        self.log_text.pack(padx=10, pady=5)
 
    # 自动获取本机物理磁盘
    def scan_physical_disks(self):
        disks = []
        for i in range(16):  # 扫描0-15号物理磁盘
            try:
                disk_path = f"\\\\.\\PhysicalDrive{i}"
                # 测试是否能打开
                handle = win32file.CreateFile(
                    disk_path, win32file.GENERIC_READ,
                    win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
                    None, win32file.OPEN_EXISTING, 0, None
                )
                if handle != win32file.INVALID_HANDLE_VALUE:
                    disks.append(f"物理磁盘{i} - {disk_path}")
                    win32file.CloseHandle(handle)
            except:
                continue
        self.disk_combo["values"] = disks
        if disks:
            self.disk_combo.current(0)
            self.log(f"✅ 找到 {len(disks)} 个物理磁盘")
        else:
            self.log("❌ 未找到物理磁盘,请以管理员身份运行!")
 
    # 日志输出
    def log(self, msg):
        current_time = time.strftime("%H:%M:%S")
        self.log_text.insert(tk.END, f"[{current_time}] {msg}\n")
        self.log_text.see(tk.END)
        self.root.update()
 
    # 开始扫描
    def start_scan(self):
        if not self.disk_var.get():
            messagebox.showerror("错误", "请先选择磁盘!")
            return
        # 创建保存目录
        if not os.path.exists(SAVE_PATH):
            os.makedirs(SAVE_PATH)
        # 按钮状态
        self.start_btn.config(state=tk.DISABLED)
        self.pause_btn.config(state=tk.NORMAL)
        self.stop_btn.config(state=tk.NORMAL)
        # 重置状态
        self.running = True
        self.paused = False
        self.stop_flag = False
        # 启动线程
        self.scan_thread = threading.Thread(target=self.do_scan, daemon=True)
        self.scan_thread.start()
 
    # 暂停/继续
    def pause_scan(self):
        if not self.running:
            return
        if not self.paused:
            self.paused = True
            self.pause_btn.config(text="继续")
            self.log("⏸ 扫描已暂停")
        else:
            self.paused = False
            self.pause_btn.config(text="暂停")
            self.log("▶ 扫描继续")
 
    # 停止扫描
    def stop_scan(self):
        if not self.running:
            return
        self.stop_flag = True
        self.running = False
        self.paused = False
        self.log("⏹ 手动停止扫描")
        self.reset_buttons()
 
    # 重置按钮
    def reset_buttons(self):
        self.start_btn.config(state=tk.NORMAL)
        self.pause_btn.config(state=tk.DISABLED, text="暂停")
        self.stop_btn.config(state=tk.DISABLED)
 
    # 核心:磁盘裸扇区读取 + JPG搜索
    def do_scan(self):
        disk_path = self.disk_var.get().split(" - ")[-1]
        self.log(f"

上一篇:windows 计算机名称 注册表里查看

下一篇:没有了

Copyright © 2002-2020 南昌伟航数据恢复 版权所有  备案号:赣ICP备14010646-1号, 赣公网安备 36010302000054号

地址:江西省南昌市西湖区八一大道新大地2号楼3楼320(地铁2号线永叔路口2出口) 电话:13879170742 邮箱:827981817@qq.com

关注我们

服务热线

13879170742

扫一扫,关注我们