2025年6月4日 星期三 乙巳(蛇)年 三月初八 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

一个python写的可视化本地处理的OCR

时间:01-11来源:作者:点击数:32

可以单个处理图片,也可以选择文件夹批量处理,完全本地cpu处理

需要用到的python库

  • pip install PyQt5
  • pip install opencv-python
  • pip install paddleocr
  • pip install numpy
  • pip install pillow
  • pip install pyperclip

python版本 3.8或者3.9

python下载地址:https://www.python.org/downloads/windows/

python代码

  • import sys
  • import os
  • from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QFileDialog, QTextEdit, QLabel, QMessageBox, QProgressBar
  • from PyQt5.QtGui import QPixmap, QImage
  • from PyQt5.QtCore import Qt, QThread, pyqtSignal
  • import cv2
  • from paddleocr import PaddleOCR
  • import numpy as np
  • from PIL import Image
  • import pyperclip
  • class OCRThread(QThread):
  • progress_update = pyqtSignal(int)
  • result_ready = pyqtSignal(list)
  • def __init__(self, ocr, file_list):
  • super().__init__()
  • self.ocr = ocr
  • self.file_list = file_list
  • def run(self):
  • results = []
  • for i, file in enumerate(self.file_list):
  • try:
  • result = self.ocr.ocr(file, cls=True)
  • results.append((os.path.basename(file), result))
  • except Exception as e:
  • results.append((os.path.basename(file), None))
  • print(f"处理文件 {file} 时出错: {str(e)}")
  • self.progress_update.emit(int((i + 1) / len(self.file_list) * 100))
  • self.result_ready.emit(results)
  • class OCRApp(QMainWindow):
  • def __init__(self):
  • super().__init__()
  • self.initUI()
  • self.ocr = PaddleOCR(use_angle_cls=True, lang="ch")
  • self.current_image = None
  • def initUI(self):
  • self.setWindowTitle('OCR应用')
  • fixed_width = 400
  • fixed_height = 500
  • self.setFixedSize(fixed_width, fixed_height)
  • central_widget = QWidget()
  • self.setCentralWidget(central_widget)
  • main_layout = QVBoxLayout()
  • central_widget.setLayout(main_layout)
  • self.image_label = QLabel(self)
  • self.image_label.setAlignment(Qt.AlignCenter)
  • self.image_label.setFixedSize(fixed_width - 20, 200)
  • main_layout.addWidget(self.image_label)
  • button_layout = QHBoxLayout()
  • self.open_file_button = QPushButton('选择图片', self)
  • self.open_file_button.clicked.connect(self.open_file)
  • button_layout.addWidget(self.open_file_button)
  • self.open_folder_button = QPushButton('选择文件夹', self)
  • self.open_folder_button.clicked.connect(self.open_folder)
  • button_layout.addWidget(self.open_folder_button)
  • self.copy_button = QPushButton('复制内容', self)
  • self.copy_button.clicked.connect(self.copy_content)
  • button_layout.addWidget(self.copy_button)
  • main_layout.addLayout(button_layout)
  • self.progress_bar = QProgressBar(self)
  • self.progress_bar.setVisible(False)
  • main_layout.addWidget(self.progress_bar)
  • self.result_text = QTextEdit(self)
  • self.result_text.setReadOnly(True)
  • main_layout.addWidget(self.result_text)
  • def open_file(self):
  • file_name, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "图片文件 (*.png *.jpg *.bmp)")
  • if file_name:
  • self.process_image(file_name)
  • def open_folder(self):
  • directory = QFileDialog.getExistingDirectory(self, "选择文件夹")
  • if directory:
  • files = [os.path.join(directory, f) for f in os.listdir(directory) if f.lower().endswith(('.png', '.jpg', '.bmp'))]
  • if files:
  • self.process_multiple_images(files)
  • else:
  • QMessageBox.warning(self, "提示", "文件夹中没有符合条件的图片文件。")
  • def process_image(self, file_name):
  • self.current_image = cv2.imread(file_name)
  • if self.current_image is None:
  • QMessageBox.warning(self, "错误", "无法加载图片,文件可能已损坏或格式不支持。")
  • return
  • self.display_image(self.current_image)
  • try:
  • result = self.ocr.ocr(file_name, cls=True)
  • self.display_result([(os.path.basename(file_name), result)])
  • except Exception as e:
  • QMessageBox.warning(self, "错误", f"OCR处理失败: {str(e)}")
  • def process_multiple_images(self, files):
  • self.progress_bar.setVisible(True)
  • self.progress_bar.setValue(0)
  • self.ocr_thread = OCRThread(self.ocr, files)
  • self.ocr_thread.progress_update.connect(self.update_progress)
  • self.ocr_thread.result_ready.connect(self.display_result)
  • self.ocr_thread.start()
  • def update_progress(self, value):
  • self.progress_bar.setValue(value)
  • def display_image(self, img):
  • height, width, channel = img.shape
  • bytes_per_line = 3 * width
  • q_img = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
  • pixmap = QPixmap.fromImage(q_img)
  • label_width = self.image_label.width()
  • label_height = self.image_label.height()
  • scale = min(label_width / width, label_height / height)
  • new_width = int(width * scale)
  • new_height = int(height * scale)
  • scaled_pixmap = pixmap.scaled(new_width, new_height, Qt.KeepAspectRatio, Qt.SmoothTransformation)
  • self.image_label.setPixmap(scaled_pixmap)
  • def display_result(self, results):
  • self.result_text.clear()
  • for file_name, result in results:
  • self.result_text.append(f"文件: {file_name}")
  • if result and len(result) > 0 and result[0]:
  • try:
  • sorted_result = sorted(result[0], key=lambda x: (x[0][0][1], x[0][0][0]))
  • for line in sorted_result:
  • text = line[1][0]
  • self.result_text.append(text)
  • except Exception as e:
  • self.result_text.append(f"解析结果时出错: {str(e)}")
  • else:
  • self.result_text.append("未识别到文本")
  • self.result_text.append("\n")
  • self.progress_bar.setVisible(False)
  • if len(results) > 1:
  • QMessageBox.information(self, "完成", f"已完成 {len(results)} 个文件的识别")
  • def copy_content(self):
  • content = self.result_text.toPlainText()
  • pyperclip.copy(content)
  • QMessageBox.information(self, "提示", "内容已复制到剪贴板")
  • if __name__ == '__main__':
  • app = QApplication(sys.argv)
  • ex = OCRApp()
  • ex.show()
  • sys.exit(app.exec_())

 

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