? ? ? ?
目錄
特征點(diǎn)分類
1 ORB
①特征點(diǎn)檢測(cè)
②計(jì)算特征描述
2 SIFT
1 SIFT特征檢測(cè)的步驟
①.在DOG尺度空間中獲取極值點(diǎn),即關(guān)鍵點(diǎn)。
②.特征點(diǎn)方向估計(jì)
③生成特征描述
④.代碼實(shí)現(xiàn)
3.SURF
①.SURF的介紹
②.SURF算法步驟
③. SIFT與SURF效果比較
④代碼實(shí)現(xiàn)
4 FAST角點(diǎn)檢測(cè)且閾值可調(diào)節(jié)
補(bǔ)充
圖像金字塔
灰度質(zhì)心法
實(shí)現(xiàn)思路:
圖像本身是由亮度和色彩組成的矩陣,VO核心問題是如何根據(jù)圖像估計(jì)相機(jī)運(yùn)動(dòng)。數(shù)字圖像在計(jì)算機(jī)中是以灰度值矩陣的方式存儲(chǔ)的,灰度值不穩(wěn)定,所以采用灰度值+特征點(diǎn);圖像中的角點(diǎn)、邊緣和區(qū)塊都是具有代表性的地方,可以作為圖像特征;
? ? ? ?特征點(diǎn)由關(guān)鍵點(diǎn)和描述子組成,計(jì)算SIFT特征點(diǎn)指的是:“提取SIFT關(guān)鍵點(diǎn),并計(jì)算SIFT描述子”兩件事。
? ? ? ?關(guān)鍵點(diǎn):特征點(diǎn)在圖像里的位置,大小,方向信息;? ?描述子:描述了該關(guān)鍵點(diǎn)周圍的像素信息的向量。
特征點(diǎn)分類
1 ORB
? ? ? ?ORB特征點(diǎn)關(guān)鍵點(diǎn)為Oriented FAST計(jì)算了特征點(diǎn)的主方向、描述子為BRIER利用關(guān)鍵點(diǎn)方向信息描述子增加了旋轉(zhuǎn)不變性。
FAST角點(diǎn):局部像素灰度變化明顯的地方,速遞快。計(jì)算像素間亮度差異。ORB通過構(gòu)建圖像金字塔,并在圖像金字塔的每一層上來檢測(cè)角點(diǎn)實(shí)現(xiàn)尺度不變性;ORB特征旋轉(zhuǎn)由灰度質(zhì)心法實(shí)現(xiàn)。
BRIEF描述子是二進(jìn)制描述,需要用到漢明距離,ORB描述子為旋轉(zhuǎn)之后的BRIEF。
? ? ? ?ORB特征點(diǎn)采用FAST(features from accelerated segment test)算法來檢測(cè)特征點(diǎn)。FAST核心思想是拿一個(gè)點(diǎn)跟它周圍的點(diǎn)比較,如果它和其中大部分的點(diǎn)都不一樣就可以認(rèn)為它是一個(gè)特征點(diǎn)。比如我們可以那一個(gè)點(diǎn)與它周圍半徑是3的圓上的所有像素點(diǎn)進(jìn)行比較,如下圖所示:
①特征點(diǎn)檢測(cè)
?
有了計(jì)算的方案和策略,接下來我們來看計(jì)算的具體過程。
FAST具體計(jì)算過程:
①?gòu)膱D片中選取一個(gè)像素點(diǎn)P,下面我們將判斷它是否是一個(gè)特征點(diǎn)。我們首先把它的密度(即灰度值)設(shè)為Ip。
②設(shè)定一個(gè)合適的闕值t :當(dāng)2個(gè)點(diǎn)的灰度值之差的絕對(duì)值大于t時(shí),我們認(rèn)為這2個(gè)點(diǎn)不相同。
③考慮該像素點(diǎn)周圍的16個(gè)像素。(見上圖)
④現(xiàn)在如果這16個(gè)點(diǎn)中有連續(xù)的n個(gè)點(diǎn)都和選取像素點(diǎn)不同,那么它就是一個(gè)角點(diǎn)。 這里n設(shè)定為12。
⑤我們現(xiàn)在提出一個(gè)高效的測(cè)試,來快速排除一大部分非特征點(diǎn)的點(diǎn)。該測(cè)試僅僅檢查在位置1、9、5和13四個(gè)位置的像素。如果是一個(gè)角點(diǎn),那么上述四個(gè)像素點(diǎn)中至少有3個(gè)應(yīng)該和點(diǎn)相同。如果都不滿足,那么不可能是一個(gè)角點(diǎn)。
通過上述過程,我們的圖片像多了很多特征點(diǎn),我們用紅色標(biāo)出。
?
②計(jì)算特征描述
得到特征點(diǎn)后我們需要以某種方式 F 描述這些特征點(diǎn)的屬性。這些屬性的輸出我們稱之為該特征點(diǎn)的描述子。ORB采用BRIEF算法來計(jì)算一個(gè)特征點(diǎn)的描述子。BRIEF算法的核心思想是在關(guān)鍵點(diǎn)P的周圍以一定模式選取N個(gè)點(diǎn)對(duì),把這N個(gè)點(diǎn)對(duì)的比較結(jié)果組合起來作為描述子。
接下來看一下具體操作:? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
-
以關(guān)鍵點(diǎn)P為圓心,以d為半徑做圓O。
-
在圓O內(nèi)某一模式選取N個(gè)點(diǎn)對(duì)。這里為方便說明,N=4,實(shí)際應(yīng)用中N可以取512.
-
假設(shè)當(dāng)前選取的4個(gè)點(diǎn)對(duì)如上圖所示分別標(biāo)記為:
-
定義操作T
-
分別對(duì)已選取的點(diǎn)對(duì)進(jìn)行T操作,將得到的結(jié)果進(jìn)行組合。
假如:
則最終的描述子為:1011
#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/xfeatures2d.hpp>
#include <opencv2/highgui/highgui_c.h>
#include<opencv2/xfeatures2d/nonfree.hpp>
#include<vector>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
Mat src;
int main(int argc, char** argv)
{
src = imread("./data2/101.png", IMREAD_GRAYSCALE); //加載灰度圖像
//src = imread("./data2/101.png"); //加載圖像
if (!src.data)
{
cout << "圖片加載失敗" << endl;
return -1;
}
namedWindow("加載的灰度圖像", CV_WINDOW_NORMAL); //可任意改變窗口大小
imshow("加載的灰度圖像", src);
int numfeature = 400; //特征點(diǎn)數(shù)目
Ptr<ORB>detector = ORB::create(numfeature);
//auto detector = ORB::create(); //自動(dòng)生成特征點(diǎn)的個(gè)數(shù)
vector<KeyPoint>keypoints;
detector->detect(src, keypoints, Mat());
printf("所有的特征點(diǎn)個(gè)數(shù):%d", keypoints.size());
Mat resultImg;
drawKeypoints(src, keypoints, resultImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT); //特征點(diǎn)顏色隨機(jī)
imshow("特征點(diǎn)提取", resultImg);
imwrite("./效果圖/特征點(diǎn)提取.jpg", resultImg);
waitKey(0);
return 0;
}
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img1 = cv.imread('./data/box.png',0) # queryImage
img2 = cv.imread('./data/box_in_scene.png',0) # trainImage
# Initiate ORB detector
orb = cv.ORB_create()
# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)
# create BFMatcher object
bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
# Match descriptors.
matches = bf.match(des1,des2)
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)
# Draw first 10 matches.
img3 = cv.drawMatches(img1,kp1,img2,kp2,matches[:20],None, flags=2)
plt.imshow(img3),plt.show()
2 SIFT
? ? ? ?尺度不變特征,SIFT特征對(duì)旋轉(zhuǎn)、尺度縮放、亮度變化等保持不變性,是一種非常穩(wěn)定的局部特征。對(duì)視角變化、仿射變換、噪聲也保持一定程度的穩(wěn)定性。
1 SIFT特征檢測(cè)的步驟
①.在DOG尺度空間中獲取極值點(diǎn),即關(guān)鍵點(diǎn)。
? ? ? ?關(guān)于LOG(高斯拉普拉斯金字塔) DOG(高斯差分金字塔)參考 https://blog.csdn.net/dcrmg/article/details/52561656
? ? ? ?確定極值點(diǎn):尋找DoG極值點(diǎn)時(shí),每一個(gè)像素點(diǎn)和它所有的相鄰點(diǎn)比較,當(dāng)其大于(或小于)它的圖像域和尺度域的所有相鄰點(diǎn)時(shí),即為極值點(diǎn)。如下圖所示,比較的范圍是個(gè)3×3的立方體:中間的檢測(cè)點(diǎn)和它同尺度的8個(gè)相鄰點(diǎn),以及和上下相鄰尺度對(duì)應(yīng)的9×2個(gè)點(diǎn)——共26個(gè)點(diǎn)比較,以確保在尺度空間和二維圖像空間都檢測(cè)到極值點(diǎn)。
②.特征點(diǎn)方向估計(jì)
? ? ? ?計(jì)算以特征點(diǎn)為中心、以3×1.5σ為半徑的區(qū)域圖像的幅角和幅值,每個(gè)點(diǎn)L(x,y)的梯度的模m(x,y)以及方向θ(x,y)可通過下面公式求得
? ? ? ?計(jì)算得到梯度方向后,就要使用直方圖統(tǒng)計(jì)特征點(diǎn)鄰域內(nèi)像素對(duì)應(yīng)的梯度方向和幅值。梯度方向的直方圖的橫軸是梯度方向的角度(梯度方向的范圍是0到360度,直方圖每36度一個(gè)柱共10個(gè)柱,或者沒45度一個(gè)柱共8個(gè)柱),縱軸是梯度方向?qū)?yīng)梯度幅值的累加,在直方圖的峰值就是特征點(diǎn)的主方向。在梯度直方圖中,當(dāng)存在一個(gè)相當(dāng)于主峰值80%能量的柱值時(shí),則可以將這個(gè)方向認(rèn)為是該特征點(diǎn)輔助方向。所以,一個(gè)特征點(diǎn)可能檢測(cè)到多個(gè)方向(也可以理解為,一個(gè)特征點(diǎn)可能產(chǎn)生多個(gè)坐標(biāo)、尺度相同,但是方向不同的特征點(diǎn))。
③生成特征描述
? ? ? ?為了保證特征矢量的旋轉(zhuǎn)不變性,要以特征點(diǎn)為中心,在附近鄰域內(nèi)將坐標(biāo)軸旋轉(zhuǎn)θ(特征點(diǎn)的主方向)角度,即將坐標(biāo)軸旋轉(zhuǎn)為特征點(diǎn)的主方向。
? ? ? ?將旋轉(zhuǎn)后區(qū)域劃分為d×d(d為2或者4,通常取4)個(gè)子區(qū)域(每個(gè)區(qū)域間隔為mσ像元),在子區(qū)域內(nèi)計(jì)算8個(gè)方向的梯度直方圖,繪制每個(gè)方向梯度方向的累加值,形成一個(gè)種子點(diǎn)。
與求主方向不同的是,此時(shí),每個(gè)子區(qū)域梯度方向直方圖將0°~360°劃分為8個(gè)方向區(qū)間,每個(gè)區(qū)間為45°。即每個(gè)種子點(diǎn)有8個(gè)方向區(qū)間的梯度強(qiáng)度信息。由于存在d×d,即4×4個(gè)子區(qū)域,所以最終共有4×4×8=128個(gè)數(shù)據(jù),形成128維SIFT特征矢量。
?參考blog:圖像特征點(diǎn)提?。⊿IFT,SURF,ORB)_阿飛大魔王的博客-CSDN博客_圖像特征點(diǎn)提取
④.代碼實(shí)現(xiàn)
import numpy as np
import cv2 as cv
img = cv.imread('./data/home.jpg')
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d.SIFT_create()
kp = sift.detect(gray,None)
img=cv.drawKeypoints(gray,kp,img)
cv.imshow("SIFT", img)
cv.imwrite('sift_keypoints.jpg',img)
cv.waitKey(0)
cv.destroyAllWindows()
#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/xfeatures2d.hpp>
#include <opencv2/highgui/highgui_c.h>
#include<opencv2/xfeatures2d/nonfree.hpp>
#include<vector>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
Mat src;
int main(int argc, char** argv)
{
src = imread("./data2/101.png", IMREAD_GRAYSCALE); //加載灰度圖像
//src = imread("./data2/101.png"); //加載圖像
if (!src.data)
{
cout << "圖片加載失敗" << endl;
return -1;
}
//namedWindow("加載的灰度圖像", CV_WINDOW_NORMAL); //可任意改變窗口大小
imshow("加載的灰度圖像", src);
int numfeature = 400; //特征點(diǎn)數(shù)目
Ptr<SIFT>detector = SIFT::create(numfeature);
//auto detector = SIFT::create(); //自動(dòng)生成特征點(diǎn)的個(gè)數(shù)
vector<KeyPoint>keypoints;
detector->detect(src, keypoints, Mat());
printf("所有的特征點(diǎn)個(gè)數(shù):%d", keypoints.size());
Mat resultImg;
drawKeypoints(src, keypoints, resultImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT); //特征點(diǎn)顏色隨機(jī)
imshow("SIFT特征點(diǎn)提取", resultImg);
imwrite("./效果圖/SIFT特征點(diǎn)提取.jpg", resultImg);
waitKey(0);
return 0;
}
圖像特征點(diǎn)匹配
img1_gray = cv2.imread("./data/000029.jpg")
img2_gray = cv2.imread("./data/000087.jpg")
# sift = cv2.xfeatures2d.SIFT_create()
sift = cv2.xfeatures2d.SURF_create()
kp1, des1 = sift.detectAndCompute(img1_gray, None)
kp2, des2 = sift.detectAndCompute(img2_gray, None)
# BFmatcher with default parms
bf = cv2.BFMatcher(cv2.NORM_L2)
matches = bf.knnMatch(des1, des2, k=2)
goodMatch = []
for m, n in matches:
if m.distance < 0.50 * n.distance:
goodMatch.append(m)
goodMatch = np.expand_dims(goodMatch, 1)
# print(goodMatch[:20])
# drawMatchesKnn_cv2(img1_gray, kp1, img2_gray, kp2, goodMatch[:20])
res = cv2.drawMatchesKnn(img1_gray, kp1, img2_gray, kp2, goodMatch[:100], None, flags=2)
cv2.namedWindow('res', cv2.WINDOW_NORMAL)
cv2.resizeWindow('res', 1080, 720)
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
提取效果
?結(jié)果:(顯示了前100個(gè)匹配點(diǎn))
?
3.SURF
①.SURF的介紹
? ? ? ?SURF(Speeded Up Robust Features)改進(jìn)了特征的提取和描述方式,用一種更為高效的方式完成特征的提取和描述。Sift算法的優(yōu)點(diǎn)是特征穩(wěn)定,對(duì)旋轉(zhuǎn)、尺度變換、亮度保持不變性,對(duì)視角變換、噪聲也有一定程度的穩(wěn)定性;缺點(diǎn)是實(shí)時(shí)性不高,并且對(duì)于邊緣光滑目標(biāo)的特征點(diǎn)提取能力較弱。 SURF是對(duì)SIFT的改進(jìn),可將速度提高3倍。SURF主要是把SIFT中的某些運(yùn)算做了簡(jiǎn)化。
②.SURF算法步驟
尺度空間的極值檢測(cè):搜索所有尺度空間上的圖像,通過Hessian來識(shí)別潛在的對(duì)尺度和選擇不變的興趣點(diǎn)。
特征點(diǎn)過濾并進(jìn)行精確定位。
特征方向賦值:統(tǒng)計(jì)特征點(diǎn)圓形鄰域內(nèi)的Harr小波特征。即在60度扇形內(nèi),每次將60度扇形區(qū)域旋轉(zhuǎn)0.2弧度進(jìn)行統(tǒng)計(jì),將值最大的那個(gè)扇形的方向作為該特征點(diǎn)的主方向。
特征點(diǎn)描述:沿著特征點(diǎn)主方向周圍的鄰域內(nèi),取4×4個(gè)矩形小區(qū)域,統(tǒng)計(jì)每個(gè)小區(qū)域的Haar特征,然后每個(gè)區(qū)域得到一個(gè)4維的特征向量。一個(gè)特征點(diǎn)共有64維的特征向量作為SURF特征的描述子。
具體可以參考,寫得很好 https://www.cnblogs.com/zyly/p/9531907.html
③. SIFT與SURF效果比較
- 加速3倍
- 亮度變化下效果好
- 模糊方面優(yōu)于SIFT
- 尺度不變性不及SIFT
- 旋轉(zhuǎn)不變上差很多
④代碼實(shí)現(xiàn)
import numpy as np
import cv2 as cv
img = cv.imread('./data/000029.jpg',0)
surf = cv.xfeatures2d.SURF_create(2000)
kp, des = surf.detectAndCompute(img,None)
img1 = cv.drawKeypoints(img,kp,None,(0,0,255),4)
cv.imshow('surf', img1)
cv.waitKey(0)
cv.destroyAllWindows()
surf.setHessianThreshold(20000)
kp, des = surf.detectAndCompute(img,None)
img2 = cv.drawKeypoints(img,kp,None,(0,0,255),4)
cv.imshow('surf',img2)
cv.waitKey(0)
cv.destroyAllWindows()
4 FAST角點(diǎn)檢測(cè)且閾值可調(diào)節(jié)
- 閾值可自動(dòng)調(diào)節(jié),首先給予一個(gè)初值為40的閾值。
- 將特征點(diǎn)個(gè)數(shù)以及閾值打印出來。
#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/xfeatures2d.hpp>
#include <opencv2/highgui/highgui_c.h>
#include<opencv2/xfeatures2d/nonfree.hpp>
#include<vector>
//FAST角點(diǎn)檢測(cè)
using namespace std;
using namespace cv;
int thre = 40;
Mat src;
void trackBar(int, void*);
int main(int argc, char** argv)
{
//src = imread("./data2/88.jpg");
src = imread("./data2/88.jpg", IMREAD_GRAYSCALE); //加載灰度圖像
if (src.empty())
{
printf("無圖像加載 \n");
return -1;
}
namedWindow("input", WINDOW_NORMAL);
imshow("input", src);
namedWindow("output", WINDOW_NORMAL);
createTrackbar("threshould", "output", &thre, 255, trackBar);
waitKey(0);
return 0;
}
void trackBar(int, void*)
{
std::vector<KeyPoint> keypoints;
Mat dst = src.clone();
Ptr<FastFeatureDetector> detector = FastFeatureDetector::create(thre);
printf("閾值:%d", thre); //打印檢測(cè)到的特征點(diǎn)個(gè)數(shù),隨閾值變化
detector->detect(src, keypoints);
printf("檢測(cè)到的所有的特征點(diǎn)個(gè)數(shù):%d", keypoints.size()); //打印檢測(cè)到的特征點(diǎn)個(gè)數(shù),隨閾值變化
drawKeypoints(dst, keypoints, dst, Scalar::all(-1), DrawMatchesFlags::DRAW_OVER_OUTIMG); //隨機(jī)顏色畫出
imshow("角點(diǎn)檢測(cè)圖", dst);
imwrite("./效果圖/角點(diǎn)檢測(cè)圖.jpg", dst);
}
補(bǔ)充
ORB特征添加了尺度和旋轉(zhuǎn)描述,
尺度不變性由構(gòu)建圖像金字塔,并在金字塔每一層上檢測(cè)角點(diǎn)實(shí)現(xiàn)。
特征旋轉(zhuǎn)不變性由灰度質(zhì)心法實(shí)現(xiàn)。
圖像金字塔? ? ?實(shí)現(xiàn)ORB尺度不變性
金字塔是CV中常用到的一種圖像處理方法,金字塔底層是原始圖像;
每往上一層就對(duì)圖像進(jìn)行固定倍率的縮放,得到了不同分辨率的圖像;
較小的圖像可以看成是遠(yuǎn)處看過來的場(chǎng)景;
在特征匹配算法中,我們可以匹配不同層上的圖像,從而實(shí)現(xiàn)尺度不變性。
例如,如果相機(jī)在后退,我們就能在上一個(gè)圖像金字塔的上一層或者下一個(gè)圖像金字塔的下層中找到匹配。
-
三、理論基礎(chǔ):下采樣、上采樣、濾波器
- 下采樣:自下而上生成一個(gè)圖像金字塔,最下面一般就是原圖,依次往上的圖片尺寸減半。
- 上采樣:自上而下生成一個(gè)圖像金字塔,最上面一般是一個(gè)尺寸較小的特征圖,依次往下的圖片尺寸變?yōu)樵瓉淼亩丁?/li>
?如果我們通過下采樣生成一個(gè)金字塔,最簡(jiǎn)單的做法就是:不斷地刪除圖像的偶數(shù)行和偶數(shù)列,重復(fù)這個(gè)過程,就得到一個(gè)金字塔。
如果我們通過上采樣生成一個(gè)金字塔,最簡(jiǎn)單的就是:在每列像素點(diǎn)的右邊插入值為0的列,在每行像素點(diǎn)下面插入值為0的行,不斷重復(fù),就生成一個(gè)金字塔了。
小結(jié):
1、下采樣是圖像不斷變小的過程,上采樣是圖像不斷變大的過程。
2、一個(gè)圖像下采樣一次,在執(zhí)行一次上采樣,雖然尺寸恢復(fù)到原圖像的尺寸,但像素值已經(jīng)改變?。?!也就是這兩種操作是不可逆的。
上下采樣API:
下采樣:
cv2.pyrDown(img [, dstsize, borderType])
上采樣:
cv2.pyrUp(img [, dstsize, borderType])
默認(rèn)的尺寸都是一半一半的減小,或者一倍一倍的增加。
默認(rèn)的濾波器都是高斯濾波器
濾波器??
為了減輕圖像信息的丟失,濾波后的圖像就是原始圖像的近似圖像
為什么要用濾波器?
我們下采樣生成金字塔圖像時(shí),是直接刪除偶數(shù)行偶數(shù)列的操作,但這種操作意味著直接丟棄圖像中的信息!為了減輕圖像信息的丟失,我們?cè)谙虏蓸硬僮髦跋扔脼V波器對(duì)原始圖像濾波操作一遍,這樣濾波后的圖像就是原始圖像的近似圖像,此時(shí)我們?cè)趧h偶數(shù)行偶數(shù)列,就沒有直接的信息損失了。而對(duì)原始圖像進(jìn)行濾波操作有很多方法,比如我們可以用鄰域?yàn)V波器進(jìn)行操作,這樣生成的圖像就是平均金字塔。如果我們用高斯濾波器處理,我們就生成的是高斯金字塔?。
同理,當(dāng)我們上采樣生成圖像金字塔時(shí),我們直接右插入列下插入行操作,這種操作會(huì)生成大量的0值像素點(diǎn),這些0值像素點(diǎn)毫無意義,我們就需要對(duì)0值像素點(diǎn)進(jìn)行賦值。而賦值就是插值處理。插值處理也有很多方法,比如用區(qū)域均值補(bǔ)充,那生成的就是平均金字塔,如果用高斯核填充就是高斯金字塔
拉普拉斯金字塔
拉普拉斯金字塔是在高斯金字塔的基礎(chǔ)上生成的。
為啥要發(fā)明拉普拉斯金字塔?還是因?yàn)楦咚菇鹱炙m然它用高斯核過濾了一遍,但或多或少還是有信息丟失,而這些丟失的信息就是拉普拉斯金字塔?。所以拉普拉斯金字塔的作用就在于能夠恢復(fù)圖像的細(xì)節(jié),就是我們從高層的尺寸小的特征圖中提取特征后,我們還能通過拉普拉斯金字塔數(shù)據(jù)找回高層像素點(diǎn)對(duì)應(yīng)的底層清晰度更高的圖像,就是返回來找到更多圖像的細(xì)節(jié)。
Li = Gi - PyrUp( PyrDown(Gi) )
其中,Gi:原始圖像 ; Li:拉普拉斯金字塔圖像
灰度質(zhì)心法? ? 實(shí)現(xiàn)ORB旋轉(zhuǎn)不變形
ORB特征旋轉(zhuǎn)方面,計(jì)算圖像特征點(diǎn)附近的圖像灰度質(zhì)心。質(zhì)心是以圖像塊灰度值作為權(quán)重的中心
實(shí)現(xiàn)思路:
目的:已知形心P,求解質(zhì)心Q
1、為了保證旋轉(zhuǎn)不變性,所以要在圓內(nèi)計(jì)算;
2、為了在圓內(nèi)計(jì)算,故要知道圓的邊界,才能去索引;
3、為了知道圓的邊界,在已知縱坐標(biāo)的情況下,還需知道橫坐標(biāo)umax;
4、最終利用IC_Angle函數(shù)進(jìn)行并行求解像素和
具體操作步驟:
①在一個(gè)小的圖像塊B中,定義圖像塊矩陣為:
?②通過矩可以找到圖像塊的質(zhì)心:
?③連接圖像塊的幾何中心 O 與質(zhì)心 C,得到一個(gè)方向向量 ,于是特征點(diǎn)的方向可以定義為:
?通過以上方法,F(xiàn)AST 角點(diǎn)便具有了尺度與旋轉(zhuǎn)的描述,大大提升了它們?cè)诓煌瑘D像之間 表述的魯棒性。所以在 ORB 中,把這種改進(jìn)后的 FAST 稱為 Oriented FAST。
?
參考文獻(xiàn)
圖像特征點(diǎn)提?。⊿IFT,SURF,ORB)_阿飛大魔王的博客-CSDN博客_圖像特征點(diǎn)提取文章來源:http://www.zghlxwxcb.cn/news/detail-620983.html
圖像特征點(diǎn)提取及匹配的幾種方法總結(jié)——基于C++和OPENCV實(shí)現(xiàn)SIFT、SURF、ORB、FAST_Fighting_XH的博客-CSDN博客_vector<keypoint>?文章來源地址http://www.zghlxwxcb.cn/news/detail-620983.html
到了這里,關(guān)于Opencv圖像特征點(diǎn)提取(的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!