2015. 2. 3.
石立 喬

OpenCVとVisual C++による画像処理と認識(10)

----- いろいろな特徴検出法を試し、道路標識に応用する -----

 OpenCVには、多くの特徴検出用クラスや関数が用意されている。これは、主として動画上の物体の追跡などに用いられるが、物体認識にも応用できる。ここでは、まず最初に、単純な幾何学的図形に対して代表的な検出器をデフォルト設定で使用して比較し、次いで、設定条件を調整して検出精度を高めた上で、道路標識の認識の一助として使えないかを試してみた。

特徴検出
 特徴の検出はOpenCVの重要なテーマである。特徴には、コーナー、凹凸、テキスチャなどがあるが、拡大縮小や回転の影響が少なく、視点、明るさなどが変わっても常に同じ特徴点を検出することが好ましく、検出処理の高速化も求められて、新しい方法が次々と発表されてきた。
 特徴検出の主な目的は、複数の画像において、それぞれに存在する物体の特徴点を見つけて比較し、それらが同一の物体であることを証明することである。複数の画像が連続する動画像であれば、移動する物体の追跡であり、別の角度から撮られた画像であれば、物体の三次元的な把握である。また、一方の画像が、標準的なサンプル物体であれば、製品等の検査であったり、物体の認識であったりする。

特徴検出法のいろいろ
 古くから、エッジとエッジの交点であるコーナーが注目され、特徴点すなわちコーナーの感があった。コーナー検出では、HarrisとStephensの方法が有名で、これを実行すための関数が、OpenCVにcornerHarris()として用意された。
 やがて、これを簡素化した方法がShiとTomasiによって提案され、GFTT(Good Features To Track)と呼ばれる。これは、「動画の追跡に適した良い特徴」の意味である。実際、OpenCVでは、前述のHarris法は、GFTTの一種として、扱われるようになった。
 やがて、全く異なる手法で、高速のFAST(Features from Accelerated Test)がRostenとDrummondによって発表され、リアルタイム動画への応用が容易になった。
 全く別の発想から、画像の回転や見る方向の違いに頑強な特徴点の検出方法として、SIFT(Scale-Invariant Feature Transform)が発表されたが、これは時間がかかり、SURF(Speeded Up Robust Feature)は、SIFTをベースにして約10倍に高速化した。
 SIFTもSURFも特許権があり、OpenCVでも、nofreeとしてライブラリを別にしている。商用的に使用するには、特許権の許諾が必要で、代わりに、SURFよりさらに1桁高速で、特許契約の不要なORB(Oriented FAST and Rotated BRIEF)が推奨されている。

各種の特徴検出法(設定条件はデフォルト値使用)を比較するプログラム
 特徴を検出する検出器(detector)を使用するには、色々な方法があるが、FeatureDetectorクラスを使うことにした。図1はHarris検出法と、その簡易型であるGFTT(GoodFeatureToTrack)法、および比較的新しいOEB法を用いた場合のプログラムを示す。
 原画像はグレイスケール画像であるが、検出したコーナーをその上に赤丸で表示するため、カラー(CV_8UC3)画像src_imageとして読み込み、各検出器のためにグレイスケール化したgray_imageを用意する。

使用したOpenCV関数の説明
◎FeatureDetectorクラス
 各種検出器のインターフェイスとなる基底クラスで、設定をデフォルトのままで使用する(設定を変更することもできるが…)際に便利である。主要メンバーにcreateとdetectのメソッドがある。
 このオブジェクトを生成するには、

   Ptr<FeatureDetector> FeatureDetector abc_detector = FeatureDetector;;create(検出法タイプ);

を用いる。検出法タイプには、"HARRIS", "GFTT", "FAST", "SIFT", "SURF"、"ORB"その他がある。型名が長いので、autoで代用して宣言できる。
 これを使って検出を実行するには、

   abc_detector->detect(原画像、キーポイント、マスク);

とする。マスクはnoArray()がデフォルトなので、一般には省略する。
◎KeyPointクラスとdrawKeypoints関数
 KeyPointは特徴点保存用の多次元ベクトルで、プロパティには、Point2fクラスの座標値ptの他、向きや強さなどがあり、drawKeyPoints関数で描画できる。従来、コーナーとか特徴点(feature point)とか言っていたのを、より抽象的なキーポイントと呼ぶようになったことに注目すべきである。
 検出器で見つかったキーポイントは、

  drawKeypoints(被描画画像、キーポイント、出力画像、表示色、表示方法);

