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

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

新規登録して質問してみよう
ただいま回答率
86.12%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenCV

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

Python

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

解決済

python OpenCV で imwrite() ができない→stitchができない

yukimeat1999
yukimeat1999

総合スコア17

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenCV

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

Python

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

1回答

0リアクション

0クリップ

376閲覧

投稿2022/09/21 06:48

編集2022/09/21 09:29

前提

pythonのOpenCVで画像の読み込みと書き出しをしています。

しかし、imwrite()をしても画像が書き出しされません。
(imshow()はできました)

読み込もうとしている画像は横長の写真です。
空が映ってるはずなのですが。

環境はVisual Studio2022でやっています。

 
追記
質問への追記・修正の依頼より、imwrite()はできました。
パノラマ画像の連結ができてないようです。

実現したいこと

・OpenCVで画像を読み込んで書き出したい。
・パノラマ画像の連結をする。

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

python

# エラー文 OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:801: error: (-215:Assertion failed) !_img.empty() in function 'cv::imwrite'

私のPCの環境では、DドライブにはBDドライブがついてるのですが、なぜかエラー文中にDドライブのディレクトリが表示されている。

該当のソースコード

python

import numpy as np import cv2 import os left_photo_path = r'H:\headrace\img2_s3l\img2_s3l' upper_photo_path = r'H:\headrace\img2_s3t\img2_s3t' preparation_path = r'H:\headrace\preparation' create_path = r'H:\headrace\create' # modes = (cv2.Stitcher_PANORAMA, cv2.Stitcher_SCANS) Stitcher_PANORAMA = cv2.Stitcher.create(0) Stitcher_SCANS = cv2.Stitcher.create(1) if __name__ == "__main__": os.makedirs(preparation_path, exist_ok=True) # for文 質問用にfor文を削除し,簡単な文に編集している i = 1 preparation_lt = [] # H:\headrace\img2_s3l\img2_s3l\trims_3l00001.png preparation_lt.append(cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png'))) preparation_lt.append(cv2.imread(os.path.join(upper_photo_path, f'trims_3t{i:05}.png'))) print(os.path.join(left_photo_path, f'trims_3l{i:05}.png')) np_preparation_lt = [] np_preparation_lt = np.concatenate(preparation_lt, axis=1) # 横方向に #cv2.imshow(f'np_preparation_lt', np_preparation_lt) #cv2.waitKey(0) #cv2.destroyAllWindows() #print(f'show: trims_3l{i:05}.png') # パノラマ書き出し stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), stitched[1]) print(f'create: lt_{i:05}.png') stitched.clear() preparation_lt.clear() np_preparation_lt.clear()

試したこと

imshow()が出来る様にした。
・ディレクトリが間違っていないか確認のためprint()した。

以下は、質問への追記・修正の依頼より

1)jbpb0さんからの質問への追記・修正の依頼1つ目

cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), stitched[1])

のすぐ上に

print(stitched[1].shape)

を追加して実行したら、何て表示されますでしょうか?

print()がオーバースローされ、エラーが表示されました。

python

# エラー文 'NoneType' object has no attribute 'shape'

デバッグ状態で、stitched[1]を見てみると、

python

# デバッグ文 stitched(1, None)

が入っていました。
どこかのサイトでパノラマ作成時のエラー対策で、stitched[1]を使ってたと思ったんですが。

イメージ説明

さらに、print(stitched[0].shape)として、配列の[0]を代入すると、

python

# エラー文 'int' object has no attribute 'shape'

と、エラーが表示された。

2)jbpb0さんからの質問への追記・修正の依頼2つ目

(imshow()はできました)

「imshow()」で表示されてる画像をそのまま保存すればいいのなら、下記のようにしたらいいような

stitched = Stitcher_PANORAMA.stitch(np_preparation_lt)
cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), stitched[1])
↓ 変更
cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), np_preparation_lt)

np_preparation_ltをimwrite()すると、配列のように画像が横(右)にそのままつながった状態の画像が書き出しされました。

補足情報

OS: Windows10

Visual Studio 2022
Microsoft Visual Studio Community 2022 (64 ビット) - Current
Version 17.3.4

Python 3.8.5

Opencvは多分これ
opencv-4.6.0-vc14_vc15

以下のような質問にはリアクションをつけましょう

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

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

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

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

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

1T2R3M4

2022/09/21 07:01

>imwrite()をしても画像が表示されません。 表示するための関数ではないのでは。
jbpb0

2022/09/21 07:15

> imwrite()をしても画像が表示されません。 の「画像が表示されません」が「画像ファイルが作成できません」の書き間違いだとして、以下書きます > error: (-215:Assertion failed) !_img.empty() in function 'cv::imwrite' データが空(empty)みたいです > cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), stitched[1]) のすぐ上に print(stitched[1].shape) を追加して実行したら、何て表示されますでしょうか?
jbpb0

