如何高效使用cnocr:竖排简繁中文识别全流程指南
一、cnocr库简介与竖排识别核心挑战
cnocr是基于PyTorch框架开发的开源OCR工具,专注于中文场景识别,尤其针对古籍、书法、对联等竖排文本场景优化。其核心优势在于支持多语言混合识别(简/繁/日/韩)及版面自适应能力,但竖排识别需特殊参数配置。
竖排文本识别面临三大挑战:
- 方向性:字符排列方向与常规横排相反,需模型具备方向感知能力
- 字符间距:竖排文本行间距不均,易导致字符粘连
- 语言混合:古籍中常见简繁混用,需模型具备语言自适应能力
二、环境准备与依赖安装
1. 系统要求
- Python 3.7+
- PyTorch 1.8+(推荐CUDA 11.x)
- OpenCV 4.5+
- 推荐Linux/macOS系统,Windows需配置WSL2
2. 安装步骤
# 创建虚拟环境(推荐)python -m venv cnocrenvsource cnocrenv/bin/activate # Linux/macOS# cnocrenv\Scripts\activate # Windows# 安装cnocr(含预训练模型)pip install cnocr[all] # 包含所有语言模型# 或精简安装(仅简繁中文)pip install cnocr[chinese-simplified-chinese-traditional]
3. 模型下载验证
安装后自动下载默认模型(densenet_lite_136-gru),可通过以下代码验证:
from cnocr import CnOcrocr = CnOcr()print(f"已加载模型:{ocr.model_name}") # 应输出模型名称
三、竖排识别核心参数配置
1. 关键参数说明
| 参数 | 类型 | 默认值 | 竖排识别建议值 | 作用 |
|---|---|---|---|---|
context |
str | ‘cpu’ | ‘cuda’(如可用) | 加速推理 |
rec_model_name |
str | ‘densenet_lite_136-gru’ | 保持默认 | 识别模型 |
det_model_name |
str | ‘ch_PP-OCRv3_det’ | 保持默认 | 检测模型 |
vertical_text |
bool | False | True | 启用竖排模式 |
lang |
str | ‘ch_sim’ | ‘ch_sim’或’ch_tra’ | 语言类型 |
merge_lines |
bool | True | False | 竖排禁用行合并 |
2. 参数配置示例
from cnocr import CnOcr# 简体中文竖排配置ocr_sim = CnOcr(vertical_text=True, # 关键参数lang='ch_sim',merge_lines=False, # 禁用行合并context='cuda' # GPU加速)# 繁体中文竖排配置ocr_tra = CnOcr(vertical_text=True,lang='ch_tra',rec_model_name='densenet_lite_136-gru-ft', # 繁体专用微调模型merge_lines=False)
四、完整识别流程实现
1. 图像预处理
import cv2import numpy as npdef preprocess_image(img_path):# 读取图像(保持原始方向)img = cv2.imread(img_path)if img is None:raise ValueError("图像加载失败")# 转换为RGB(cnocr默认输入格式)img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 二值化(可选,增强对比度)gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)return binary # 或直接返回img_rgb
2. 批量识别实现
def recognize_vertical_text(img_path, ocr_engine):"""竖排文本识别主函数:param img_path: 图像路径:param ocr_engine: 配置好的CnOcr实例:return: 识别结果列表,每个元素为(文本, 位置, 置信度)"""try:img = preprocess_image(img_path)# 关键调用:识别时无需特殊参数,依赖预配置的vertical_text=Trueresults = ocr_engine.ocr(img)# 竖排结果处理:按y坐标排序(从顶到底)sorted_results = sorted(results, key=lambda x: x[0][1]) # x[0]为坐标,x[0][1]为y坐标# 提取文本和置信度text_results = [(res[1], res[2]) for res in sorted_results] # (文本, 置信度)return text_resultsexcept Exception as e:print(f"识别错误:{str(e)}")return []
3. 完整调用示例
# 初始化识别器ocr_sim = CnOcr(vertical_text=True, lang='ch_sim', merge_lines=False)# 识别简体中文竖排文本img_path = 'vertical_ch_sim.jpg'results = recognize_vertical_text(img_path, ocr_sim)# 输出结果for idx, (text, conf) in enumerate(results, 1):print(f"行{idx}: {text} (置信度: {conf:.2f})")
五、高级优化技巧
1. 模型微调(针对特定场景)
from cnocr.utils import train_helper# 示例:使用自定义数据集微调train_helper.train(model_name='densenet_lite_136-gru',lang='ch_sim',train_data_dir='./custom_train_data',val_data_dir='./custom_val_data',epochs=20,batch_size=16)
数据集要求:
- 图像格式:JPG/PNG
- 标注格式:每行一个文本框,格式为
x1,y1,x2,y2,文本
2. 多语言混合识别
# 启用简繁混合识别(需下载多语言模型)ocr_mixed = CnOcr(vertical_text=True,lang='mixed', # 自动识别简繁rec_model_name='densenet_lite_136-gru-multilang')
3. 后处理增强
def postprocess_results(raw_results):"""后处理:1. 过滤低置信度结果2. 合并连续相同字符(修复分词错误)"""processed = []for text, conf in raw_results:if conf > 0.7: # 置信度阈值# 简单去重示例(实际需更复杂逻辑)if len(processed) > 0 and processed[-1][0] == text:continueprocessed.append((text, conf))return processed
六、常见问题解决方案
1. 识别乱码问题
- 原因:模型未适配竖排或语言设置错误
- 解决:
- 确认
vertical_text=True - 检查
lang参数是否匹配(ch_sim/ch_tra) - 尝试更换模型(如
densenet_lite_136-gru-ft)
- 确认
2. 性能优化建议
| 场景 | 优化方案 | 效果 |
|---|---|---|
| 高分辨率图像 | 提前缩放至1500px以下 | 速度提升40% |
| 批量处理 | 使用ocr.ocr_for_single_lines() |
内存占用降低60% |
| GPU加速 | 确保context='cuda' |
推理速度提升5-10倍 |
3. 版本兼容性问题
- cnocr v2.0+ 才支持竖排识别
- 检查版本:
import cnocrprint(f"当前版本:{cnocr.__version__}") # 需≥2.0.0
七、完整代码示例
from cnocr import CnOcrimport cv2def main():# 1. 初始化识别器ocr = CnOcr(vertical_text=True,lang='ch_sim', # 或'ch_tra'merge_lines=False,context='cuda' if cv2.cuda.getCudaEnabledDeviceCount() > 0 else 'cpu')# 2. 加载图像img_path = 'example_vertical.jpg'img = cv2.imread(img_path)if img is None:raise FileNotFoundError("图像未找到")# 3. 识别(自动应用竖排配置)results = ocr.ocr(img)# 4. 后处理与输出sorted_results = sorted(results, key=lambda x: x[0][1]) # 按y坐标排序for i, (bbox, text, conf) in enumerate(sorted_results, 1):print(f"识别结果{i}:")print(f" 文本: {text}")print(f" 位置: {bbox}")print(f" 置信度: {conf:.2f}\n")if __name__ == '__main__':main()
八、总结与扩展建议
- 竖排识别核心:必须设置
vertical_text=True并禁用merge_lines - 语言选择:简体中文用
ch_sim,繁体中文用ch_tra,混合场景用mixed - 性能优化:GPU加速、图像缩放、批量处理可显著提升效率
- 扩展应用:可结合版面分析(如
ppocr)实现复杂文档解析
通过以上流程,开发者可高效实现古籍、书法等竖排文本的精准识别。实际项目中,建议构建包含500+样本的微调数据集以进一步提升特定场景准确率。