こしあん
2019-10-10

PyTorchで画像を小さいパッチに切り出す方法

Pocket
LINEで送る
Delicious にシェア

1.6k{icon} {views}

新刊情報

技術書典8の新刊『モザイク除去から学ぶ 最先端のディープラーニング』(A4・195ページ)好評通販中です! 機械学習の入門からGANの最先端までを書いたおすすめの本となっています! Boothで試し読みできます。情報まとめ・質問用GitHub



PyTorchで1枚の画像を複数の小さい画像(パッチ)に切り出す方法を紹介します。TensorFlowだとtf.image.extract_patchesにあたる処理です。

torch.Tensor.unfold

torch.Tensor.unfoldという関数を使います。

unfold(dimension, size, step) → Tensor

という形式で、順番にパッチを切り出す次元、パッチサイズ、パッチを切り出す間隔ですね。次元は縦と横で取ればいいので画像の4階テンソルなら2,3で取れば良いでしょう。

コード

この画像を「cat.jpg」とします。

128px × 128pxのパッチで、64px間隔に取り出すものとします。

import torch
import torchvision
from PIL import Image
import numpy as np

# テンソルの読み込み
with Image.open("cat.jpg") as img:
    original = np.expand_dims(np.asarray(img, np.float32).transpose([2, 0, 1]), axis=0) / 255.0
x = torch.as_tensor(original)
print(x.size()) # [1, 3, 821, 547]
# パッチサイズは128x128, 64px間隔で切り出す
patches = x.unfold(2, 128, 64).unfold(3, 128, 64)
print(patches.size())  # [1, 3, 11, 7, 128, 128]
# パッチをタイルして保存
out = patches.permute([0, 2, 3, 1, 4, 5]).reshape(-1, 3, 128, 128) # permuteが必要
torchvision.utils.save_image(out, "patch.png", nrow=7)

縦方向と横方向で2回パッチを取れば良いです。パッチを取った後がごちゃごちゃしていますが、次元は「バッチサイズ、チャンネル数、縦方向のパッチ数、横方向のパッチ数、縦方向のパッチ解像度、横方向のパッチ解像度」となります。縦・横はunfoldを適用する順番によって変わります。結果は次の通り。


新刊情報

技術書典8の新刊『モザイク除去から学ぶ 最先端のディープラーニング』好評通販中(A4・195ページ)です! Boothで試し読みもできるのでよろしくね!


Pocket
Delicious にシェア

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です