有的时候我们训练网络的时候,数据集在收集的过程中由于种种原因导致图像收集的不完整,比如某些种类很少,或者没有,这个时候我们就可以考虑自己生成数据集。

这个和data augmentation还不太一样,data augmentation是在数据集上做一些变化,得到更多的数据,数据生成是直接生成一些数据集。

在做OCR识别的时候,因为有些类型的数据量很少,所以就考虑了一下数据生成的方法。

安装 imagemagick 工具

imagemagick 工具,可以用来生成不同字体的图像。

imagemagick安装

生成图像格式

为了让生成的图像更加真实,我做了一下操作

  1. 修改字体
  2. 添加背景
  3. 旋转角度
  4. 增加噪点

具体实现

#coding=utf8
import os
import cv2
import pickle
import random
from glob import glob
import numpy as np # 为图像添加背景
def add_background(img):
# 从自然场景中选择一些图像,因为我是做OCR,所以我从ICDAR 2015的数据集选择了一些图像
bg_imgs_path = glob('background/*.jpg')
bg_img = cv2.imread(bg_imgs_path[random.randint(0, len(bg_imgs_path)-1)])
bg_img = cv2.cvtColor(bg_img, cv2.COLOR_RGB2GRAY)
# 这个大概是一个字的像素大小,根据具体场景而定
start_y = random.randint(0, bg_img.shape[0]-9)
start_x = random.randint(0, bg_img.shape[1]-9)
bg_img = cv2.resize(bg_img[start_y:start_y+8, start_x:start_x+8], img.shape)
beta = 0.5
# 像素叠加
return img * (1 - beta) + bg_img * beta # 随机噪点
def salt_and_pepper(img,noise_num):
noise_img = img
for i in range(noise_num):
randX = random.randint(0, img.shape[0]-1)
randY = random.randint(0, img.shape[1]-1)
if random.randint(0, 1) == 0:
noise_img[randX,randY]=0
else:
noise_img[randX,randY]=255
return noise_img # 增加噪声,高斯平滑
def add_noise(img):
# 这里没有增加噪点
img = salt_and_pepper(img, random.randint(0, 0))
filter_size = random.randint(0, 3) * 2 + 1
# 高斯平滑
img = cv2.GaussianBlur(img, (filter_size, filter_size), sigmaX=0)
return img # 旋转图像
def rotate_image(mat, angle):
# angle in degrees
# opencv python和c++的接口,这里顺序是相反的
height, width = mat.shape[:2]
image_center = (width/2, height/2)
rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.)
abs_cos = abs(rotation_mat[0,0])
abs_sin = abs(rotation_mat[0,1])
bound_w = int(height * abs_sin + width * abs_cos)
bound_h = int(height * abs_cos + width * abs_sin)
rotation_mat[0, 2] += bound_w/2 - image_center[0]
rotation_mat[1, 2] += bound_h/2 - image_center[1]
rotated_mat = cv2.warpAffine(mat, rotation_mat, (bound_w, bound_h))
return rotated_mat # 设置需要生成的数据集列表,格式: index num
# index 表示在种类标签中的索引,也就是第几类,num表示此类图像已有的个数
label_path = 'sup_remain_data.txt'
# 输出目录
local_dir = 'supplement2/' # 输出生成数据集的标签值
gen_suppl_list = 'supplement2/gen_supplement2.txt' # 每一类图像都生成总共110张,如果已经有一部分了,只需要生成剩下部分的
pic_num = 110 # 100:10
train_num = 100
test_num = 10 # 设置种类和要生成的图像个数
label_genNum = {}
with open(label_path) as fin:
lines = fin.readlines()
for line in lines:
label, num = line.strip().split(' ')
label_genNum[label] = pic_num - int(num) # 读入所有标签种类
std_label = {}
with open('data.txt') as fin:
lines = fin.readlines()
for index, line in enumerate(lines):
std_label[str(index)] = line.strip() #grav=['NorthWest','North','NorthEast','West','Center','East','SouthWest','South','SouthEast']
bgcolor=['black','white', 'gray', 'gray', 'black', 'white']
fillcolor=['white','black','black', 'white', 'gray', 'gray']
# 这个目录下放当前文字常用字体格式文件
ttfs=glob('ttfs/*') count = 0
with open(gen_suppl_list, 'w') as fout:
for label, gen_num in label_genNum.items():
count += 1
print count
for i in range(gen_num):
img_name = label + '_' + str(i) + '.jpg'
print str(label) + ' ' + std_label[label] + ' ' + label + '_' + str(i)
fout.write(str(label) + ' ' + std_label[label] + ' ' + label + '_' + str(i) +'\n')
if os.path.exists(local_dir+img_name):
continue
#index_g = random.randint(0, len(grav)-1)
index_b = random.randint(0, len(bgcolor)-1)
index_t = random.randint(0, len(ttfs)-1)
#font_size = random.randint(20, 40)
# 设置字体、填充方式、背景颜色、像素点大小、图像输出大小
system_cmd = 'convert -font {0} -fill {1} -background {2} -pointsize 30 -colorspace Gray -gravity "Center" ' \
'-size 40x40 label:"{3}" "{4}"'.format(ttfs[index_t], fillcolor[index_b], bgcolor[index_b], std_label[str(label)], local_dir+img_name)
os.system(system_cmd)
img = cv2.imread(local_dir+img_name, 0)
# 几种变化效果叠加,这样生成的图像就是具有多种效果的,不需要单独每种效果生成过多的图像
img = add_background(img)
img = add_noise(img)
img = rotate_image(img, random.randint(-5, 5))
#cv2.imshow('gen image', img)
#cv2.waitKey(0)
cv2.imwrite(local_dir+img_name, img) print count
print 'language supplement-set 生成完毕...'

