一次完整的OCR实践记录
一、任务介绍
这次的任务是对两百余张图片里面特定的编号进行识别,涉及保密的原因,这里就不能粘贴出具体的图片了,下面粘贴出一张类似需要识别的图片。

假如说我的数据源如上图所示,那么我需要做的工作就是将上面图片里面标红的数字给识别出来。
我采用的算法是GitHub - YCG09/chinese_ocr: CTPN + DenseNet + CTC based end-to-end Chinese OCR implemented using tensorflow and keras,这是基于Tensorflow和keras框架采用ctpn+densenet+CTC算法来完成对图片指定内容的字符识别。
二、 图像标注
既然要进行OCR识别,那么一定要对已有的数据源进行图像标注工作,这里采用的工具是labelImg,相信大家如果有搞深度学习这块的话一定对这个工具不会陌生。

对图像具体的标注流程,我这里就不做说明了,网上有很多资料可以查找。这里需要作特别说明的是,对于ctpn的训练,label的名字为text,对于densenet的训练来说的话,就需要把标注框里面的内容当作label。
然后就是数据增强这块,这里需要记录的有两点,一就是原始的数据源比较少就必须做数据增强,不然做出来的效果肯定不太行,二就是怎么做数据增强,由于这里的数据比较简单,需要识别的内容也是有规律可行的,那这里就用不着采用比较复杂的数据增强,所以我做的数据增强就是对图像随机进行裁剪和倾斜,当然这里裁剪的尺寸和倾斜的角度一定要控制好,不然就会影响图片的质量。
import cv2
import numpy as np
import random
import os
from PIL import Image# 数据增强的代码img_path = r "*****************"
save_path = r "****************"# 随机倾斜图片
def rotate_ima(img_path,save_path):for file in os.listdir(img_path):img = cv2.imread(os.path.join(img_path, file ), 0 )rows,cols = img.shape# cols-1 and rows-1 are the coordinate limits.# 每张图片倾斜4张for i in range ( 4 ):a = random.randint( 2 , 6 )print (a)# 指定左右倾斜for j in range ( 2 ):a = - aM = cv2.getRotationMatrix2D(((cols - 1 ) / 2.0 ,(rows - 1 ) / 2.0 ),a, 1 )dst = cv2.warpAffine(img,M,(cols,rows))#cv2.imshow('img',img)#cv2.imshow('dst',dst)cv2.imwrite(os.path.join(save_path, 'rot_' + str (i) + '_' + str (j) + file ),dst)#cv2.waitKey(0)cv2.destroyAllWindows()# 随机裁剪图片
def cut_img(img_path,save_path):all_file = []for file in os.listdir(img_path):all_file.append( file )file1 = random.sample(all_file, 2 )for x in file1:im = Image. open (os.path.join(img_path,x))crop_all = []for c in range ( 5 ): # 对每张图片随机生成5张for i in range ( 4 ):a = random.randint( 100 , 400 )crop_all.append(a)region = im.crop((crop_all[ 0 ],crop_all[ 1 ],im.size[ 0 ] - crop_all[ 2 ],im.size[ 1 ] - crop_all[ 3 ]))region.save(os.path.join(save_path, 'cut_' + str (c) + '_' + x))#rotate_ima(img_path,save_path)
cut_img(img_path,save_path)
然后我大概生成了3000张左右的图片就开始进行数据标注了,标注了大概六七个小时才把这些数据标注给完成。
有了这些标注数据过后,就可以正式开始训练了。
三、CTPN训练
关于CTPN训练流程在chinese_ocr/ctpn at master · YCG09/chinese_ocr · GitHub的readme已经说的很清楚了。但是我这里就列出我所踩的坑吧。
最开始我直接把标注的数据制作成VOC2007数据集的格式丢进去训练,然后训练出来的效果并不好,后面我才在周围同事的提醒下有一个关键的步骤忘了做。

因为CTPN是进行文字检测并不同于普通的目标检测,它的检测原理是对单个的字符进行检测然后拼接在一起。

因为我们在进行数据标注的时候是对一整行文本进行拉框标注,但是如果要进行CTPN训练的话就需要对这个框划分成很多个矩形小框,划分的方法就是上面的split_label.py程序。
但是要进行上面一步的前提就是需要更改标注文件,使用labelImg标注出来的文件是一个图像对应一个xml文件,但是这里需要更改成一个图像对应一个txt文件,txt里面存放的是标注框的四个坐标,共计八个点(注意坐标点的顺序)。如下所示
410,1554,1723,1554,1723,1736,410,1736
然后在运行split_label.py,接着ToVoc.py,这里面的代码细节需要自行更改,这里就不做说明了。
然后就可以正式开始训练了,截图如下:

