Opencv (C++) シリーズ学習 --- SIFT、SURF、ORB 演算子の特徴検出

          この記事では、特徴検出と記述子の動作原理については詳しく説明しません。これについては、今後の更新で詳しく説明します。この記事では、主によく使用される 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 - 高速機能検出器のしきい値です。

ORB 演算子の詳細: OpenCV: cv::ORB クラス リファレンスhttps://docs.opencv.org/3.2.0/db/d95/classcv_1_1ORB.html#adc371099dc902a9674bd98936e79739c 

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 で、半径と方向を指定した円を使用してキーポイントを描画します。

結果を示す:d776a75954bc4592afe93bf1611b8e5d.png

おすすめ

転載: blog.csdn.net/qiaodahua/article/details/127935120