1. 程式人生 > >opencv(30)---特徵檢測與匹配(1)---SIFT特徵點提取

opencv(30)---特徵檢測與匹配(1)---SIFT特徵點提取

基本概念

特徵點的檢測和匹配是計算機視覺中非常重要的技術之一, 在物體識別、視覺跟蹤、三維重建等領域都有很廣泛的應用。OpenCV提供瞭如下幾種特徵檢測方法:

  • “FAST”——FastFeatureDetector
  • “STAR”——StarFeatureDetector
  • “SIFT”——SIFT(nonfree module)
  • “SURF”——SURF(nonfree module)
  • “ORB”——ORB
  • “MSER”——MSER
  • “GFTT”——GoodFeaturesToTrackDetector
  • “HARRIS”——(配合Harris detector)
  • “Dense”——DenseFeatureDetector
  • “SimpleBlob”——SimpleBlobDetector

  • 注意

在OpenCV3版本中, 許多著名的特徵檢測運算元(如SIFT、SURF、ORB)穩定版的原始碼已從官方發行的OpenCV3中移除, 而轉移到一個名為xfeature2d的第三方庫中, 所以使用OpenCV3時需要特別注意!

SIFT特徵檢測的原理

SIFT(Scale Invariant Feature Transform)—尺度不變特徵變換,是由David G. Lowe在1999年(《Object Recognition from Local Scale-Invariant Features》)提出的高效區域檢測演算法,在2004年(《Distinctive Image Features from Scale-Invariant Keypoints》)得以完善。SIFT特徵對旋轉、尺度縮放、亮度變化等保持不變性, 是非常穩定的區域性特徵, 現在應用很廣泛。

這裡寫圖片描述

前面我們學過一些角點檢測方法, 比如Harris角點檢測, 特悶具有旋轉不變性, 即使影象發生旋轉, 我們也能找到同樣的角點。但是, 如果對影象進行縮放, 角點就可能不是角點了, 所以D.Lowe提出了尺度不變特徵變換檢測演算法—SIFT。

原理介紹如下

尺度空間極值檢測

從上圖我們可以很明顯的看出來在不同的尺度空間不能使用相同的視窗檢測極值點, 對小的角點要用小的視窗, 對大的角點只能使用大的視窗。為了達到這個目的我們要使用尺度空間濾波器(尺度空間濾波器可以使用一些列具有不同方差 σ 的高斯卷積核構成), 使用具有不同方差值 σ 的高斯拉普拉斯運算元(LoG)對影象進行卷積, LoG 由於具有不同的方差值 σ 所以可以用來檢測不同大小的斑點(當 LoG 的方差 σ 與斑點直徑相等時能夠使斑點完全平滑)。簡單來說方差 σ 就是一個尺度變換因子。例如,上圖中使用一個小方差 σ 的高斯卷積核是可以很好的檢測出小的角點, 而使用大方差 σ 的高斯卷積核時可以很好的檢測出大的角點。所以我們可以在尺度空間和二維平面中檢測到區域性最大值, 如(x, y, σ), 這表示在 σ 尺度中(x, y)點可能是一個關鍵點。(高斯方差的大小與視窗的大小存在一個倍數關係: 視窗大小等於 6 倍方差加 1, 所以方差的大小也決定了視窗大小)但是這個 LoG 的計算量非常大,所以 SIFT 演算法使用高斯差分運算元(DoG)來對LoG做近似。

