CV学习笔记(二十):数据集拼接生成
作者:云时之间
来源:知乎
链接:https://zhuanlan.zhihu.com/p/139918526
编辑:王萌
上一次使用了text_renderer尝试生成类似于银行卡的数据,但是实际下来效果并不好,我分析了一下原因:
①:text_renderer输出的背景和真实银行卡图片有很大的差异
②:大多数银行卡采用的是突出的字体,text_renderer很难去模拟
分析出以上的问题后,现在的重点开始转换成如何去近似的模拟银行卡数据集,最好的方法就是使用真实的银行卡卡号片段来拼接成数据。
一边说代码,一边捋顺思路:
一:准备数据
首先准备了大概50张的银行卡卡号片段的真实图片,尽量保证每张图片的长度为3-4位,为什么分为3-4位?分析了大多数的银行卡后,发现一个规律:
信用卡卡号:0000 0000 0000 0000
储蓄卡卡号:0000 0000 0000 0000 000
我们用CTPN检测的时候,往往会一段一段的检测,然后拼接起来,这种效果理论上会更好准备的数据如下:
图片的分辨率180*46
现在分析代码:
第一步:选择生成数量,读取图片
这部分注释很清楚,不再赘述
二:裁剪图片,拼接图片
这部分是整个程序之中的关键,我绘制了一个图,结合图来说一下
因为准备的数据集是3-4个字符一张图,DenseNet的输入长度为10时比较合适(具体为什么还没搞清楚),因此拼接的图片字符长度也是10个字符:读取图片
这里用到cut_image函数对image3进行裁剪:
裁剪前后对比:
对图片进行拼接:
拼接后效果:
三:数据增强
因为DenseNet的输入为280*32的图像,并且为减少计算,需要将图像转换为灰度图像
转换为灰度图像后,这里需要使用ImageDataGenerator类,简单的说ImageDataGenerator是keras.processing.image模块里的图片生成器,每次喂进去一个batch_size的数据,然后对这个批次的数据进行样本增强,用来扩充样本数据集的大小,增强模型的泛化能力,更模拟真实情况,比如旋转,缩放,对比度转换等等。
四:划分训练集和测试集
我们将训练集和测试集按照8:2的比例进行划分
运行,数据生成完毕
五:代码
import osimport numpy as npimport cv2from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_imgimport os#ToTAL是生成样本种子数量 ,真实样本数量为 TOTAL * 10print("--------实际生成样本数为ToTal* 10--------")TOTAL=int(input("输入要生成的种子数:"))#图片路径,显示图片的名称path_image=r'./images_base/'list_path=os.listdir(path_image)loca=["0,0,30,46","30,0,60,46","60,0,90,46","90,0,120,46"]ALLIMAGE=len(list_path)#得到给出的训练集数量,image_base的数量print("总共{0}张图片,需要生成{1}张图片\n------------正在生成中------------------".format(ALLIMAGE,TOTAL*10))if not os.path.exists("./images"): os.mkdir("./images")#对半裁图片,输入图片从120*46->60*46def cut_image(imge,l2,l3,l0=0,l1=46): src2 = imge[l0:l1, l2:l3] return src2for i in range(TOTAL): #生成0-allmage,三个的随机数 rad_num=np.random.randint(0,ALLIMAGE,(1,3)) img_path=[] for j in rad_num[0]: #取image_base里边的随机图片 img_path.append([r"./images_base/"+str(list_path[j])]) # img_path=img_path[0] imge1=cv2.imread(" ".join(img_path[0])) imge2 = cv2.imread(" ".join(img_path[1])) imge3 = cv2.imread(" ".join(img_path[2])) src1=cut_image(imge3, 0, 60) tmp = np.zeros((46, 300, 3), np.uint8) tmp[0:46, 0:120] = imge1 tmp[0:46, 120:240] = imge2 tmp[0:46, 240:300] = src1 cv2.imshow("-",tmp) cv2.waitKey(0) ''' 名称为image1的前4位+image2前4位+src1的前两位 ''' name = " ".join(img_path[0]).split("/")[2][0:4] + " ".join(img_path[1]).split("/")[2][0:4] + \ " ".join(img_path[2]).split("/")[2][0:2] + "I" # print(name) ''' tmp输入300*46->DenseNet输入为280*32->Reshape后灰度 ''' tmp = cv2.resize(tmp, (280, 32)) tmp = cv2.cvtColor(tmp, cv2.COLOR_BGR2GRAY) ''' 数据增强: 随机旋转,除以总宽度0.01,除以总宽度0.015, 空间随机缩放范围0.06 随机填充 ''' datagen = ImageDataGenerator( #数据增强 rotation_range=2, width_shift_range=0.01, height_shift_range=0.015, zoom_range=0.06, fill_mode='nearest') #把图片的整数结构转成浮点型 x = img_to_array(tmp) x = x.reshape((1,) + x.shape) i = 0 ''' 接收numpy数组和标签为参数,生成经过数据提升或标准化后的batch数据,并在一个无限循环中不断的返回batch数据 ''' for batch in datagen.flow(x, batch_size=1, # save_to_dir 文件夹 prefix图片名字 format格式 save_to_dir='images', save_prefix=name, save_format='jpg'): i += 1 if i > 10: # 如果不break会无限循环 break # otherwise the generator would loop indefinitely # cv2.imwrite("./out_data/" + name, tmp)print("=====生成数据集======")path_image=r'./images/'list_path=os.listdir(path_image)'''生成训练集和测试集的txt文件'''f1=open("./data_train.txt",'w')f2=open("./data_test.txt",'w')for i in list(list_path)[0:int(len(list_path)*0.8)]: #划分80%训练 f1.write(""+str(i)) label=list(i)[0:10] for j in label: if j=="_": f1.write(" " + str(11)) else: f1.write(" "+str(int(j)+1)) f1.write("\n")for i in list(list_path)[int(len(list_path)*0.8):]: f2.write(""+str(i)) label=list(i)[0:10] for j in label: if j=="_": f2.write(" " + str(11)) else: f2.write(" "+str(int(j)+1)) f2.write("\n")print("数据集生成完毕")
©著作权归作者所有:来自51CTO博客作者mb5fca0b6a49e47的原创作品,如需转载,请注明出处,否则将追究法律责任
更多相关文章
- CV学习笔记(二十五):数据集标注与制作
- CV学习笔记(二十七):Python Base64 格式图片上传
- 数据结构与算法—小白也能搞懂二叉排序(查找)树
- 数据结构与算法—队列(搞懂最常用数据结构之一)
- 数据结构与算法—栈详解(看完面试考试再也不怕了)
- 一文多图搞懂数据结构的双链表!
- 数据结构于算法—线性表详解(顺序表、链表)
- 浅谈网路爬虫
- 数据结构与算法—绪论