資料擴增(Data Agumentation)是一種用於機器學習中
資料不夠時,增加更多等價資料的手段

安裝套件

這邊用到的是keras裡對影像做前處理的ImageDataGenerator
所以首先當然要先安裝Keras
由於keras需要用到Tensorflow,所以我們也一起安裝

1
2
pip install tensorflow
pip install Keras

安裝完套件後,在程式的最一開始載入

1
2
from keras.preprocessing.image import ImageDataGenerator
import cv2

翻轉

建立垂直翻轉與水平翻轉的物件

1
2
datagen_vertical=ImageDataGenerator(vertical_flip=True, horizontal_flip=False)
datagen_horizontal=ImageDataGenerator(vertical_flip=False, horizontal_flip=True)

需要注意的是,翻轉執行後未必會真的翻轉
簡單來說就是當你對100張圖片進行翻轉,可能只產生95張經過翻轉的圖片、5張原圖

錯切變換

Shear Range是一種固定X軸,將Y軸改變的方法(或是反過來)

1
datagen_shear=ImageDataGenerator(shear_range=100.0)

舉例來說,原本的圖片長這樣

使用Shear Range後會變成這樣,扭曲的程度由參數控制

更多資料增強手段

這邊僅介紹vertical/horizontal flip與shear range等三種方法
事實上還有更多方式能夠增加資料量
如vertical/horizontal shift, zoom, rotation…等
可以參考Keras的官方文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
tf.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,
channel_shift_range=0.0,
fill_mode="nearest",
cval=0.0,
horizontal_flip=False,
vertical_flip=False,
rescale=None,
preprocessing_function=None,
data_format=None,
validation_split=0.0,
dtype=None,
)

完整程式碼

以下程式碼對整個目錄進行資料增強
每張圖片分別生成一張水平翻轉、一張垂直翻轉、一張錯切變換

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from keras.preprocessing.image import ImageDataGenerator
import cv2
from os import listdir

d='路徑名稱改這裡~~'
#初始化物件,建立垂直翻轉、水平翻轉、錯切變換。而翻轉實際執行時為隨機挑選,不是每個圖片都會被翻轉
datagen_vertical=ImageDataGenerator(vertical_flip=True, horizontal_flip=False)
datagen_horizontal=ImageDataGenerator(vertical_flip=False, horizontal_flip=True)
datagen_shear=ImageDataGenerator(shear_range=100.0)

print("Processing...")
for file in listdir(d):
img=cv2.imread(d+'\\'+file,3) #3:讀取圖片中所有的 channels,包含透明度的 channel。
img1=img.reshape((1,)+img.shape) #reshape中的1代表讀入一張圖片
i=1
#記得創建目標資料夾(注意目標資料夾不可創立在原本的資料夾路徑下,建議與此.py放一樣的位置)
for batch in datagen_vertical.flow(img1, batch_size=1, save_to_dir='Argumentation', save_prefix='vertical_flip_'+file.split('.')[0]):
i+=1
if i>1:
break
for batch in datagen_horizontal.flow(img1, batch_size=1, save_to_dir='Argumentation', save_prefix='horizontal_flip_'+file.split('.')[0]):
i+=1
if i>=2:
break
for batch in datagen_shear.flow(img1, batch_size=1, save_to_dir='Argumentation', save_prefix='shear_range_'+file.split('.')[0]):
i+=1
if i>=2:
break
print ('done')