這裡寫圖片描述
在 DoG 搞定之後, 就可以在不同的尺度空間和 2D 平面中搜索區域性最大值了, 對於影象中的一個畫素點而言,它需要與自己周圍的8鄰域, 以及尺度空間中上下兩層中的相鄰的18(2x9)個點相比, 如果是區域性最大值, 它就可能是一個關鍵點, 基本上來說關鍵點是影象在相應尺度空間中的最好代表,該演算法的作者在文章中給出了 SIFT 引數的經驗值: octaves=4(通過降低取樣從而減小影象尺寸, 構成尺寸減小的影象金字塔(4層), 尺度空間為5, 也就是每個尺寸使用 5 個不同方差的高斯核進行卷積, 初始方差是 1.6, k等於 這裡寫圖片描述

關鍵點(極值點)定位

一旦找到關鍵點, 我們就要對它們進行修正從而得到更準確的結果, 作者使用尺度空間的泰勒級數展開來獲得極值的準確位置, 如果極值點的灰度值小於閾值(0.03)就會被忽略掉, 在 OpenCV 中這種閾值被稱為contrastThreshold。DoG 演算法對邊界非常敏感, 所以我們必須要把邊界去除。Harris演算法除了可以用於角點檢測之外還可以用於檢測邊界, 作者就是使用了同樣的思路, 作者使用 2x2 的 Hessian 矩陣計算主曲率。從 Harris 角點檢測的演算法中, 我們知道當一個特徵值遠遠大於另外一個特徵值時檢測到的是邊界, 所以他們使用了一個簡單的函式, 如果比例高於閾值(OpenCV中稱為邊界閾值), 這個關鍵點就會被忽略,文章中給出的邊界閾值為10。所以低對比度的關鍵點和邊界關鍵點都會被去除掉, 剩下的就是我們感興趣的關鍵點了。

為關鍵點(極值點)指定方向引數

現在我們要為每一個關鍵點賦予一個反向引數, 這樣它才會具有旋轉不變性。獲取關鍵點(所在尺度空間)的鄰域, 然後計算這個區域的梯度級和方向, 根據計算得到的結果建立一個含有 36 個 bins(每10度一個 bin)的方向直方圖。(使用當前尺度空間 σ 值的 1.5 倍為方差的圓形高斯視窗和梯度級做權重), 直方圖中的峰值為主方向引數, 如果其他的任何柱子的高度高於峰值的80% 被認為是輔方向, 這就會在相同的尺度空間相同的位置構建除具有不同方向的關鍵點, 這對應匹配的穩定性會有幫助。

關鍵點描述符

新的關鍵點描述符被建立了, 選取與關鍵點周圍一個16x16 的鄰域, 把它分成16個 4x4 的小方塊, 為每個小方塊建立一個具有8個bin的方向直方圖。總共加起來有128個 bin, 由此組成長為 128 的向量就構成了關鍵點描述符。除此之外還要進行幾個測量以達到對光照變化,旋轉等的穩定性。

關鍵點匹配

下一步就可以採用關鍵點特徵向量的歐式距離來作為兩幅影象中關鍵點的相似性判定度量。取第一個圖的某個關鍵點, 通過遍歷找到第二幅影象中的距離最近的那個關鍵點。但有些情況下, 第二個距離最近的關鍵點與第一個距離最近的關鍵點靠的太近,這可能是由於噪聲等引起的, 此時要計算最近距離與第二近距離的比值, 如果比值大於 0.8, 就忽略掉, 這會去除 90% 的錯誤匹配, 同時只去除 5%的正確匹配(文獻所說)。
請記住這個演算法是受專利保護的, 所以這個演算法包含在 OpenCV中的收費模組中。

SIFT特徵檢測程式碼以及應用

函式原型

這裡寫圖片描述

  • nfeatures: 特徵點數目(演算法對檢測出的特徵點排名, 返回最好的nfeatures個特徵點)
  • nOctaveLayers: 金字塔中每組的層數
  • contrastThreshold: 過濾掉較差的特徵點的對閾值, contrastThreshold越大, 返回的特徵點越少
  • edgeThreshold: 過濾掉邊緣效應的閾值, edgeThreshold越大, 特徵點越多(被多濾掉的越少)
  • sigma: 金字塔第0層影象高斯濾波係數, 也就是σ

過載操作符

這裡寫圖片描述
這裡寫圖片描述

  • img: 8位灰度影象
  • mask: 需要檢測影象的掩碼(可選)
  • keypoints: 檢測到的特徵點
  • descriptors: 特徵點描述的輸出向量(如果不需要輸出, 需要傳cv::noArray())
  • useProvidedKeypoints: 是否進行特徵點檢測, ture則檢測特徵點, false只計算影象特徵描述

KeyPoint類—特徵點檢測相關的資料結構, 用於表示特徵點

這裡寫圖片描述

繪製關鍵點: drawKeypoints()函式

函式原型

這裡寫圖片描述

  • image: 輸入影象
  • keypoints: 根據原影象得到的特徵點
  • outImage: 輸出影象, 其內容取決於第5個引數識別符號flag
  • color: 所繪製關鍵點的顏色
  • flags: 繪製關鍵點的特徵識別符號, 預設值為DrawMatchsFlags::DEFAULT, 其他:

    這裡寫圖片描述

應用例項

這裡寫圖片描述

這裡寫圖片描述

程式碼

Mat srcImg1 = imread("00.jpg");
Mat srcImg2 = imread("01.jpg");
//定義SIFT特徵檢測類物件
SiftFeatureDetector siftDetector1;
SiftFeatureDetector siftDetector2;
//定義KeyPoint變數
vector<KeyPoint>keyPoints1;
vector<KeyPoint>keyPoints2;
//特徵點檢測
siftDetector1.detect(srcImg1, keyPoints1);
siftDetector2.detect(srcImg2, keyPoints2);
//繪製特徵點(關鍵點)
Mat feature_pic1, feature_pic2;
//drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar(0, 0, 255));
//drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar(0, 0, 255));
drawKeypoints(srcImg1, keyPoints1, feature_pic1, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(srcImg2, keyPoints2, feature_pic2, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
//顯示原圖
imshow("src1", srcImg1);
imshow("src2", srcImg2);
//顯示結果
imshow("feature1", feature_pic1);
imshow("feature2", feature_pic2);
waitKey(0);

相關推薦

opencv(30)---特徵檢測匹配1---SIFT特徵提取

基本概念 特徵點的檢測和匹配是計算機視覺中非常重要的技術之一, 在物體識別、視覺跟蹤、三維重建等領域都有很廣泛的應用。OpenCV提供瞭如下幾種特徵檢測方法: “FAST”——FastFeatureDetector “STAR”——StarFeatureD

影象特徵描述匹配——BRIEF特徵描述匹配

         傳統的特徵點描述子如SIFT,SURF描述子,每個特徵點採用128維(SIFT)或者64維(SURF)向量去描述,每個維度上佔用4位元組,SIFT需要128×4=512位元組記憶體,SURF則需要256

opencv影象特徵檢測匹配harris,sift,surf,fast,breif,orb,BFmatch,FlannBasedMatcher

本文簡單概括各種演算法的提出背景及opencv實現,對具體原理不做討論一般而言,一個物體的角點最能夠代表物體的特徵,所以所謂的特徵檢測又叫角點(Corner)檢測harris是最早提出的特徵提取演算法:opencv實現如下:dst=cv2.cornerHarris(gray,

OpenCv-C++-ORB特徵檢測匹配

影象的特徵點可以簡單的理解為影象中比較顯著顯著的點,如輪廓點,較暗區域中的亮點,較亮區域中的暗點等。 ORB的全稱是ORiented Brief,採用FAST(features from accelerated segment test)演算法來檢測特徵點。 與Brisk,AKAZE

OpenCv-C++-BRISK特徵檢測匹配

BRISK:Binary Robust Invariant Scalable Keypoints。它是一種二進位制的特徵描述運算元。它具有較好的旋轉不變性、尺度不變性,較好的魯棒性等。在對有較大模糊的影象配準時,BRISK演算法在其中表現最為出色。 演算法原理參考下面這篇文章,其中的表達

OpenCV學習筆記】三十七、特徵檢測匹配(二)——SIFT特徵匹配

特徵檢測與匹配(二)——SIFT特徵點匹配 1.SIFT特徵點提取 2.繪製特徵點 3.特徵點描述符(特徵向量)提取 4.使用暴力匹配器進行暴力匹配 5.對匹配結果進行篩選(依據DMatch結構體中的float型別變數distance進行篩選) 6.繪製匹配結果 先上ppt

OpenCV學習筆記__特徵檢測匹配之 SURF演算法

SURF 演算法  ——“加速版的具有魯棒性的特徵”演算法 步驟: 特徵檢測 —— 特徵描述 —— 特徵匹配 實現流程: (1)特徵檢測:SurfFeatureDetector類 . detec

【CV】實驗二:特徵檢測匹配

概述   特徵檢測與匹配的目標是識別一個影象中的關鍵點與另一個影象中的對應點之間的配對。在此實驗中,你將編寫程式碼以檢測影象中的特徵點(對於平移、旋轉和照明具有一定的不變性),並在另一個影象中找到最佳匹配特徵。   實施細節 特徵檢測 參考資料 Harris角點檢測演算法——lwzkil

SURF特徵檢測匹配

好的特徵應該具有以下幾個特點: 重複性:不同影象相同的區域應該能被重複檢測到,而且不受到旋轉、模糊、光照等因素的影響; 可區分性:不同的檢測子,應該可以被區分出來,而為了區分它們,應運而生的就是與檢測對應的描述子了; 數量適宜:檢測子可別太多,不然啥阿貓阿狗都能出

深度圖像檢測算法總結對比1

超過 技術 由於 ear step ron for width 一次 1. R-CNN:Rich feature hierarchies for accurate object detection and semantic segmentation 技術路線:se

深度影象檢測演算法總結對比1

1. R-CNN:Rich feature hierarchies for accurate object detection and semantic segmentation 技術路線:selective search + CNN + SVMs Step1:候選框提取

Opencv 短期學習筆記1——最新opencv+vs2017

現在處於考研期間,很少有時間敲程式碼和學習,正好這個星期的事情不是很多,離考研還有一定的時間,之前有接觸過opencv,但是系統的學習不是很多。之前有很多記到了有道筆記上面,沒發寫出來和大家分享。一、程式學習執行的環境:1、openc下載與配置下載opencv的網站有不少,到

基於Harris的特徵檢測匹配

<span style="font-size:10px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255); font-weight: normal;">

【學習opencv】實現霍夫變換1檢測直線

目前想對於霍夫圓檢測進行修改,想法是若能在固定圓心的橫座標的情景下去搜索圓,若要實現就需要對霍夫檢測有一定的深入瞭解。 霍夫變換原理 霍夫變換原理實則就是引數空間的轉變。 極座標轉換 首先因為直角座標系中垂直於x軸的直線不存在,即轉換用極座標表示

人臉檢測1——HOG特徵

一、概述   前面一個系列,我們對車牌識別的相關技術進行了研究,但是車牌識別相對來說還是比較簡單的,後續本人會對人臉檢測、人臉識別,人臉姿態估計和人眼識別做一定的學習和研究。其中人臉檢測相對來說比較簡單,譬如Dlib庫中直接封裝了現成的庫函式 frontal_face_detector 供相關人員使用,但是D

QT+Opencv實現人臉檢測性別識別(1)

seetaface開源人臉檢測框架實現人臉檢測,opencv+dnn模組實現性別分類,qt做顯示介面,完成一個課程設計。 依賴庫:opencv3.1+ 包含dnn模組,QT5 1.性別分類網路訓練 1.1.訓練資料準備 下載lfw人臉資

lixuxmint系統定制配置1-系統初始配置

visible 可能 white div 當前 圖片 num lines 引導 小書匠 Linux 經常安裝新的系統,每次安裝完都得去搜索一邊如何將系統部署為之前的環境,不僅耗費時間,還不一定能弄回之前的環境,現在把從裸機->到工作環境的系統定制及配置過程記錄下來

Chap03知識抽取挖掘1

eva image str spa 實體 方法 深度學習 ron int 大綱 1.知識抽取任務定義和相關比賽 2.面向結構化數據的知識抽取 3.面向半結構化數據的知識抽取 4.實踐展示:基於百科數據的知識抽取 競賽:MUC ACE KBP SemEval

redis叢集分片1-redis伺服器叢集、客戶端分片 redis叢集分片1-redis伺服器叢集、客戶端分片

redis叢集與分片(1)-redis伺服器叢集、客戶端分片   下面是來自知乎大神的一段說明,個人覺得非常清晰,就收藏了。 為什麼叢集? 通常,為了提高網站響應速度,總是把熱點資料儲存在記憶體中而不是直接從後端 資料庫中

redis集群分片1-redis服務器集群、客戶端分片

服務器集群 包含 工作 direct 數據丟失 網站 這一 線性 取模 下面是來自知乎大神的一段說明,個人覺得非常清晰,就收藏了。 為什麽集群? 通常,為了提高網站響應速度,總是把熱點數據保存在內存中而不是直接從後端數據庫中讀取。Redis是一個很好的Cache工具