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

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

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

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

Python

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

Q&A

解決済

3回答

2227閲覧

1以上の画素値を持つピクセルの最頻値を求めたい

Minarai_stu

総合スコア4

OpenCV

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

Python

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

0グッド

0クリップ

投稿2020/11/21 12:15

編集2020/11/22 04:53

前提・実現したいこと

1以上の画素値を持つピクセルの最頻値を求めたいです。

発生している問題

最頻値の値が1になるはずですが、私のコードだと22となっています... 補足情報に画像(Brow)とヒストグラムを載せておきます。

該当のソースコード

python

1import cv2 2import numpy as np 3from scipy import stats 4 5Bmode = stats.mode(Brow[Brow>0]) [0][0] 6print("B mode:"+str(Bmode))

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

イメージ説明
img_green_masked
イメージ説明
Blue
イメージ説明

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

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

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

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

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

can110

2020/11/22 02:07

元の画像と、画像の読み取り部分を含めた最小限の再現ソースを提示すると回答が得られやすくなります。
Minarai_stu

2020/11/22 04:44

アドバイスありがとうございます。 元となる画像などを追記いたします。
guest

回答3

0

回答ではなく検証結果ですが。
単純画像で試してみましたが、処理には問題ないと思います。
元画像の読み取りからBrow変数にセットするまでの処理に問題はないでしょうか。

Python

1import cv2 2import numpy as np 3from scipy import stats 4from PIL import Image, ImageDraw 5 6# テスト画像 7img = Image.new('RGB', (500,200), (0,0,0)) 8draw = ImageDraw.Draw(img) 9draw.rectangle((50,50,150,150), fill=(200,200,200)) 10draw.rectangle((200,50,400,150), fill=(100,100,100))# こちらのほうが大きい 11 12img.save('ret.png') 13img = np.array(img, dtype=np.uint8) 14Brow = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 15 16print(stats.mode(Brow[Brow>0])) 17# ModeResult(mode=array([100], dtype=uint8), count=array([20301])) 18 19Bmode = stats.mode(Brow[Brow>0]) [0][0] 20print("B mode:"+str(Bmode)) # B mode:100

イメージ説明

投稿2020/11/22 02:26

can110

総合スコア38256

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

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

Minarai_stu

2020/11/22 05:01 編集

ご回答ありがとうございます。 その可能性が高そうですので、元の画像からBrowに変換するまでのコードを見直しています。 以下の処理で、img_green_masked(補足情報に画像あり)からBlue、Browを導きました。ですが、最頻値は正しい値がでていません。 ただ、cv2.imwiteでBlueの画像を保存し、再び読み込むと、最頻値が1となります。 この原因について現在悩んでおります。 #色の分解(BlueとBrowを出すコード) RGB =cv2.split(img_green_masked) Blue = RGB[0] Brow = np.array(Blue).flatten()
guest

0

fourteenlengthさんが上げてくれた画像を使ってやってみたら、「B mode:4」と表示されました

python

1import numpy as np 2import cv2 3from scipy import stats 4Brow = cv2.cvtColor(cv2.imread("./img.png"), cv2.COLOR_BGR2GRAY) 5Bmode = stats.mode(Brow[Brow>0])[0][0] 6print("B mode:"+str(Bmode))

確認したら、0を除外したら、やはり4が個数最大でした

python

1histogram, _ = np.histogram(Brow.flatten(), bins=np.arange(np.max(Brow)+2)) 2print(histogram)

投稿2020/11/22 02:25

編集2020/11/23 07:42
jbpb0

総合スコア7651

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

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

Minarai_stu

2020/11/22 05:13 編集

ご回答ありがとうございます。 私の説明文不足で申し訳ありません。 画像はBGR成分のBを抜き出した画像となっています。 となるとBはグレー画像で、以下のコードは不要となりますか?(私の認識間違いかもしれません) Brow = cv2.cvtColor(cv2.imread("./img.png"), cv2.COLOR_BGR2GRAY) jbpb0様に最頻値を求めるコードの産出地はヒストグラムと一致することを教えていただきましたので、私が指定する元の画像の処理にミスがあったのだと思います。 以下の処理で、img_green_masked(補足情報に画像あり)からBlue、Browを導きました。ですが、最頻値は正しい値がでていません。 ただ、cv2.imwiteでBlueの画像を保存し、再び読み込むと、最頻値が1となります。 この原因について現在悩んでおります。 #色の分解(BlueとBrowを出すコード) RGB =cv2.split(img_green_masked) Blue = RGB[0] Brow = np.array(Blue).flatten()
guest

0

ベストアンサー

追記)

1. 以下の写真を"img_green_masked.jpeg"と名前を付けて保存してください。
イメージ説明

2. 画像と同じフォルダに以下のファイルを(適当な名前).pyと名前を付けて保存して走らせてください。

Python3

1import cv2 2import numpy as np 3 4from scipy import stats 5 6def calc_Bmode(img): 7 if len(img.shape)==3: 8 print(img.shape,"--> ",end="") 9 BGR = cv2.split(img_col) 10 img = BGR[0] 11 print(img.shape) 12 else: 13 print(img.shape) 14 15 16 Brow = np.array(img).flatten() 17 Bmode = stats.mode(Brow[Brow>0])[0][0] 18 print("Bmode", Bmode) 19img_col =cv2.imread("./img_green_masked.jpeg") 20 21BGR = cv2.split(img_col) 22Blue = BGR[0] 23 24print("---一旦保存法---") 25cv2.imwrite("./blue.jpeg",Blue) 26img_blue_loaded = cv2.imread("./blue.jpeg") 27calc_Bmode(img_blue_loaded) 28cv2.imshow("img_blue_loaded",cv2.resize(img_blue_loaded,None,fx=0.25,fy=0.25)) 29cv2.waitKey(0) 30 31print("---色の分解法---") 32calc_Bmode(Blue) 33 34cv2.imshow("Blue",cv2.resize(Blue,None,fx=0.25,fy=0.25)) 35 36cv2.waitKey(0) 37

