HSVで画像を2値化して恐竜君を検出してみる
前回はRGBで画像を分離した後で、画像を2値化してみた。ただ、今回対象としている画像のように、緑色の物体を検出したいような場合は、画像をRGB空間から色相(Hue)、彩度(Saturation)、明度(Value)のHSV空間に変換して色相で検出した方が、明るさの影響を受けないので検出しやすい。
ということで、今回はMATLABの機能で画像をRGB→HSV変換した後に、HSVに分離してH(色相)で閾値を決めて恐竜君を検出してみる。
ちなみに以下が前回RGB分離してから2値化したもの↓ 恐竜君は塊としてうまく検出できているが、上の方に机の端が入り込んでしまっている。
開発環境
MATLAB online
MATLAB R2022a
Image Processing Toolbox
RGB→HSV変換する
まずはいつものごとく、画像を半分のサイズにリサイズしておく。※画像が大きくて扱いずらいため
A = imread('dinosaur.jpg'); Asmall = imresize(A, 0.5);
AsmallをRGB→HSVに変換するが、こちらはMATLABでrgb2hsvという関数が用意されているので、こちらを使う。
Ahsv = rgb2hsv(Asmall);
これで変換は完了。rgb2hsvの詳細については以下の公式ドキュメントを参照。ちなみに今回のケースのように0~255の値をとるuint8型のRGB画像をHSVに変換した場合、HSVはdouble型になり、Hは0~1の範囲の値になる。
https://jp.mathworks.com/help/matlab/ref/rgb2hsv.html
H、S、Vに分離する
これをH、S、Vに分離するが、こちらについては前回と同様にimsplit関数を使えばOK。
[H,S,V] = imsplit(Ahsv);
これでワークスペースにH、S、Vのそれぞれの行列が保存される。montage関数で並べて表示してみたのが以下の画像。左からH、S、Vの並びになっている。
せっかくなので、RGBで分離してみた時とも比較してみる。HSVで分離した場合とかなり様子が異なっていることがわかる。画像だとちょっとわかりにくいが、Hの恐竜君の領域は大体0.50前後の値になっているため、このあたりの数値で閾値を決めてやればうまく恐竜君を検出できそう。
H(色相)で閾値を決めて画像を2値化する
さっそくHで閾値を決めて画像を2値化してみる。なるべく0.50に近い値だけ検出したいので、以下のように2つ閾値を設定して論理和を取って2値化してみる。
BW = (H > 0.45) & (H < 0.55);
2値化してみたのが以下の画像。恐竜君の形がほぼ消えることなく、恐竜君以外のものはほぼ消えているので、かなり良い感じに検出できている。
今回のケースでは写真内で恐竜君だけ色が違うので、Hを使うことでうまく検出ができた。どういう検出方法が良いかはケースバイケースだとは思うが、MATLABはいろいろと関数がデフォルトで用意されているので、簡単に試行錯誤ができてかなり便利。
今後のネタは特に決めてないが、面白そうな関数があれば試してみたい。
参考文献
画像の色抽出 ~RGBとHSVでの色抽出~ | 画像認識の技術ブログ | マクセルフロンティア株式会社
以下の本も適宜参照してます。
MATLAB/Simulink記事まとめ
MATLABとSimulinkの記事は以下にまとめてます。