本文目录导读:

我来详细介绍如何编写手写文字识别脚本,包括多种实现方案:
使用Tesseract OCR(最简单的方案)
安装准备
# 安装Tesseract pip install pytesseract pillow # Windows需要下载安装Tesseract # https://github.com/UB-Mannheim/tesseract/wiki
基础脚本
import pytesseract
from PIL import Image
import cv2
import numpy as np
def preprocess_image(image_path):
"""图像预处理"""
# 读取图像
img = cv2.imread(image_path)
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化处理
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 降噪
denoised = cv2.medianBlur(thresh, 3)
return denoised
def recognize_handwriting(image_path):
"""识别手写文字"""
# 预处理图像
processed_img = preprocess_image(image_path)
# 配置Tesseract参数
custom_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
# 识别文字
text = pytesseract.image_to_string(
processed_img,
lang='chi_sim+eng', # 中文+英文
config=custom_config
)
return text.strip()
# 使用示例
result = recognize_handwriting('handwriting.jpg')
print(f"识别结果: {result}")
使用深度学习模型(高精度方案)
使用PaddleOCR
# 安装PaddleOCR
# pip install paddlepaddle paddleocr
from paddleocr import PaddleOCR
# 初始化OCR
ocr = PaddleOCR(
use_angle_cls=True, # 使用方向分类
lang='ch', # 中文识别
use_gpu=False # 是否使用GPU
)
def recognize_with_paddle(image_path):
"""使用PaddleOCR识别手写文字"""
result = ocr.ocr(image_path, cls=True)
text_result = []
for line in result:
for word_info in line:
text = word_info[1][0] # 文字内容
confidence = word_info[1][1] # 置信度
text_result.append({
'text': text,
'confidence': confidence
})
return text_result
# 使用示例
results = recognize_with_paddle('handwriting.jpg')
for item in results:
print(f"文字: {item['text']}, 置信度: {item['confidence']:.2f}")
使用EasyOCR
# pip install easyocr
import easyocr
# 初始化识别器
reader = easyocr.Reader(['ch_sim', 'en']) # 中英文
def recognize_with_easyocr(image_path):
"""使用EasyOCR识别"""
results = reader.readtext(image_path)
text_result = []
for (bbox, text, confidence) in results:
text_result.append({
'text': text,
'confidence': confidence,
'bbox': bbox
})
return text_result
# 使用示例
results = recognize_with_easyocr('handwriting.jpg')
for item in results:
print(f"文字: {item['text']}, 置信度: {item['confidence']:.2f}")
完整的GUI应用
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import pytesseract
import cv2
import numpy as np
class HandwritingRecognizer:
def __init__(self, root):
self.root = root
self.root.title("手写文字识别工具")
self.root.geometry("800x600")
# 创建界面组件
self.create_widgets()
def create_widgets(self):
# 选择图片按钮
self.btn_select = tk.Button(
self.root,
text="选择图片",
command=self.select_image
)
self.btn_select.pack(pady=10)
# 图片显示区域
self.label_image = tk.Label(self.root)
self.label_image.pack(pady=10)
# 识别按钮
self.btn_recognize = tk.Button(
self.root,
text="识别文字",
command=self.recognize_text,
state=tk.DISABLED
)
self.btn_recognize.pack(pady=5)
# 结果显示
self.text_result = tk.Text(self.root, height=10, width=60)
self.text_result.pack(pady=10)
# 复制按钮
self.btn_copy = tk.Button(
self.root,
text="复制结果",
command=self.copy_result
)
self.btn_copy.pack(pady=5)
def select_image(self):
file_path = filedialog.askopenfilename(
filetypes=[("Image files", "*.jpg *.jpeg *.png *.bmp")]
)
if file_path:
self.image_path = file_path
# 显示图片
image = Image.open(file_path)
image.thumbnail((400, 300))
photo = ImageTk.PhotoImage(image)
self.label_image.config(image=photo)
self.label_image.image = photo
self.btn_recognize.config(state=tk.NORMAL)
def recognize_text(self):
if hasattr(self, 'image_path'):
try:
# 图像预处理
img = cv2.imread(self.image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(
gray, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU
)
# 识别文字
text = pytesseract.image_to_string(thresh, lang='chi_sim+eng')
# 显示结果
self.text_result.delete(1.0, tk.END)
self.text_result.insert(1.0, text.strip())
except Exception as e:
messagebox.showerror("错误", f"识别失败:{str(e)}")
def copy_result(self):
text = self.text_result.get(1.0, tk.END).strip()
if text:
self.root.clipboard_clear()
self.root.clipboard_append(text)
messagebox.showinfo("成功", "结果已复制到剪贴板")
# 运行应用
if __name__ == "__main__":
root = tk.Tk()
app = HandwritingRecognizer(root)
root.mainloop()
批量处理脚本
import os
from pathlib import Path
import pandas as pd
def batch_recognize(input_folder, output_file):
"""批量识别手写文字"""
results = []
# 支持的文件格式
image_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff'}
# 遍历文件夹
for image_path in Path(input_folder).iterdir():
if image_path.suffix.lower() in image_extensions:
try:
text = recognize_handwriting(str(image_path))
results.append({
'filename': image_path.name,
'text': text,
'status': '成功'
})
print(f"处理完成: {image_path.name}")
except Exception as e:
results.append({
'filename': image_path.name,
'text': '',
'status': f'失败: {str(e)}'
})
# 保存到Excel
df = pd.DataFrame(results)
df.to_excel(output_file, index=False)
print(f"结果已保存到: {output_file}")
# 使用示例
batch_recognize('handwriting_images/', 'recognition_results.xlsx')
图像预处理优化
def advanced_preprocess(image_path):
"""高级图像预处理"""
img = cv2.imread(image_path)
# 1. 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. 自适应阈值
binary = cv2.adaptiveThreshold(
gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2
)
# 3. 去噪声
kernel = np.ones((1, 1), np.uint8)
opening = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
# 4. 边缘增强
laplacian = cv2.Laplacian(gray, cv2.CV_64F)
sharpened = cv2.convertScaleAbs(gray - 0.5 * laplacian)
# 5. 扭曲校正
coords = np.column_stack(np.where(binary > 0))
angle = cv2.minAreaRect(coords)[-1]
if angle < -45:
angle = 90 + angle
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated = cv2.warpAffine(
gray, M, (w, h),
flags=cv2.INTER_CUBIC,
borderMode=cv2.BORDER_REPLICATE
)
return rotated
性能优化建议
def optimize_recognition(image_path):
"""优化识别流程"""
# 1. 区域检测(只识别文字区域)
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用MSER检测文字区域
mser = cv2.MSER_create()
regions, _ = mser.detectRegions(gray)
# 合并邻近区域
hulls = [cv2.convexHull(p.reshape(-1, 1, 2)) for p in regions]
# 2. 裁剪并识别每个区域
results = []
for hull in hulls:
x, y, w, h = cv2.boundingRect(hull)
roi = gray[y:y+h, x:x+w]
# 只识别大于最小尺寸的区域
if w > 20 and h > 20:
text = pytesseract.image_to_string(roi, config='--psm 8')
if text.strip():
results.append(text.strip())
return ' '.join(results)
选择建议
- 快速上手:使用Tesseract OCR
- 精度要求高:使用PaddleOCR或EasyOCR
- 需要GUI:使用tkinter创建应用
- 批量处理:使用文件夹遍历处理
- 中文识别:PaddleOCR效果最好
根据你的具体需求选择合适的方案,需要更详细的实现说明吗?