EmguCV Image Process: Detecting and Matching Interest Points
參考OpenCV 2 Computer Vision Application Programming Cookbook第八章
介紹內容如下:
Detecting Harris corners
Detecting FAST features
Detecting the scale-invariant SURF features
Describing SURF features
上一篇介紹了如何擷取SURF features
也了解到了SURF features是屬於尺度不變性(scale-invariant)
而這些特徵點,可以透過其周圍鄰近點的資訊取得特徵描述子(feature descriptors)
由於這些視覺上的資訊包含了特徵點附近的鄰近點
因此可用來辨別不同影像上的特徵點是否相似
feature descriptors一般使用N-dimensional vectors來描述一個特徵點
在理想的狀況下
feature descriptors是不受光線、小幅度的變形透視所影響
而好的feature descriptors採用簡單的距離公式,例如:歐幾里得距離(Euclidean distance)
這樣的特性,將可構成相當有用的工具
用來處理特徵匹配的演算法
SURF的方法與上一篇介紹的相同
只是現在要取出兩張影像的特徵點
還要取出特徵點描述子(feature descriptors)
Image<Gray, Byte> modelImage = new Image<Gray, byte>("image.jpg");
//Construct the SURF feature detector object
SURFDetector surf = new SURFDetector(
    10000,   //threshold
    false); //extended descriptors
//Detect the SURF features
VectorOfKeyPoint modelKeypoints = surf.DetectKeyPointsRaw(modelImage, null);
//Extraction of the SURF descriptors
Matrix<float> modelDescriptors = surf.ComputeDescriptorsRaw(modelImage, null, modelKeypoints);
Image<Gray, Byte> observedImage = new Image<Gray, byte>("image2.jpg");
VectorOfKeyPoint observedKeypoints = surf.DetectKeyPointsRaw(observedImage, null);
//Extraction of the SURF descriptors
Matrix<float> observedDescriptors = surf.ComputeDescriptorsRaw(observedImage, null, observedKeypoints);
分別載入兩張不同的影像一張作為model image,一張作為observed image
model image
observed image
也分別去擷取特徵點與特徵描述子
接著透過BruteForceMatcher這個類別來做匹配的工作
如下所示:
//Construction of the matcher BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); //Add the model descriptors matcher.Add(modelDescriptors); //Number of nearest neighbors to search for int k=8; //The resulting n*k matrix of descriptor index from the training descriptors Matrix<int> trainIdx = new Matrix<int>(observedDescriptors.Rows, k); //The resulting n*k matrix of distance value from the training descriptors Matrix<float> distance = new Matrix<float>(observedDescriptors.Rows, k); //Match the two image descriptors matcher.KnnMatch(observedDescriptors, trainIdx, distance, k, null);
BruteForceMatcher的建構式須帶入以何種距離方式計算
這裡帶入的是DistanceType.L2,就是前面提到的歐幾里得距離
而這裡的k代表搜尋的鄰近點的最少數量
而在匹配的過程中,需要建立index、distance的兩個矩陣資料
而這兩個矩陣資料之後會用到
//This matrix indicates which row is valid for the matches.
Matrix<byte> mask = new Matrix<byte>(distance.Rows, 1);
mask.SetValue(255);
//The distance different ratio which a match is consider unique, a good number will be 0.8
double uniquenessThreshold = 0.5;
//Filter the matched Features, such that if a match is not unique, it is rejected.
Features2DToolbox.VoteForUniqueness(distance, uniquenessThreshold, mask);
//Draw the matched keypoints
Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeypoints, observedImage, observedKeypoints,
    trainIdx, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);
這裡利用Features2DToolbox.VoteForUniqueness方法來做篩選
帶入計算過後的distance的矩陣資料,帶入參數,跟一個過濾矩陣
EmguCV上提供的最佳參數設定為:0.8
但由於出來的匹配線太過複雜,因此這裡改成0.5
得到過濾矩陣mask後,連同model image、observed image、model image特徵點、observed image特徵點、index矩陣、過濾矩陣mask...等等
帶入Features2DToolbox.DrawMatches,回傳結果影像
匹配結果影像
由於這個影像的重複性很高
都是一格一格的區塊,因此在匹配上是有難度的
可以多嘗試不同的影像來做配對
EmguCV所提供的影像配對
看起來效果就相當不錯~!!




 
作者已經移除這則留言。
回覆刪除