SIFT演算法原理步驟及opencv實現
阿新 • • 發佈:2019-01-10
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;
}
匹配效果一般。安倍匹配還可以(可能秋田犬的緣故),默克爾鼻子跑牆上去了..