前提・実現したいこと
プログラミング初心者です。
ファイル内の画像を一括で読み込み、読み込んだ画像をトリミングしたいです。
その際、一枚ごとにトリミングする領域を選択したいと考えています。
そしてトリミングした画像は新しく作ったディレクトリに保存したいです。
以下のエラーメッセージが発生しました。
ご指摘、アドバイスをどうぞよろしくお願いします。
発生している問題・エラーメッセージ
Select a ROI and then press SPACE or ENTER button! Cancel the selection process by pressing c button! Traceback (most recent call last): File "triming_vo3.py", line 20, in <module> selected = cv2.selectROI(img) cv2.error: OpenCV(4.4.0) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-71670poj\opencv\modules\highgui\src\window.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'
python
1### 該当のソースコード 2 3import cv2 4import os 5import sys 6 7if __name__ == '__main__': 8 args = sys.argv 9 data_dir = args[1].replace('\', '/') 10 trimed_dir = data_dir + 'trimed' 11 os.mkdir(trimed_dir) 12 files = os.listdir(data_dir) 13 img_files = [ 14 f for f in files if '.tif' in f or '.jpg' in f or '.png' in f] 15 print(img_files) 16 for img_file in img_files: 17 img_dir = data_dir + img_file 18 img = cv2.imread(img_dir) 19 20 selected = cv2.selectROI(img) 21 if sum(selected): 22 imCrop = img[int(selected[1]):int(selected[1]+selected[3]), 23 int(selected[0]):int(selected[0]+selected[2])] 24 file_dir = data_dir + trimed_dir + '/' + img_file 25 cv2.imwrite(file_dir, imCrop) 26 print('All images are saved') 27
試したこと
以下の3点です。
- imreadの読み込みができていないと考え、ファイル名を半角英数字に直しました。しかしエラーメッセージが変わらず。
- selected = cv2.selectROI(img)のところで、エラーメッセージが表示されているので、正しい引数かどうか調べました。しかし、ファイル名のimg_dirとしているため、問題ないと考えています。
- img = cv2.imread(img_dir)の下の行に、print(img.shape())としましたが、'NoneType' object has no attribute 'shape'なエラーが出ました。
補足情報(FW/ツールのバージョンなど)
imreadのあたりでprint(img_dir)してみて、間違ってないか確認してみてください
返信ありがとうございます。print(img_dir)で一枚目の写真が入力されました。その後、Select a ROI and then press SPACE or ENTER button! Cancel the selection process by pressing c button!のエラーが出ました。
print(img_dir)の結果は合ってます?
どんな結果が表示されるか、差し支えなければ書いてください (ユーザ名等の個人情報は伏せ字でいいですが、それ以外はそのまま書いてください)
['immersion_02ni_10_1.tif', 'immersion_02ni_10_2.tif']
images_2immersion_02ni_10_1.tif
Select a ROI and then press SPACE or ENTER button!
Cancel the selection process by pressing c button!
Traceback (most recent call last):
File "triming_vo2.py", line 24, in <module>
selected = cv2.selectROI(img)
cv2.error: OpenCV(4.4.0) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-71670poj\opencv\modules\highgui\src\window.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'
画像二枚のファイル名が編集されているはずですが、実際に出力されたのは一枚だけでした。
あと、質問のpythonコードを、エラーと同じ書き方に変えてください
現状コードがとても読み辛いです
img_dir = data_dir + img_file
で、「data_dir」と「img_file」をつなげてますよね
「data_dir」には、何が入っているのでしょうか?
data_dir = args[1].replace('\\', '/')
なので、pythonコードを実行する時に引数でフォルダ名を指定してるのですよね?
ありがとうございます。コードを元に戻しました!
画像が入ったフォルダ名(images_2)を指定して、実行しています。
> python triming_vo2.py images_2
「images_2」が「data_dir」の中身なら、
images_2immersion_02ni_10_1.tif
の「images_2」とファイル名の間に「/」が要ります
【追記】
file_dir = data_dir + trimed_dir + '/' + img_file
と同じやり方で、
img_dir = data_dir + img_file
を直す
質問のコードの
import cv2
のすぐ上に、
```python
だけの行を挿入してください
そうしてもらえたら、コードが見やすくなります
丁寧にありがとうございます!今後質問する際に気を付けたいと思います。
コードは見やすくなりましたが、forやifの下のインデント(行頭のスペース)が無くなってます
何度もありがとうございます。
画像の読み込みができました。ありがとうございました。
ただ、トリミングされた画像が保存されませんでした。
読み込みと同様にして調べます
まずは、imwriteのあたりでprint(file_dir)して、表示されるパス(ファイル名含む)が正しいか確認
また、表示されたパスからファイル名を除いたフォルダパスが、実際に存在しているか確認
一文字でも間違えてたら保存できないので、フォルダの区切り文字等も含めて、よーく見る
また、やはりimwriteのあたりで
print(imCrop.shape)
print(imCrop)
とかやってみて、トリミングデータのサイズや、中のデータがおかしくないか、確認する
ありがとうございます。
> python triming_vo2.py images_2
['immersion_02ni_10_1.tif', 'immersion_02ni_10_2.tif']
images_2/immersion_02ni_10_1.tif
Select a ROI and then press SPACE or ENTER button!
Cancel the selection process by pressing c button!
images_2images_2_trimed/immersion_02ni_10_1.tif
saved!
images_2/immersion_02ni_10_2.tif
Select a ROI and then press SPACE or ENTER button!
Cancel the selection process by pressing c button!
images_2images_2_trimed/immersion_02ni_10_2.tif
saved!
トリミング用のフォルダは作成されましたが、そのフォルダにトリミングした画像が保存されません。
「images_2images_2_trimed/immersion_02ni_10_1.tif」
「images_2images_2_trimed/immersion_02ni_10_2.tif」
って書かれてますけど、それは意図に合ってますか?
> トリミング用のフォルダは作成されましたが
は、「images_2images_2_trimed」というフォルダが、本当にできたのですか?
実際にできたのは「images_2_trimed」ではないですか?
合っていません。実際は、トリミングされた画像ファイル名が、「元データ_trimed.tif」を想定していました。二つ目ですが、実際に作成できたのは、「images_2_trimed」でした。
また、file_dir = data_dir + trimed_dir + '/' + img_file→file_dir = data_dir + '/' + img_file
とすると、トリミングができました。しかし、その場合は元フォルダの画像がトリミングされてしまいます。「images_2_trimed」は作成されますが、データは保存されません。トリミングした画像の保存ができていないのかと思っています。
file_dir = data_dir + trimed_dir + '/' + img_file
の前か後に、
print(data_dir)
print(trimed_dir)
を追加して、その結果をよーく見て、落ち着いて考えてください
そうすれば、なぜプログラムが「images_2images_2_trimed」というフォルダにファイルを保存しようとしたのかが分かるはずです
また、
file_dir = data_dir + '/' + img_file
に変えたら「元フォルダの画像がトリミングされて」しまう原因も分かるはずです
闇雲に変えてみるのではなく、今何が起きているのか、なぜ意図した通りにならないのかを、ちゃんと調べて把握してください
コードを修正するのは、それからです
改善できました。!!!早くコードを修正することばかりに気を取られていました。落ち着いて考えたら、分かりました。エラー時のアプローチの仕方も教えて頂きありがとうございました。
file_dir = trimed_dir + '/' + img_file
とすることで出来ました。最初からこの分の意味を理解していなかったことが今回のエラーの原因でした。
ベストアンサーを選んで、質問を解決済にするやり方が分かりません。教えていただけますでしょうか。
保存するファイル名を「元データ_trimed.tif」とするには、元のファイル名を
元データ:immersion_02ni_10_1 等
と
拡張子:.tif 等
に一旦分けた上で、「元データ」と「_trimed」と「拡張子」をつなげる、ということをします
ファイル名を、拡張子とそれ以外に分離する関数もpythonにはあるので、そういうものを使いながら、落ち着いて考えながらコードを書けば、そんなに難しくはありません
やるべきことを順番に正しくやれば、必ずできます
もし機会があれば、挑戦してみてください
ありがとうございます。挑戦します!
回答1件
あなたの回答
tips
プレビュー