【Numpy】np.tile()で作る禰豆子の帯の柄
『鬼滅の刃』の竈門禰豆子の帯の柄を、Numpyのnp.tile()
を使って作ってみる。
作業環境
【参考】
NumPy配列ndarrayをタイル状に繰り返し並べるnp.tile | note.nkmk.me
np.tile()の使い方の確認
配列.repeat(回数, axis=軸)
とnp.tile(配列, (1次元倍率, 2次元倍率,3次元倍率))
は元の配列を次元軸に数倍拡大できるが、違いを確認しておく。
import numpy as np import matplotlib.pyplot as plt
# 元の配列を生成 nry = np.arange(3) # repeatで拡大 nry_repeat = nry.repeat(3) # tileで拡大 nry_tile = np.tile(nry, 3) # 表示 print("元の配列", nry) print("repeat", nry_repeat) print("tile", nry_tile)
元の配列 [0 1 2]
repeat [0 0 0 1 1 1 2 2 2]
tile [0 1 2 0 1 2 0 1 2]
各要素が繰り返すか、塊で繰り返すかの違いがある。
次は次元を増やした配列で試してみます。
# 元の配列を生成 ndry = np.arange(1,10).reshape(3,3) print("元の配列 2次元\n\n", ndry) print("="*40) print("repeat, 軸0\n\n", ndry.repeat(2,axis=0)) print("="*40) print("repeat, 軸1\n\n", ndry.repeat(2,axis=1)) print("="*40) print("tile 2\n\n", np.tile(ndry, 2)) print("="*40) print("tile (2,3)\n\n", np.tile(ndry,(2,3))) print("="*40) print("tile (1,2)\n\n", np.tile(ndry, (1,2)))
元の配列 2次元
[[1 2 3]
[4 5 6]
[7 8 9]]
========================================
repeat, 軸0
[[1 2 3]
[1 2 3]
[4 5 6]
[4 5 6]
[7 8 9]
[7 8 9]]
========================================
repeat, 軸1
[[1 1 2 2 3 3]
[4 4 5 5 6 6]
[7 7 8 8 9 9]]
========================================
tile 2
[[1 2 3 1 2 3]
[4 5 6 4 5 6]
[7 8 9 7 8 9]]
========================================
tile (2,3)
[[1 2 3 1 2 3 1 2 3]
[4 5 6 4 5 6 4 5 6]
[7 8 9 7 8 9 7 8 9]
[1 2 3 1 2 3 1 2 3]
[4 5 6 4 5 6 4 5 6]
[7 8 9 7 8 9 7 8 9]]
========================================
tile (1,2)
[[1 2 3 1 2 3]
[4 5 6 4 5 6]
[7 8 9 7 8 9]]
np.tile(配列, 2)
は np.tile(配列, (1,2))
と等しい。
画像作成
竈門禰豆子の帯の市松模様をnp.tile()
で作っていきます。
手順
- 単色で色違いの2枚の画像を互い違いに4枚使って正方形に組んだブロックを作る
- np.tile()で倍増させて拡大する
単色の色
禰豆子の帯は2色の市松模様です。
- 白:RGB(251, 242, 239)
- 赤茶:RGB(154, 49, 72)
この2色を使います。
単色の画像サイズ
- 15ピクセル角。
基となるゼロ配列の生成
2色を互い違いに4枚組み合わせたブロックを基本配列とします。
# 単色の一辺サイズ p=15 # ゼロ配列生成 np_block = np.zeros((p*2) * (p*2), dtype=int).reshape(p*2, p*2) #np_block
2*2のブロック生成
上で作成した基本ブロックを、互い違いになるように色の値を変更していきます。
それをRGBの3つ作ります。
白R=251に変更
# コピー np_block_r = np_block.copy() # 値を変更 np_block_r[0:15, 0:15] = 251 np_block_r[15:30, 15:30] = 251 #np_block_r
白G=242に変更
# コピー np_block_g = np_block.copy() np_block_g[0:15, 0:15] = 242 np_block_g[15:30, 15:30] = 242 #np_block_g
白B=239に変更
# コピー np_block_b = np_block.copy() np_block_b[0:15, 0:15] = 239 np_block_b[15:30, 15:30] = 239 #np_block_b
赤茶R=154に変更
# np_block_r[0:15, 15:30] = 154 np_block_r[15:30, 0:15] = 154 #np_block_r
赤茶G=49に変更
# np_block_g[0:15, 15:30] = 49 np_block_g[15:30, 0:15] = 49 #np_block_g
赤茶B=72に変更
# np_block_b[0:15, 15:30] = 72 np_block_b[15:30, 0:15] = 72 #np_block_b
三次元方向に結合
RGBの3つの配列を、三次元方向に結合します。
np_nezu_block = np.stack([np_block_r, np_block_g, np_block_b], axis=2)
plt.imshow(np_nezu_block)
これが基の配列でできた基本ブロックになる。
次は、この基本ブロックを繰り返すことで画像を拡大させていく。
np.tile()で繰り返し
np_Nezuko = np.tile(np_nezu_block, (5,7,1)) plt.imshow(np_Nezuko)
できました。
コードをまとめる
import numpy as np import matplotlib.pyplot as plt ### 設定 ### # 各色の一辺のサイズ(ピクセル) p=15 ### 基のブロック生成 # 2色を互い違いにした4枚のブロックのゼロ配列 np_block = np.zeros((p*2) * (p*2), dtype=int).reshape(p*2, p*2) ### 色の変更 ### ## 白R=251に変更 # コピー np_block_r = np_block.copy() # 値を変更 np_block_r[0:p, 0:p] = 251 np_block_r[p:p+p, p:p+p] = 251 ## 白G=242 # コピー np_block_g = np_block.copy() # 色の変更 np_block_g[0:p, 0:p] = 242 np_block_g[p:p+p, p:p+p] = 242 ## 白B=239 # コピー np_block_b = np_block.copy() # 色の変更 np_block_b[0:p, 0:p] = 239 np_block_b[p:p+p, p:p+p] = 239 ## 赤茶R=154 # 色の変更 np_block_r[0:p, p:p+p] = 154 np_block_r[p:p+p, 0:p] = 154 ## 赤茶G=49 # 色の変更 np_block_g[0:p, p:p+p] = 49 np_block_g[p:p+p, 0:p] = 49 ## 赤茶B=72 # 色の変更 np_block_b[0:p, p:p+p] = 72 np_block_b[p:p+p, 0:p] = 72 ### RGBを三次元方向に結合 ### np_nezu_block = np.stack([np_block_r, np_block_g, np_block_b], axis=2) #plt.imshow(np_nezu_block) ### ブロックを繰り返す ### np_Nezuko = np.tile(np_nezu_block, (5,7,1)) # 画像の表示 plt.imshow(np_Nezuko) # 画像の保存 plt.axis("off") plt.savefig("禰豆子の帯.jpg")
今回は以上です。
前回の炭治郎の羽織の柄と少し作り方を変えた。
しかし色の変更の方法はだいぶんアホっぽい。もっと簡単にできるはず…
【関連】
さらに改良した。
【Numpy】np.tile()で市松模様を作る - よちよちpython