2022/09/21 07:35

> (imshow()はできました) 「imshow()」で表示されてる画像をそのまま保存すればいいのなら、下記のようにしたらいいような stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), stitched[1]) ↓ 変更 cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), np_preparation_lt)
jbpb0

2022/09/21 09:14

> np_preparation_ltをimwrite()すると、配列のように画像が横(右)にそのままつながった状態の画像が書き出しされました。 その書き出された画像と、「imshow()」で表示されたものは、同じはずなのですが > (imshow()はできました) の「できました」の意味は、表示はされたけど、その表示されてる画像は本当に欲しい画像ではない、ということでしょうか?
jbpb0

2022/09/21 09:22 編集

「imshow()」で表示されてる画像は本当に欲しい画像ではないなら、 stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) ↓ 修正 stitched = Stitcher_PANORAMA.stitch(preparation_lt) で、どうでしょうか? (「cv2.imwrite()」の行は質問のコードのまま)
yukimeat1999

2022/09/21 09:52

imshow()はimread()できてるか分からないから記述してテストしてたので、preparation_ltやnp_preparation_ltの画像は書き出したい画像ではないです。 分かりにくくてすみません。 【stitch部分に関して】 配列に、「パノラマとして繋げたい画像」を順番に入れていき、別の変数に配列をstitchして繋げたパノラマ画像を保存するプログラムになるそうです(多分)。 いろんなサイトを見比べながらそう解釈しました。 > stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) > ↓ 修正 > stitched = Stitcher_PANORAMA.stitch(preparation_lt) これを実行したところ、 cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), stitched[1]) のところで、エラーが出ました。 # エラー文 OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:801: error: (-215:Assertion failed) !_img.empty() in function 'cv::imwrite'
jbpb0

2022/09/21 10:45

> stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) > ↓ 修正 > stitched = Stitcher_PANORAMA.stitch(preparation_lt) に加えて、さらに preparation_lt.append(cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png'))) preparation_lt.append(cv2.imread(os.path.join(upper_photo_path, f'trims_3t{i:05}.png'))) ↓ 変更 pictmp = cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png')) sizex = pictmp.shape[1] preparation_lt.append(pictmp[:, :int(sizex*0.6)]) preparation_lt.append(pictmp[:, int(sizex*0.4):]) もやったら、どうなりますでしょうか? エラー出ますか? (できる画像の内容は気にせず、エラーが出るかどうかだけ)
yukimeat1999

2022/09/21 11:26

> > stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) > > ↓ 修正 > > stitched = Stitcher_PANORAMA.stitch(preparation_lt) > > に加えて、さらに > > preparation_lt.append(cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png'))) > preparation_lt.append(cv2.imread(os.path.join(upper_photo_path, f'trims_3t{i:05}.png'))) > ↓ 変更 > pictmp = cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png')) > sizex = pictmp.shape[1] > preparation_lt.append(pictmp[:, :int(sizex*0.6)]) > preparation_lt.append(pictmp[:, int(sizex*0.4):]) エラーが出ました。 stitched = Stitcher_PANORAMA.stitch(preparation_lt) この部分で、 # エラー文 Unknown C++ exception from OpenCV code
jbpb0

2022/09/21 11:34

コードの順番は、元通りですよ これをこれに変える、と書いてるだけです
yukimeat1999

2022/09/21 11:43 編集

順番は変更していません。 ご指摘のあった箇所のみ置き換えて、実行した結果、 imwrite()ではなく、stitched = Stitcher_PANORAMA.stitch(preparation_lt)の部分でエラーが出ました。 以下、if文内のコード一部抜粋。 os.makedirs(preparation_path, exist_ok=True) # for文 質問用にfor文を削除し,簡単な文に編集している i = 1 preparation_lt = [] # H:\headrace\img2_s3l\img2_s3l\trims_3l00001.png #preparation_lt.append(cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png'))) #preparation_lt.append(cv2.imread(os.path.join(upper_photo_path, f'trims_3t{i:05}.png'))) pictmp = cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png')) sizex = pictmp.shape[1] preparation_lt.append(pictmp[:, :int(sizex*0.6)]) preparation_lt.append(pictmp[:, int(sizex*0.4):]) print(os.path.join(left_photo_path, f'trims_3l{i:05}.png')) np_preparation_lt = [] np_preparation_lt = np.concatenate(preparation_lt, axis=1) # 横方向に #cv2.imshow(f'np_preparation_lt', np_preparation_lt) #cv2.waitKey(0) #cv2.destroyAllWindows() #print(f'show: trims_3l{i:05}.png') # パノラマ書き出し #stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) stitched = Stitcher_PANORAMA.stitch(preparation_lt) #エラー # エラー文 # Unknown C++ exception from OpenCV code #print(stitched[0].shape) #cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), np_preparation_lt) cv2.imwrite(os.path.join(preparation_path, f'create_preparation_lt_{i:05}.png'), stitched[1]) print(f'create: lt_{i:05}.png') stitched.clear() preparation_lt.clear() np_preparation_lt.clear()
jbpb0

2022/09/21 11:50

stitched = Stitcher_PANORAMA.stitch(preparation_lt) のすぐ上に下記を追加して実行した結果を教えてください print(pictmp.shape) print(sizex) print(type(preparation_lt)) print(len(preparation_lt)) print(type(preparation_lt[0])) print(type(preparation_lt[1])) print(preparation_lt[0].shape) print(preparation_lt[1].shape)
yukimeat1999

2022/09/21 11:57

ご指摘いただいた箇所に、print文を8行追加し実行した結果、以下のようにコンソールに出力されました。 # 出力結果 H:\headrace\img2_s3l\img2_s3l\trims_3l00001.png (300, 1920, 3) 1920 <class 'list'> 2 <class 'numpy.ndarray'> <class 'numpy.ndarray'> (300, 1152, 3) (300, 1152, 3)
jbpb0

2022/09/21 14:11 編集

データの形式は合ってるようです stitched = Stitcher_PANORAMA.stitch(preparation_lt) のすぐ下に下記を追加して実行したら、結果表示されますでしょうか? print(type(stitched[1])) print(stitched[1].shape) エラーが起きてるので、上記追加行まで到達しないでしょうか?
yukimeat1999

2022/09/21 12:40

stitched = Stitcher_PANORAMA.stitch(preparation_lt) のすぐ下に print(type(stitched[1])) print(stitched[1].shape) を追加し実行しましたが、 ご指摘の通り、 stitched = Stitcher_PANORAMA.stitch(preparation_lt) の部分でエラーが出てるので、追記したprint文まで到達しませんでした。
jbpb0

2022/09/21 14:12 編集

変更したコードは、一つの画像を重複するように二つに分割(左から60%と右から60%)したものを結合するようにしたので、画像の中心付近に何か写ってれば、それを手がかりにして容易に位置を合わせて結合できるはずなのですが 下記のようにしても、ダメでしょうか? (他はこれまでと同じ) pictmp = cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png')) ↓ 変更 pictmp = np.random.randint(0, 255, (500, 1000, 3)).astype(np.uint8)
yukimeat1999

2022/09/21 15:45

> pictmp = cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png')) > ↓ 変更 > pictmp = np.random.randint(0, 255, (500, 1000, 3)).astype(np.uint8) を変更し実行したところ、 このサイトの最後の方に貼ってある画像みたいな砂嵐が書き出されました。 https://blanktar.jp/blog/2020/08/python-opencv-create-virtual-webcam それと、 stitched.clear() ここでエラーが出てしまいました。 # エラー文 'tuple' object has no attribute 'clear' たびたび申し訳ないです。
jbpb0

2022/09/22 00:01

> 砂嵐が書き出されました。 乱数で作った画像なので、それで正常です 乱数で作った画像なら合成できてるので、質問者さんが使ってる画像が合成に向かないものなのかもしれません コードの > preparation_lt.append(cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png'))) preparation_lt.append(cv2.imread(os.path.join(upper_photo_path, f'trims_3t{i:05}.png'))) のところを元(質問のもの)に戻して、 https://github.com/opencv/opencv_extra/tree/4.x/testdata/stitching から「s1.jpg」と「s2.jpg」をダウンロードして、それらを使ってみてください
jbpb0

2022/09/22 00:04

> 'tuple' object has no attribute 'clear' stitched.clear() ↓ 修正 stitched = () np_preparation_lt.clear() ↓ 修正 np_preparation_lt = []
jbpb0

2022/09/22 00:16

> stitched = Stitcher_PANORAMA.stitch(preparation_lt) の後で、「stitched[0]」の値を調べてください その値が「0」の場合は合成に成功してるので、「stitched[1]」を「cv2.imwrite()」で保存できます 値が「0」以外の場合は合成に失敗してるので、「cv2.imwrite()」で保存できません 「0」以外の意味は、 https://docs.opencv.org/3.3.0/d2/d8d/classcv_1_1Stitcher.html の「Public Types」の「enum Status {」の下を見てください
yukimeat1999

2022/09/22 02:59

「s1.jpg」と「s2.jpg」をダウンロードし、Pathと参照するファイル名を変更し実行したところ、 「s1.jpg」と「s2.jpg」のパノラマが作成できました。 > > stitched = Stitcher_PANORAMA.stitch(preparation_lt) > > の後で、「stitched[0]」の値を調べてください > その値が「0」の場合は合成に成功してるので、「stitched[1]」を「cv2.imwrite()」で保存できます > 値が「0」以外の場合は合成に失敗してるので、「cv2.imwrite()」で保存できません 「s1.jpg」と「s2.jpg」の合成時は、「stitched[0]」の値は0(OK)でした。 stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) stitched = Stitcher_PANORAMA.stitch(preparation_lt) この2文のどちらかを片方ずつ実行しても、 元々の私が用意している画像だと、「stitched[0]」の値は1(ERR_NEED_MORE_IMGS)でした。 友人も同じ画像でpython OpenCVでstitchingを行っているのですが、そちらでは合成できてるようなのですが、pythonやOpenCVのバージョンによって対応している画像の種類に違いはありますか?
jbpb0

2022/09/22 03:17

> stitched = Stitcher_PANORAMA.stitch(np_preparation_lt) はムリです 「np_preparation_lt」って、 > np_preparation_lt = np.concatenate(preparation_lt, axis=1) で一枚につなげたものですので、一枚では「合成」できません 「s1.jpg」と「s2.jpg」を使った場合でも、stitched[0]は「1」になるはずです
jbpb0

2022/09/22 03:41

当方で確認したところ、(オーバーラップしてるところが全く無い)合成がムリな二枚の画像を使ったら、 > stitched = Stitcher_PANORAMA.stitch(preparation_lt) の場合も、stitched[0]は「1」になりました > pythonやOpenCVのバージョンによって対応している画像の種類に違いはありますか? 分かりません https://qiita.com/itoshogo3/items/7a3279668b24008a3761 に解説されてるように、いろんなことをやってて、そのどれかが失敗したらダメなのですが、opencvのバージョンによって動作が変わるということは考えられます (考えられるだけで、それが原因かどうかは分かりません)
yukimeat1999

2022/09/22 16:02

np.concatenate()について理解しました。 いろいろお調べいただきありがとうございます。 自分なりに、今ある画像を連結するために調べてて気になったことがあり、質問させてください。 もともと下のコードを書いてた部分(2行それぞれ)を、 preparation_lt.append(cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png'))) 次のコードみたいに、一度imgに入れてから、appendしたのですが、 img = cv2.imread(os.path.join(left_photo_path, f'trims_3l{i:05}.png')) print(type(img)) # <class 'numpy.ndarray'> #img = pil2cv(img) #print(type(img)) # <class 'numpy.ndarray'> preparation_lt.append(img) img = 0 print(img) # 0 この時、imgの上にカーソルを近づけると、 (variable) img: Mat と表示されます。 C++のOpenCVではMat型を使うプログラムが多く解説されていますが、 pythonのOpenCVでは、Mat型について記述のあるサイトを見つけることができませんでした。 ここで一度imgに画像を入れるようにしたことで疑問に思ったのですが、画像をMat型で扱えていないから起きたエラーなのかなとも思いました。 Mat型はpythonではできないのでしょうか。 下のサイトを参考に、append()する前に、画像の変換を行おうとしました。 https://qiita.com/derodero24/items/f22c22b22451609908ee どっちもnumpyだったので、意味はなかったです。 この時使用した関数は、 def pil2cv(image): ''' PIL型 -> OpenCV型 ''' new_image = np.array(image, dtype=np.uint8) # カラー new_image = cv2.cvtColor(new_image, cv2.COLOR_RGB2BGR) return new_image
jbpb0

2022/09/26 00:37

合成がうまくいくかどうかが、opencvで読み込んだ後の形式の違いにあるのではないか、と思うのなら、画像を読み込んだ後に、 print(type(img)) print(img.ndim) print(img.shape) print(img.dtype) とか実行して、合成がうまくいく画像とうまくいかない画像で相違点が無いか、を確認してみてください (「img.shape」の最初の二つの数値は、画像の縦横の画素数なので、違ってても大丈夫です)
jbpb0

2022/09/26 00:49

https://github.com/opencv/opencv_extra/tree/4.x/testdata/stitching の「s1.jpg」と「s2.jpg」で合成ができるのなら、現状のコードは正しいはず https://tech-blog.s-yoshiki.com/entry/36#%E4%BB%96%E3%81%AE%E7%94%BB%E5%83%8F%E3%81%A7%E3%82%82%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F の「他の画像でも試してみた」の「失敗した画像」のように、(コードが正しくて)重複する物が写ってても合成できない場合もあります そのままでは合成ができない画像でも、明るさとか色合いとか輪郭の強調度合いとか、何か画像処理をしたら合成ができるようになる、という可能性はありますけど、 https://qiita.com/itoshogo3/items/7a3279668b24008a3761 に解説されてる各ステップのどこでコケてて、どうしたらうまくいくのかを調べないと、分かりません

まだ回答がついていません

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

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

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

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

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenCV

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

Python

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