印刷字体识别系统

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 一个基于Python的印刷字体识别系统,遵循 GNU_GPL_v3 许可,具备字体倾斜校正、行与字符分割及字符识别功能。采用HOG算法训练SVM模型,使用Chars74K数据集。系统包含简单UI,支持动态加载和结果展示。核心算法包括自适应扩展+连通域辅助的行分割,以及垂直投影+连通域+极小值法细分粘连字符的字符分割。项目文件结构清晰,涵盖图像处理、模型训练与加载等功能模块。

印刷字体识别系统

*本项目遵循 GNU_GPL_v3 许可

简介

使用 Python 编写,带简单 UI。
可实现字体倾斜校正、行和字符分割、字符识别。

项目地址:https://github.com/kjx52/PFRS

倾斜校正使用传统的投影法。
行分割采用 自适应扩展+连通域辅助+智能 padding,字符分割采用 垂直投影+连通域+极小值法细分粘连字符。
字体识别使用 HOG 算法,公开 Chars74K 数据集训练。该数据集可在这里找到。
技术细节描述详见第四节。

还有一点,这个系统虽然对手写体具有一定的区分能力,但大部分情况下还是差强人意。
改进方面可以试一下使用torchvision的 datasets 手写数据集来训练。

from torchvision import datasets
train = datasets.EMNIST(root='data', split='letters', train=True, download=True)

使用方法

本项目集成性很高,使用简单。
不幸的是本仓库永远没有还没有发布版。

  1. 下载测试数据集和本仓库
  2. 将数据集放到本仓库目录下改为EnglishFnt.tgz
  3. 运行
    pip install -r requirements.txt   # 下载软件包
    python main.py                    # 执行
    

项目内容

文件结构树:

Printing_font_recognition_system/
│  character_recognition.py
│  config.py
│  dataset_loader.py
│  image_processing.py
│  main.py
│  requirements.txt
│  test_system.py
│  ui.py
│
├─screenshot/
└─templates/

其中:

  • main.py 是系统的集成启动器,负责所有的检查和任务执行,包括加载训练数据、训练和加载模型、启动UI界面等。启动器的下一步改进可能包括加入模型切换功能。
  • ui.py 是配套的一个简单的图形化界面,包括控制面板和结果展示等,该UI实现了动态加载和总控。一堆警告,但它跑起来了。下一步或将加入 debug 调试功能。
  • image_processing.py 图形处理脚本,包括倾斜校正以及行、字符分割等功能。
  • character_recognition.py 涉及到支持向量机(SVM)模型的训练和加载,用 HOG 特征提取算法识别字符。
  • dataset_loader.py 用于解压和加载 Chars74K 训练数据集。
  • config.py 包括该系统的配置参数,如模型存储路径和训练数据路径等:
    # config.py
    MODEL_PATH = 'models/svm_classifier.pkl'
    MODEL_DIR = 'models'
    IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png']
    DATASET_DIR = 'datasets'
    CHARS74K_ZIP = './EnglishFnt.tgz'
    TEMP_DIR = 'templates'
    
  • requirements.txt,该系统所需的软件包,请确保其全部安装了。

一些算法实现

分割

预处理对图片进行灰度化、二值化和去噪操作。
行分割最初采用水平投影来实现,但在不同字体下会产生很多问题,如由于“j”和“g”等下半部分超出其他字符,故会被分到新行中。现在我们使用 自适应扩展+连通域辅助+智能 padding 的方法来解决这一问题。

# 其他代码...

#合并有“尾巴”的行
merged_ranges = []
i = 0
while i < len(line_ranges):
    s, e = line_ranges[i]
    line_height = e - s
    # padding为行高的20%,最小2像素
    padding = max(2, int(line_height * 0.2))
    e_ext = min(processed.shape[0], e + padding)
    # 检查扩展区是否有黑色像素
    ext_region = processed[e:e_ext, :]
    has_tail = np.sum(ext_region > 0) > 0
    # 如果扩展区有内容且与下一行重叠,合并
    if has_tail and i + 1 < len(line_ranges):
        next_s, next_e = line_ranges[i+1]
        if e_ext > next_s:
            merged_ranges.append((s, next_e))
            i += 2
            continue
        # 如果扩展区无内容,回滚到未扩展
        merged_ranges.append((s, e_ext if has_tail else e))
        i += 1

