Python OpenCVでHSVの閾値を用いて二値化してみた。inRange使用(ソースコードとサンプル画像有)

2023年3月26日

はじめに

OpenCVで色ベースでの物体検出には二値化が必要そうだったので、試してみました。

元画像↓

今回、使用する元画像は以下になります。

実行環境

Python:3.9.7
OpenCV:4.5.3

inRangeに関して

指定した範囲の画素を「255」(下限値≤対象の画素≤上限値は「255」)
それ以外の画素を「0」にする関数。

cv2.inRange(二値化したい画像, 下限値, 上限値)

OpenCV inRange()参考URL

ソースコードに関して

OpenCV(Python)でトラックバーを用いて、閾値を指定して二値化するソースコードを紹介します。
import cv2
import numpy as np

def nothing(x):
    pass

img = cv2.imread("./test.png", cv2.IMREAD_COLOR)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL)
cv2.namedWindow('Binarization', cv2.WINDOW_NORMAL)

cv2.createTrackbar('H-Low', 'Binarization', 0, 255, nothing)
cv2.createTrackbar('S-Low', 'Binarization', 0, 255, nothing)
cv2.createTrackbar('V-Low', 'Binarization', 0, 255, nothing)

cv2.createTrackbar('H-Upp', 'Binarization', 255, 255, nothing)
cv2.createTrackbar('S-Upp', 'Binarization', 255, 255, nothing)
cv2.createTrackbar('V-Upp', 'Binarization', 255, 255, nothing)

while(1):
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break

    HL = cv2.getTrackbarPos('H-Low', 'Binarization')
    SL = cv2.getTrackbarPos('S-Low', 'Binarization')
    VL = cv2.getTrackbarPos('V-Low', 'Binarization')
    lower = (HL,SL,VL)

    HU = cv2.getTrackbarPos('H-Upp', 'Binarization')
    SU = cv2.getTrackbarPos('S-Upp', 'Binarization')
    VU = cv2.getTrackbarPos('V-Upp', 'Binarization')
    upper = (HU,SU,VU)

    bin_img = cv2.inRange(hsv, lower, upper)
    cv2.imshow('Binarization', bin_img)

cv2.destroyAllWindows()

実行結果

トラックバーを操作することにより、二値化された画像を表示することができます。
・トラックバー「H-Low」、「S-Low」「V-Low」で「色相」、「彩度」、「明度」の下限値を指定することができます。
・トラックバー「H-Upp」、「S-Upp」、「V-Upp」で「色相」、「彩度」、「明度」の上限値を指定することができます。
・「Escキー」を入力することで終了します。
以下、実行時のサンプルになります。
閾値二値化テスト
元画像と比較すると薄紫色で記載した「テスト」の部分のみが抽出出来ていることがわかると思います。

補足

HSVの配列構造に関して、以下で解説しています。
もし、よろしければ一読お願いします。
OpenCVでHSV変換した際のhsv[:,:,0]~hsv[:,:,2](色空間)に関して