この記事では、OpenCVの InRange 関数を使って、特定の色の範囲を抽出する方法を紹介する。
使用する画像
今回のサンプル画像は次のものを使用し、この画像から図形の色だけを抽出してみる。正方形の部分はグラデーションになっているが、その部分も考慮した処理にする。
スポンサーリンク
inRange
OpenCVで画像から特定の色の範囲を抽出する場合は、inRange
関数を使用する。この関数は、指定した色の範囲の画素を 255、それ以外の画素を0として2値化する関数である。
【使用例】
result = cv.inRange(src, lower, upper)
この関数は引数を 3つとり、1つ目は元の画像の多次元配列で、2つ目は抽出する画素の下限、3つ目は上限を指定する。戻り値には、元の画像を 255と 0で 2値化した多次元配列を返す。
inRange
で色の範囲を指定する際、色の指定で一般的に用いられる RGBか、色を「色相」「彩度」「明度」の3種で指定する HSVのどちらかで指定する。
戻り値のイメージ
inRange
関数の戻り値は、元の画像を 255
と 0
で 2値化した2次元配列となる。
例えば、5px x 7px
の画像から、3 x 3
の正方形の色を抽出した場合の戻り値は次のようになる。
[[0, 0, 0, 0, 0],
[0, 255, 255, 255, 0],
[0, 255, 255, 255, 0],
[0, 255, 255, 255, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
RGBで色の抽出をしてみる
RGB色指定で上のサンプル画像から、図形部分の色を抽出する。OpenCVでは、RGBはBGRの順に色を指定するので注意。
import cv2
import numpy as np
from IPython.display import Image, display
lower = np.array([200, 120, 0]) # 抽出する色の下限(BGR)
upper = np.array([255, 255 , 150]) # 抽出する色の上限(BGR)
img_mask = cv2.inRange(img, lower, upper) # inRangeで元画像を2値化
# 2値化した画像を表示
ret, encoded = cv2.imencode(".jpg", img)
display(Image(encoded))
【実行結果】
HSVで色の抽出をしてみる
次は、HSVで上と同じように色を抽出してみる。
HSV色空間は「色相(Hue)・彩度(Saturation)・明度(Value)」で色を表したもので、一般的に色の抽出をする場合は HSV 色空間に変換して行ったほうが選択しやすい。
OpenCVでのHSV色指定は、次の値の範囲で行う。
名前 | 値の範囲 |
---|---|
色相(H) | 0〜180 |
彩度(S) | 0〜255 |
明度(V) | 0〜255 |
実際に HSV色空間で上の図形の色を抽出するコードを書いてみる。
import cv2
import numpy as np
from IPython.display import Image, display
lower = np.array([70, 0 , 0]) # 抽出する色の下限(HSV)
upper = np.array([110, 255, 255]) # 抽出する色の上限(HSV)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 画像をHSV色空間に変換
img_mask = cv2.inRange(hsv, lower, upper) # inRangeで元画像を2値化
# 2値化した画像を表示
ret, encoded = cv2.imencode(".jpg", img)
display(Image(encoded))
以下が実行結果。色指定の問題かもしれないが先ほどのRGBで抽出した物よりも、より鮮明に画像から図形の色を抽出できている。
【実行結果】
スポンサーリンク
まとめ
OpenCVで特定の色を抽出する方法を紹介した。
画像の2値化などは、画像認識処理における前処理で重要な部分であるため、inRange
の使い方などはしっかり押さえておいた方が良さそうだ。
0 件のコメント:
コメントを投稿