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

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

詳細はこちら
Python

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

Q&A

解決済

1回答

9301閲覧

pythonの画像出力について

kshota

総合スコア1

Python

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

0グッド

0クリップ

投稿2020/11/28 13:16

編集2020/12/01 07:44

前提・実現したいこと

画像セグメンテーションで、画像を出力したいのですができません。
https://docs.opencv.org/master/d3/db4/tutorial_py_watershed.htmlの一番最後にある二つの画像を出力したいです。

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

Traceback (most recent call last):
File "color.py3", line 39, in <module>
cv.imshow('marks',markers)
cv2.error: OpenCV(4.4.0-dev) /export/ruby/GIT/OpenCV/opencv/modules/highgui/src/precomp.hpp:137: error: (-215:Assertion failed) src_depth != CV_16F && src_depth != CV_32S in function 'convertToShow'

該当のソースコード

python

1import numpy as np 2import os 3import sys 4vnum = str(sys.version_info[0]) + "." + str(sys.version_info[1]) 5UsrLocalLibPath = '/usr/local/lib/python' + vnum + '/dist-packages' 6if not os.path.exists( UsrLocalLibPath + "/cv2" ) == True: 7 print("user local lib path for cv2 does not exist: " + UsrLocalLibPath) 8 exit(-1) 9sys.path.append(os.path.join(os.path.dirname(__file__), UsrLocalLibPath)) 10import cv2 as cv 11from matplotlib import pyplot as plt 12img = cv.imread('coins.png') 13gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY) 14ret, thresh = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV+cv.THRESH_OTSU) 15 16# noise removal 17kernel = np.ones((3,3),np.uint8) 18opening = cv.morphologyEx(thresh,cv.MORPH_OPEN,kernel, iterations = 2) 19# sure background area 20sure_bg = cv.dilate(opening,kernel,iterations=3) 21# Finding sure foreground area 22dist_transform = cv.distanceTransform(opening,cv.DIST_L2,5) 23ret, sure_fg = cv.threshold(dist_transform,0.7*dist_transform.max(),255,0) 24# Finding unknown region 25sure_fg = np.uint8(sure_fg) 26unknown = cv.subtract(sure_bg,sure_fg) 27 28# Marker labelling 29ret, markers = cv.connectedComponents(sure_fg) 30# Add one to all labels so that sure background is not 0, but 1 31markers = markers+1 32# Now, mark the region of unknown with zero 33markers[unknown==255] = 0 34 35markers = cv.watershed(img,markers) 36img[markers == -1] = [255,0,0] 37 38cv.imshow('marks',markers) 39cv.waitKey(0) 40cv.destroyAllWindows()

試したこと

imshowで画像を表示する部分のプログラムがうまくいかないのですが、エラーを見て調べてもなにが原因か分かりません。教えていただけると嬉しいです。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

jbpb0

2020/11/28 14:29

imreadで画像ファイルを読んで、それをそのままimshowで表示するのは、問題無いのでしょうか? それが問題無いなら、うまくいかないのはおそらくimshowで表示しようとしているデータが正常ではないのだから、そちらが意図通りになっているのかを追いかけた方がいいと思います
kshota

2020/12/01 07:41

調べてみましたが、markersがどの型で表示できるのかよく分かりません。私が画像を表示したい画像を表示サイトはhttps://docs.opencv.org/master/d3/db4/tutorial_py_watershed.htmlの最後の画像二つですが、出力方法が書かれていなく悩んでいます。
jbpb0

2020/12/01 08:12 編集

cv.imshow('marks',markers) の直前で、 print(markers.dtype) print(np.min(markers)) print(np.max(markers)) を実行すると、markersは int32 で、入っている値は -1~25 であることが分かります http://opencv.jp/opencv-2.1/cpp/user_interface.html#cv-imshow のimshowの説明を読むと、int32(符号有り32bit整数)は表示できるデータ型に入ってませんので、fourteenlengthさんも回答に書いてますが、表示できる型のどれかに変換する必要があります その際に問題になるのが、データ中に負の数(-1)があることです 負の数は表示できませんが、無視して表示しなくても良いのか?? あるいは、表示する必要があるので、正の数に変換する必要があるのか?? 正の数に変換する場合は、もともとある正の数(最大25)と区別する必要が有るのか無いのか?? それによって、どのような型に変換すればよいのか、また、単に型変換だけでよいのか、あるいは、負の数を特定の正の数に変換する必要があるのか、とかが決まります そのあたりを考慮しながら、どのようにしたら自分が意図した通りの表示になるのか考えて、いろいろやってみるといいと思いますよ 挙げられたpythonコードの上から下まで、各ステップで何をしているのか、段階的に理解していけば、自ずと答えは分かるでしょう
kshota

2020/12/03 07:27

ありがとうございます。 #fig, ax = plt.subplots(figsize=(6, 6)) #ax.imshow(markers, cmap="tab20b") #plt.show() とすることによりいけました。
guest

回答1

0

ベストアンサー

-215:Assertion failedは、型が一致しない、データがそもそもないなど、データを裁く前に「これはさすがにないわ」というエラーをあらかじめつゆ払いする際に発生するエラーです。

src_depth != CV_16F && src_depth != CV_32S
OpenCVの気持ち:imshowはint32でも、float16でもないものがほしかったんだけどなぁ

ということになります。

Python3

1# cv.imshow('marks',markers) 2cv.imshow('marks',markers.astype(np.float32))

に差し替えたら動きませんか?
こちらでは動いて輪郭らしきものがとらえられました。

投稿2020/11/28 23:52

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kshota

2020/12/01 06:50

返信ありがとうございます。私も先ほど試してみましたところ、黒色の輪郭がでました。なのですが私が出したい画像がこちらhttps://docs.opencv.org/master/d3/db4/tutorial_py_watershed.htmlのサイトの最後のカラフルな画像と赤色の輪郭の画像なのですが色々試してみましたがうまくいきませんでした。
退会済みユーザー

退会済みユーザー

2020/12/01 22:21

markers[unknown==255] = 0の下でmarkersをimshowをすると、ドーナッツ状の画像が見えるはずです。 img[markers == -1] = [255,0,0] の後にimgをimshowすると、写真に輪郭をマークして表示されます。ここでmarkersをimshowすると、グラデーション画像として表示されます。 カラフルに表示されるのはmatplotlibのグラフを表示する際にグレースケールをカラー画像に置き換える機能でできます。 https://www.google.com/search?sxsrf=ALeKk02T6WAIiTdEnoQbcJ4zQLOQ_c9ChA%3A1606861218044&ei=osHGX7iQAor70gTLtYvwDQ&q=matplotlib+jet+%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB&oq=matplotlib+jet+%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB&gs_lcp=CgZwc3ktYWIQAzIFCAAQzQI6BAgjECc6AggAOgUIABDLAToECAAQHjoGCAAQBRAeOgUIIRCgAToGCAAQCBAeUK4cWIIzYIQ2aAJwAHgAgAGgA4gBgRqSAQowLjExLjMuMC4ymAEAoAEBqgEHZ3dzLXdpesABAQ&sclient=psy-ab&ved=0ahUKEwi46erA6K3tAhWKvZQKHcvaAt4Q4dUDCA0&uact=5 でなんとなくわかると思います。
退会済みユーザー

退会済みユーザー

2020/12/02 13:52

書きそびれてました。jbpb0さんの操作(正規化と言います)をこれらの前に適宜行ってください。使う関数は、最大値を求めるnp.max()と最小値を求めるnp.mean()です。 1. 画像の最小値を求める 2. 画像に最小値を加算して「最小値を加算した画像」を用意する 3. 「最小値を加算した画像」の最大値を求める 4. 正規化した画像=(「最小値を加算した画像」÷最大値)×255 5. 正規化した画像をnp.uint8に変換する(8bit integerの画像にする)
kshota

2020/12/03 07:30

ありがとうございます。imshow(img)で赤い輪郭が見え、うまくいきました。細かいところの解説までありがとうございます。とても勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問