Chapter 06

モザイクアート化したい画像の分割

eetann / えーたん
eetann / えーたん
2020.11.05に更新

この章の概要

モザイクアート化したい画像を分割します。分割した領域は類似度が高い画像に置き換えられます。

そのまま分割すると余る

モザイクアート化したい画像の縦と横のサイズを2倍にしてから、縦50個、横が28個のブロックに分割します。画像を2倍にしたのは、分割数を増やしつつブロックの高さと幅を小さくしすぎないためです。

I = skimage.transform.resize(I, (I.shape[0]*2, I.shape[1]*2, 3), anti_aliasing=True)
row_split = 50
col_split = 28
print("ブロックの高さ:{}".format(I.shape[0] / row_split))
print("ブロックの幅:{}".format(I.shape[1] / col_split))
print("ブロックの高さの余り:{}".format(I.shape[0] % row_split))
print("ブロックの幅の余り:{}".format(I.shape[1] % col_split))

ブロックの高さ:24.96
ブロックの幅:34.92857142857143
ブロックの高さの余り:48
ブロックの幅の余り:26

そのまま分割すると、端の方で余りが出ます。ここでは、あまりの部分については切り捨てることにします。分割にはskimage.util.view_as_blocks()を使います。

import skimage.util
row1_size = I.shape[0] // row_split
col1_size = I.shape[1] // col_split
I_tri = I[:(row1_size*row_split), :(col1_size*col_split), :]
Ims = skimage.util.view_as_blocks(I_tri, (row1_size, col1_size, 3))

分割できてるのか確認してみましょう。
ここでは、画像Iの左上から3x3ブロック分を表示します。

plt.imshow(I[:row1_size*3, :col1_size*3, :])
plt.axis("off")
plt.show()

Iの方

次に分割したブロックImsで左上から3x3ブロック分を表示します。

n = 1
for vs in range(3):
    for hs in range(3):
        plt.subplot(3, 3, n)
        plt.imshow(Ims[vs, hs, 0, :, :, :])
        plt.axis("off")
        n += 1
plt.show()

Imsの方
画像が分割されていることが確認できました。
ここで、分割したブロックは、Ims[縦のブロックのインデックス, 横のブロックのインデックス, 0]のように指定します。実際にprint(Ims.shape)Imsのshapeを確認すると、

(50, 28, 1, 24, 34, 3)

となっています。これは、

(縦のブロック数、横のブロック数、RGBのブロック数、ブロックの縦のサイズ, ブロックの横のサイズ, RGB)

の数値です。