Устранение ложных срабатываний в дескрипторах функций
Учитывая две карты сетки занятости, преобразованные в шкалу серого cv::Mat, я использовал дескриптор объектов ORB и сопоставил извлеченные объекты из обоих изображений. Большинство из них ложные срабатывания. Здесь ниже я показал только одно отношение, чтобы показать, что это действительно ложный положительный результат.
В конечном итоге, я хочу найти правильное преобразование между двумя картами сетки заполнения, чтобы объединить их карты в одну глобально согласованную карту. Текущий код, который у меня есть, показан ниже:
// Load the two maps
nav_msgs::OccupancyGrid map1;
initOccupancyGridMap1(map1);
nav_msgs::OccupancyGrid map2;
initOccupancyGridMap2(map2);
// Convert the two maps to grayscale images
cv::Mat im1 = cvtMapToMat(map1);
cv::Mat im2 = cvtMapToMat(map2);
// Feature Descriptor Extraction
cv::OrbFeatureDetector featureDetector;
cv::OrbDescriptorExtractor featureExtractor;
std::vector<cv::KeyPoint> kp1;
std::vector<cv::KeyPoint> kp2;
cv::Mat d1;
cv::Mat d2;
std::vector<cv::DMatch> matches;
cv::BFMatcher dematc(cv::NORM_HAMMING, false);
// 1. Detect keypoints
featureDetector.detect(im1, kp1);
featureDetector.detect(im2, kp2);
// 2. Extract descriptors
featureExtractor.compute(im1, kp1, d1);
featureExtractor.compute(im2, kp2, d2);
// 3. Match keypoints
dematc.match(d1, d2, matches);
for (int i = 0; i < matches.size(); i++){
std::vector<cv::DMatch> match(1,matches[i]);
std::cout << "Distance: " << match[0].distance << std::endl;
cv::Mat img_show;
drawMatches(im1, kp1, im2, kp2, match, img_show);
imshow("Matches", img_show);
cv::waitKey(0);
}
1 ответ
Чтобы убрать точки, которые очень похожи, я использовал второго ближайшего соседа. Если точка совпадает с одной точкой, которая почти равна другой, вы не можете быть уверены, что совпадение правильное.
Например, если ваша точка A совпадает с точками B и C, вы можете считать B хорошим совпадением, если они отличаются не менее чем на 25% (это различие - то, что я выбрал, но вы можете попробовать с другими числами).,
Код выглядит так:
// 2. Extract descriptors
featureExtractor.compute(im1, kp1, d1);
featureExtractor.compute(im2, kp2, d2);
// 3. Match keypoints
std::vector<cv::DMatch> goodMatches;
// Instead match only one point, try to match with 2.
matcher.knnMatch( d1, d2, matches, 2 );
for(int i = 0; i< matches.size(); i++){ // matches from matcher
//with this condition we check that the points are at least 25% diferent.
if(matches[i].at(0).distance< 0.75*matches[i].at(1).distance){
goodMatches.push_back(matches[i].at(0));
}
}