で被描画画像の上に描画し、出力画像に出力する。被描画画像と出力画像を同一にできる。表示色は、Scalar::all(-1)がデフォルトで、これは表示のたびに色をランダムに変える。特定の色にするには、Scalar(0, 0, 255)等を用いる。表示方法は、DrawMatchesFlags::DRAW_OVER_OUTIMGがデフォルトで、ただ単に同じ大きさの円を描くのみであるが、DrawMatchesFlags::DRAW_RICH_KEYPOINTSにすると、強さを円の半径で、方向を矢印で表示する。


図1 デフォルト条件でコーナー検出を試すプログラム


 図2は図1のプログラムで得られた結果で、デフォルト設定では、真のコーナー以外に、傾斜を持った辺がコーナーとして検出されている。GFTTよりはHarrisの方が、誤検出がやや少ない。FASTは、鋭いコーナーは苦手のようで、半径の小さい円弧には良く反応する。ORBはFASTを改良し、高速化したものであるが、やはりコーナー検出は十分でない。
 なお、SIFTとSURFについても、同様にデフォルト条件で試みた、プログラムは省略するが、図3に、その結果を示す。SIFTでは図形の中心点や図形と図形の間の中間点が特徴点として検出されている。SURFもその傾向があり、これらは、個々の図形よりは、全画像を対象に特徴点を求めているような気がして、物体の外形を検知する目的には不適当かも知れない。


図2 デフォルト条件でのコーナー検出結果


 

図3 SIFTとSURFの結果を参考として示す(プログラムは省略)


Harris、GFTT、ORBを条件設定して使用するプログラム
 FeatureDetectorの代わりに、それぞれのアルゴリズムのDetectorを用いて条件設定したプログラム(変更部分のみ)を図4に、結果を図5に示す。主な設定条件は以下の通り。
 GoodFeaturesToTrackDetectorで、
  1)検出するコーナーの数の上限を40個と、低く設定し、真のコーナー以外の検出を防いだ。
  2)最短距離を10に増やし、近接するコーナー(無いはずなので)を除外した。
  3)Harrisの場合、係数kを0.12に上げると、円周部分にあった偽コーナーが消えた。
 OrbFeatureDetectorで、
  1)最大検出数を80に下げた。
  2)エッジしきい値とパッチサイズを7に下げた。これにより、それまで検出されなかった三角形のコーナーが検出できた。
  3)ピラミッドレベル数を下げた。これにより、同一点近傍に複数の検出があったのが無くなった。

使用したOpenCV関数の説明
 ここで紹介する各Detectorは個々のアルゴリズムのラッパークラスであり、デフォルト値以外でカスタマイズして使用するのに便利である。
◎GoodFeaturesToTrackDetector(略したGFTTDetectorと同じ)クラス

 このコンストラクタの引数は、

   GoodFeaturesToTrackDetector gftt_detector(最大検出数=1000、品質レベル=0.01、最小距離=1、ブロックサイズ=3、Harris検出器使用=false、係数k=0.04);

のようにする。すべての引数がデフォルト値を持ち、Harris検出器使用はfalseがデフォルトである。これをcornerMinEigenVal関数で使用する場合(単にGFTTとも言う)はデフォルトのままで、cornerHarris関数で使用する場合は、これをtrueにする。係数kはHarrisの場合のみに意味がある。
 あとは、

  gftt_detector.detect(原画像、キーポイント);

で検出を実行する。
◎OrbFeatureDetectorクラス
 このコンストラクタの引数は、

   OrbFeatureDetector orb_detector(最大検出数=500、ピラミッドレイヤー間の縮小比率=1.2f、ピラミッドレベル数=8、エッジしきい値=31、最初のレベル=0、WTA_K=2、スコアタイプ=0、パッチサイズ=31);

で、すべての引数にデフォルトが設定されている。レイヤー間比率は、1以上でないと意味がなく、1に近いとレイヤー数が多く必要になり、時間がかかる。エッジしきい値とパッチサイズは同じに揃える。WTA_Kは、比較する点の数を表し、2が2個のため簡単で、これを大きくすると時間がかかる。スコアタイプは、デフォルトの0がORB::HARRIS_SCOREで、1はORB::FAST_SCOREである。
 あとは、

  orb_detector.detect(原画像、キーポイント);

で検出を実行する。


図4 結果を見ながら条件を細かく調節したプログラム



図5 条件を細かく調節して改善した結果


