前提
素人なのでご教授いただければ幸いです。
Open-CVで色の割合を求めるシステムをつくっている。
実現したいこと
紅葉を定点観測して得た画像を分析して紅葉日と落葉日を判断させたい。その中で今回、撮影した画像のなかの色の割合を出したいと考えています。
発生している問題
紅葉と判定している部分が明らかに35%を超えているように感じているが35%と出ており、おかしい気がする。
該当のソースコード
import numpy as np import cv2 import collections import pandas as pd from matplotlib import pyplot as plt img_bgr = cv2.imread('IMG_7170.jpg', 6) for i in range(int(hit/2)):img_bgr[i] = img_bgr[i] / 2 img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV) hsv_min = np.array([ 20, 64, 0]) hsv_max = np.array([ 90, 255, 255]) mask = cv2.inRange(img_hsv, hsv_min, hsv_max) plt.imshow(mask) print("Rust ratio is :", sum(mask) / 255 / hit / wid * 100, '%')
試したこと
他の画像でやってみたが他の画像だとそれ相応の値が出ていると感じている。
> hsv_min = np.array([ 47, 255, 173])
hsv_max = np.array([0, 255, 255])
だと、
H:47以上、0以下
S:255だけ
V:173以上、255以下
に合致したものだけになります
まずHがありえない条件(min>max)なので、検出数が0になります
画像の検出したい「黄色」の部分のHSV変換後のHの値を確認して、それが範囲に入るように(かつ、min<maxになるように)設定してみてください
また、Sが255だけって彩度maxのみなので、画像から検出したい「黄色」の部分のSが本当に255なのか、確認した方がいいですよ
もちろんVの確認も要ります
画像の検出したい「黄色」の部分のHSV変換後のH, S, Vの値を確認して、それらが全て範囲に入るように、「hsv_min」と「hsv_max」を設定してみてください
画像の左端の「黄色」と、真ん中やや右の「黄色」は、また違うでしょうし
jbpb0さんありがとうございます!
試行錯誤して行っております非常に感謝してます。ありがとうございます。
maskは2次元なので、「sum(mask)」は一つの値ではなく、画像の横方向の画素数と同じ要素数の配列になるはずです
「sum(mask)」じゃなくて「np.sum(mask)」でしょうか?
質問の現在の画像をダウンロードして、質問のコードを「np.sum(mask)」に変えて、「hit」と「wid」に画像の縦・横方向の画素数をそれぞれ入れて、他はそのままで実行したら、
Rust ratio is : 78.22978741277834 %
となり、
> 35%と出ており
とはなりませんでした
画像かコードか、どちらか(あるいは両方)が質問者さんが実際に実行して確認してるものと、違うのですかね
> for i in range(int(hit/2)):img_bgr[i] = img_bgr[i] / 2
は、画像の上半分を暗くしてるようですが、この質問の内容とは関係無いですよね
この処理は要るのですか?
> hsv_min = np.array([ 20, 64, 0])
と、V(明るさ)の下限を「0」にすると、たとえば木の幹のようにかなり暗くて(黒に近くて)、目視ではどんな色かよく分からないものも色判定の対象になってしまいます
実際、質問のmask画像を見ると、木の幹で「黄色」と判定されてる部分が多いようです
Vの下限をもう少し大きくして、木の幹のようにかなり暗いところは色判定から除外されるようにした方がいいのではないですかね
なお、Vの範囲を変える場合は、下記はやらない方がいいと思いますよ
> for i in range(int(hit/2)):img_bgr[i] = img_bgr[i] / 2
jbpb0さん何度もありがとうございます。
変更したところうまくいきました!!
私の回答で解決しませんでしょうか?

