深層学習特に画像分類・物体検知タスクで精度を上げるために画像回転・左右反転を行って、教師画像を増やす、ということがよーく行われます。
ただ、それらのタスクって、意外に重たい処理だったりするので、
並列処理を実行することで、手軽に(=大袈裟過ぎない範囲で)速く終わらせることを目的に書いたスクリプトです。
今回は、並行処理にjoblib
を利用。
ライブラリ設定
import cv2
from scipy import ndimage
import os
from joblib import Parallel, delayed
もろもろ設定
とりあえず、デフォルトで、30度ずつ回転させる前提でのスクリプトです。
画像数の増減に関しては、適宜設定値を変えるなり、引数でそれらを与える感じに書き直すのもいいかも知れません。
## 角度の定義
rIntr = 30
## 回転開始角度
rs = 30
##回転終了角度
re = 330
## input images
Image_DIR = '<Replace your path for input images>'
## output images
output_DIR = '<Replace your path for output images>'
関数
def getFilesInDirectory(directory, postfix = ""):
fileNames = [s for s in os.listdir(directory) if not os.path.isdir(os.path.join(directory, s))]
if not postfix:
return fileNames
else:
return [s for s in fileNames if s.lower().endswith(postfix)]
## mirror inversion
def generate_flip(I):
fimg = I.copy()
return cv2.flip(fimg ,0)
## Generate(rotate) images & store for each image
def generate_rot(imgFilename, rs, re, rIntr, output_DIR, image_type):
I = cv2.imread(imgFilename)
## mirror-inversion, if needed
if image_type == 'Reverse':
I = generate_flip(I)
for r in range(rs, re+1, rIntr):
## Rotation of each image
Irot = ndimage.rotate(I, r, reshape=False)
## Store images
FILENAME = imgFilename+'_'+str(image_type)+'_'+str(r)+'.jpg'
print('Completed for '+str(FILENAME))
cv2.imwrite(os.path.join(output_DIR,FILENAME), Irot)
実行
if __name__ == "__main__":
## Input imageのファイル名取得
os.chdir(Image_DIR)
imgFilenames = getFilesInDirectory(Image_DIR, ".jpg")
## Normal rotation
Parallel(n_jobs=-1, verbose=3,
backend="threading"
)([delayed(generate_rot)(imgFilename=imgFilename,
rs=rs,
re=re,
rIntr=rIntr,
output_DIR=output_DIR,
image_type='Normal')
for imgFilename in imgFilenames])
## Reverse rotation
Parallel(n_jobs=-1, verbose=3,
backend="threading"
)([delayed(generate_rot)(imgFilename=imgFilename,
rs=rs,
re=re,
rIntr=rIntr,
output_DIR=output_DIR,
image_type='Reverse')
for imgFilename in imgFilenames])