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
上一篇介紹了FAST features detection
而當我們試著要去配對不同影像上的特徵(features)時
會遇到一個問題:尺度(scale)的變化
在不同的影像上
感興趣的物件之間的距離可能有所不同
大小也可能有所不同
如果這時去試著配對不同影像的相同特徵時
由於尺度的變化,以至於在亮度(intensity)上的特徵是無法配對的
為了解決這個問題
許多尺度不變性(scale-invariant)的特徵概念被提出來
而SIFT(Scale-Invariant Feature Transform)就是屬於其中一種
其偵測局部最大值(local maxima)的特徵
並且使用Laplacian filter作為特徵的擷取(blob detection)
在EmguCV 2.4.2上有直接實作此方法
(2.4.0以前的版本建構式的引數有所不同)
使用起來相當簡單
Image<Gray, Byte> image = new Image<Gray, byte>(@"E:\EmguCVBlogImage\chapter8\image.jpg"); //Construct the SIFT feature detector object SIFTDetector sift = new SIFTDetector( 0, //the desired number of features 3, //the number of octave layers 0.04, //feature threshold 10, //detector parameter 1.6); //sigma //feature point detection VectorOfKeyPoint keypoints = sift.DetectKeyPointsRaw(image, null); //draw keypoints on an image Image<Bgr, byte> result = Features2DToolbox.DrawKeypoints<Gray>( image, //original image keypoints, //vector of keypoints new Bgr(255, 255, 255), // keypoint color Features2DToolbox.KeypointDrawType.DRAW_RICH_KEYPOINTS); //drawing type先建立SIFT的類別
建構式帶入的參數分別是:
要偵測的特徵數量(0表示不限制)
octave稱之為高斯影像金字塔,在這裡設定每組金字塔內由多少張影像組成
特徵偵測的閥值,初始值為0.04
邊界偵測的閥值,初始值為10
sigma通常以做為表示,其實作的意義就是filter的aperture size
這裡還有一點提醒
在Features2DToolbox.DrawKeypoints的方法中
繪圖的類型選擇是:Features2DToolbox.KeypointDrawType.DRAW_RICH_KEYPOINTS
其結果如下:
除了特徵點的位置外,還多了特徵點的方向和大小的表示
而關於SIFT的演算法其實非常的複雜
wiki上有蠻詳細的介紹可以參考
不過我想wiki上的內容是沒多少人看得懂的
而這篇網誌用中文+圖解介紹的SIFT演算法相當清楚,比較適合參考
由於SIFT的演算法的運算量太過複雜
以至於有人提出了SURF(Speeded Up Robust Features)演算法
此方法提升了原本SIFT的效率
原先SIFT在建立高斯影像金字塔時相當耗時
而SURF採用了近似Hessian的矩陣對每一個pixel作摺積(Convolution)
得到近似的高斯模糊的影像,因而提升了速度
使用方法也很簡單
Image<Gray, Byte> image = new Image<Gray, byte>(@"E:\EmguCVBlogImage\chapter8\image.jpg"); //Construct the SURF feature detector object SURFDetector surf = new SURFDetector( 5000, //threshold false); //extended descriptors //Detect the SURF features VectorOfKeyPoint keypoints = surf.DetectKeyPointsRaw(image, null); //draw keypoints on an image Image<Bgr, byte> result = Features2DToolbox.DrawKeypoints<Gray>( image, //original image keypoints, //vector of keypoints new Bgr(255, 255, 255), // keypoint color Features2DToolbox.KeypointDrawType.DRAW_RICH_KEYPOINTS); //drawing typeSURF建構式的參數只有兩個
一個是threshold,emguCV的文件上說300~500,在這張影像上5000比較適合
第二個參數表示是否要採用擴充的描述子,這個會在下一篇介紹
所以先採用false
出來的結果如下:
所偵測出來的特徵值還蠻多的
為了要測試旋轉、尺度的不變性
所以製作了另一張圖
這裡試著把影像作一些放大和旋轉
一樣帶入程式中
看會得到什麼樣的結果
與原本的結果做比較
大部分的特徵點的位置、大小、方向是雷同的
但也有些許是不一樣的
那如何利用這些特徵點
就等下一篇來介紹嚕!!
作者已經移除這則留言。
回覆刪除可以不用做預處理,直接把原始影像帶入即可.
刪除但如果想要有特別被偵測到的特徵值,或許可以考慮先進行預處理的動作.
請問我目前使用C#可以找到特徵點個數,我要怎麼轉換成位置座標或是把特徵點圈或框出來?
回覆刪除VectorOfKeyPoint keypoints = surf.DetectKeyPointsRaw(image, null);
刪除出來的keypoints就是一個point的集合,裡面就有包含point的座標位置。