圖像識別基本算法之SURF



圖像識別、人臉識別可行的算法有很多。但是作為學習,如果能理清這個問題研究的歷程及其主線,會對你深入理解當前研究最新的發展有很多幫助。本文是自己在學習過程中的筆記,大多內容來自於網絡,出處請參考最后的引文部分。

Sift算法

Sift算法是David Lowe於1999年提出的局部特征描述子,並於2004年進行了更深入的發展和完善。Sift特征匹配算法可以處理兩幅圖像之間發生平移、旋轉、仿射變換情況下的匹配問題,具有很強的匹配能力。總體來說,Sift算子具有以下特性:

  1. Sift特征是圖像的局部特征,對平移、旋轉、尺度縮放、亮度變化、遮擋和噪聲等具有良好的不變性,對視覺變化、仿射變換也保持一定程度的穩定性。
  2. 獨特性好,信息量豐富,適用於在海量特征數據庫中進行快速、准確的匹配。
  3. 多量性,即使少數的幾個物體也可以產生大量Sift特征向量。
  4. 速度相對較快,經優化的Sift匹配算法甚至可以達到實時的要求。
  5. 可擴展性強,可以很方便的與其他形式的特征向量進行聯合。

其Sift算法的三大工序為:

  1. 提取關鍵點;
  2. 對關鍵點附加詳細的信息(局部特征)也就是所謂的描述器;
  3. 通過兩方特征點(附帶上特征向量的關鍵點)的兩兩比較找出相互匹配的若干對特征點,也就建立了景物間的對應關系。

提取關鍵點和對關鍵點附加詳細的信息(局部特征)也就是所謂的描述器可以稱做是Sift特征的生成,即從多幅圖像中提取對尺度縮放、旋轉、亮度變化無關的特征向量,Sift特征的生成一般包括以下幾個步驟:

  1. 構建尺度空間,檢測極值點,獲得尺度不變性;
  2. 特征點過濾並進行精確定位;
  3. 為特征點分配方向值;
  4. 生成特征描述子;

Surf算法

SURF是speed up robust feature的縮寫,可以視為加速版的Sift算法。
SURF的特點:

  1. 使用積分圖像完成圖像卷積(相關)操作;
  2. 使用Hessian矩陣檢測特征值;
  3. 使用基於分布的描述符(局部信息)。

SURF算法的一般步驟為:

  1. 構建Hessian矩陣;
  2. 構建尺度空間;
  3. 精確定位特征點;
  4. 主方向確定;


跟TensorFlow中碰到的情況一樣,目前這些常用的算法,在大多的機器學習框架中都已經封裝完成了。使用者已經不需要詳細的了解內在算法就可以直接使用。

下面是網上轉來的使用OPENCV進行SURF特征點檢測示例源碼:

#include "highgui/highgui.hpp"    
#include "opencv2/nonfree/nonfree.hpp"    
#include "opencv2/legacy/legacy.hpp"   
#include <iostream>  
  
using namespace cv;  
using namespace std;  
  
int main(int argc,char *argv[])    
{    
    Mat image01=imread(argv[1]);    
    Mat image02=imread(argv[2]);    
    Mat image1,image2;    
    image1=image01.clone();  
    image2=image02.clone();  
  
    //提取特征點    
    SurfFeatureDetector surfDetector(4000);  //hessianThreshold,海塞矩陣閾值,並不是限定特征點的個數   
    vector<KeyPoint> keyPoint1,keyPoint2;    
    surfDetector.detect(image1,keyPoint1);    
    surfDetector.detect(image2,keyPoint2);    
  
    //繪制特征點    
    drawKeypoints(image1,keyPoint1,image1,Scalar::all(-1),DrawMatchesFlags::DEFAULT);      
    drawKeypoints(image2,keyPoint2,image2,Scalar::all(-1),DrawMatchesFlags::DRAW_RICH_KEYPOINTS);       
    imshow("KeyPoints of image1",image1);    
    imshow("KeyPoints of image2",image2);    
  
    //特征點描述,為下邊的特征點匹配做准備    
    SurfDescriptorExtractor SurfDescriptor;    
    Mat imageDesc1,imageDesc2;    
    SurfDescriptor.compute(image1,keyPoint1,imageDesc1);    
    SurfDescriptor.compute(image2,keyPoint2,imageDesc2);    
  
    //特征點匹配並顯示匹配結果    
    //BruteForceMatcher<L2<float>> matcher;    
    FlannBasedMatcher matcher;  
    vector<DMatch> matchePoints;    
    matcher.match(imageDesc1,imageDesc2,matchePoints,Mat());  
  
    //提取強特征點  
    double minMatch=1;  
    double maxMatch=0;  
    for(int i=0;i<matchePoints.size();i++)  
    {  
        //匹配值最大最小值獲取  
        minMatch=minMatch>matchePoints[i].distance?matchePoints[i].distance:minMatch;  
        maxMatch=maxMatch<matchePoints[i].distance?matchePoints[i].distance:maxMatch;  
    }  
    //最大最小值輸出  
    cout<<"最佳匹配值是: "<<minMatch<<endl;  
    cout<<"最差匹配值是: "<<maxMatch<<endl;  
  
    //獲取排在前邊的幾個最優匹配結果  
    vector<DMatch> goodMatchePoints;  
    for(int i=0;i<matchePoints.size();i++)  
    {  
        if(matchePoints[i].distance<minMatch+(maxMatch-minMatch)/2)  
        {  
            goodMatchePoints.push_back(matchePoints[i]);  
        }  
    }  
  
    //繪制最優匹配點  
    Mat imageOutput;  
    drawMatches(image01,keyPoint1,image02,keyPoint2,goodMatchePoints,imageOutput,Scalar::all(-1),  
        Scalar::all(-1),vector<char>(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);       
    imshow("Mathch Points",imageOutput);    
    waitKey();    
    return 0;    
}  

引文及參考

SURF算法原理
Opencv Surf算子特征提取與最優匹配
特征點檢測學習_2(surf算法)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM