一次完整的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  = - a
                M  = 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地址。记录下这个更多是方便自己以后查阅。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/4695.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring----整合Mybatis

项目结构具体如下: 准备一个数据库: 架构是spring_db,表名为user_tb 结构如下: 第一步:配置pom文件(导入相应的坐标,注意spring-mybatis与mybatis的版本需要相对应,可以去官网查找…

Python(黄金时代)——多线程、多进程、协程

基本使用 基本概念 进程 几乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程 进程是处于运行过程中的程序,并且具有一定的独立功能 进程是系统进行资源分配调度的一个独立单位 线程 线程&…

基于springboot物资管理系统(程序+数据库)

大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里为大家分享优质的实战项目,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路…

迅镭激光带您沉浸式直击展会现场!线上直播、云端互动,精彩持续!

2023 ITES深圳工业展 迅镭展位10-B06 深圳国际会展中心-宝安新馆 今天(3月29日),2023 ITES深圳工业展在深圳国际会展中心(宝安新馆)盛大开幕!迅镭激光以“行业高端典范、引领智造未来”为主题,携多款旗舰产品展示领先技术,展会首日便收获了超…

为了开放互联,明道云做了十件事

本文来自明道云资深研发经理孙伟,在明道云2022年秋季伙伴大会活动演讲,经校对编辑后整理为演讲精华。 一、开放没有选择 很多客户选择我们的一个重要原因,是明道云所能提供的产品开放能力。开放其实是没有选择的,坦白来讲&#…

SpringBoot接参注解与校验失败后的三种异常

文章目录一、SpringBoot中的参数传递注解1、PathVariable2、RequestParam3、RequestBody4、不用注解或者ModelAttribute二、参数类型校验失败后的三种异常一、SpringBoot中的参数传递注解 先看看非json下参数的接收和传递: 1、PathVariable PathVariable注解用于…

软件框架-实现使用@Component@Data@Configuration@Bean(配置类控制类实体类)等方法实现将配置文件从8080端口显示在网页上

一、前言 1.该程序代码是使用idea2021.12版本编写的,若使用其他软件请对照好配置; 2.这个程序具体的内容我忘了,只知道使用ComponentConfigurationPropertiesData ConfigurationBeanRestControllerAutowiredGetMapping等方法写的&#xff0…

chatGPT学英语,真香!!!

文章目录学习目标学习内容目标方式过程学习时间学习产出学习目标 能够在三个月的练习后,和真人外教比较流畅的沟通! 最近chatGPT实在是太火了,各种事情都能干,能改论文、写代码和翻译。 看到B站很多教程教我们直接用chatGPT进行…

【数据库管理】②实例管理及数据库启动关闭

1. 实例和参数文件 1.1 instance 用于管理和访问 database. instance 在启动阶段读取初始化参数文件(init parameter files). 1.2 init parameter files [rootoracle-db-19c ~]# su - oracle [oracleoracle-db-19c ~]$ [oracleoracle-db-19c ~]$ cd $ORACLE_HOME/dbs [oracl…

Docker 翻脸,不再开源,期待后续

前几日,Docker Hub出了一件大事!但凡创建了“organisation”的用户都收到了一封含有简短PDF链接的邮件。邮件的内容“金钱味”十足:如果不按照要求升级付费,用户就将失去对数据的访问权限。此举不仅会破坏开源项目的自动化构建&am…

GPT-4发布,这类人才告急,大厂月薪10W+疯抢

ChatGPT最近彻底火出圈,各行各业都在争相报道,甚至连很多官媒都下场“跟风”。ChatGPT的瓜还没吃完,平地一声雷,GPT-4又重磅发布! 很多小伙伴瑟瑟发抖:“AI会不会跟自己抢饭碗啊?” 关于“如何…

C++ 16 vector容器

目录 一、vector容器 1.1 简介 1.2 构造函数 1.3 赋值操作 1.4 容量和大小 1.5 插入删除 1.6 数据存取 1.7 互换容器 1.8 预留空间 一、vector容器 1.1 简介 ① vector数据结构和数组非常相似,也称为单端数组。 ② vector与普通数组区别:不同…

6.链路层和局域网

链路层链路层的主体是网络适配器,也称为网络接口卡2. 变换局域网链路层交换机的任务是在主机和路由器之间承载数据报没有两个适配器有相同的MAC地址适配器到哪里,MAC地址都不会改变主机移动时,主机的IP地址需要随之改变,以改变连接…

Vue+springboot 高校图书馆座位预约选座系统java毕业设计项目推荐

目前现有的图书馆选座管理系统对于用户而言其选座管理流程仍然过于繁琐,对于图书馆选座管理而言其系统安全性并不能保障。同时整套系统所使用的技术相对较为落后,界面不能动态化展示。相比较于其它同类型网站而言不能体现技术先进性。 1.2 项目目标 图书…

Python视频软件解析教程【源码可送】

人生苦短,我用python 快放假了… 有的人出去玩~ 有的人在家里呆着看电视~ 这次就来康康怎么做一个好玩的小软件~ (嘘~自己用) 瓜子花生小零食准备好了吗? 效果展示 我们先看看效果 这是本次要写的界面 主流视频都可以看&…

JDK20正式发布了GA版本,短期维护支持,以及JDK21预览

最近,Oracle发布了JDK20,相比对于Java开发者来说,JDK的发版是比较收关注的事情了,小简也来和大家一起了解了解JDK20发生了什么变化呢? 首先,JDK20是一个短周期版本,有6个月的维护时间&#xff0…

Maven和Gradle的区别

首先谈谈为什么要学习Maven? 依赖管理 大家还记得在学习JavaWeb时需要向web项目中引入少许jar包嘛?还记得引入jar包的繁琐过程嘛?实际项目中可能光基座需要引入的jar包就成千上万,jar包从哪里获取也是一个问题。项目中的jar包不仅…

ChatGPT写作文章-快速使用ChatGPT不用注册方式

如何更好地使用ChatGPT批量生成文章:详细教程 作为一款强大的文本生成器,ChatGPT可以帮助您快速、高效地批量生成文章。但如果您还不知道如何更好地使用ChatGPT,那么这篇详细的列表教程将会指导您如何使用它来生成高质量的文章,提…

“工业转型,大势所趋”:ITES深圳工业展暨阿里巴巴1688工业采购节开幕

2023年以来,中国制造业快速发展、需求深度释放,创造了大量的产业机遇。与此同时,国内外社会经济发展不确定因素众多,制造类企业、专业买家呼唤提升发展确定性;面临时代变局,工业品市场渴望在发展模式、合作…

华为OD机试题,用 Java 解【删除指定目录】问题 | 含解题说明

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典本篇题目:删除指定目录 题目 某文件系统…