🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

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

Q&A

解決済

1回答

8081閲覧

IndexError:tuple index out of rangeが発生している理由と解決方法が分かりません

hamasaki

総合スコア6

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

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

0グッド

0クリップ

投稿2019/11/25 07:37

実現したいこと

Python、OpenCVなどを用いて、動画をフレーム間差分法で加工した後にその動画を分割してjpgファイルとして保存しています。そして、その分割した画像を一枚一枚自動でトリミングしようとしているのですがその途中の処理でIndexErrorが発生しました。

私自身、初心者なのでほかの方がネットで公開されているソースコードをもとに作成しています。調べても解決方法がわからなかったため今回はこのように質問させていただきました。

該当のソースコード

Python

1import cv2 2import numpy as np 3from PIL import Image 4import os 5import shutil 6 7def video_2_frames(video_file, image_dir, image_file): 8 # Delete the entire directory tree if it exists. 9 if os.path.exists(image_dir): 10 shutil.rmtree(image_dir) 11 12 # Make the directory if it doesn't exist. 13 if not os.path.exists(image_dir): 14 os.makedirs(image_dir) 15 16 # Video to frames 17 global i 18 global j 19 global count 20 i=0 21 j=0 22 count=0 23 cap = cv2.VideoCapture(video_file) 24 fgbg = cv2.bgsegm.createBackgroundSubtractorMOG() 25 while(cap.isOpened()): 26 flag, frame = cap.read() # Capture frame-by-frame 27 if flag == False: # Is a frame left? 28 break 29 if i==30: 30 fgmask = fgbg.apply(frame) 31 cv2.imwrite(image_dir+image_file % str(j), fgmask) # Save a frame 32 print('Save', image_dir+image_file % str(j)) 33 i = 0 34 j += 1 35 i+=1 36 37 cap.release() # When everything done, release the capture 38 39video_2_frames('./movie.mp4','./image_dir/','img_%s.jpg') 40 41def nparray_to_rgb(nparry:np.array): 42 return (int(nparry[0]),int(bg_color[1]),int(bg_color[2])) 43 44def find_edge(img_path:str): 45 img = cv2.imread(img_path,0) 46 blur = cv2.blur(img,(5,5)) 47 print('blur') 48 print(blur) 49 edges = cv2.Canny(blur,100,200) 50 print('edges') 51 print(edges) 52 return edges 53 54def find_target(edges): 55 results = np.where(edges==255) 56 print('results') 57 print(results) 58 top = np.min(results[0]) 59 bottom = np.max(results[0]) - 1 60 left = np.min(results[1]) 61 right = np.max(results[1]) - 1 62 return (left,top,right,bottom) 63 64 65def to_RGB(image:Image): 66 if image.mode == 'RGB': return image 67 background = Image.new("RGB", image.size, (255, 255, 255)) 68 print('background') 69 print(background) 70 background.paste(image, mask=image.split()[3]) # 3 is the alpha channel 71 background.format = image.format 72 return background 73 74def get_crop_img(img_path:str): 75 #im=cv2.imread('./hamasaki_trim/img_'+str(count)+'.png',0) 76 edges = find_edge(img_path) 77 left,top,right,bottom = find_target(edges) 78 rgb_img = to_RGB(Image.open(img_path)) 79 trim_img = rgb_img.crop((left, top, right, bottom)) 80 cv2.imwrite('./image_dir/img_'+str(count)+'_trim.jpg',trim_img) 81 print('crop_img') 82 83for count_img in range(1,j): 84 print('crop_'+str(count_img)) 85 get_crop_img('./image_dir/img_'+str(count_img)+'.jpg') 86 count_img+=1 87 count+=1

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

line 71, in to_RGB background.paste(image, mask=image.split()[3]) # 3 is the alpha channel IndexError: tuple index out of range

このエラーはどのようにすれば解決できるでしょうか?
また、なぜ発生しているのか教えていただけると幸いです。

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

開発環境(IDE):Spyder(Python3.7)

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

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

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

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

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

guest

回答1

0

ベストアンサー

このエラーはどのようにすれば解決できるでしょうか?

image.split()[3]

ということは、画像のチャンネル数は RGBA の4チャンネルであることが前提となっていますが、おそらく image にグレースケール画像が渡されて、1チャンネルしかないので、エラーになっているのではないでしょうか。
憶測なので、image.mode の値を print して RGBA であることを確認してみてください。

このエラーはどのようにすれば解決できるでしょうか?

「RGBA 画像でない場合は処理をしない」ような例外処理を追加する必要があるでしょう。

投稿2019/11/25 07:45

tiitoi

総合スコア21956

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

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

hamasaki

2019/11/25 12:05

image.modeの値をprintしたらLと表示されたのでグレイスケールが渡されていたようです。 なので、to_RGB関数の条件式をif image.mode != 'RGBA': return imageに変更したら通りました…! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問