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

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

詳細はこちら
OpenCV

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

Python

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

Q&A

解決済

2回答

967閲覧

マスク領域外のS(彩度)の分散を求めたい

Minarai_stu

総合スコア4

OpenCV

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

Python

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

0グッド

0クリップ

投稿2020/12/27 05:04

前提・実現したいこと

HSVで閾値を指定してマスク処理を行い、マスクされていない部分の彩度(S)の分散を求めたいです。

わからない部分

RGBが0の場合、彩度は0として考えてよいのでしょうか?
RGBが0の場合、明度は0ですが、色相や彩度はどの値でも取れると認識していて、どう扱えばよいのか困っています。

もしRGBが0の場合は彩度が0であれば、以下のコードを適用できると考えています。
彩度の分散=np.var(彩度の配列[彩度の配列>0])

どうか、お力をお貸しいただけますと幸いです。

該当のソースコード

photos_dir = "/content/drive/MyDrive/1221/D" files = glob.glob(photos_dir + "/*.tiff") # creat green mask (H value for green is from 100/360*179 until 180/360*179) in OpenCV lower_green = np.array([28 , 16, 0]) upper_green = np.array([50, 255, 255]) green_mask=cv2.inRange(img_HSV,lower_green,upper_green) # crop green area img_green_masked = cv2.bitwise_and(img_BGR, img_BGR, mask=green_mask) img_HSV2 = cv2.cvtColor(img_green_masked, cv2.COLOR_BGR2HSV) HSV2=cv2.split(img_HSV2) V1=HSV2[1] Vrow1=np.array(V1).flatten() Vmean1 = Vrow2[0 < Vrow1].mean() VV1=np.var(Vrow1[Vrow1>0])

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

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

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

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

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

guest

回答2

0

いいえ、RGBが0や255のときの彩度や、R=G=Bのときの色相は、未定義です。
データ上扱いづらいので仮に「0」などと置く場合もあるでしょうが(というよりそれがほとんどでしょうが)、分散を求めるなど数学的な扱いをしたいのであれば結果が意味のある数値になるよう扱いを変えなければなりません。
例えばRGB(0,0,1),(0,0,2),(0,0,3)と(0,0,0),(0,0,1),(0,0,2)に対する結果は近いものになってほしいはずです。
今回の場合、RGBが0付近や255付近の値を計算から除外するのが妥当でしょうか。

投稿2020/12/27 09:40

ikadzuchi

総合スコア3047

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

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

Minarai_stu

2020/12/27 10:15

ikadzuchi様、ご回答ありがとうございます。 RGBが0の場合のSは未定義なのですね! 私はマスク部分以外のSの分散を求めようとしております。 私はマスクに対応するSの値を除外して分散を計算しようと考えていましたが、マスク部分はRGBが0なので、対応するSの値は未定義であり、この方法は不適切であることが理解できました。 私はマスク部分以外のSの分散を求める適切な方法がわからないのですが、何か良い方法はありませんでしょうか?(厚かましい質問、大変申し訳ありあません)
guest

0

ベストアンサー

こんにちは、はい、RGBともに0の場合は便宜上HSVのどの値も0になります。たとえばこのページなどがわかりやすいと思います。
ただ、厳密には未定義のようです。
https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93)

python

1import cv2 2import numpy as np 3from matplotlib import pyplot as plt 4im=cv2.imread('sample.png') 5rgb=cv2.cvtColor(im, cv2.COLOR_BGR2RGB) 6plt.imshow(rgb) 7img_HSV = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) 8# creat green mask (H value for green is from 100/360*179 until 180/360*179) in OpenCV 9lower_green = np.array([28 , 16, 0]) 10upper_green = np.array([50, 255, 255]) 11green_mask=cv2.inRange(img_HSV,lower_green,upper_green) 12# crop green area 13img_green_masked = cv2.bitwise_and(im, im, mask=green_mask) 14img_green_masked_rgb=cv2.cvtColor(img_green_masked, cv2.COLOR_BGR2RGB) 15plt.imshow(img_green_masked_rgb) 16img_HSV2 = cv2.cvtColor(img_green_masked, cv2.COLOR_BGR2HSV) 17s_channel=img_HSV2[:,:,1] 18np.var(s_channel[s_channel>0]) 19# flatten()を使う場合 20V1=img_HSV2[:,:,1] 21Vrow1=np.array(V1).flatten() 22VV1=np.var(Vrow1[Vrow1>0]) 23print(VV1)

イメージ説明
彩度の分散はここのコードのように、シンプルに計算してしまっても構わない気がしたのですが、いかがでしょうか。

投稿2020/12/27 05:58

編集2020/12/27 11:04
Kenta_py

総合スコア132

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

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

Minarai_stu

2020/12/27 08:54

ご回答ありがとうございます。 彩度はBGR最大値が分母にあり、また変換ツールでV=0の場合はH,Sは0以外の値でもB,G,Rの値が0と示されていたので、BGRが0の場合はSを0として扱ってよいのか大変迷っていました。 OpenCVではBGRが0の場合、Sが0として表現されるのですね! コードまでいただきありがとうございます。 マスクしている部分(S=0の部分)を除外したいと考えて、 彩度の分散=np.var(彩度の配列[彩度の配列>0]) としているのですが、np.varだけでよかったのでしょうか?
Kenta_py

2020/12/27 11:00

ご返信ありがとうございます。回答に関して、追記させてください。opencvでもRGBが[0 0 0]のHSVは0として0として返されますが、ikadzuchiさまのおっしゃるように、未定義のようですね。不勉強で失礼いたしました。https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93 また、0や255付近のものを避けるために、もともとMinarai_stuさまの書かれていたコードがよさそうですね。訂正しているのでご確認ください。もし間違いがあれば教えてください。よろしくお願いいたします。
Minarai_stu

2020/12/28 02:27

Kenta_py様、ご返信、ご回答と参照コード改善、リンクの添付をありがとうございます。 ありがたく参考にさせていただいております。 重ねての質問となってしまいますが、 V1=HSV2[1]とs_channel=img_HSV2[:,:,1] は列数、行数を表現しているか否かということで、同じとしてみてよろしいのでしょうか?
Kenta_py

2020/12/28 06:49

役に立ったようで嬉しいです。img_HSV2[:,:,1]では、縦方向の上から下まで、横方向の左から右まで、2チャンネル目(0の次)を取ってくるという意味です。そのため、ここではimg_HSV2[:,:,1]としておけば良いと思います。
Minarai_stu

2020/12/28 09:17

理解することができました。 ご回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問