Deep Learning等で大きな画像をいくつかに分割したり、分割した画像を結合させたりすることがよくあるが、まとまった記事がなさそうだったのでメモ。
動作環境
- Ubuntu 16.04
- Python 3.5.2
- numpy 1.13.3
- opencv-python 3.2
画像の分割(vsplit、hsplit)
画像の分割にはnumpyのvsplit(縦方向分割)とhsplit(横方向分割)を使用する。注意点としては分割する画像の画素数が分割数で割り切れること。詳細はリファレンスマニュアルを参照のこと。
使用している変数の説明
| 変数名|役割|
|:------|------------------:|:------------------:|
|img|入力画像(OpenCVで読み込んだものを想定)|
|size|分割したい画素数(今回は64x64の画像にしたいので64)|
|v_size|(縦方向分割用)sizeで割り切れるよう画素の端数を切り捨てた値|
|h_size|(横方向分割用)sizeで割り切れるよう画素の端数を切り捨てた値|
|v_split|np.vsplitに入力する分割数|
|h_split|np.hsplitに入力する分割数|
使用する画像
縦方向だけの分割
import numpy as np
v_size = img.shape[0] // size * size
h_size = img.shape[1]
img = img[:v_size, :h_size]
v_split = img.shape[0] // size
out_img = []
out_img.extend(np.vsplit(img, v_split))
結果
横方向だけの分割
import numpy as np
v_size = img.shape[0]
h_size = img.shape[1] // size * size
img = img[:v_size, :h_size]
h_split = img.shape[1] // size
out_img = []
out_img.extend(np.hsplit(img, h_split))
結果
縦横の分割
import numpy as np
v_size = img.shape[0] // size * size
h_size = img.shape[1] // size * size
img = img[:v_size, :h_size]
v_split = img.shape[0] // size
h_split = img.shape[1] // size
out_img = []
[out_img.extend(np.hsplit(h_img, h_split))
for h_img in np.vsplit(img, v_split)]
結果
複数枚の縦横の分割
import numpy as np
v_size = imgs[0].shape[0] // size * size
h_size = imgs[0].shape[1] // size * size
imgs = [i[:v_size, :h_size] for i in imgs]
v_split = imgs[0].shape[0] // size
h_split = imgs[0].shape[1] // size
out_imgs = []
[[out_imgs.extend(np.hsplit(h_img, h_split))
for h_img in np.vsplit(img, v_split)] for img in imgs]
画像の結合(vstack、hstack)
分割した画像を結合するときはnumpyのvstack(縦方向結合)とhstack(横方向結合)を使用する。詳細は分割と同様にリファレンスマニュアルを参照のこと。今回はそのまま結合しても面白くないので、画像をシャッフルして結合する。
shuffle = np.random.permutation(range(len(img)))
img = np.vstack((
np.hstack(img[shuffle[0:5]]),
np.hstack(img[shuffle[5:10]]),
np.hstack(img[shuffle[10:15]]),
))
imgを直接シャッフルしていないのは汎用性を持たせるため。