今天就来一招搞定数据增强(data_Augmentation),让你在机器学习/深度学习图像处理的路上,从此不再为数据不够而发愁。且来看图片从250张>>>>任意张的华丽增强,每一张都与众不同。
开始之前呢,我们先把这件大事给细分下,一步一步的来:
首先,图像读取,需要对文件夹操作;
然后,增强图像(重点,重点,重点);
最后,保存图像。
来看下此次任务中,待增强的图像和标签,主要是为了做图像分割做图像准备。这个图像懂的应该能看出来,这是一个婴儿头围的医学图像,现实场景意义很强。上图(以3张图为例):
train_img
train_label
成双成对,这样在后续的文件读取中会比较的方便(大神可以自己改改,练练动手能力)
那动手吧!!!
ImageDataGenerator()是keras.preprocessing.image模块中的图片生成器,同时也可以在batch中对数据进行增强,扩充数据集大小,增强模型的泛化能力。比如进行旋转,变形,归一化等,它所能实现的功能且看下面的详细部分吧。
keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,samplewise_center=False,featurewise_std_normalization=False,samplewise_std_normalization=False,zca_whitening=False,zca_epsilon=1e-06,rotation_range=0,#整数。随机旋转的度数范围。width_shift_range=0.0,#浮点数、一维数组或整数height_shift_range=0.0,#浮点数。剪切强度(以弧度逆时针方向剪切角度)。brightness_range=None,shear_range=0.0,zoom_range=0.0,#浮点数或[lower,upper]。随机缩放范围channel_shift_range=0.0,#浮点数。随机通道转换的范围。fill_mode=nearest,#{'constant','nearest','reflect'or'wrap'}之一。默认为nearest。输入边界以外的点根据给定的模式填充:cval=0.0,horizontal_flip=False,vertical_flip=False,rescale=None,preprocessing_function=None,data_format=None,validation_split=0.0,dtype=None)这里就以单张图片为例,详述下这个图像增强大杀器的具体用法,分别以旋转(rotation_range),长宽上平移(width_shift_range,height_shift_range)
输入图像:
先来看下两者合并后的图像:
merge
到这里,我们进行增强变换,演示下这里增强部分是咋用的,且看:滑慢点,有GIF图
otation=1.2
width_shift_range=0.05
eight_shift_range=0.05
这里才只是演示了三个就那么的强大,详细,这要能增强多少图片啊,想想都可怕,想都不敢想啊!!!
增强汇总
这里是合并部分,单幅增强的大图效果详情看这里:
merge改变通道排布方式
这里,且看单幅图像的增强代码(建议去下载仔细看,往后看,有方式):
这里先说下对图像和标签一起增强的步骤,有人该问为什么还要标签了。这里针对的问题是图像分割,pix2pix的任务,即输入时一般图像,输出是目标分割后图像,在上面就是train_img和train_label的一一对应关系,这里开始分解步骤来说增强:
1.train_img+train_label=merge,也就是图像+椭圆形的那个;2.对merge图像进行增强;3.将merge图像按通道拆分,1的逆过程。
前面只涉及步骤1和2,故先对这两块做详述,如下:着重讲下Augmentation类中augmentation函数部分和对单幅图像增强部分。
1.读取train_img,train_label;
#load_imageimg_t=load_img('../one/img/0.png')img_l=load_img('../one/label/0.png')2.因为要讲上述img_t和img_l进行合并,采用矩阵形式进行操作,这里将读取到的图像转换为矩阵形式;
3.train_img+train_label=merge.把label当做train的第三个通道
后面注释部分,是对合并后的通道进行任意组合的形式,会出现不同的效果,如前文中三个特写图(具体自己可尝试)
#把label当做train的第三个通道x_t[:,:,2]=x_l[:,:,0]#x_t=x_t[...,[2,0,1]]#image-102,120,2104.为了保存merge后图像,此时该从array_to_image了,然后保存图像文件;
5.此时执行对merge图像的增强操作;
开始前,既然我们要defdo_augmentate(),我们先想想对一幅图像的增强,需要些什么:
image图像文件;
save_to_dir保存增强后的文件夹地址;
批增强的数量。
至于别的,先看这里
flow(self,X,y,batch_size=32,shuffle=True,seed=None,save_to_dir=None,save_prefix=,save_format=png)x:样本数据,秩应为4,在黑白图像的情况下channel轴的值为1,在彩色图像情况下值为3y:标签batch_size:整数,默认32shuffle:布尔值,是否随机打乱数据,默认为Truesave_to_dir:None或字符串,该参数能让你将提升后的图片保存起来,用以可视化save_prefix:字符串,保存提升后图片时使用的前缀,仅当设置了save_to_dir时生效save_format:'png'或'jpeg'之一,指定保存图片的数据格式,默认'jpeg'yields:形如(x,y)的tuple,x是代表图像数据的numpy数组.y是代表标签的numpy数组.该迭代器无限循环.seed:整数,随机数种子flow:接收numpy数组和标签为参数,生成经过数据提升或标准化后的batch数据,并在一个无限循环中不断的返回batch数据
6.由于flow的输入X需要一个秩为4的数组,所以需要对他变形,加上img.shape=3
话不多说,先看下拆分代码部分,还是先说步骤:
1.读取merge文件夹内图片;2.按照之前组合的形式进行拆分为img_train和img_label,同时保存在两个文件夹内,一一对应。
Pythonrindex()返回子字符串str在字符串中最后出现的位置,如果没有匹配的字符串会报异常,你可以指定可选参数[beg:end]设置查找的区间。
举个栗子:
打印的结果
现在,把上文中的一段专门来看下打印结果
截取图像地址
最后,看下拆分后的图片保存的结果吧!!!
aug_train_img
aug_train_label
这里特意说下,图像的数量是自己设置的,在这里,imgnum数量,决定了对单幅图像增强的数量。(如果你需要对其中增强的多一些,就把这块给修改下)
defdo_augmentate(self,img,save_to_dir,save_prefix,batch_size=1,save_format=png,imgnum=30):四、图像增强之批处理这块的内容,不想做太多的解释了,只是由单幅图像的读取,改为对文件夹内所有图片的读取。
批处理部分train_img,2是文件名
批处理部分train_label,14是文件名
注意:待增强的图像放在image文件夹下的子文件夹下,例如,待增强图片在文件夹flower内,则此事flower的文件夹是image的子文件夹,这里多进行尝试就好。
原图
增强后的图像
同时呢,自己需要哪些变换,可以自行对ImageDataGenerator内容就行查询修改,这里不赘述;
简单粗暴,原图是这样的:
简单的几句代码,就能够实现许许多多的增强结果
importAugmentor#待增强图像放在test文件夹下即可#会自动的创建output文件,用于保存增强后的图像p=Augmentor.Pipeline('./test')#增强的方式,逆时针随机旋转90度(随机概率可自行设定)p.rotate90(probability=0.5)p.skew_corner(probability=0.7,magnitude=1)#增强的个数p.sample(20)来看下增强后的结果,代码中的注释部分很详细,主要是做了这几件事情:
更加多样的增强方式和数量可以自行增加。(美女都被拉变形了,罪恶啊罪恶)