機械学習の画像分野を勉強しております。一つの画像から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