3. 表示される画像に「識別文字」は見えますね?
** =(別のファイルを間違えて開いている可能性は排除できますね?**

4. どちらの方法でも同じBmodeになっていますか?


元のファイルと少し違うようで値が違いますができました。
1以上の~を修正しました。
22となるのはNumpyだとかScipyのせいではなさそうな気がします。
(イメージの指定違い?)


Python3

1import cv2 2import numpy as np 3 4from scipy import stats 5 6img = cv2.cvtColor(cv2.imread("./img.png"),cv2.COLOR_BGR2GRAY) 7 8print("1以上の条件なし Numpy") 9arr, count = np.unique(img, return_counts=True) 10idx = np.argmax(count) 11print("Maximum index[RAW]:",arr[idx]) 12print("Count: [RAW] ",count[idx]) 13# print(count) 14 15print("1以上の条件あり Numpy") 16arr, count = arr[1:], count[1:] 17idx = np.argmax(count) 18print("Maximum index: ",arr[idx]) 19print("Count: ",count[idx]) 20 21print("1以上の条件あり Scipy") 22Bmode = stats.mode(img[img>0])[0][0] 23print(Bmode) 24

イメージ説明

投稿2020/11/22 01:27

編集2020/11/22 08:09
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

jbpb0

2020/11/23 07:46 編集

Brow[Brow>0] をやっているから、flatten()したみたいな形式になってますけど import numpy as np import cv2 from scipy import stats Brow = cv2.cvtColor(cv2.imread("./img.png"), cv2.COLOR_BGR2GRAY) Brow.shape # (231, 174) Brow[Brow>0].shape # (12526,) 数が231*174よりも少ないのは、値が0の27668個が除外されているから
退会済みユーザー

退会済みユーザー

2020/11/22 03:09

指摘ありがとうございます。回答のコードだと「1以上の画素値を持つピクセルの」が落ちてますね。
Minarai_stu

2020/11/22 04:37

ご回答ありがとうございます。 modeにかける対象の処理を間違えていたのかもしれません。 Browの前段階の画像(Blue)をcv2.imwriteで一度保存し、その画像を読み込み最頻値を算出すると1となります。 ただ、Browを対象にするとやはり22となってしまします。 Browは以下のように出しました。 #色の分解 RGB =cv2.split(img_green_masked) Blue = RGB[0] Brow = np.array(Blue).flatten()
Minarai_stu

2020/11/22 04:45

img_green_maskedとBlueの画像を補足情報に追記します。
退会済みユーザー

退会済みユーザー

2020/11/22 08:10

確認方法を追記しました。時間のある時に走らせた結果をお知らせください。
jbpb0

2020/11/22 08:59

fourteenlengthさんが追記されたコードですが、関数「calc_Bmode」内で引数に無い「img_col」が使われているので、引数に渡された「img_blue_loaded」(一旦ファイルに保存されて読みだされたデータ)ではなく、「img_col」(元々のデータ)が使われます 関数「calc_Bmode」内の BGR = cv2.split(img_col) を BGR = cv2.split(img) と直すと、Bmodeは変わります calc_Bmode(img_blue_loaded) (1478, 1108, 3) --> (1478, 1108) Bmode 1 calc_Bmode(Blue) (1478, 1108) Bmode 2
jbpb0

2020/11/22 09:19

画素値からヒストグラムで集計しても、そうなってます histogram_img_blue_loaded, _ = np.histogram(img_blue_loaded[:, :, 0].flatten(), bins=np.arange(256 + 1)) print(histogram_img_blue_loaded) histogram_img_col_B, _ = np.histogram(img_col[:, :, 0].flatten(), bins=np.arange(256 + 1)) print(histogram_img_col_B) JPEGに保存して読みだしたら、画像データが変わってますね print(img_blue_loaded[:, :, 0]) print(img_col[:, :, 0])
jbpb0

2020/11/22 09:38

ファイルに保存するところを cv2.imwrite("./blue.jpeg",Blue, [int(cv2.IMWRITE_JPEG_QUALITY), 100]) と変えて、画質を上げて保存したら、Bmodeは同じになりました calc_Bmode(img_blue_loaded) (1478, 1108, 3) --> (1478, 1108) Bmode 2 calc_Bmode(Blue) (1478, 1108) Bmode 2 ただし、ヒストグラムで各画素値の頻度を比べたら違うので、やはりデータはJPEGに保存して読みだしたら変わっています 少しでもデータが変わったら困るのなら、JPEGに保存するのは止めて、PNGとかにした方がいいと思います
退会済みユーザー

退会済みユーザー

2020/11/22 10:44

teratailにアップロードするとpngもjpegになってしまうので苦肉の策でした…。 ご指定いただいたように、Minarai_stuさんの「Browを対象にするとやはり22となってしまします」の正体はファイル形式の違いかもしれませんね。
Minarai_stu

2020/11/22 12:17

jbpb0様、fourteenlength様多くのコメントありがとうございます。 おかげさまで、png形式ではなくjpg形式で画像を保存して比較していたことが問題であることがわかりました。 コードの問題でなく、拡張子の選択ミスで多くのお時間をお取りしてしまい大変申し訳ありませんでした...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問