Вручную выполнить парное сопоставление в OpenCV из ключевых точек функций - PullRequest
8 голосов
/ 15 марта 2012

Вот моя проблема.Я вручную извлек ключевые функции SURF на нескольких изображениях.Но я также уже знаю, какая пара очков будет соответствовать.Дело в том, что я пытаюсь создать свои подходящие пары, но я не понимаю как.Я попытался, посмотрев на код, но это беспорядок.

Прямо сейчас я знаю, что размер матрицы functions.descriptors такой же, как и количество ключевых точек (другое измерение1).В коде для обнаружения совпадающих пар используются только дескрипторы, поэтому он сравнивает строки (или столбцы, я не уверен) или матрицу из двух дескрипторов и определяет, есть ли что-то общее.

Но в моемВ этом случае я уже знаю, что есть совпадение между ключевой точкой i из изображения 1 и ключевой точкой j из изображения 2. Как я могу описать это как значение MatchesInfo.В частности, совпадения элементов типа std :: vector .

РЕДАКТИРОВАТЬ: Итак, для этого мне не нужно использовать какие-либо совпадения или что-то вроде этого.Я знаю, какие пары собираются вместе!

1 Ответ

6 голосов
/ 10 апреля 2012

Если я правильно понял ваш вопрос, я предполагаю, что вы хотите, чтобы ключевые точки совпадали в std::vector<cv::DMatch> с целью их рисования с помощью OpenCV cv::drawMatches или использования с какой-либо аналогичной функцией OpenCV. Поскольку я также недавно делал сопоставление «вручную», вот мой код, который рисует произвольные совпадения, изначально содержащиеся в std::vector<std::pair <int, int> > aMatches, и отображает их в окне:

const cv::Mat& pic1 = img_1_var;
const cv::Mat& pic2 = img_2_var;
const std::vector <cv::KeyPoint> &feats1 = img_1_feats;
const std::vector <cv::KeyPoint> &feats2 = img_2_feats;
    // you of course can work directly with original objects
    // but for drawing you only need const references to
    // images & their corresponding extracted feats

std::vector <std::pair <int, int> > aMatches;
    // fill aMatches manually - one entry is a pair consisting of
    //      (index_in_img_1_feats, index_in_img_2_feats)


// the next code draws the matches:
std::vector <cv::DMatch> matches;
matches.reserve((int)aMatches.size());

for (int i=0; i < (int)aMatches.size(); ++i)
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                      std::numeric_limits<float>::max()));

cv::Mat output;

cv::drawMatches(pic1, feats1, pic2, feats2, matches, output);

cv::namedWindow("Match", 0);
cv::setWindowProperty("Match", CV_WINDOW_FULLSCREEN, 1);
cv::imshow("Match", output);    
cv::waitKey();
cv::destroyWindow("Match");

В качестве альтернативы, если вам нужна более полная информация о совпадениях для целей, более сложных, чем рисование, вы можете также установить правильное значение расстояния между совпадениями. Например. если вы хотите рассчитать расстояния с использованием расстояния L2 , вам следует заменить следующую строку:

for (int i=0; i < (int)aMatches.size(); ++i)
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                      std::numeric_limits<float>::max()));

с этим (заметьте, для этого также необходима ссылка на векторы дескрипторов объектов):

cv::L2<float> cmp;

const std::vector <std::vector <float> > &desc1 = img_1_feats_descriptors;
const std::vector <std::vector <float> > &desc2 = img_2_feats_descriptors;

for (int i=0; i < (int)aMatches.size(); ++i){
    float *firstFeat = &desc1[aMatches[i].first];
    float *secondFeat = &desc2[aMatches[i].second];
    float distance = cmp(firstFeat, secondFeat, firstFeat->size());
    matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                      distance));
}

Обратите внимание, что в последнем фрагменте descX[i] является дескриптором для featsX[i], причем каждый элемент внутреннего вектора является одним компонентом вектора дескриптора. Также обратите внимание, что все векторы дескрипторов должны иметь одинаковую размерность.

...