SIFT(Scale-Invariant Feature Transform)の概要
SIFT(スケール不変特徴変換)は、画像の中から回転やスケーリング、照明の変化に対して頑健な局所特徴量を抽出するためのアルゴリズムです。1999年にDavid Loweによって提唱され、物体認識や画像のパノラマ合成、3D再構成など、コンピュータビジョンの幅広い分野でデファクトスタンダードの一つとして利用されてきました。
アルゴリズムの主要なプロセス
SIFTは主に以下の4つのステップを経て特徴量を抽出します。
- スケール空間の極値検出: ガウス関数の差分(DoG: Difference of Gaussian)を用いて、異なるスケール(解像度)の画像群から特徴的な点を探索します。これにより、サイズが変化しても検知可能なポイントを特定します。
- キーポイントの特定: 検出された候補点の中から、コントラストが低い点やエッジ上の不安定な点を除去し、精度の高いキーポイント(特徴点)を選別します。
- オリエンテーション(方向)の割り当て: キーポイント周辺の勾配方向に基づいて、各点に主方向を割り当てます。これにより、画像が回転していても同一の特徴として認識できる「回転不変性」を確保します。
- キーポイント記述子の生成: キーポイント周辺の領域を記述子(通常128次元のベクトル)として数値化します。この際、周囲の勾配情報を利用することで、照明の変化や視点のわずかなズレに対しても強い耐性を持たせます。
SIFTの主な特性
- 局所性: 特徴が局所的な領域に基づいているため、画像の一部が隠れている(オクルージョン)場合や、背景にノイズが多い環境でも機能します。
- 不変性: スケールの拡大縮小、回転に対して高い不変性を持ち、アフィン変換に対してもある程度の耐性があります。
- 独特性: 記述子の識別能力が高く、大規模なデータベースの中から特定の物体を高い精度で照合することが可能です。
- 多量性: 比較的小さな物体からも多数の特徴点が得られるため、情報の密度が高いマッチングが可能です。
PythonとOpenCVによる実装例
OpenCVを利用することで、SIFTによる特徴点抽出と記述子の計算を簡潔に実装できます。以下のコードは、画像から特徴点を検出し、可視化する例です。
import cv2
import numpy as np
# 画像の読み込み(グレースケール変換)
source_img = cv2.imread('input_image.jpg')
gray_scale = cv2.cvtColor(source_img, cv2.COLOR_BGR2GRAY)
# SIFT検出器の初期化
sift_detector = cv2.SIFT_create()
# キーポイントの検出と記述子の計算
keypoints, feature_descriptors = sift_detector.detectAndCompute(gray_scale, None)
# 特徴点を画像上に描画(リッチな描画オプションを使用)
output_canvas = cv2.drawKeypoints(
source_img,
keypoints,
None,
flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
)
# 結果の表示
cv2.imshow('SIFT Feature Extraction', output_canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()
また、2つの画像間で特徴をマッチングさせる場合は、BFMatcher(Brute-Force Matcher)やFlannBasedMatcherを使用します。
# 2つの記述子間でマッチングを実行
matcher = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)
matches = matcher.match(descriptors1, descriptors2)
# 距離(類似度)に基づいてソート
matches = sorted(matches, key=lambda x: x.distance)
# 上位の結果を描画
match_result = cv2.drawMatches(img1, kp1, img2, kp2, matches[:30], None, flags=2)
C#環境における利用
.NET環境でSIFTを利用する場合、OpenCVのラッパーライブラリであるOpenCvSharpやEmgu CVを利用するのが一般的です。かつてSIFTは特許(米国特許第6,711,293号)により商用利用に制限がありましたが、2020年に特許が満了したため、現在は最新のライブラリ標準版で自由に利用できるようになっています。
C#での基本的な実装フローは以下の通りです:
- NuGetパッケージマネージャーから
OpenCvSharp4をインストールします。 SIFT.Create()メソッドを使用してインスタンスを作成します。DetectAndComputeメソッドを呼び出し、KeyPoint配列とMat型の記述子を取得します。
代替アルゴリズムとの比較
SIFTは非常に高精度ですが、計算コストが比較的高いという側面があります。リアルタイム性が極めて重要なアプリケーション(モバイルデバイスなど)では、以下の代替アルゴリズムが検討されることがあります:
- SURF (Speeded-Up Robust Features): SIFTを高速化した手法。
- ORB (Oriented FAST and Rotated BRIEF): 計算量が非常に少なく、特許フリーの代替として広く普及。
- AKAZE: 非線形スケール空間を利用し、より境界の保存に優れた手法。