この記事では、特徴検出と記述子の動作原理については詳しく説明しません。これについては、今後の更新で詳しく説明します。この記事では、主によく使用される 3 つの特徴検出アルゴリズムのパラメーター情報と簡単なアプリケーションを紹介します。
1. 3 つのオペレーター SIFT、SURF、ORB のパラメーターの紹介
【1】SIFT演算子の定義の紹介
static Ptr<SIFT> create(
int nfeatures =0,//需要的特征点的数量,是对特征点的质量进行排名,返回最好的前几个;
int n0ctaveLayers =3,//金字塔的层数;
double contrastThrehold =0.04,//过滤特征点的阈值;
double edgeThreshold =10;//过滤边缘效应的阈值;
double sigma=1.6;//用于预处理光滑的;
)
(1) nfeature パラメータの場合、必要な特徴点の数であり、0 に設定すると、見つかったすべての特徴点が返されます。
(2) n0ctavelayers の場合、ピラミッド層数は設定値に 3 を加算して計算されます。
(3) コントラスト閾値は、品質の悪いものを除去する閾値であり、値が大きいほどフィルタリングされます。
(4)edgeThreshold はエッジ効果をフィルタリングするためのしきい値であり、値が大きいほどフィルタリングが少なくなります。
(5) シグマは画像の前処理を滑らかにするために使用され、画像にノイズなどが存在する場合、値を大きくすると効果的です。
【2】SURF演算子の定義の紹介
static Ptr<SURF> create(
double hessianThreshold=100,//SURF中使用的hessian关键点检测器的阈值
int nOctaves = 4, //关键点检测器将使用的金字塔组数量
int nOctaveLayers = 3,//高斯金字塔每个组内图像的层数
bool extended = false, //扩展描述符标志(true使用扩展的128个元素的描述符,false使用64个元素的描述符)
bool upright = false//旋转的特征标志(true不计算方向,false计算方向)
);
検出プロセスは次のとおりです。
(1) スケール空間での極値検出: すべてのスケール空間で画像を検索し、ヘッセ行列を使用してスケールと選択に対して不変である潜在的な特徴点を特定します。
(2) 特徴点フィルタリングと精密位置決め
(3) 特徴方向の割り当て: 統計的特徴点の円形フィールド内の Harr ウェーブレット特徴。つまり、60°セクター内で、統計のために 60°セクター領域を 0.2 ラジアンずつ回転させ、最大値を持つセクターの方向を特徴点の主方向として使用します。
(4) 特徴点の記述: 特徴点の主方向の近傍において、4X4X4 の長方形領域をとり、各小領域の Harr 特徴をカウントし、各領域の 4 次元特徴ベクトルを取得します。特徴点は、SURF特徴の記述子として合計64次元の特徴ベクトルを持ちます。
【3】ORBオペレーターの定義の紹介
ORB の正式名は ORiented Brief で、FAST (加速セグメント テストの特徴) アルゴリズムを使用して特徴点を検出します。BriskやAKAZEと同様に、ORBも特徴点抽出と特徴点記述の2つに分かれています。特徴抽出は、FAST (加速セグメントテストによる特徴) アルゴリズムから開発されており、特徴点の周囲の画像グレー値に基づいて、候補特徴点の周囲の円内のピクセル値を検出します。候補点の周囲の点と候補点の間のグレー値の差が十分に大きい場合、候補点は特徴点であると見なされます。特徴点記述は、BRIEF (Binary Robust Independent Elementary features) 特徴記述アルゴリズムに基づいて改善されています。
FAST特徴点検出手法とBRIEF特徴記述子を組み合わせ、独自のベースで改良・最適化を行っています。ORB アルゴリズムは sift の 100 倍、surf の 10 倍高速であると言われています。ORB アルゴリズムは、BRIEF の欠点を解決するために改良されており、主にノイズ感度と回転不変性という 2 つの欠点を解決します。
Ptr<ORB> create(
int nfeatures =500,
float scaleFactor=1.2f,
int nlevels=8,
int edgeThreshold=31,
int firstLevel=0,
int WTA_K=2,
int scoreTyoe=0,
int patchSize=31,
int fastThreshold=20
);
(1) nfeatures は抽出される特徴点の最大数です。
(2)scaleFactor - SIFT のものと同様の、ピラミッド画像間のスケール パラメータ。
(3) nlevels – ガウス ピラミッドの層の数。
(4)edgeThreshold - エッジの閾値この値は主に後続の patchSize に基づいて決定され、エッジに近いピクセルとedgeThreshold内のピクセルは特徴点を検出しません。
(5) firstLevel - SIFT を見た後は誰もが知っているように、最初のレイヤーのインデックス値を指定できます。ここではデフォルトは 0 です。
(6) WET_K - BIREF 記述子の生成に使用される点ペアの数 (通常は 2) を 3 または 4 に設定することもできます。その場合、ハミング距離を記述子間の距離の計算に使用することはできず、代わりにバリアントを使用する必要があります。OpenCV では、WET_K = 2 が設定されている場合、選択されたポイント ペアには 2 ポイントのみが含まれます。マッチングする場合、距離パラメータは NORM_HAMMING を選択します。WET_K が 3 または 4 に設定されている場合、BIREF 記述子は 3 または 4 ポイントを選択し、その後、以下 マッチング時に選択する必要がある距離パラメータは NORM_HAMMING2 です。
(7) スコアタイプ - 特徴点のソートに使用されるアルゴリズム HARRIS_SCORE または FAST_SCORE を選択できますが、前者よりもわずかに速いだけです。
(8)patchSize – BIREF 記述子の特徴点近傍サイズを計算するために使用されます。
(9) FastThreshold - 高速機能検出器のしきい値です。
2. コード例
#include<opencv2\opencv.hpp>
#include<opencv2\xfeatures2d.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\xfeatures2d\nonfree.hpp>
#include<iostream>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
int main(int argc,char** argv)
{
//【0】改变字体颜色
system("color 2F");
//【1】载入源图片并显示
Mat srcImage1 = imread("E:\\乔大花进度\\11-17\\surf特征检测\\1.jpg",1);
Mat srcImage2 = imread("E:\\乔大花进度\\11-17\\surf特征检测\\2.jpg", 1);
//【2】显示图片
imshow("原始图1",srcImage1);
imshow("原始图2",srcImage2);
int minHessian = 400;//默认值为100
vector<KeyPoint>keyPoints, keyPoints1;
Mat resultImg, resultImage1;
//关于定义的方法主要有两种
//第一种指针形式定义
// Ptr<SURF\SIFT\ORB>detector = SURF\SIFT\ORB::create(minHessian, 4, 3, false, false);
//第二种算子形式定义
//SiftFeatureDetector\SurfFeatureDetector定义
//第一种定义方式更普遍使用
//SURF特征检测 //也可以写成SURF::create(minHessian)
Ptr<SURF>detector = SURF::create(minHessian, 4, 3, false, false);
detector->detect(srcImage1, keyPoints, Mat());
//绘制关键点
drawKeypoints(srcImage1, keyPoints, resultImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
imshow("KetPoint image", resultImg);
//SIFT特征检测
Ptr<SIFT>detector1 = SIFT::create();
detector1->detect(srcImage2, keyPoints1, Mat());
//绘制关键点
drawKeypoints(srcImage2, keyPoints1, resultImage1, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("KetPoint image1" ,resultImage1);
waitKey(0);
system("pause");
return 0;
}
(1) 特徴検出器が定義された後、検出された特徴点は detect によって抽出され、キーポイントに保存されます。
(2) 検出された特徴点を描画して表示するには、drawkeypoints オペレーターを使用します。よく使用される表示方法は 2 つあります
1 つ目はデフォルトの DEFAULT で、キーポイントを小さな円で囲みます。2 つ目は DRAW_RICH_KEYPOINTS で、半径と方向を指定した円を使用してキーポイントを描画します。
結果を示す: