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所提供的影像配對
看起來效果就相當不錯~!!
作者已經移除這則留言。
回覆刪除