Visual Basic でOpenCV㉔ - 特徴点マッチング

Visual BasicOpenCVを用い、2 つの画像に先の特徴点検出を実行し、それぞれのマッチングを行う例を紹介します。

特徴点マッチング

2 つの画像に先の特徴点検出を実行し、それぞれのマッチングを行います。本例は特徴点の検出に、AKAZE を用います。フォームやそれに対応するソースコードなどは、これまでに紹介済みです。

CCvFunc.vb

実際に特徴点検出を行う、CCv の派生クラスCCvFunc のDoCvFunction メソッドを示します。

'特徴点の取得
Private Function DetectXrossMatch(imgs As Mat()) As _
                                            (DMatch(), KeyPoint()())
    Dim keyp = New KeyPoint(imgs.Length - 1)() {}
    Dim matches As 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")

                '特徴量ベクトル同士のマッチング結果を配列へ格納
                matches = matcher.Match(descriptors0, descriptors1)
            End Using
        End Using
    End Using
    Return (matches, keyp)
End Function

'----------------------------------------------------------------
' OpenCVを使用して処理
Public Function DoCvFunction(ByVal srcNames As List(Of String)) As Bitmap
    Dim srcs = New Mat(1) {}
    For i = 0 To 1
        srcs(i) = Cv2.ImRead(srcNames(i))
    Next

    Dim result = DetectXrossMatch(srcs)

    ' draw matches
    mDst = New Mat()
    Cv2.DrawMatches(srcs(0), result.Item2(0), srcs(1),
                                result.Item2(1), result.Item1, mDst)

    Return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mDst)
End Function

DoCvFunction メソッドは、Form2から呼び出されます。渡された引数を利用し、2つの画像を読み込みます。読み込んだ画像を引数にDetectXrossMatchメソッドを呼び出します。その結果をCv2.DrawMatches メソッドに与え、2 つの画像から得られるキーポイント同士のマッチするものを、出力画像上に描画します。
DetectXrossMatchメソッドは、AKAZE のDetectAndCompute メソッドを利用し特徴点をkeyp(0)、keyp(1)へ抽出します。同時に、画像のキーポイントに対するディスクリプター、descriptors0とdescriptors1 を求めます。そして、ディスクリプターの2 つの集合同士を比較するDescriptorMatcher オブジェクトのMatch メソッドでディスクリプターのマッチするものをDMatch 配列のmatches に求めます。このmatches と keyp を呼び出し元へ返します。
呼び出し元は、Cv2.DrawMatches メソッドで特徴点の移動を描画します。

実行

2つの画像をドロップすると、特徴点同志を線でつないだ画像が現れます。表示中のフォームに、さらに画像をドロップすると先に指定した画像が押し出される形で、最後の2つが処理対象になります。
以降にドロップする2つの画像と、ドロップ後の表示を示します。