OpenCV画像特徴抽出学習4、SIFT特徴検出アルゴリズム

1. SIFT特徴検出の概要 

SIFTの正式名称は、カナダの David G.Lowe 教授によって提案された Scale Invariant Feature Transform、スケール不変特徴変換です。SIFT 特徴は、回転、スケール スケーリング、明るさの変化などに対して不変であり、非常に安定した局所特徴です。

1.1 SIFTアルゴリズムの特徴

  1. 画像の局所的な特徴は、回転、スケーリング、明るさの変化に対して変化せず、視野角の変化、アフィン変換、ノイズに対してもある程度の安定性を維持します。
  2. 優れた一意性と豊富な情報により、大規模な特徴データベースの高速かつ正確なマッチングに適しています。
  3. 大量の、少数のオブジェクトでも、多数の SIFT 特徴が生成される可能性があります
  4. 高速、最適化された SIFT マッチング アルゴリズムにより、リアルタイム パフォーマンスも実現可能
  5. 登録の拡張により、他の特徴ベクトルと簡単に組み合わせることができます。

1.2 SIFT特徴検出の手順

  1. スケール空間の極値検出は、すべてのスケール空間にわたって画像を検索し、ガウス微分を通じて潜在的なスケールおよび選択不変の関心点を特定します。
  2. 特徴点の位置特定 各候補位置で、フィッティング詳細モデルを使用して位置スケールを決定し、安定性に応じてキーポイントが選択されます。
  3. 特徴方向の割り当ては、画像の局所的な勾配方向に基づいて、各キー ポイントの位置に 1 つ以上の方向を割り当てます。その後のすべての操作は、キー ポイントの方向、スケール、位置を変換することで、これらの不変性を提供します。特徴。
  4. 特徴点の説明 各特徴点の周囲の近傍内で、画像の局所的な勾配が選択されたスケールで測定され、これらの勾配は比較的大きな局所的な形状変形と照明変換を可能にする表現に変換されます。

================================================= ==============

2. ガウスカーネルによるスケール空間の構築

網膜上の物体の結像プロセスは、画像のぼやけの程度によってシミュレートされます。物体が近づくほど、サイズが大きくなり、画像がぼやけます。これはガウス スケール空間であり、さまざまなパラメータを使用してぼかします。画像 (解像度レート定数) は、スケール空間の別の表現形式です。
画像とガウス関数の畳み込み演算により画像がぼやける可能性があり、異なる「ガウス カーネル」を使用すると、異なる程度のぼやけを持つ画像が得られることがわかっています。画像のガウス スケール空間は、さまざまなガウスを使用した畳み込みによって取得できます。

                                       L\left ( x,y,\sigma \right )=G\left ( x,y,\sigma \right )\cdot I\left ( x,y \right )

ここで、G\left ( x,y,\sigma \right )はガウス カーネル関数です。

                                        G\left ( x,y,\sigma \right )=\frac{1}{2\pi \sigma ^{2}}e^{\frac{x^{2}+y^{2}}{2 \sigma ^{2}}}

\シグマこれはスケール空間係数と呼ばれるもので、ガウス正規分布の標準偏差で画像のぼやけの程度を反映しており、値が大きいほど画像がぼやけ、対応するスケールが大きくなります。L\left ( x,y,\sigma \right )画像のガウス スケール空間を表します。


スケール空間を構築する目的は、異なるスケールに存在する特徴点を検出することです。特徴点を検出するためのより優れた演算子は、ガウスのラプラシアン演算子 (  \デルタ^{2}GLoG)です。

                                                \Delta ^{2}=\frac{\partial ^{2}}{\partial x^{2}}+\frac{\partial^{2} }{\partial y^{2}}

kk を 2 つの隣接するガウス スケール空間のスケール係数とすると、DoG の定義は次のようになります。

                           G\left ( x,y,\sigma \right )=\left [ G\left ( x,y,k\sigma \right ) -G\left ( x,y,\sigma \right )\right ]\cdot I\left ( x,y \right )\\ =L\left ( x,y,k\sigma \right )-L\left ( x,y,\sigma \right )