# 其他代码...

上述代码是智能 padding 的部分,在完成基础分割后我们会将该行向下扩展 padding 的距离,用来检测是否有遗漏,若没有则回滚。padding 高度为行高的 20%,最小为 2 像素。

对于字符分割,单独使用传统垂直投影法在针对粗体字符的分割部分可能会出现字符粘连问题,故现在使用 垂直投影+连通域+极小值法细分粘连字符 进行缓解。

# 其他代码...

for start, end in optimized_ranges:
    # 粘连字符细分
    w = end - start
    char_img = line_img[:, start:end]
    h = char_img.shape[0]
    # 如果宽度过大,尝试在该区域内寻找极小值分割
    if w > h * 1.2:
        # 在该区域内做二次垂直投影
        sub_processed = self.preprocess_image(char_img)
        sub_proj = np.sum(sub_processed, axis=0)
        min_indices = [
            k
            for k in range(1, len(sub_proj) - 1)
            if sub_proj[k] < sub_proj[k - 1]
            and sub_proj[k] < sub_proj[k + 1]
            and sub_proj[k] < threshold
        ]
        # 根据极小值点分割
        last = 0
        for idx in min_indices + [w]:
            if idx - last > 3:
                sub_char = char_img[:, last:idx]
                if sub_char.shape[1] > 3:
                    char_images.append(sub_char)
            last = idx
    elif 3 < w < h * 3 and h > 5:
        char_images.append(char_img)
    cv2.rectangle(line_img_copy, (start, 0), (end, line_img.shape[0]), (0, 0, 255), 1)

# 其他代码...

需要注意的是,即使是使用了连通域和极小值法,在面对某些紧凑字体时,该方法依然会失效。

识别

字符识别部分包含两个主要函数。
preprocess_char_img 函数负责将训练样本统一为白底黑字,居中填充到32x32。
train_svm_classifier 被设计为模型训练函数,它包括

  1. HOG特征的提取和标准化
  2. PCA降维
  3. 训练模型并保存

具体实现:

# 其他代码...

def train_svm_classifier(self, samples, labels):
    """使用公开数据集训练SVM分类器"""
    print("开始训练SVM分类器...")

    # 提取HOG特征
    features = []
    for img in tqdm(samples):
        pre_img = self.preprocess_char_img(img)
        fd = hog(pre_img, orientations=9, pixels_per_cell=(8, 8),
        cells_per_block=(2, 2), visualize=False)
        features.append(fd)

    x = np.array(features)
    y = np.array(labels)

    # 特征标准化
    self.scaler = StandardScaler()
    x_scaled = self.scaler.fit_transform(x)

    # PCA降维
    self.pca = PCA(n_components=0.95)  # 保留95%的方差
    x_pca = self.pca.fit_transform(x_scaled)

    # 训练SVM
    self.svm_model = SVC(kernel='rbf', C=10, gamma=0.001, probability=True)
    self.svm_model.fit(x_pca, y)

    print("完成,已保存到", MODEL_PATH)

    # 保存模型
    joblib.dump({
   
        'model': self.svm_model,
        'scaler': self.scaler,
        'pca': self.pca
    }, MODEL_PATH)

# 其他代码...

该模型训练速度快,方便部署和使用。

后记

本项目遵循 GNU_GPL_v3 许可

该系统还有诸多问题亟需解决。Such as the damn UI.
不过作为课设应该是合格了。

Jessarin
2025/06/12

目录
相关文章
|
1月前
|
机器学习/深度学习 数据可视化 算法
数据分布不明确?5个方法识别数据分布,快速找到数据的真实规律
本文深入探讨了数据科学中分布识别的重要性及其实践方法。作为数据分析的基础环节,分布识别影响后续模型性能与分析可靠性。文章从直方图的可视化入手,介绍如何通过Python代码实现分布特征的初步观察,并系统化地讲解参数估计、统计检验及distfit库的应用。同时,针对离散数据、非参数方法和Bootstrap验证等专题展开讨论,强调业务逻辑与统计结果结合的重要性。最后指出,正确识别分布有助于异常检测、数据生成及预测分析等领域,为决策提供可靠依据。作者倡导在实践中平衡模型复杂度与实用性,重视对数据本质的理解。
98 3
数据分布不明确?5个方法识别数据分布,快速找到数据的真实规律
|
1月前
|
JSON API 数据格式
淘宝天猫店铺订单列表、订单详情、订单物流 API 接口全攻略
淘宝天猫订单API接口简介:支持订单列表查询、订单详情获取及物流轨迹追踪功能。通过taobao.trades.sold.get等接口批量查询订单,按状态/时间筛选;taobao.trade.fullinfo.get获取订单详细信息;taobao.logistics.trade.trackget实时跟踪物流状态。开发者需注册账号、申请权限,并使用编程语言调用API,传递必要参数(如App Key、订单ID),处理JSON返回数据。适用于多场景订单管理与物流同步。
|
14天前
|
SQL JSON 分布式计算
Spark SQL架构及高级用法
Spark SQL基于Catalyst优化器与Tungsten引擎,提供高效的数据处理能力。其架构涵盖SQL解析、逻辑计划优化、物理计划生成及分布式执行,支持复杂数据类型、窗口函数与多样化聚合操作,结合自适应查询与代码生成技术,实现高性能大数据分析。
|
2月前
|
存储 Rust Go
介绍一下这只小水獭 —— Fluss Logo 背后的故事
Fluss是一款开源流存储项目,致力于为Lakehouse架构提供高效的实时数据层。其全新Logo以一只踏浪前行的小水獭为核心形象,象征流动性、适应性和友好性。水獭灵感源于“Fluss”德语中“河流”的含义,传递灵活与亲和力。经过30多版设计迭代,最终呈现动态活力的视觉效果。Fluss计划捐赠给Apache软件基金会,目前已开启孵化提案。社区还推出了系列周边礼品,欢迎加入钉钉群109135004351参与交流!
604 3
介绍一下这只小水獭 —— Fluss Logo 背后的故事
|
18天前
|
人工智能 自然语言处理 搜索推荐
AI 搜索 MCP 最佳实践
本文介绍了如何通过 MCP 协议,快速调用阿里云 OpenSearch 、ElasticSearch 等工具,帮助企业快速集成工具链、降低开发复杂度、提升业务效率。
142 29
AI 搜索 MCP 最佳实践
|
1月前
|
定位技术
安徽京准分享:北斗RDSS授时和北斗授时RNSS的区别
安徽京准分享:北斗RDSS授时和北斗授时RNSS的区别
166 15
|
存储 运维 开发工具
警惕日志采集失败的 6 大经典雷区:从本地管理反模式到 LoongCollector 标准实践
本文探讨了日志管理中的常见反模式及其潜在问题,强调科学的日志管理策略对系统可观测性的重要性。文中分析了6种反模式:copy truncate轮转导致的日志丢失或重复、NAS/OSS存储引发的采集不一致、多进程写入造成的日志混乱、创建文件空洞释放空间的风险、频繁覆盖写带来的数据完整性问题,以及使用vim编辑日志文件导致的重复采集。针对这些问题,文章提供了最佳实践建议,如使用create模式轮转日志、本地磁盘存储、单线程追加写入等方法,以降低日志采集风险,提升系统可靠性。最后总结指出,遵循这些实践可显著提高故障排查效率和系统性能。
282 20
|
1月前
|
人工智能 物联网
“一丹一世界”三等奖 |咖菲猫咪_商业海报案例分享
“一丹一世界”三等奖 |咖菲猫咪_商业海报案例分享
248 85

热门文章

最新文章