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

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

ただいまの
回答率

88.60%

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 154

Minarai_stu

score 3

前提・実現したいこと

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

発生している問題

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

該当のソースコード

import cv2
import numpy as np
from scipy import stats

Bmode = stats.mode(Brow[Brow>0]) [0][0] 
print("B mode:"+str(Bmode))

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

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

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • can110

    2020/11/22 11:07

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

    キャンセル

  • Minarai_stu

    2020/11/22 13:44

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

    キャンセル

回答 3

checkベストアンサー

+1

追記)

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

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

import cv2
import numpy as np

from scipy import stats

def calc_Bmode(img):
    if len(img.shape)==3:
        print(img.shape,"--> ",end="")
        BGR = cv2.split(img_col)
        img = BGR[0]
        print(img.shape)
    else:
        print(img.shape)


    Brow = np.array(img).flatten()
    Bmode = stats.mode(Brow[Brow>0])[0][0]
    print("Bmode", Bmode)
img_col =cv2.imread("./img_green_masked.jpeg")

BGR = cv2.split(img_col)
Blue = BGR[0]

print("---一旦保存法---")
cv2.imwrite("./blue.jpeg",Blue)
img_blue_loaded = cv2.imread("./blue.jpeg")
calc_Bmode(img_blue_loaded)
cv2.imshow("img_blue_loaded",cv2.resize(img_blue_loaded,None,fx=0.25,fy=0.25))
cv2.waitKey(0)

print("---色の分解法---")
calc_Bmode(Blue)

cv2.imshow("Blue",cv2.resize(Blue,None,fx=0.25,fy=0.25))

cv2.waitKey(0)

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

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


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


import cv2
import numpy as np

from scipy import stats

img = cv2.cvtColor(cv2.imread("./img.png"),cv2.COLOR_BGR2GRAY)

print("1以上の条件なし Numpy")
arr, count = np.unique(img, return_counts=True)
idx = np.argmax(count)
print("Maximum index[RAW]:",arr[idx])
print("Count:       [RAW] ",count[idx])
# print(count)

print("1以上の条件あり Numpy")
arr, count = arr[1:], count[1:]
idx = np.argmax(count)
print("Maximum index:     ",arr[idx])
print("Count:             ",count[idx])

print("1以上の条件あり Scipy")
Bmode = stats.mode(img[img>0])[0][0]
print(Bmode)


イメージ説明

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/11/22 18: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 19:44

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

    キャンセル

  • 2020/11/22 21:17

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

    キャンセル

+1

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

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

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/11/22 14:12 編集

    ご回答ありがとうございます。
    私の説明文不足で申し訳ありません。
    画像は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()

    キャンセル

+1

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

import cv2
import numpy as np
from scipy import stats
from PIL import Image, ImageDraw

# テスト画像
img = Image.new('RGB', (500,200), (0,0,0))
draw = ImageDraw.Draw(img)
draw.rectangle((50,50,150,150), fill=(200,200,200))
draw.rectangle((200,50,400,150), fill=(100,100,100))# こちらのほうが大きい

img.save('ret.png')
img = np.array(img, dtype=np.uint8)
Brow = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

print(stats.mode(Brow[Brow>0]))
# ModeResult(mode=array([100], dtype=uint8), count=array([20301]))

Bmode = stats.mode(Brow[Brow>0]) [0][0] 
print("B mode:"+str(Bmode)) # B mode:100


イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/11/22 14:00 編集

    ご回答ありがとうございます。
    その可能性が高そうですので、元の画像から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()

    キャンセル

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

  • ただいまの回答率 88.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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