DoG の応答画像は、隣接する 2 つのガウス空間の画像を減算することで得られます。DoG 画像を取得するには、最初にガウス スケール空間を構築する必要があります。ガウス スケール空間は、画像ピラミッド ダウンサンプリングに基づいてガウス フィルタリングを追加することによって取得できます。つまり、各層に対して異なるパラメータ σσ を使用します。ガウスぼかしを実行するには、画像ピラミッドを使用します。ピラミッドの各レイヤーに複数のガウスぼかし画像を含めます。ダウンサンプリングする場合、ピラミッドより上の画像グループの最初の画像は、その下の画像グループの最後から 2 番目の画像をダウンサンプリングすることによって取得されます。

ガウス ピラミッドには複数のグループがあり、各グループには複数の層があります。グループ内の複数のレイヤー間のスケールは異なります (つまり、使用されるガウス パラメーター σ が異なります)。また、2 つの隣接するレイヤー間のスケールは、スケーリング係数 k だけ異なります。各グループに S レイヤーがある場合、k=2^{\frac{1}{S}}前の画像グループの一番下の画像は、次のグループのスケール 2σ の画像を係数 2 でダウンサンプリングすることによって取得されます (最初にガウス ピラミッドが一番下の層から確立されます)。ガウス ピラミッドが構築された後、隣接するガウス ピラミッドを減算することで DoG ピラミッドが得られます。
ガウスピラミッドのグループ数は一般的に次のようになります。

                                              o=\left [ log_{2} min\left ( m,n \right )\right ]-a

o はガウス ピラミッドの層の数を示し、m と n はそれぞれ画像の行と列です。減算される係数 a は0-log_{2}\left ( m,n \right )その間の任意の値にすることができ、特に必要なピラミッドの上部イメージのサイズに関連します。
ガウスぼかしパラメータ\シグマ(スケール空間) は、次の関係によって取得できます。

                                                 \sigma \left ( o,s \right )= \sigma _{0}\cdot 2^{\frac{o+s}{S}}

ここで、o はグループが属するグループ、s はグループが含まれるレイヤー、\シグマ_{0}初期スケール、S は各グループ内のレイヤーの数です。アルゴリズムの実装では\sigma_{0}=1.6o_{分}=-1まず元の画像の長さと幅が 2 倍になります。S=3、ここから同じグループ内の隣接するレイヤーの画像スケール関係を知ることができます。

                                                    \sigma _{s+1}=k\cdot\sigma _{s}=2^{\frac{1}{S}}\cdot \sigma _{s}

隣接するグループ間のスケール関係:

                                                    \シグマ_{0+1}=2\シグマ_{0}

================================================= ===============

3. DoG空間極値検出

スケール空間の極点を見つけるために、各ピクセルがその画像ドメイン (同じスケール空間) およびスケール ドメイン (隣接するスケール空間) 内のすべての隣接点と比較され、ピクセルがすべてのピクセルよりも大きい (または小さい) 場合、対応する点が隣接する場合、変更された点が極値点となります。図に示すように、中央の検出点は、それが位置する画像の 3×3 近傍の 8 ピクセル、および隣接する上下のレイヤーの 3×3 領域の 18 ピクセルと比較する必要があります。合計26ピクセルです。


上記の説明から、画像の各グループの最初と最後のレイヤーを比較して極値を取得することはできないことがわかります。スケール変換の連続性を満たすために、ガウスぼかしを使用して画像の各グループの最上層に 3 つの画像を生成します。ガウス ピラミッドの各グループには S+3 層の画像があり、DoG ピラミッドの各グループには S+ 2グループの画像。

