目的
- このチュートリアルでは、BGR \(\leftrightarrow\) Gray、BGR \(\leftrightarrow\) HSV など、ある色空間から別の色空間へ画像を変換する方法を学ぶ。
- それに加えて、動画中の色のついた物体を抽出するアプリケーションを作成する。
- 次の関数を学ぶ: cv.cvtColor()、cv.inRange() など。
色空間の変換
OpenCVには150を超える色空間変換の手法が用意されている。しかしここでは、最も広く使われている2つ、BGR \(\leftrightarrow\) Gray と BGR \(\leftrightarrow\) HSV のみを扱う。
色変換には関数 cv.cvtColor(input_image, flag) を使用する。ここで flag は変換の種類を決定する。
BGR \(\rightarrow\) Gray 変換には、フラグ cv.COLOR_BGR2GRAY を使用する。同様に BGR \(\rightarrow\) HSV にはフラグ cv.COLOR_BGR2HSV を使用する。その他のフラグを取得するには、Pythonのターミナルで次のコマンドを実行するだけでよい:
>>> import cv2 as cv
>>> flags = [i for i in dir(cv) if i.startswith('COLOR_')]
>>> print( flags )
- 覚え書き
- HSVでは、色相(hue)の範囲は[0,179]、彩度(saturation)の範囲は[0,255]、明度(value)の範囲は[0,255]である。ソフトウェアによって異なるスケールを使用する。したがって、OpenCVの値をそれらと比較する場合は、これらの範囲を正規化する必要がある。
物体追跡
BGR画像をHSVに変換する方法が分かったので、これを使って色のついた物体を抽出できる。HSVでは、BGR色空間よりも色を表現しやすい。このアプリケーションでは、青色の物体を抽出してみる。手順は次のとおりである:
- 動画の各フレームを取得する
- BGRからHSV色空間へ変換する
- 青色の範囲についてHSV画像をしきい値処理する
- 青色の物体だけを抽出したので、その画像に対して好きな処理を行える。
以下は詳細にコメントを付けたコードである:
import cv2 as cv
import numpy as np
while(1):
_, frame = cap.read()
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
if k == 27:
break
Class for video capturing from video files, image sequences or cameras.
Definition videoio.hpp:786
void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)
Checks if array elements lie between the elements of two other arrays.
void bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray())
computes bitwise conjunction of the two arrays (dst = src1 & src2) Calculates the per-element bit-wis...
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
int waitKey(int delay=0)
Waits for a pressed key.
void destroyAllWindows()
Destroys all of the HighGUI windows.
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0, AlgorithmHint hint=cv::ALGO_HINT_DEFAULT)
Converts an image from one color space to another.
下の画像は青色の物体の追跡を示している:
image
- 覚え書き
- 画像にはいくらかノイズがある。これを除去する方法は後の章で説明する。
- これは物体追跡における最も単純な手法である。輪郭の関数を学べば、物体の重心を求めてそれを使って物体を追跡したり、カメラの前で手を動かすだけで図を描いたりと、多くの面白いことができるようになる。
追跡対象のHSV値を見つける方法は?
これは stackoverflow.com でよく見られる質問である。とても簡単で、同じ関数 cv.cvtColor() を使える。画像を渡す代わりに、求めたいBGR値を渡すだけでよい。例えば、緑のHSV値を求めるには、Pythonのターミナルで次のコマンドを試す:
>>> green = np.uint8([[[0,255,0 ]]])
>>> print( hsv_green )
[[[ 60 255 255]]]
そして [H-10, 100,100] と [H+10, 255, 255] をそれぞれ下限と上限とする。この方法以外にも、GIMPなどの画像編集ツールやオンラインの変換ツールを使ってこれらの値を求めることもできるが、HSVの範囲を調整するのを忘れないこと。
演習
- 複数の色のついた物体を抽出する方法を見つけてみよう。例えば、赤、青、緑の物体を同時に抽出する。