ITいろいろ

プログラミングやクラウド、データ解析など、ITにかかわることをいろいろと書いています。

色調で簡易的な物体検出

今日は色調を見て赤色のものを検出するプログラムを紹介します。 色で検知するにはHSVを利用します。こちらもまた後程紹介します。

コード紹介

# import
import cv2

# 検知する範囲の指定
target_x1, target_x2, target_y1, target_y2 = 300, 350, 200, 250

# Webカメラから入力を開始
cap = cv2.VideoCapture(0)
while True:
    # カメラの画像を読み込む
    _, frame = cap.read()

    # 判定個所のトリミング
    frame_judge = frame[target_y1:target_y2, target_x1:target_x2]

    # HSV変換
    hsv = cv2.cvtColor(frame_judge, cv2.COLOR_BGR2HSV)

    # HSVそれぞれを一次元配列に格納
    h, s, v = hsv[:, :, 0].flatten(), hsv[:, :, 1].flatten(), hsv[:, :, 2].flatten()
    
    # HSVそれぞれの平均
    h_mean, s_mean, v_mean = h.mean(), s.mean(), v.mean()

    # 検知範囲を矩形で表示
    cv2.rectangle(frame, (target_x1, target_y1), (target_x2, target_y2), (255, 255, 255), thickness=2)

    # print(h_mean, s_mean, v_mean)
    if( ( 0 <= h_mean < 30 or 150 <= h_mean < 180 ) and s_mean >= 100 ):
        # 文字の出力
        cv2.putText(frame, text='Red!', org=(50, 50), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1.0, color=(0, 0, 255), thickness=2)

    # ウィンドウに画像を出力
    cv2.imshow('Camera', frame)
    
    # ESCかEnterキーが押されたらループを抜ける
    k = cv2.waitKey(500) & 0xFF  # 500msec毎
    if k == 27 or k == 13: break

cap.release()   # カメラを開放
cv2.destroyAllWindows() # ウィンドウを破棄

出力結果

枠内に赤色が入った時に「Red!」と表示されるようになりました。

少し解説

HSVについて

色の表現を以下3つの観点で行う方法です。

H: 色相
S: 彩度
V: 明度

引用:Wikipedia ja.wikipedia.org

Wikipediaの画像にあるように、Sの値が小さいと黒っぽいもしくは白っぽい色になるため、Sは100以上にします。

Hの値は以下の表を参考にしてください。

Hの値
0~30, 150~179
30~90
90~150

関数

flatten() 多次元配列を一次元配列に変換

python hsv[:, :, 1]は[[1,1,...,1][1,1,...,1]]のように多次元になっています。python hsv[:, :, 1].flatten()とすることで、[1,1,...,1]というように一次元の配列にすることができます。

mean() 平均値の計算

上記一次元配列にしたもの(h)に対して、python h.mean()とすることで配列内の平均値を求めることができます。

つまり、検知範囲の中のH(色相)の平均を出していることになります。

cv2.rectangle 画像に四角形を表示

python cv2.rectangle(frame, (target_x1, target_y1), (target_x2, target_y2), (255, 255, 255), thickness=2) で、四角形を表示しています。

第一引数:画像
第二引数:左上の座標
第三引数:右下の座標
第四引数:線の色
第五引数:線の太さ

となります。

cv2.putText 画像にテキストを表示

python cv2.putText(frame, text='Red!', org=(50, 50), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1.0, color=(0, 0, 255), thickness=2)でテキストを表示します。

第一引数:画像
第二引数:表示するテキスト
第三引数:左上の座標
第四引数:フォント種類
第五引数:フォントサイズ
第六引数:テキストの色
第七引数:テキストの太さ

です。