S=3、つまり各グループに 3 層があるとします。つまりk=2^{\frac{1}{S}}=2^{\frac{1}{3}}、各グループには (S-1) 個の 3 層画像を持つガウス ピラミッドと、(S-1) 個の 3 層画像を持つ DoG ピラミッドがあります。各グループの DoG ピラミッドと各グループの画像は (S-2) 2 層あります。DoG ピラミッドの最初のグループにはそれぞれ σ と kσ の 2 層のスケールがあり、2 番目のグループにはそれぞれ 2σ と 2kσ の 2 層のスケールがあります。2 つの項目だけを比較して極値を取得することはできないため (ただし、次の場合のみ)左側と右側に値があります)極値があります)。

極端な値を比較して取得することは不可能であるため、各グループの画像に対してガウスぼかしを実行し続けてスケールを形成し、\シグマ ,k\シグマ ,k^{2}\シグマ ,k^{3}\シグマ ,k^{4}\シグマ中央の 3 つの項目を選択できるようにする必要があります\シグマ,k\シグマ,k^{2}\シグマ,k^{3}\シグマ前のセットのダウンサンプリングから得られた、対応する次の 3 つのアイテムのセットは、2k\シグマ ,2k^{2}\シグマ ,2k^{3}\シグマ最初のアイテムが2k\sigma =2^{\frac{4}{3}}\sigma前のセットの最後のアイテムのスケールとちょうどk^{3}\sigma =2^{\frac{2}{2}}\sigma連続しているものです。

================================================= ===

4. 悪い極値点(特徴点)を削除する

比較により検出されたDoGの極値点は、実際には離散空間内で探索されるが、離散空間は連続空間をサンプリングした結果であるため、離散空間内で見つかった極値点が本当の意味での極値点であるとは限らない。そのため、条件を満たさない点を排除するように努める必要があります。スケール スペース DoG 関数を使用してカーブ フィッティングを実行し、極端な点を見つけることができます。このステップの本質は、DoG の非常に非対称な局所曲率を持つ点を削除することです。

削除要件を満たさないポイントには、主に次の 2 つのタイプがあります。

  • コントラストの低い特徴点
  • 不安定なエッジ応答ポイント

 1. コントラストの低い特徴点を除去する

候補特徴点 x、そのオフセットは として定義され\ワイドティルダ{x}、そのコントラストは H(x)、その絶対値 ∣H(x)∣、H(x) にテイラー展開を適用します。

                                          H\left ( x \right )=H+\frac{\partial H^{T}}{\partial x}x+\frac{1}{2}x^{T}\frac{\partial ^{2}H }{\部分 x^{2}}x

x は H(x) の極値点なので、上式の導関数を 0 に設定すると、次のようになります。

                                          \widetilde{x}=\frac{\partial ^{2}H^{-1}}{\partial H^{2}}\cdot \frac{\partial H}{\partial x} 

 次に、取得した\ワイドティルダ{x}値を H(x) のテイラー展開に代入します。 

                                          H\left ( \widetilde{x} \right )= H+\frac{1}{2}\frac{\partial H^{T}}{\partial x}\widetilde{x}

 コントラストのしきい値を T に設定します。 の場合H\left ( \widetilde{x} \right )>T、特徴点は保持され、それ以外の場合は削除されます。

2. 不安定なエッジ応答点を排除する 

エッジの勾配の方向では、主曲率の値は比較的大きくなりますが、エッジの方向に沿っては、主曲率の値は小さくなります。候補特徴点の DoG 関数 H(x) の主曲率は、 3×3ヘッセ行列 HHの固有値に比例します                                        。

                                                     H=\begin{vmatrix} d_{xx},d_{xy}\\ d_{yy},d_{yx}\\ \end{vmatrix} 

このうち、 はd_{xx}、d_{xy}、d_{yy}候補点近傍の対応位置の差分により求められる。特定の値を見つけることを避けるために、H 特徴量比を使用できます。a=\lambda _{最大}H の最大固有値、 を\beta =\lambda _{分}H の最小固有値としましょう。取得することができます:

                                                 T_{r}\left ( H \right )=d^{xx}+d_{yy}=\alpha +\beta

                                                 Det\left ( H \right )=d_{xx}+d_{yy}-d_{xy}^{2}=\alpha \cdot \beta

