BRIEF記述子生成アルゴリズム

3123 ワード

OpenCVを勉強して微信公衆番号【OpenCV学堂】に注目する
一:紹介
SIFTアルゴリズムは一般に各キーに対して128個の特徴ベクトルを記述子として生成し,SURFアルゴリズムは通常キーに対して少なくとも64個の特徴ベクトルを記述子として生成することを知っている.しかし、画像にとっては、このような記述サブメモリの数千個または数万個の作成にオーバーヘッドが大きく、実行速度に深刻な影響を及ぼします.特に,組み込み機器と一定の機器ではメモリ制限が顕著であり,マッチング時の計算にも時間がかかる.
 
しかし,実際にはこれらの特徴データOpenCVはマッチングの際に完全に利用されず,PCA,LDAなどの方法で圧縮したり,LSH(局所敏感ハッシュ)法でこれらの特徴記述子圧縮を浮動小数点数からバイナリ文字列に変換してハミング距離(HammingDistance)で比較したりする.これにより簡単な排他的または動作(OXR)とビット値計算によりオブジェクト特徴マッチングの実現を加速することができ,SSE命令セットのCPUに対してこの方法は大幅に加速することができる.しかし,この方法ではまず記述子を計算し,LSH法を用いて圧縮する必要があり,過剰なメモリオーバーヘッドを回避することはできない.
 
一方,Brief法はキーによって直接バイナリ文字列を生成し,中間記述サブ生成ステップをスキップすることで,メモリ要件と計算オーバーヘッドを大幅に低減できる.Brief法の主な考え方は,各キーアクセサリに対していくつかの画素点を選択し,これらの画素点の画素値をバイナリ文字列に組み合わせ,その文字列をキーの記述子として用いることである.
この方法は2010年に提案された.その結果、256個の点から128個の点を選択した場合、回転していないオブジェクトの識別率が非常に高く、SURFよりも速度が速いことが実験的に試験された.しかし,オブジェクトが回転している場合,Briefは回転不変性認識をうまくサポートできないため,特に回転角度が30度以上では精度が急速に低下する.
 
二:Brief記述子生成ステップ
Brief記述子生成はまず十分なランダム点対を生成する必要があり,次いでランダム点対座標に基づいて対応する画素値を得,すべての点対に対してバイナリ文字列接合を行い,接合が完了すると記述子を生成する.
ステップ1:キー周囲のSxSサイズの正方形画像ブロックを選択し、ガウスブラーを行います.これは画像ランダムノイズを低減する必要があるためであり,OpenCVはBriefを完了する際に効率の問題を考慮してGaussファジイではなく積分図に基づく箱ファジイ法を採用した.
ステップ2:n個のピクセルポイントペアを選択し、nの値は256が一般的であり、128、512であってもよい.各点対比較画素値は以下のように出力される.
N個のポイントペアの完了操作に対して最終的にバイナリ文字列が得られ、以下のように表現される.
 
三:方法
ガウスファジイ比較
ガウスsigmaパラメータを0~3の間で実験的に比較すると精度が高く,窓サイズの値を9 x 9で比較的良好なぼかしノイズ除去効果が得られた.論文の実験結果は以下の通りである.
ランダムポイント生成方法の比較
ランダムに点対を生成する方法について,論文では5つのランダム方法を実験結果と比較し,5つの方法は以下のように記述した.
図は次のとおりです.
画像の5つのジオメトリサンプリングのテスト結果は次のとおりです.
このうち2つ目の方法は他の4つよりやや優位であり、最も悪い方法は5つ目の方法である.
四: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...
"); 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; }

実行結果