GLM-OCR模型训练数据准备Python脚本批量处理与标注文件生成1. 引言想训练一个能看懂自家产品说明书、识别特定票据、或者读懂手写笔记的OCR模型吗通用模型虽然强大但面对五花八门的字体、独特的排版或者模糊的拍摄环境往往就有点力不从心了。这时候为自己的垂直场景定制一个GLM-OCR模型就成了一个非常实际的选择。而定制化训练的第一步也是最关键、最耗时的一步就是准备高质量的训练数据。这就像教一个孩子认字你得先给他准备好清晰、多样的字帖。今天我们就来聊聊怎么用Python脚本把一堆原始图片变成GLM-OCR模型能“吃”得下的标准“口粮”。这篇文章的目标很直接手把手带你搞定数据准备的整个流程。我们会从最基础的图片裁剪开始到用一些简单技巧增强数据的多样性最后生成模型需要的标注文件。整个过程我都会配上可以直接运行的Python代码哪怕你刚接触Python跟着做也能跑通。准备好了吗我们开始吧。2. 准备工作与环境搭建在动手写脚本之前我们得先把“厨房”收拾好把需要的“食材”和“工具”备齐。2.1 你需要准备什么原始图片这是你的核心素材。可以是手机拍的、扫描的或者从网上下载的。建议先统一放到一个文件夹里比如叫做raw_images。标注信息每张图片里文字的位置和内容是什么初期你可能需要手动标注一些或者利用现有工具如LabelImg、PPOCRLabel先产生一个基础版本。我们假设你已经有了一份初步的标注格式可能是每张图片对应一个.txt文件里面记录了文字框的坐标和文本内容。Python环境确保你的电脑上安装了Python3.7或以上版本。打开命令行输入python --version检查一下。2.2 安装必要的Python库我们需要几个强大的帮手来处理图片和文件。打开你的命令行终端Windows上是CMD或PowerShellMac/Linux上是Terminal依次输入下面的命令来安装它们pip install Pillow opencv-python numpy tqdm简单解释一下这几个库是干什么的Pillow (PIL)Python里处理图片的老牌主力功能全面接口友好。opencv-python (cv2)计算机视觉的瑞士军刀在图像处理、增强方面非常高效。numpyPython科学计算的基础高效处理数组我们的图片数据就是数组。tqdm一个能给你的循环加上美观进度条的小工具处理大量文件时特别有用让你知道程序跑到哪了。安装成功后我们就可以进入正题了。3. 第一步批量裁剪与区域提取拿到一张包含文字的图片我们通常不需要整张图只需要把有文字的区域精准地“抠”出来。这一步能有效减少无关背景的干扰让模型更专注于文字本身。3.1 读取标注与基础裁剪假设我们的标注文件是类似这样的image_001.txtx1,y1,x2,y2,x3,y3,x4,y4,text 100,50,300,50,300,150,100,150,产品名称 50,200,250,200,250,300,50,300,规格参数这表示有两个文本框每个用四个点的坐标通常是左上、右上、右下、左下和文本内容来定义。我们来写一个脚本根据这些坐标把文字区域裁剪出来import os from PIL import Image import numpy as np from tqdm import tqdm def crop_text_regions(image_dir, label_dir, output_dir): 根据标注文件裁剪图片中的文字区域。 参数: image_dir: 原始图片文件夹路径 label_dir: 标注文件(.txt)文件夹路径 output_dir: 裁剪后图片的输出文件夹路径 # 创建输出目录 os.makedirs(output_dir, exist_okTrue) # 获取所有图片文件 image_files [f for f in os.listdir(image_dir) if f.lower().endswith((.png, .jpg, .jpeg, .bmp))] # 使用tqdm显示进度条 for img_file in tqdm(image_files, desc正在裁剪图片): img_path os.path.join(image_dir, img_file) label_path os.path.join(label_dir, os.path.splitext(img_file)[0] .txt) # 如果对应的标注文件不存在则跳过 if not os.path.exists(label_path): continue # 打开图片 image Image.open(img_path) img_width, img_height image.size # 读取标注文件 with open(label_path, r, encodingutf-8) as f: lines f.readlines() for idx, line in enumerate(lines): parts line.strip().split(,) if len(parts) 9: # 确保有足够的坐标和文本 continue # 解析坐标最后一部分是文本 coords list(map(int, parts[:8])) text parts[8] # 从8个坐标点中找出最小和最大的x、y值确定裁剪矩形框 xs coords[0::2] # 所有x坐标 ys coords[1::2] # 所有y坐标 left, top max(0, min(xs)), max(0, min(ys)) right, bottom min(img_width, max(xs)), min(img_height, max(ys)) # 确保区域有效 if right left or bottom top: continue # 裁剪区域 region image.crop((left, top, right, bottom)) # 生成输出文件名原图名_序号_部分文本.jpg safe_text text[:20].replace(/, _).replace(\\, _) # 防止非法字符 output_filename f{os.path.splitext(img_file)[0]}_{idx}_{safe_text}.jpg output_path os.path.join(output_dir, output_filename) # 保存裁剪后的图片 region.save(output_path) # 这里可以先不保存标注我们后面统一生成 # 但可以记录下信息比如把文本内容写在文件名里或者存到一个临时列表 print(f裁剪完成图片已保存至: {output_dir}) # 使用示例 if __name__ __main__: crop_text_regions( image_dir./raw_images, label_dir./raw_labels, output_dir./cropped_images )运行这个脚本你的cropped_images文件夹里就会充满一个个干净的文字区域小图了。4. 第二步数据增强——让数据“变”出花样如果只有几百张裁剪图模型很容易“过拟合”也就是只认识你给的这些样本换张类似的就不认识了。数据增强就是通过一些简单的图像变换人工创造出更多的、多样化的训练样本让模型变得更健壮。4.1 几种实用的增强方法我们主要介绍三种简单又有效的方法旋转、模糊和噪声。我们用OpenCV来实现因为它处理起来速度很快。import cv2 import numpy as np import os from tqdm import tqdm import random def augment_image(image_path, output_dir, augmentations[rotate, blur, noise]): 对单张图片进行数据增强并保存增强后的版本。 参数: image_path: 输入图片路径 output_dir: 增强图片输出目录 augmentations: 需要进行的增强操作列表 img cv2.imread(image_path) if img is None: return base_name os.path.splitext(os.path.basename(image_path))[0] # 保存原始图片作为增强的基准 cv2.imwrite(os.path.join(output_dir, f{base_name}_orig.jpg), img) # 1. 随机旋转小角度 if rotate in augmentations: angle random.uniform(-10, 10) # 随机旋转-10到10度 height, width img.shape[:2] center (width // 2, height // 2) rotation_matrix cv2.getRotationMatrix2D(center, angle, 1.0) rotated cv2.warpAffine(img, rotation_matrix, (width, height), borderModecv2.BORDER_REPLICATE) cv2.imwrite(os.path.join(output_dir, f{base_name}_rot.jpg), rotated) # 2. 高斯模糊模拟轻微失焦 if blur in augmentations: # 随机选择模糊核大小必须是正奇数 ksize random.choice([3, 5]) blurred cv2.GaussianBlur(img, (ksize, ksize), 0) cv2.imwrite(os.path.join(output_dir, f{base_name}_blur.jpg), blurred) # 3. 添加高斯噪声模拟图像传感器噪声 if noise in augmentations: mean 0 var random.uniform(1, 10) # 随机噪声方差 sigma var ** 0.5 gaussian np.random.normal(mean, sigma, img.shape).astype(np.uint8) noisy cv2.add(img, gaussian) cv2.imwrite(os.path.join(output_dir, f{base_name}_noise.jpg), noisy) # 可以组合增强比如旋转模糊 if rotate in augmentations and blur in augmentations: # 先旋转 angle random.uniform(-5, 5) height, width img.shape[:2] center (width // 2, height // 2) M cv2.getRotationMatrix2D(center, angle, 1.0) img_rot cv2.warpAffine(img, M, (width, height), borderModecv2.BORDER_REPLICATE) # 再模糊 img_rot_blur cv2.GaussianBlur(img_rot, (3, 3), 0) cv2.imwrite(os.path.join(output_dir, f{base_name}_rot_blur.jpg), img_rot_blur) def batch_augment(input_dir, output_dir): 批量处理一个文件夹内的所有图片。 os.makedirs(output_dir, exist_okTrue) image_files [f for f in os.listdir(input_dir) if f.lower().endswith((.png, .jpg, .jpeg, .bmp))] for img_file in tqdm(image_files, desc正在进行数据增强): img_path os.path.join(input_dir, img_file) augment_image(img_path, output_dir) print(f数据增强完成增强后图片已保存至: {output_dir}) # 使用示例 if __name__ __main__: # 对裁剪后的图片进行增强 batch_augment( input_dir./cropped_images, output_dir./augmented_images )运行后augmented_images文件夹里的图片数量会是原来的好几倍。每张原始图都衍生出了旋转版、模糊版、带噪声的版本甚至还有组合增强的版本。模型看到的数据多样性一下子就丰富起来了。5. 第三步生成模型所需的标注文件数据准备好了最后一步就是告诉模型每张图片对应什么文字。GLM-OCR等主流OCR模型通常接受特定的标注格式比如每行一个“图片路径\t文本内容”的.txt文件或者一个包含所有信息的.json文件。5.1 生成标准格式的标注文件我们需要遍历所有增强后的图片根据它们的文件名我们在裁剪时把文本信息嵌入了文件名或者一个单独的映射关系来生成最终的标注。这里我们以生成一个简单的train.txt为例格式为image_path text_label。import os import json from tqdm import tqdm def generate_annotation_txt(image_dir, output_txt_path): 生成标准的训练标注txt文件。 假设图片文件名格式为原图名_序号_文本内容.jpg image_files [f for f in os.listdir(image_dir) if f.lower().endswith((.png, .jpg, .jpeg, .bmp))] annotations [] for img_file in tqdm(image_files, desc正在生成标注): # 从文件名中提取文本标签根据你的命名规则调整 # 例如doc_01_0_产品名称.jpg - 产品名称 try: # 去掉扩展名按_分割取最后一部分作为文本 # 注意如果你的文本中包含_这种简单方法会出错需要更稳健的解析或使用额外文件 base_name os.path.splitext(img_file)[0] # 假设文件名结构是 {前缀}_{序号}_{文本} parts base_name.split(_) if len(parts) 3: # 文本部分是序号之后的所有部分用_重新连接防止原文本有_被分割 text_label _.join(parts[2:]) else: text_label base_name # 如果解析失败用整个文件名不含扩展名 # 构建相对路径或绝对路径 img_relative_path os.path.join(image_dir, img_file) annotations.append(f{img_relative_path}\t{text_label}) except Exception as e: print(f处理文件 {img_file} 时出错: {e}) continue # 写入txt文件 with open(output_txt_path, w, encodingutf-8) as f: f.write(\n.join(annotations)) print(f标注文件已生成: {output_txt_path}) print(f共生成 {len(annotations)} 条标注。) def generate_annotation_json(image_dir, output_json_path): 生成JSON格式的标注文件结构更灵活。 image_files [f for f in os.listdir(image_dir) if f.lower().endswith((.png, .jpg, .jpeg, .bmp))] data_list [] for img_file in tqdm(image_files, desc正在生成JSON标注): try: base_name os.path.splitext(img_file)[0] parts base_name.split(_) text_label _.join(parts[2:]) if len(parts) 3 else base_name img_path os.path.join(image_dir, img_file) # 构建一个字典可以包含更多信息如图片尺寸等 data_item { filename: img_file, text: text_label, path: img_path # 可以添加 width, height 等信息如果需要的话 } data_list.append(data_item) except Exception as e: print(f处理文件 {img_file} 时出错: {e}) continue # 写入JSON文件 with open(output_json_path, w, encodingutf-8) as f: json.dump(data_list, f, ensure_asciiFalse, indent2) print(fJSON标注文件已生成: {output_json_path}) # 使用示例 if __name__ __main__: # 生成TXT格式标注 generate_annotation_txt( image_dir./augmented_images, output_txt_path./annotations/train.txt ) # 生成JSON格式标注可选 generate_annotation_json( image_dir./augmented_images, output_json_path./annotations/train.json )重要提示上面从文件名提取文本的方法比较简陋。在实际项目中更可靠的做法是维护一个独立的字典或文件来映射每个裁剪后的图片文件与其对应的原始标注文本。你可以把第三步裁剪脚本中记录的文本信息比如存到一个列表或字典里传递给数据增强和标注生成步骤。6. 总结走完这一套流程你就拥有了一套为GLM-OCR模型量身定制的训练数据了经过裁剪、增强的图片以及格式规范的标注文件。这个过程看似步骤不少但一旦用脚本自动化起来处理成百上千张图片也就是几分钟的事。回顾一下关键点裁剪让模型聚焦增强让模型健壮规范的标注让模型能正确学习。这些脚本只是一个起点你可以根据自己数据的特性去调整比如增加对比度调整、透视变换等更复杂的增强手段或者处理更复杂的标注格式。数据质量直接决定了模型效果的上限。花时间把数据准备这一步做扎实后面的模型训练往往会事半功倍。接下来你就可以拿着这些准备好的数据投入到GLM-OCR的微调训练中去了。希望这篇教程能帮你扫清数据准备上的障碍祝你训练出识别精准的专属OCR模型获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。