OCR训练数据生成方法的更多相关文章

  1. pytorch:EDSR 生成训练数据的方法

    Pytorch:EDSR 生成训练数据的方法 引言 Winter is coming 正文 pytorch提供的DataLoader 是用来包装你的数据的工具. 所以你要将自己的 (numpy arr ...

  2. 谷歌BERT预训练源码解析(一):训练数据生成

    目录预训练源码结构简介输入输出源码解析参数主函数创建训练实例下一句预测&实例生成随机遮蔽输出结果一览预训练源码结构简介关于BERT,简单来说,它是一个基于Transformer架构,结合遮蔽词 ...

  3. tflearn kears GAN官方demo代码——本质上GAN是先训练判别模型让你能够识别噪声,然后生成模型基于噪声生成数据,目标是让判别模型出错。GAN的过程就是训练这个生成模型参数!!!

    GAN:通过 将 样本 特征 化 以后, 告诉 模型 哪些 样本 是 黑 哪些 是 白, 模型 通过 训练 后, 理解 了 黑白 样本 的 区别, 再输入 测试 样本 时, 模型 就可以 根据 以往 ...

  4. 生成JSON数据--官方方法

    官方生成方法: 1)需要什么就给什么,要属性就给属性,要对象就给对象,要集合就给集合 2)添加都是使用put()方法 要求: 1.生成如下JSON数据: {"age":4,&quo ...

  5. 对抗生成网络-图像卷积-mnist数据生成(代码) 1.tf.layers.conv2d(卷积操作) 2.tf.layers.conv2d_transpose(反卷积操作) 3.tf.layers.batch_normalize(归一化操作) 4.tf.maximum(用于lrelu) 5.tf.train_variable(训练中所有参数) 6.np.random.uniform(生成正态数据

    1. tf.layers.conv2d(input, filter, kernel_size, stride, padding) # 进行卷积操作 参数说明:input输入数据, filter特征图的 ...

  6. [Oracle]快速生成大量模拟数据的方法

    快速生成大量模拟数据的方法: create table TEST(id integer, TEST_NUMBER NUMBER(18,6)); insert into TEST select i+j, ...

  7. QT使用QJson生成解析Json数据的方法

    QT中使用json还是比较方便的,下面用例子直接说明 举例子之前首先推荐一个在线解析json格式的网站,具体格式用法如下图所示: 之后根据这个格式进行json数据解析. QT使用json需要包含的头文 ...

  8. oracle中生成大批量数据的方法-下

    方法五:使用PLSQL的数据生成器 首先测试环境建立:dept表 CREATE TABLE dept(deptno NUMBER(6),dname VARCHAR2(20),loc VARCHAR2( ...

  9. tensorflow读取训练数据方法

    1. 预加载数据 Preloaded data # coding: utf-8 import tensorflow as tf # 设计Graph x1 = tf.constant([2, 3, 4] ...

随机推荐

  1. js一个数组变为指定长度的多个数组

    var dataArr = [0,1,2,3,4,5,6,7,8,9,10]; var newArr = []; var s = parseInt(dataArr.length / 4); var n ...

  2. cascade(级联)和inverse关系详解

    序言 写这篇文章之前,自己也查了很多的资料来搞清楚这两者的关系和各自所做的事情,但是百度一搜,大多数博文感觉说的云里雾里,可能博主自己清楚是怎么一回事,但是给一个不懂的人或者一知半解的人看的话,别人也 ...

  3. 爬虫实战【10】利用Selenium自动登陆京东签到领金币

    今天我们来讲一下如何通过python来实现自动登陆京东,以及签到领取金币. 如何自动登陆京东? 我们先来看一下京东的登陆页面,如下图所示: [插入图片,登陆页面] 登陆框就是右面这一个框框了,但是目前 ...

  4. vs2008 怎么在Release下调试代码

    vs2008 怎么在Release下调试代码 (适用VS2005/VS2008) 在当前工程点击右键选择properties,选择 All Configurations C++>General- ...

  5. iis express worker process已停止工作

    以管理员方式运行命令提示符工具,然后执行以下语句 netsh winsock reset 重启电脑

  6. HDU 3388 Coprime(容斥原理+二分)

    Coprime Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. 转!!DNS域名解析使用的是TCP协议还是UDP协议?

    原文地址:https://segmentfault.com/a/1190000006100959 DNS同时占用UDP和TCP端口53是公认的,这种单个应用协议同时使用两种传输协议的情况在TCP/IP ...

  8. Notice公告

    把网页放大到125%食用效果更佳 考试题目的密码是ftp的密码 博猪很菜,菜得抠脚,如果写的有什么问题可以在评论区指出:-) 博猪qq:1755833514

  9. POS杂项数据SAP记账程序

    *&---------------------------------------------------------------------* *& Report ZDQFI_904 ...

  10. JVM原理及内存结构

    JVM是按照运行时数据的存储结构来划分内存结构的,JVM在运行java程序时,将它们划分成几种不同格式的数据,分别存储在不同的区域,这些数据统一称为运行时数据.运行时数据包括java程序本身的数据信息 ...