ランドマーク認識に Surf を使用しています。これは私が考えたプロセスです:
1) ランドマークごとに 1 つの Surf Descriptor を事前に保存する
2) ユーザーがランドマーク (建物など) の写真を撮る
3) この画像 (写真) に対して Surf Descriptor が計算されます。
4) この記述子は、格納されている各ランドマーク記述子と比較され、11 個の最も近い特徴点間の DMatch.distance が最も小さい記述子が、認識されたランドマークとして選択されます。
5) 取得した画像と保存されているランドマーク画像の間の回転と縮尺比を計算したい。
機能記述子はキーポイントの一意の縮小表現にすぎないため、キーポイントを介してのみこの回転とスケール比を取得できると理解しています。そのため、ランドマークごとにキーポイントと機能記述子の両方を保存する必要があります。そうですか?
これは私が今していることです:
cv::SurfFeatureDetector surf(4000);
..
surf.detect(image1, keypoints1);
surf.detect(image2, keypoints2);
..
cv::SurfDescriptorExtractor surfDesc;
surfDesc.compute(image1, keypoints1, descriptor1);
surfDesc.compute(image2, keypoints2, descriptor2);
..
vector<cv::DMatch> descriptorsMatch;
BruteForceMatcher<cv::L2<float> > brute;
brute.match(desc1, desc2, descriptorsMatch);
//Use only the 11 best matched keypoints;
nth_element( descriptorsMatch.begin(), descriptorsMatch.begin()+10, descriptorsMatch.end() );
descriptorsMatch.erase( descriptorsMatch.begin()+11, descriptorsMatch.end() );
..
for ( .. it = descriptorsMatch.begin(); it != descriptorsMatch.end() .. )
{
distanceAcumulator +=it->distance;
angleAcumulator += abs(keypoints1[it->queryIdx].angle - keypoints2[it->trainIdx].angle) % 180 ;
scaleAcumulator1 +=keypoints1[it->queryIdx].size;
scaleAcumulator2 +=keypoints2[it->trainIdx].size;
}
angleBetweenImages = angleAcumulator/11;
scaleBetweenImages = scaleAcumulator1/scaleAcumulator2;
similarityBetweenImages = distanceAcumulator/11;
..