我正在使用 Surf 进行地标识别。这是我想的过程:
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;
..