その中にはTr\left ( H \right )行列 H の痕跡があり、Det\left ( H \right )行列 H の行列式です。\gamma =\frac{\alpha }{\beta }最大固有値と最小固有値の比を表すとすると、次のようになります

                                      \frac{Tr\left ( H \right )^{2}}{Det\left ( H \right )}=\frac{\left ( \alpha +\beta \right )^{2}}{\alpha \ cdot \beta }=\frac{ \left ( \gamma \beta +\beta \right )^{2}}{\gamma \beta ^{2}}=\frac{\left ( \gamma +1 \right ) ^{2}}{\ガンマ }

上式の結果は 2 つの固有値の比に関係しており、特定のサイズとは関係がありません。2 つの固有値が等しい場合、その値は最小となり、γγ の増加とともに増加します。したがって、主曲率が特定のしきい値を下回っているかどうかを検出するにはT\ガンマ、以下を検出するだけで済みます。

                                                        \frac{Tr\left ( H \right )^{2}}{Det\left ( H \right )}> \frac{\left ( T\gamma +1 \right )^{2}}{T\gamma }

上の式が真の場合は特徴点を削除し、そうでない場合は特徴点を保持します。

================================================= =======================

5. 特徴点の主な方向を見つける

上記の手順を経て、異なるスケールに存在する特徴点が見つかりましたが、画像の回転不変性を実現するには、特徴点の方向を割り当てる必要があります。特徴点の近傍ピクセルの勾配分布特性を使用して方向パラメータを決定し、画像の勾配ヒストグラムを使用してキーポイントの局所構造の安定した方向を取得します。特徴点が見つかると、その特徴点のスケールが得られ\シグマ、特徴点が位置するスケール画像も得られます。

\シグマ特徴点を中心とし半径3×1.5の領域画像の引数と振幅を計算しますノイズの干渉を避けるため、円形領域内の全点の勾配の大きさと方向を計算した後、極点を 中心

                                     m^{'}\left ( x,y \right )= m\left ( x,y \right )\cdot W\left ( x,y \right )

                                     W\left ( x,y \right )=\frac{w\left ( x,y \right )}{\sum w\left ( x,y \right )}

                                      w\left ( x,y \right )=e^{\frac{d^{2}}{2\cdot \left ( 1.5\sigma \right )^{2}}} 

各点L\左 ( x,y \右 )における勾配の係数m\left ( x,y \right )と方向は\theta \left ( x,y \right )、次の式で取得できます。

勾配の方向を計算した後、ヒストグラムを使用して、特徴点の近傍のピクセルに対応する勾配の方向と大きさをカウントする必要があります。勾配方向のヒストグラムの横軸は勾配方向の角度です (勾配方向の範囲は 0 ~ 360 度で、ヒストグラムは 36 度ごとに合計 10 列、または 36 度ごとに合計 8 列あります) 45 度)、縦軸は勾配方向に対応する勾配割り当ての累積です。

より正確な方向を取得するために、通常は、離散勾配ヒストグラムを補間して適合させることができます。具体的には、キーポイントの方向は、メインピークに最も近い 3 つのバー値から放物線補間によって取得できます。勾配ヒストグラムにおいて、メインピークのエネルギーの80%に相当する列値がある場合、その方向が特徴点の補助方向とみなせ、1つの特徴量で複数の方向を検出できる。

特徴点の主な方向を取得した後、各特徴点について 3 つの情報\left ( x,y,\sigma ,\theta \right )、つまり位置、スケール、方向を取得できます。これから、SIFT 特徴領域を決定できます。SIFT 特徴領域は 3 つの値で表され、中心は特徴点の位置を表し、半径はキーポイントのスケールを表し、矢印は主方向を表します。複数の方向を持つキーポイントを複数のコピーにコピーし、コピーされた特徴点にそれぞれ方向値を割り当てることができ、1 つの特徴点から、同じ座標、同じスケールで異なる方向を持つ複数の特徴点が生成されます。

