學(xué)習(xí)OpenCV關(guān)注微信公眾號(hào)【OpenCV學(xué)堂】
一:介紹
我們知道SIFT算法通常通過對(duì)每個(gè)關(guān)鍵點(diǎn)生成128個(gè)特征向量作為描述子、SURF算法通常對(duì)關(guān)鍵點(diǎn)生成最少64個(gè)特征向量作為描述子。但是對(duì)于圖像來說創(chuàng)建上千或者上萬個(gè)這樣的描述子內(nèi)存開銷比較大,運(yùn)行速度受到嚴(yán)重影響。特別對(duì)嵌入式設(shè)備與一定設(shè)備來說,內(nèi)存限制尤為明顯,而且匹配的時(shí)候計(jì)算也比較耗時(shí)。
但是實(shí)際上這些特征數(shù)據(jù)OpenCV在匹配的時(shí)候并沒有完全利用上,而是通過PCA、LDA等方法對(duì)它進(jìn)行壓縮,或者是LSH(局部敏感哈希)方法把這些特征描述子壓縮從浮點(diǎn)數(shù)轉(zhuǎn)換為二進(jìn)制字符串,然后通過漢明距離(HammingDistance)進(jìn)行比較。這樣就可以通過簡單的異或操作(OXR)與位值計(jì)算來加速實(shí)現(xiàn)對(duì)象特征匹配,對(duì)于SSE指令集的CPU這種方法可以大大加速。但是這種方法仍然需要首先計(jì)算描述子,然后使用LSH方法進(jìn)行壓縮,無法避免過度的內(nèi)存開銷。
而Brief方法可以直接通過關(guān)鍵點(diǎn)生成二進(jìn)制字符串,跳過了中間描述子生成步驟,這樣就大大減低了內(nèi)存要求與計(jì)算開銷。Brief方法主要思路是對(duì)每個(gè)關(guān)鍵點(diǎn)附件選擇若干個(gè)像素點(diǎn),將這些像素點(diǎn)的像素值組合成二進(jìn)制字符串,然后使用該字符串作為該關(guān)鍵點(diǎn)的描述子。
此方法是在2010年提出來的。結(jié)果實(shí)驗(yàn)測(cè)試在選取256個(gè)點(diǎn)甚至128個(gè)點(diǎn)情況下對(duì)沒有旋轉(zhuǎn)對(duì)象識(shí)別率非常高而且速度比SURF還快。但是當(dāng)對(duì)象有旋轉(zhuǎn)時(shí)候由于Brief不能很好的支持旋轉(zhuǎn)不變性識(shí)別,特別是當(dāng)旋轉(zhuǎn)角度超過30度以上,準(zhǔn)確率會(huì)快速下降。
二:Brief描述子生成步驟
Brief描述子生成首先需要產(chǎn)生足夠多的隨機(jī)點(diǎn)對(duì),然后根據(jù)隨機(jī)點(diǎn)對(duì)坐標(biāo)得到對(duì)應(yīng)像素值,對(duì)所有點(diǎn)對(duì)進(jìn)行二進(jìn)制字符串拼接,拼接完成即生成了描述子。
第一步:選擇關(guān)鍵點(diǎn)周圍SxS大小正方形圖像區(qū)塊,進(jìn)行高斯模糊。這樣做的原因是需要降低圖像隨機(jī)噪聲,OpenCV在完成Brief的時(shí)候考慮到效率問題并沒有采用高斯模糊而是采用了基于積分圖的盒子模糊方法。
第二步:選擇n個(gè)像素點(diǎn)對(duì),其中n的取值常見為256、此外還可以是128、512。每個(gè)點(diǎn)對(duì)比較像素值輸出如下。

對(duì)N個(gè)點(diǎn)對(duì)完成操作最終得到了二進(jìn)制字符串,表達(dá)如下:

三:方法
高斯模糊比較
通過實(shí)驗(yàn)對(duì)比高斯sigma參數(shù)在0~3之間準(zhǔn)確率比較高,窗口大小取值在9x9取得比較好的模糊去噪效果。論文中實(shí)驗(yàn)結(jié)果圖示如下:

隨機(jī)點(diǎn)生成方法比較
對(duì)于隨機(jī)生成點(diǎn)對(duì)的方法,論文中給出了五種隨機(jī)方法與實(shí)驗(yàn)結(jié)果比較,五種方法描述如下:

圖示如下:

對(duì)圖像五個(gè)幾何采樣完成測(cè)試結(jié)果如下:

其中第二種方法比其他四種稍微有點(diǎn)優(yōu)勢(shì),而最不好的方法則是第五種方法。
四:OpenCV中Biref描述子演示
#include <opencv2/opencv.hpp>#include <opencv2/xfeatures2d.hpp>#include <iostream>using namespace cv;using namespace std;using namespace cv::xfeatures2d;int main(int argc, char** argv) { Mat img1 = imread("D:/tree.png", IMREAD_GRAYSCALE); Mat img2 = imread("D:/tree_in_scene.png", IMREAD_GRAYSCALE); Mat src = imread("D:/gloomyfish/14.png", IMREAD_GRAYSCALE); Mat src1 = imread("D:/gloomyfish/14.png"); if (!img1.data || !img2.data) { PRintf("could not load images.../n"); return -1; } imshow("box", img1); imshow("scene", img2); auto detector = FastFeatureDetector::create(); vector<KeyPoint> keypoints_obj; vector<KeyPoint> keypoints_scene; detector->detect(img1, keypoints_obj, Mat()); detector->detect(img2, keypoints_scene, Mat()); auto descriptor = BriefDescriptorExtractor::create(); Mat descriptor_obj, descriptor_scene; descriptor->compute(img1, keypoints_obj, descriptor_obj); descriptor->compute(img2, keypoints_scene, descriptor_scene); BFMatcher matcher(NORM_L2); vector<DMatch> matches; matcher.match(descriptor_obj, descriptor_scene, matches); Mat resultImg; drawMatches(img1, keypoints_obj, img2, keypoints_scene, matches, resultImg); imshow("Brief Descriptor Match Result", resultImg); waitKey(0); return 0;}運(yùn)行結(jié)果
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注