質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

受付中

画像分野の機械学習において、1つの画像から5つの正方形を切り抜くコードを実装したい

sasuraibito
sasuraibito

総合スコア5

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1回答

1グッド

2クリップ

333閲覧

投稿2022/11/16 00:20

編集2022/11/16 01:38

機械学習の画像分野を勉強しております。一つの画像からn個の正方形の画像を切り抜き、一個の画像から計n+1(n個の正方形画像と元の画像)個のベクトルを抽出するという作業を進めているのですが、中々うまくいかずに困っています。

元のコードでは、slice_image関数で以下コードのように画像の左端(ar[:, :desired_size])、真ん中(ar[:, middle-half:middle+half])、右端(ar[:, ar.shape[1]-desired_size:ar.shape[1]])から3つの正方形を切り抜いています。
そこで自分は、横の位置をmiddle-2halfからmiddleまで、middleからmiddle+2halfまでの二つの正方形画像を切り抜いて、計五つの正方形を得たいと考えました。

しかしその部分のコードを実装したところ、エラーが発生してしまい、そこから問題を解決できない状況にあります。

python

1 2def slice_image(im, desired_size): 3 ''' 4 Resize and slice image 5 ''' 6 old_size = im.size 7 ratio = float(desired_size)/min(old_size) 8 new_size = tuple([int(x*ratio) for x in old_size]) 9 im = im.resize(new_size, Image.ANTIALIAS) 10 ar = np.array(im) 11 images = [] 12 if ar.shape[0] < ar.shape[1]: 13 middle = ar.shape[1] // 2 # 横のサイズの半分を取得 14 half = desired_size // 2 # 欲しい画像サイズの半分を取得 15 16 images.append(Image.fromarray(ar[:, :desired_size]))# 欲しい画像サイズで横に左からdesired_size分を切り抜き 17 images.append(Image.fromarray(ar[:, middle-half:middle+half])) # 画像横方向に中心middleから-half,中心middleからhalfにかけて切り抜き.middleを中心としてサイズはdesired_sizeになる. 18 images.append(Image.fromarray(ar[:, ar.shape[1]-desired_size:ar.shape[1]])) # 欲しい画像サイズで横に下からdesired_size分を切り抜き 19 else: 20 middle = ar.shape[0] // 2 21 half = desired_size // 2 22 23 images.append(Image.fromarray(ar[:desired_size, :])) 24 images.append(Image.fromarray(ar[middle-half:middle+half, :])) 25 images.append(Image.fromarray(ar[ar.shape[0]-desired_size:ar.shape[0], :])) 26 27 return images 28 29 def resize_pad_image(im, desired_size): 30 ''' 31 Resize and pad image to a desired size 32 ''' 33 old_size = im.size 34 ratio = float(desired_size)/max(old_size) 35 new_size = tuple([int(x*ratio) for x in old_size]) 36 im = im.resize(new_size, Image.ANTIALIAS) 37 38 # create a new image and paste the resized on it 39 new_im = Image.new("RGB", (desired_size, desired_size)) 40 new_im.paste(im, ((desired_size-new_size[0])//2, 41 (desired_size-new_size[1])//2)) 42 43 return new_im

質問したいこと

・一つの画像から五つの別の位置の正方形の切り抜きを取得するためのコードが正しいのか
・このエラーを解決したい

追加したコード

以下のコードをslice_image()のif分とelse文の両方に追加しました。

python

1images.append(Image.fromarray(ar[:, middle-2*half:middle])) 2images.append(Image.fromarray(ar[:, middle:middle+2*half]))

発生している問題・エラーメッセージ

上のコード追加して実行したのですが、以下コードでの実行でエラーが発生してしまいました。
この原因について教えていただきたいです。
該当のコード

python

1image_encoder = ClipEncoderMulti(4) 2image = Image.open("dataset/img/42953.png").convert("RGB") 3 4sliced_images = slice_image(image, 288) 5sliced_images = [np.array(preprocess(im)) for im in sliced_images] 6 7image = resize_pad_image(image, image_encoder_size) 8image = np.array(preprocess(image)) 9 10sliced_images = [image] + sliced_images 11sliced_images = torch.from_numpy(np.array(sliced_images)).to(device) 12 13print(sliced_images.shape) 14print(image_encoder(sliced_images).shape) 15