================================================= ======================= 

6. 機能説明の生成

上記の手順により、SIFT 特徴点の位置、スケール、方向情報が見つかりました。次に、キーポイントを記述するためにベクトルのセットが必要になり、特徴点記述子が生成されます。この記述子には、特徴点だけでなく、特徴点の周囲のオブジェクトやその寄与ピクセルも含まれます。一致率を確保するには、記述子に高い独立性が必要です
特徴記述子の生成には、大まかに 3 つのステップがあります。

  1. 回転の主方向を修正し、回転の不変性を確保します。
  2. 記述子を生成し、最終的に 128 次元の特徴ベクトルを形成します
  3. 正規化処理では、特徴ベクトルの長さを正規化し、照明の影響をさらに除去します。

特徴ベクトルの回転不変性を確保するには、特徴点を中心としてその近傍で座標軸をθθ(特徴点の主方向)だけ回転させる、つまり座標を回転させる必要があります。軸を特徴点の主方向に合わせます。回転後の近傍のピクセルの新しい座標は次のとおりです。

                                                \begin{vmatrix} x^{'}\\ y^{'}\\ \end{vmatrix}=\begin{bmatrix} cos\theta ,-sin\theta \\ sin\theta ,-cos\theta \\ \end{bmatrix}\begin{vmatrix} x\\ y\\ \end{vmatrix}

回転後、主方向を中心として 8×8 のウィンドウが取得されます。以下の図に示すように、左の図の中心は現在のキー ポイントの位置であり、各セルはキー ポイント近傍が位置するスケール空間内のピクセルを表し、各ピクセルの勾配の大きさと勾配の方向は次のようになります。矢印の方向はピクセルの勾配方向を表し、長さは勾配の大きさを表し、ガウス ウィンドウによって重み付けされます。最後に、右図に示すように、4×4の小ブロックごとに8方向の勾配ヒストグラムを描画し、各勾配方向の累積値を計算してシード点を作成します。各特徴点は 4 つのシード点から構成され、各シード点は 8 方向のベクトル情報を持ちます。この近傍方向情報の組み合わせにより、アルゴリズムの耐ノイズ能力が強化され、同時に、位置決めエラーとの特徴マッチングに対するより合理的なフォールト トレランスが提供されます。

主方向を求める場合とは異なり、各シード領域の勾配ヒストグラムは 0 ~ 360 の 8 方向区間に分割され、各区間は 45 度です。つまり、各シード ポイントは 8 方向の勾配強度情報を持ちます。4×4 の合計 16 個のシード ポイントを使用して各キー ポイントを記述するため、キー ポイントは 128 次元の SIFT 特徴ベクトルを生成できます。

================================================= =======================

コード:

#include"stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include "math.h"

#include <opencv2/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
using namespace std;
//using namespace cv::features2d;

int main(int argc, char** argv) {
	Mat src = imread("F:/photo/i.jpg", IMREAD_GRAYSCALE);
	if (src.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", WINDOW_AUTOSIZE);
	imshow("input image", src);

	int numFeatures = 400;
	Ptr<SIFT> detector = SIFT::create(numFeatures);
	vector<KeyPoint> keypoints;
	detector->detect(src, keypoints, Mat());
	printf("Total KeyPoints : %d\n", keypoints.size());

	Mat keypoint_img;
	drawKeypoints(src, keypoints, keypoint_img, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
	namedWindow("SIFT KeyPoints", WINDOW_AUTOSIZE);
	imshow("SIFT KeyPoints", keypoint_img);

	waitKey(0);
	return 0;
}

効果の実現:

おすすめ

転載: blog.csdn.net/weixin_44651073/article/details/127978307