Visual Basic とOpenCVを用い、2 つの画像に先の特徴点検出を実行し、双方向マッチングを行う例を紹介します。
特徴点マッチング・双方向
2 つの画像に先の特徴点検出を実行し、それぞれのマッチングを行います。本例は特徴点の検出に、AKAZE を用います。フォームやそれに対応するソースコードなどは、これまでに紹介済みです。
先のプログラムは、マッチングを片方向にしか行っていないものでした。本例は逆方向のマッチングも行い、両方に含まれるものだけを抽出し精度を向上させます。
CCvFunc.vb
実際に特徴点検出を行う、CCv の派生クラスCCvFunc のDoCvFunction メソッドを示します。
: '特徴点の取得、fwd, bwd チェック Private Function DetectXrossMatch(imgs As Mat()) As _ (List(Of DMatch), KeyPoint()()) Dim keyp = New KeyPoint(imgs.Length - 1)() {} Dim lMatches As New List(Of DMatch)() 'Using detector = ORB.Create() Using detector = AKAZE.Create() Using descriptors0 = New Mat() Using descriptors1 = New Mat() '特徴量の検出と特徴量ベクトルの計算 detector.DetectAndCompute(imgs(0), Nothing, keyp(0), descriptors0) detector.DetectAndCompute(imgs(1), Nothing, keyp(1), descriptors1) 'マッチング方法 Dim matcher As DescriptorMatcher = DescriptorMatcher.Create("BruteForce") '特徴量ベクトル同士のマッチング結果を配列へ格納 Dim fwdMatches As DMatch() = matcher.Match(descriptors0, descriptors1) Dim bckMatches As DMatch() = matcher.Match(descriptors1, descriptors0) For i = 0 To fwdMatches.Length - 1 Dim forward As DMatch = fwdMatches(i) Dim bckward As DMatch = bckMatches(forward.TrainIdx) If bckward.TrainIdx = forward.QueryIdx Then lMatches.Add(forward) End If Next End Using End Using End Using Return (lMatches, keyp) End Function '---------------------------------------------------------------- ' OpenCVを使用して処理 Public Function DoCvFunction(ByVal srcNames As List(Of String)) As Bitmap : End Function :
DoCvFunction メソッドは、前節とまったく同一です。
DetectXrossMatchメソッドで両方向のマッチングを行い、両方に含まれるものだけを抽出することで精度を向上させます。先のマッチングはdescriptors0 からdescriptors1 のマッチングのみを行っています。それに対して本プログラムでは、descriptors0 からdescriptors1 のマッチングとdescriptors1 からdescriptors0 のマッチングを行い、それぞれをfwdMatches とbckMatches に格納します。そして、For ループで両者の中の一致するものだけをlMatches にAdd メソッドで追加します。これによって、ループを抜けるとlMatches に精度の高い特徴点だけが残ります。
実行
以降に、実行例を示します。ドロップした画像は以前と同じです。