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

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

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

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

Q&A

1回答

732閲覧

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

sasuraibito

総合スコア5

Python

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

1グッド

2クリップ

投稿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👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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となってしまう状態に対応できなかったゆえにエラーが発生したことがのちにわかりました。 この点については自己解決しました。 ありがとうございます。
guest

回答1

0

縦の長さ==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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sasuraibito

2022/11/18 09:35

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問