1. 程式人生 > >SIFT演算法原理步驟及opencv實現

SIFT演算法原理步驟及opencv實現

opencv sift需要在2版本,3不行。

步驟

整體步驟

1)原影象—->特徵點檢測(位置,角度,層)——->特徵點描述(16*8維的特徵向量)—–>原圖目標的特徵點集

2)目標影象–>特徵點檢測——->特徵點描述—–>目標圖的特徵點集

3)兩幅圖片的特徵點集合進行:特徵點匹配——–>匹配點矯正

opencv演算法步驟

1)讀入兩幅圖片

2)特徵點檢測
生成一個SiftFeatureDetector的物件,用SIFT特徵的探測器來探測一幀圖片中SIFT點的特徵、然後將特徵存到一個KeyPoint型別的vector中。
KeyPoint:

  • angle:角度,表示關鍵點的方向,通過Lowe大神的論文可以知道,為了保證方向不變形,SIFT演算法通過對關鍵點周圍鄰域進行梯度運算,求得該點方向。-1為初值。

  • class_id:當要對圖片進行分類時,我們可以用class_id對每個特徵點進行區分,未設定時為-1,需要靠自己設定-

  • octave:代表是從金字塔哪一層提取的得到的資料。

  • pt:關鍵點點的座標

  • response:響應程度,代表著該關鍵點是該點角點的程度。

  • size:該點直徑的大小

3)特徵點描述
對影象所有KEYPOINT提取其特徵向量,通過SiftDescriptorExtractor提取,結果放在一個Mat的資料結構中。這個資料結構才真正儲存了該特徵點所對應的特徵向量。
4、對兩幅圖的特徵向量進行匹配,得到匹配值。

程式碼

#include <stdio.h>  
#include <iostream>  
#include "opencv2/core/core.hpp"  
#include "opencv2/highgui/highgui.hpp"  
#include<opencv2/legacy/legacy.hpp>
#include "opencv2/nonfree/features2d.hpp"   //SurfFeatureDetector實際在該標頭檔案中  

using namespace cv;
using namespace std;

int main(int
argc, char** argv) { Mat src = imread("1.jpg", 1); Mat src2 = imread("2.jpg", 1);//旋轉後 if (!src.data||!src2.data) { cout << " --(!) Error reading images " << endl; } //1--初始化SIFT檢測運算元 int minHessian = 40; SiftFeatureDetector detector(minHessian); //2--使用SIFT運算元檢測特徵點 vector<KeyPoint> kp1,kp2; detector.detect(src, kp1); detector.detect(src2, kp2); //--繪製特徵點 Mat keypointImg, keypointImg2; drawKeypoints(src, kp1, keypointImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT); imshow("SIFT kp1", keypointImg); cout << "keypoint1 number: " << kp1.size() << endl; drawKeypoints(src, kp2, keypointImg2, Scalar::all(-1), DrawMatchesFlags::DEFAULT); imshow("SIFT kp2", keypointImg2); cout << "keypoint2 number: " << kp2.size() << endl; //3--特徵向量提取 SiftDescriptorExtractor extractor; Mat descriptor1, descriptor2; extractor.compute(src, kp1, descriptor1); extractor.compute(src2, kp2, descriptor2); //imshow("desc", descriptor1); //cout << endl << descriptor1 << endl; //4--特徵匹配 BruteForceMatcher<L2<float>> matcher; vector<DMatch> matches; Mat img_matches; matcher.match(descriptor1, descriptor2, matches); //--繪製匹配 drawMatches(src, kp1, src2, kp2, matches, img_matches); imshow("matches", img_matches); waitKey(0); return 0; }

這裡寫圖片描述
匹配效果一般。安倍匹配還可以(可能秋田犬的緣故),默克爾鼻子跑牆上去了..