2013年6月5日 星期三

EmguCV Image Process: Detecting and Matching Interest Points part5

20101219030.jpg
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所提供的影像配對

看起來效果就相當不錯~!!

1 則留言: