sift演算法大家都比較熟悉,網上的版本很多,剛開始接觸時我主要研究的是c++,因為相對於c#,基於open cv c++的sift演算法資料更多,但是由於想要實現較為理想的介面效果,最終還是放棄了使用c++轉而使用c#。
c#中sift演算法主要分為三種:
1)脫離emgu cv平台,完全手動實現所有sift演算法函式,這樣的程式雖然實現有些困難,但是完全可借助已有的c++程式做更改,而且這樣做最大的好處就是對sift演算法的原理有更深的理解。
2)實現時使用少量emgu cv函式(例如影像的讀取,灰度值獲得等),但是大部分工作還是依賴於.net平台自行完成。
3)基本上程式完全借助於emgu cv提供的介面,核心函式完全由emgu cv提供。
1. 尺度空間極值檢測:搜尋所有尺度上的影象位置。通過高斯微分函式來識別潛在的對於尺度和旋轉不變的興趣點。
2. 關鍵點定位:在每個候選的位置上,通過乙個擬合精細的模型來確定位置和尺度。關鍵點的選擇依據於它們的穩定程度。
3. 方向確定:基於影象區域性的梯度方向,分配給每個關鍵點位置乙個或多個方向。所有後面的對影象資料的操作都相對於關鍵點的方向、尺度和位置進行變換,從而提供對於這些變換的不變性。
4. 關鍵點描述:在每個關鍵點周圍的鄰域內,在選定的尺度上測量影象區域性的梯度。這些梯度被變換成一種表示,這種表示允許比較大的區域性形狀的變形和光照變化。
使用emgu cv實現上述步驟非常簡單,程式如下:
//確定匹配影象
//將影象轉為emgu cv的處理格式
imageimg1 = new image(bt1);
imageimg2 = new image(bt2);
//使用emgu cv探測特徵點
siftdetector sift = new siftdetector();
var f1 = sift.detectfeatures(img1, null);
var f2 = sift.detectfeatures(img2, null);
到此已經獲得了兩張相片的特徵點f1,f2,接下來就是將相互匹配的特徵點相連:
for (int i = 0; i < f1.length; i++)
//排序,獲得歐式距離最近點以及次近點
for (int k = 0; k < 2; k++)
} } }
//若最近點與次近點比值小於閾值0.49,繪製特徵點連線
if (dist[0]/dist[1] < 0.49)
} //描述子距離計算函式
SIFT演算法的幾個問題
sift演算法在影象搜尋方面,用作基礎特徵,個人感覺有一些問題,記錄在這裡 1 求主方向階段太過依賴影象區域性畫素的梯度方向,有可能使找到的主方向不準確 而後面的特徵向量以及匹配嚴重依賴主方向,一旦有偏差效果會顯著下降 2 圖層金字塔的層如何取是個問題,如果取得不夠緊密,會在匹配時出現偏差 而如果取...
opencv2 4 sift演算法的使用
與opencv2.3.1版本的sift演算法的程式設計方法有所不同,貌似opencv2.4版本之後將sift surf演算法移到了nonfree區。所以,需要包換的標頭檔案 include include opencv nonfree249d.lib和opencv features2d249d.li...
計算機視覺CV中特徵點提取SIFT演算法的學習筆記
sift演算法,即 scale invariant feature transform,尺度無關的特徵變換演算法。以上方法檢測到的極值點是離散空間的極值點,以下通過擬合三維二次函式來精確確定關鍵點的位置和尺度,同時去除低對比度的關鍵點和不穩定的邊緣響應點 因為dog運算元會產生較強的邊緣響應 以增強...