エラー文

python

1ValueError Traceback (most recent call last) 2Input In [28], in <cell line: 4>() 3 1 image_encoder = ClipEncoderMulti(4) 4 2 image = Image.open("dataset/img/42953.png").convert("RGB") 5----> 4 sliced_images = slice_image(image, 288) 6 5 sliced_images = [np.array(preprocess(im)) for im in sliced_images] 7 7 image = resize_pad_image(image, image_encoder_size) 8 9Input In [25], in slice_image(im, desired_size) 10 25 half = desired_size//2 11 27 images.append(Image.fromarray(ar[:desired_size, :])) 12---> 28 images.append(Image.fromarray(ar[:, middle-2*half:middle])) 13 29 images.append(Image.fromarray(ar[:, middle:middle+2*half])) 14 30 images.append(Image.fromarray(ar[middle-half:middle+half, :])) 15 16File ~/.pyenv/versions/3.9.11/lib/python3.9/site-packages/PIL/Image.py:2974, in fromarray(obj, mode) 17 2971 else: 18 2972 obj = obj.tostring() 19-> 2974 return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) 20 21File ~/.pyenv/versions/3.9.11/lib/python3.9/site-packages/PIL/Image.py:2901, in frombuffer(mode, size, data, decoder_name, *args) 22 2898 im.readonly = 1 23 2899 return im 24-> 2901 return frombytes(mode, size, data, decoder_name, args) 25 26File ~/.pyenv/versions/3.9.11/lib/python3.9/site-packages/PIL/Image.py:2843, in frombytes(mode, size, data, decoder_name, *args) 27 2840 args = mode 28 2842 im = new(mode, size) 29-> 2843 im.frombytes(data, decoder_name, args) 30 2844 return im 31 32File ~/.pyenv/versions/3.9.11/lib/python3.9/site-packages/PIL/Image.py:794, in Image.frombytes(self, data, decoder_name, *args) 33 792 # unpack data 34 793 d = _getdecoder(self.mode, decoder_name, args) 35--> 794 d.setimage(self.im) 36 795 s = d.decode(data) 37 797 if s[0] >= 0: 38 39ValueError: tile cannot extend outside image

補足情報(FW/ツールのバージョンなど)

コードを全てこのサイトから引用しました。
https://towardsdatascience.com/how-to-get-high-score-using-mmbt-and-clip-in-hateful-memes-competition-90bfa65cb117

sasuraibito👍を押しています

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

2022/11/16 02:27

こちらの質問が複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました。

ara_ara

2022/11/16 04:44

ご自身による改変を加える前に,まずコピーしたソースコードが正しく動作するかは検証されましたか.
PondVillege

2022/11/16 06:40

横長画像のときは,横方向に切り抜くためaxis = 1の箇所にスライス文を書きましたが,縦長画像を切り抜くときはaxis = 0の箇所にスライス文を書きましょう.
sasuraibito

2022/11/16 11:57

ara_ara様 はい、元のコードの動作確認の方は済んでおります。
sasuraibito

2022/11/16 12:01

ps_aux_grep様 おっしゃる通り、縦長でaxis = 1にスライス文を書いていたことは訂正したのですが、どうやら根本的にこの手法が間違っており、2*half>middleとなってしまう状態に対応できなかったゆえにエラーが発生したことがのちにわかりました。 この点については自己解決しました。 ありがとうございます。

回答1

1

縦の長さ==desired_size
横の長さ==ar.shape[1]
横の長さ/2==middle

a=(desired_size-middle)//2とし、

x座標が、
(middle-a)-halfから(middle-a)+halfまでの
ものと、
(middle+a)-halfから(middle+a)+halfまでのもの

でスライスすると新たに二つの正方形が得られる

これで解決しました。

投稿2022/11/16 12:04

sasuraibito

総合スコア5

ps_aux_grep👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

sasuraibito

2022/11/18 09:35

これで実行したのですが、またtile cannot extend outside imageエラーが発生してしまったので、引き続き検討します。

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。