这里粘贴出一个错误需要注意:

解决方案就是删除cache文件夹
四、DenseNet+CTC训练
DenseNet+CTC训练主要分为两个步骤,一是图像处理,二是txt文件处理。
图像处理的话,在我们拿到标注好的数据之后需要对原始图像进行裁剪工作,就是根据标注的坐标裁剪出具体的图像,就拿上面的图像来说,我们需要的图像如下所示。

然后再对裁剪后的图像进行resize工作,resize成(280,32),这样的话图像处理这一部分就算完成了。
txt处理的话,这里我们需要对xml文件进行一系列处理来达到下面的效果。

前面card_900.jpg代表图像名称,后面这一串字符代表需要识别的字符在下面这个文件里面的位置索引。

注意这里txt里面存放的是所有图像里面待识别字符的编号,不是一个图像对应一个txt。
做到这一步过后,在把生成的txt划分成训练集和测试集,就算成功制作出来训练DenseNet的数据集了。

然后就可以开始训练了,截图如下:

五、总结
这次这个小的OCR项目历时大概十天左右,从数据标注再到训练模型,里面踩了很多坑,也做了很多次尝试,也查阅了很多资料,也向周围同事请教了很多次,总算功夫不负有心人,总算完成了这次项目。
这个记录只是记录了大概的流程,很多代码细节并不方便透露,更多详情参阅上面给出的GitHub地址。记录下这个更多是方便自己以后查阅。
相关文章:
一次完整的OCR实践记录
一、任务介绍 这次的任务是对两百余张图片里面特定的编号进行识别,涉及保密的原因,这里就不能粘贴出具体的图片了,下面粘贴出一张类似需要识别的图片。 假如说我的数据源如上图所示,那么我需要做的工作就是将上面图片里面标红的数…...
Java中常见的密码学知识
现代密码学 散列函数 散列函数,也见杂凑函数、摘要函数或哈希函数,可将任意长度的消息经过运算,变成固定长度数值,常见的有MD5、SHA-1、SHA256,多应用在文件校验,数字签名中。 MD5 可以将任意长度的原文生…...
Leetcode.2171 拿出最少数目的魔法豆
题目链接 Leetcode.2171 拿出最少数目的魔法豆 Rating : 1748 题目描述 给你一个 正 整数数组 beans,其中每个整数表示一个袋子里装的魔法豆的数目。 请你从每个袋子中 拿出 一些豆子(也可以 不拿出),使得剩下的 非空…...
day1 计算机组成与结构考点汇总
一、重点知识点 计算机硬件组成、运算器、控制器奇偶校验码、循环冗余校验码、海明码指令系统:指令操作数寻址方式、CISC和RISC、指令流水线的计算存储系统:分级存储、局部性原理、cache、主存编址计算、磁盘输入输出技术:程序查询方式、中断…...
Java虚拟机的类加载机制
Java虚拟机的类加载机制综述类的生命周期类加载器双亲委派模型---综述 我们编写的Java代码如何能在一个操作系统上运行呢?一般来说,我们使用javac命令将.java文件编译成.class文件,也就是Java字节码文件,然后由JVM将字节码文件加…...
分治法实现合并排序(归并排序),理解分治算法思想,实现分治算法的完美例子合并排序(含码源与解析)
🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨,经典算法的解析✨都在这儿,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 -…...
Typescript 类 (class)
基本用法 (通过关键字 class) // 基本用法 class VueService {constructor() {} // 构造器 } 类的约束(通过关键字 implements) // 接口定义属性类型 interface VueProps {name: stringinit: () > void }// 约束类 class VueService implements Vue…...
KDZD程控超低频高压发生器
一、产品概述 本产品接合了现代数字变频技术,采用微机控制,升压、降压、测量、保护自动化。由于电子化,所以体积小重量轻、大屏幕液晶显示,清晰直观、且能显示输出波形、打印试验报告。 设计指标符合《电力设备专用测试仪器通用…...
【华为OD机试 2023最新 】 过滤组合字符串(C++)
文章目录 题目描述输入描述输出描述用例题目解析C++题目描述 数字0、1、2、3、4、5、6、7、8、9分别关联 a~z 26个英文字母。 0 关联 “a”,”b”,”c”1 关联 “d”,”e”,”f”2 关联 “g”,”h”,”i”3 关联 “j”,”k”,”l”4 关联 “m”,”n”,”o”5 关联 “p”,”q”…...
Java笔记034-坦克大战【2】
目录 坦克大战【2】 线程-应用到坦克大战 坦克大战0.3 思路分析: 代码实现: 坦克大战0.4 增加功能 特别说明 思路分析: 代码实现: 坦克大战0.5 增加功能 思路分析: 代码实现: 坦克大战【2】 …...
【算法】【数组与矩阵模块】桶排序思想解决无序数组排序后相邻数间的最大差值
目录前言问题介绍解决方案代码编写java语言版本c语言版本c语言版本思考感悟写在最后前言 当前所有算法都使用测试用例运行过,但是不保证100%的测试用例,如果存在问题务必联系批评指正~ 在此感谢左大神让我对算法有了新的感悟认识! 问题介绍 …...
C语言—函数
函数库函数自定义函数函数的参数函数的调用函数的嵌套调用和链式访问函数的声明和定义函数递归递归与迭代函数递归的经典题目维基百科(台湾方面维护的,翻译形式跟大陆有所差异)中对函数的定义:子程序在计算机科学中,子…...
Autosar模式管理实战系列03-基于Davinci工具的WDGM配置
本文框架 前言1.WdgMConfigSet 配置2. 新建监控实体(SE)2.1 新建检测点(Checkpoint)2.2 设置 WdgMInternalTransitions3. WdgMLocalStatusParams配置4. WdgMAliveSupervision配置5. 代码插入指导前言 前面我们介绍了WdgM(看门狗管理)是一个 AutoSAR 的基础模块,负责管理看门…...
AutoML-sklearn and torch
一、auto-sklearn 1.1 环境依赖 额外安装swig 第三方库 linux 支持, mac,windows不支持 1.2 示例代码 time_left_for_this_task 设定任务最大时间 per_run_time_limit 每个子任务最大训练时间 include 可以限制任务训练的模型 import autosklearn.classific…...
《扬帆优配》算力概念股大爆发,主力资金大扫货
3月22日,9股封单金额超亿元,工业富联、鸿博股份、鹏鼎控股分别为3.01亿元、2.78亿元、2.37亿元。 今日三大指数团体收涨,收盘共34股涨停,首要集中于数字经济方向,其间云核算、CPO大迸发。除去5只ST股,算计2…...
机械臂+底盘三维模型从solidworks到moveit配置功能包
文章目录 导出底盘STEP加载机械臂模型组合机械臂和底盘三维模型导出URDF在moveit中进行配置新建工作目录设置ROS工作空间的环境变量进入moveit setup加载URDF文件self-CollisionsPlanning groupsRobot posesControllersSimulationAuthor information生成配置包在rviz中进行可视…...
高并发系统设计:缓存、降级、限流、(熔断)
高并发系统设计:缓存、降级、限流、(熔断) 在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。 非核心服务可以采用降级、熔断,核心服务采用缓存和限流(隔离流量可以最大限度的保障业务无损)。 缓存 缓…...
《辉煌优配》放量大涨,A股成交额重回万亿!PCB板块继续领跑
多只绩优PCB概念股超跌。 今日A股放量反弹,成交额从头站上万亿关口。芯片板块掀涨停潮,景嘉微、芯原股份20cm涨停,紫光国微、兆易创新、跃岭股份等封板;AI算力、存储器、光模块、云核算等板块全线拉升,板块内个股再度批…...
Vue封装的过度与动画
动画效果 先把样式封装好,然后设置一个动画 不需要vue也能实现的动画的效果,我们只需要判断一下,然后动态的添加和删除类名即可 那能不能不自己写动态,就靠vue 首先我们要靠<transition>标签把需要动画的包裹起来 vue中…...
流量监控-ntopng
目录介绍安装使用介绍 ntopng是原始ntop的下一代版本,ntop是监视网络使用情况的网络流量探测器。ntopng基于libpcap,并且以可移植的方式编写,以便实际上可以在每个Unix平台,MacOSX和Windows上运行。 ntopng(是的&…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
