色による探索 (cv::inRange)

Hueを最大180に設定している。元のイメージの黄色と黄緑色、青色の矩形と円は全て認識することが出来ているが、それよりも先にHue0〜10程度で認識されていなければならない赤色の矩形が認識されていない。

赤が認識されないということで別な実装方法を試してみた。表題にネタバレしているがinRangeメソッドを使う方法だ。

cv::inRange

cv::inRange - Operations on Arrays ― OpenCV 2.4.4.0 documentation

inRangeは配列中の要素がをパラメタで与えられた下限と上限値の範囲に収まっているかを検査して、収まっている要素を出力する。

つまりはこのメソッドを使うことで配列にHue(色相)の上限と下限でフィルタをかけることができる訳だ。

色による2値化(cv::inRange版)
+ (cv::Mat)binarizeHSB:(cv::Mat)src hueMin:(double)hueMin hueMax:(double)hueMax saturation:(double)saturation brightness:(double)brightness
{
    cv::Mat hsb;
    cv::Mat result;
    // カラー画像をHSV画像に変換
    cv::cvtColor(src, hsb, CV_RGB2HSV, 3);
    // inRangeによるフィルタ
    cv::inRange(hsb, cv::Scalar(hueMin, saturation, brightness, 0) , cv::Scalar(hueMax, 255, 255, 0), result);
    return result;
}

cv::thresholdを使う場合に比べてチャネル毎の論理演算が不要なので、コードが非常にすっきりとしている。

実行結果

今回はアスペクト比を修正した。


Hue最大を33程度に設定。今度はいきなり赤色の矩形が認識されている。


Hue最大を38にすることで黄緑の矩形を認識する。黄色と色相で5しか違わないのだがはっきりと分離できる。


Hue最大を110にすることで外縁を含めて、全ての矩形を認識する。

このようにcv:thresholdを使うことがベストでは無いケースもあるのだが、同様の処理を行うのに複数の方法を試すことができるのが、OpenCVの汎用性の高さだろう。