note.nkmk.me

NumPy配列ndarrayをタイル状に繰り返し並べるnp.tile

Date: 2019-03-19 / tags: Python, NumPy, 画像処理

NumPyの関数np.tile()を使うと配列ndarrayを任意のタイル状に繰り返し並べた新たなndarrayを生成できる。

ここでは以下の内容について説明する。

  • np.tile()の基本的な使い方
  • 二次元配列(多次元配列)の場合
  • 画像処理への応用(タイル状に繰り返し並べる)
スポンサーリンク

np.tile()の基本的な使い方

一次元配列を例とする。

import numpy as np

a = np.arange(3)
print(a)
# [0 1 2]

np.tile()の第一引数Aに元のndarray、第二引数repsに繰り返す数を指定する。新たな配列が返され、元の配列自体は変更されない。

a_tile = np.tile(a, 3)
print(a_tile)
# [0 1 2 0 1 2 0 1 2]

print(a)
# [0 1 2]

第二引数repsにタプルを指定すると、各軸に対して元の配列が繰り返される。

例えばreps(2, 3)とすると、axis=0(行方向)に2回、axis=1(列方向)に3回繰り返され、結果は二次元配列になる。

なお行方向・列方向という言葉は定義が曖昧だが、ここでは行数が増えると伸びていく方向(=縦)を行方向、列数が増えると伸びていく方向(=横)を列方向としている。

print(np.tile(a, (2, 3)))
# [[0 1 2 0 1 2 0 1 2]
#  [0 1 2 0 1 2 0 1 2]]

print(np.tile(a, (2, 3)).shape)
# (2, 9)

タプルの要素数が増えた場合も考え方は同じ。タプルの要素数が3だと三次元配列となる。

print(np.tile(a, (2, 3, 4)))
# [[[0 1 2 0 1 2 0 1 2 0 1 2]
#   [0 1 2 0 1 2 0 1 2 0 1 2]
#   [0 1 2 0 1 2 0 1 2 0 1 2]]
# 
#  [[0 1 2 0 1 2 0 1 2 0 1 2]
#   [0 1 2 0 1 2 0 1 2 0 1 2]
#   [0 1 2 0 1 2 0 1 2 0 1 2]]]

print(np.tile(a, (2, 3, 4)).shape)
# (2, 3, 12)

二次元配列(多次元配列)の場合

元の配列ndarrayが多次元配列の場合として二次元配列を例とする。

a_2d = np.arange(6).reshape(2, 3)
print(a_2d)
# [[0 1 2]
#  [3 4 5]]

第二引数repsを整数で指定したり、元の配列の次元数ndim(二次元配列の場合は2)より少ない要素数のタプルで指定したりする場合、最後の次元の軸に沿って元の配列が繰り返される。

例えばreps=2reps=(2, )(要素数1個のタプル)とすると以下のような結果となる。

print(np.tile(a_2d, 2))
# [[0 1 2 0 1 2]
#  [3 4 5 3 4 5]]

print(np.tile(a_2d, (2, )))
# [[0 1 2 0 1 2]
#  [3 4 5 3 4 5]]

これはreps=(1, 2)と等価。axis=1に対して2回繰り返される。

print(np.tile(a_2d, (1, 2)))
# [[0 1 2 0 1 2]
#  [3 4 5 3 4 5]]

axis=0に対してのみ繰り返したい場合は、例えばreps=(2, 1)とすればよい。

print(np.tile(a_2d, (2, 1)))
# [[0 1 2]
#  [3 4 5]
#  [0 1 2]
#  [3 4 5]]

一次元配列の例と同様に、元の配列より次元を増やすことも可能。

print(np.tile(a_2d, (2, 2, 2)))
# [[[0 1 2 0 1 2]
#   [3 4 5 3 4 5]
#   [0 1 2 0 1 2]
#   [3 4 5 3 4 5]]
# 
#  [[0 1 2 0 1 2]
#   [3 4 5 3 4 5]
#   [0 1 2 0 1 2]
#   [3 4 5 3 4 5]]]

print(np.tile(a_2d, (2, 2, 2)).shape)
# (2, 4, 6)

画像処理への応用(タイル状に繰り返し並べる)

np.tile()を利用するとNumPy配列ndarrayとして読み込んだ画像をタイル状に繰り返し並べることができる。

画像の読み込みや保存などNumPyを使った画像処理の基礎については以下の記事を参照。

ここではPillowを使って画像を読み込んでいるが、ndarrayとして読み込むのであればOpenCVなど他のライブラリを使っても同じ。

カラー画像の場合、読み込んだndarrayshape(形状)は(高さ, 幅, 色数)となる。

これをnp.tile()で繰り返すには第二引数reps(縦の繰り返し数, 横の繰り返し数, 1)とする。末尾の1がない(縦の繰り返し数, 横の繰り返し数)とすると、上述のように(1, 縦の繰り返し数, 横の繰り返し数)とみなされてしまいうまくいかないので注意。

import numpy as np
from PIL import Image

img = np.array(Image.open('data/src/lena_square.png').resize((128, 128)))

print(img.shape)
# (128, 128, 3)

img_tile = np.tile(img, (2, 3, 1))

print(img_tile.shape)
# (256, 384, 3)

Image.fromarray(img_tile).save('data/dst/lena_numpy_tile.jpg')

元の画像。上のサンプルコードでは読み込み時に縮小して使っている。

lena square

タイル状に並べた画像。

np.tile image

例のように、np.tile()では同じ画像を繰り返し並べることしかできない。異なる画像をタイル状に並べたい場合は以下の記事を参照。

np.tile()を活用した例として、グラデーション画像の生成がある。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事