道路標識の検出への応用を探る
 道路標識の「止まれ」は三角形で、「進入禁止」は外側が円(これはHoughで検出できる)で、内部に横長の四辺形がある。これらのコーナーを検出して、道路標識を探せないかと考えて、下記の内容から成るプログラムを作成した。
 1)原画像を読み込み、赤色を抽出する(「画像処理と認識(4)」ですでに説明済み)
 2)モルフォロジー処理のcloseで、周辺の黒ノイズを除去する。
 3)openを繰り返して「止まれ」の白文字を消す。
 4)コーナーを検出して原画像のコピー上に描画する。
 図6は、1)の部分を、図8は2)~3)を、図10は4)の部分を示す。図10は図4とほとんど同じで、GoodFeaturesToTrackDetectorの代わりに、GFTTDetectorを使い(現在は、内容的には全く同じで両方が使えるが、OpenCV 3.0からは、GFTTのみになる)、gray_imageがopen_imageに変わっている。
 図7、図9、図11は、それぞれの結果である。

使用したOpenCV関数の説明
◎MorphologyEx関数
 これには、

  morphologyEx(グレイ入力画像、出力画像、モーフィング動作タイプ、カーネル(エレメント)、ポイントアンカー=Point(-1, -1)、繰り返し回数=1、周辺処理=BORDER_CONSTAMT、周辺値=morphlogyDefaultValue());

のように引数を与える。
 モーフィング動作タイプの主要なものには、
   MORPH_OPEN -------- erode(収縮)してからdilate(膨張)する。白ノイズの除去に使える。
   MORPH_CLOSE ------- dilateしてからerodeする。黒ノイズの除去に使える。
   MORPH_GRADIENT ---- dilate結果からerode結果を引く。エッジ画像が得られる。
がある。erodeは白から見ると収縮であるが、黒から見ると膨張になる。dilateは白から見て膨張、黒からは収縮である。
◎getStructuringElement関数

  getStructuringElement(カーネル形状、カーネルサイズ、アンカーポイント=Point(-1, -1));

となっていて、カーネル(エレメント)の形状には、MORPH_RECT、MORPF_ELLIPS、EMORPH_CROSSがある。一般的にはMORPH_RECTで良い。カーネルサイズは、elodeやdilateの強度に応じて、Size(3, 3)やSize(5, 5)を用いる。


図6 原画像を読み込み赤色を抽出するプログラム



図7 赤色を抽出した結果



図8 モルフォロジー加工をするプログラム



図9 closeでノイズを除去し、openで「止まれ」の文字を消した



図10 条件設定して道路標識のコーナーを検出するするプログラム



図11 最終的に得られた特徴点


結 論
 OpenCVでの特徴検出は難しい。資料を見ても、多くは動画において、移動する物体(特に人物)の追跡に用いられている。それが何であるかを認識するには、サンプルとのマッチングが行われる。
 ここでは、特徴点のうちの、特に単なるコーナーに注目して、検出性能の優劣を調べた。ここで取り上げたサンプルと方法に関する限り、古典的なHarrisやGFTTが比較的好成績を示した。特許的に制約のあるSIFTやSURFに代わって開発された高速のORBにも十分期待が持てる。 応用として、コーナーから道路標識を検出できないかを試みたが、前処理が面倒で、得られた結果も十分とは言えなかった。テンプレートマッチングや学習による認識などの方が適しているのかもしれない。ここでも、デフォルト設定では不十分で、試行錯誤による細かい条件調整が必要であった。


参考文献
Harris(1988)
 C.Harris and M.Stephens, "A Combined Corner and Edge Detection"
 http://www.bmva.org/bmvc/1988/avc-88-023.pdf
GFTT(1994)
 J. Shi and C. Tomasi, "Good Features to Track"
 http://movement.nyu.edu/mocap11f/papers/lec03_OpenCV_FeaturesFinding.pdf
FAST(2006)
 E. Rosten and T. Drummond, "Machine Learning for High-Speed Corner Detection"
 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.60.3991&rep=rep1&type=pdf
SIFT(2004)
 D.Lowe, "Distinctive Image Features from Scale Invariant Keypoints"
 http://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf
SURF(2006)
 H.Bay, T.Tuytelaars and L.V.Gool, "SURF: Speeded Up Robust Features"
 http://www.vision.ee.ethz.ch/~surf/eccv06.pdf
ORB(2011)
 E.Rublee, V.Rabaud, K.Konolige and G.Badski, "ORB: An Efficient Alternative to SIFT and SURF"
 http://www.vision.cs.chubu.ac.jp/CV-R/pdf/Rublee_iccv2011.pdf



「Visual C++の勉強部屋」(目次)へ