Python创建CRNN训练用的LMDB数据库文件
CRNN简介
CRNN由 Baoguang Shi, Xiang Bai, Cong Yao提出,2015年7月发表论文:“An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition”,链接地址:https://arxiv.org/abs/1507.05717v1
CRNN(卷积循环神经网络)集成了卷积神经网络(CNN)和循环神经网络(RNN)的优点。CRNN可以直接从序列标签(例如单词,句子)中学习,不需要详细的单个分别标注,并且对图像序列对象的长度无限定,只需要在训练和测试阶段对图像高度做一下归一化。于现有技术相比,CRNN在场景文本识别上表现良好。
CRNN中训练数据的格式是LMDB,保存了两种数据,一种是图片数据,一种是标签数据,它们各有其key,如下所示:
准备CRNN训练数据集
数据集图片是若干带有文字的图片,文字的高度约占图片高度的80%~90%,数据集标签是txt文本格式,文本内容是图片上的文字,文本名字要跟图片名字一致,如123.jpg对应标签需要是123.txt。
例如有 01.jpg 和 02.jpg 两个样本,标签文件是 01.txt 和 02.txt :
创建用于CRNN训练的LMDB数据
# -*- coding: utf-8 -*-
import os
import lmdb # install lmdb by "pip install lmdb"
import cv2
import numpy as np
#from genLineText import GenTextImage
def checkImageIsValid(imageBin):
if imageBin is None:
return False
imageBuf = np.fromstring(imageBin, dtype=np.uint8)
img = cv2.imdecode(imageBuf, cv2.IMREAD_GRAYSCALE)
if img is None:
return False
imgH, imgW = img.shape[0], img.shape[1]
if imgH * imgW == 0:
return False
return True
def writeCache(env, cache):
with env.begin(write=True) as txn:
for k, v in cache.iteritems():
txn.put(k, v)
def createDataset(outputPath, imagePathList, labelList, lexiconList=None, checkValid=True):
"""
Create LMDB dataset for CRNN training.
ARGS:
outputPath : LMDB output path
imagePathList : list of image path
labelList : list of corresponding groundtruth texts
lexiconList : (optional) list of lexicon lists
checkValid : if true, check the validity of every image
"""
#print (len(imagePathList) , len(labelList))
assert(len(imagePathList) == len(labelList))
nSamples = len(imagePathList)
print '...................'
# map_size=1099511627776 定义最大空间是1TB
env = lmdb.open(outputPath, map_size=1099511627776)
cache = {}
cnt = 1
for i in xrange(nSamples):
imagePath = imagePathList[i]
label = labelList[i]
if not os.path.exists(imagePath):
print('%s does not exist' % imagePath)
continue
with open(imagePath, 'r') as f:
imageBin = f.read()
if checkValid:
if not checkImageIsValid(imageBin):
print('%s is not a valid image' % imagePath)
continue
########## .mdb数据库文件保存了两种数据,一种是图片数据,一种是标签数据,它们各有其key
imageKey = 'image-%09d' % cnt
labelKey = 'label-%09d' % cnt
cache[imageKey] = imageBin
cache[labelKey] = label
##########
if lexiconList:
lexiconKey = 'lexicon-%09d' % cnt
cache[lexiconKey] = ' '.join(lexiconList[i])
if cnt % 1000 == 0:
writeCache(env, cache)
cache = {}
print('Written %d / %d' % (cnt, nSamples))
cnt += 1
nSamples = cnt-1
cache['num-samples'] = str(nSamples)
writeCache(env, cache)
print('Created dataset with %d samples' % nSamples)
def read_text(path):
with open(path) as f:
text = f.read()
text = text.strip()
return text
import glob
if __name__ == '__main__':
#lmdb 输出目录
outputPath = '../data/lmdb/trainMy'
# 训练图片路径,标签是txt格式,名字跟图片名字要一致,如123.jpg对应标签需要是123.txt
path = '../data/dataline/*.jpg'
imagePathList = glob.glob(path)
print '------------',len(imagePathList),'------------'
imgLabelLists = []
for p in imagePathList:
try:
imgLabelLists.append((p,read_text(p.replace('.jpg','.txt'))))
except:
continue
#imgLabelList = [ (p,read_text(p.replace('.jpg','.txt'))) for p in imagePathList]
##sort by lebelList
imgLabelList = sorted(imgLabelLists,key = lambda x:len(x[1]))
imgPaths = [ p[0] for p in imgLabelList]
txtLists = [ p[1] for p in imgLabelList]
createDataset(outputPath, imgPaths, txtLists, lexiconList=None, checkValid=True)
读取LMDB数据集中图片
# -*- coding: utf-8 -*-
import numpy as np
import lmdb
import cv2
with lmdb.open("../data/lmdb/train") as env:
txn = env.begin()
for key, value in txn.cursor():
print (key,value)
imageBuf = np.fromstring(value, dtype=np.uint8)
img = cv2.imdecode(imageBuf, cv2.IMREAD_GRAYSCALE)
if img is not None:
cv2.imshow('image', img)
cv2.waitKey()
else:
print 'This is a label: {}'.format(value)
Python创建CRNN训练用的LMDB数据库文件的更多相关文章
- python中读写LMDB数据库
LMDB的全称是Lightning Memory-Mapped Database(快如闪电的内存映射数据库),它的文件结构简单,包含一个数据文件和一个锁文件: LMDB文件可以同时由多个进程打开,具有 ...
- 【PyTorch】PyTorch使用LMDB数据库加速文件读取
PyTorch使用LMDB数据库加速文件读取 原始文档:https://www.yuque.com/lart/ugkv9f/hbnym1 对于数据库的了解较少,文章中大部分的介绍主要来自于各种博客和L ...
- python模块之bsddb: bdb高性能嵌入式数据库 1.基础知识
转自:http://blog.csdn.net/zhaoweikid/article/details/1665741 bsddb模块是用来操作bdb的模块,bdb是著名的Berkeley DB,它的性 ...
- python生成数据后,快速导入数据库
1.使用python生成数据库文件内容 # coding=utf-8import randomimport time def create_user(): start = time.time() ...
- python创建MySQL多实例-1
python创建MySQL多实例-1 前言 什么是多实例 多实例就是允许在同一台机器上创建另外一套不同配置文件的数据库,他们之间是相互独立的,主要有以下特点, 1> 不能同时使用一个端口 2&g ...
- 使用python创建mxnet操作符(网络层)
对cuda了解不多,所以使用python创建新的操作层是个不错的选择,当然这个性能不如cuda编写的代码. 在MXNET源码的example/numpy-ops/下有官方提供的使用python编写新操 ...
- 【python】用 sqlacodegen 将存在的数据库表 转化成model.py
Flask的sqlalchemy对数据库表的模型提供了很多易用的方法.为了使用这些内容,需要将数据库表按照Flask识别的格式创建成Model,但是一般我们都是在已经创建好的数据库环境中开发Pytho ...
- python创建项目
一.准备下载 python3.6.6 https://www.python.org/downloads/windows/(需要注意你的电脑是32位还是64位) mysql 5.1.72 https:/ ...
- Python学习笔记:sqlite3(sqlite数据库操作)
对于数据库的操作,Python中可以通过下载一些对应的三方插件和对应的数据库来实现数据库的操作,但是这样不免使得Python程序变得更加复杂了.如果只是想要使用数据库,又不想下载一些不必要的插件和辅助 ...
随机推荐
- CNN学习笔记:池化层
CNN学习笔记:池化层 池化 池化(Pooling)是卷积神经网络中另一个重要的概念,它实际上是一种形式的降采样.有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见 ...
- CSS小知识---table表格
所用的仍是bootstrap的模板 <link rel="stylesheet" href="css/bootstrap.min.css"> < ...
- Eclipse+maven 导致Eclipse启动后Build workspaces卡死或者下载缓慢的问题
参考文档: (1)Eclipse 一直不停 building workspace完美解决总结 (2)eclipse 一直building workspace 问题 解决办法: (1)第一步: 修改ec ...
- Linux设备驱动程序加载/卸载方法 insmod和modprobe命令
linux加载/卸载驱动有两种方法. 1.modprobe 注:在使用这个命令加载模块前先使用depmod -a命令生成modules.dep文件,该文件位于/lib/modules/$(uname ...
- MPU6050工作原理及STM32控制MPU6050
源:MPU6050工作原理及STM32控制MPU6050 MPU6050 介绍
- MySQL二进制日志文件过期天数设置说明
今天在处理业务库中二进制文件的时候,想更改二进制文件的过期天数,发现日期如果设置成2位以上的整数.都会出现如下的警告.不能成功的设置过期日期天数.MySQL版本从5.1到5.5都是一样的. mysql ...
- C++中虚函数和纯虚函数的区别与总结
首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实 ...
- 关于C/C++中main函数参数的学习
因为面对对象作业(2018.5.21)的要求,去学习了C/C++中main函数参数的意义,以及一些简单的使用(从命令行指令的接受),不给予赘述.(仅为个人拙见,还望看官指正) 首先,带有参数的main ...
- Merge k Sorted Lists, k路归并
import java.util.Arrays; import java.util.List; import java.util.PriorityQueue; /* class ListNode { ...
- Spring scope解惑
在2.0之前只有两种singleton和prototype(网上说的,没去验证),后面增加了session.request.global session三种专门用于web应用程序上下文的Bean Si ...