Ответ 1
Решение на самом деле довольно тривиально. Поскольку мы знаем, что каждая строка в нашей маске дает информацию, если у нас есть более высокий или более высокий уровень. Однако у нас есть 2 набора точек в качестве входных данных, так как точно строка, содержащая одно значение, представляет две точки? Природа такого рода индексирования появилась в моем сознании, думая, как на самом деле эти два набора точек появляются в findHomography() (в моем случае я вычислял гомографию между двумя изображениями). Оба набора имеют равное количество точек в них из-за простого факта, что они извлекаются из совпадений между нашими парами изображений. Это означает, что строка в нашей маске является фактическим индексом точек в двух наборах, а также индексом в векторе совпадений для двух изображений. Я успешно сумел вручную ссылаться на небольшое подмножество совпадающих точек на основе этого, и результаты ожидаются. Важно, чтобы вы не изменяли порядок ваших совпадений и 2D-очки, которые вы извлекли из них, используя ключевые точки, указанные в каждом cv::DMatch
. Ниже вы можете увидеть простой пример для одной пары индексов.
for(int i = 0; i < matchesObjectScene.size(); ++i)
{
// extract points from keypoints based on matches
pointsObject.push_back(keypointsObject.at(matchesObjectScene.at(i).queryIdx).pt);
pointsScene.push_back(keypointsScene.at(matchesObjectScene.at(i).trainIdx).pt);
}
// compute homography using RANSAC
cv::Mat mask;
cv::Mat H = cv::findHomography(pointsObject, pointsScene, CV_RANSAC, ransacThreshold, mask);
В приведенном выше примере, если мы напечатаем несколько более сложных
int maskRow = 10;
std::cout << "POINTS: object(" << pointsObject.at(maskRow).x << "," << pointsObject.at(maskRow).y << ") - scene(" << pointsScene.at(maskRow).x << "," << pointsScene.at(maskRow).y << ")" << std::endl;
а затем снова, но на этот раз используя наши ключевые точки (также можно сделать с извлеченными 2D-точками)
std::cout << "POINTS (via match-set): object(" << keypointsObject.at(matchesCurrentObject.at(maskRow).queryIdx).pt.x << "," << keypointsObject.at(matchesCurrentObject.at(maskRow).queryIdx).pt.y << ") - scene(" << keypointsScene.at(matchesCurrentObject.at(maskRow).trainIdx).pt.x << "," << keypointsScene.at(matchesCurrentObject.at(maskRow).trainIdx).pt.y << ")" << std::endl;
мы получаем тот же результат:
POINTS: object(462,199) - sscene(485,49)
POINTS (via match-set): object(462,199) - scene(485,49)
Чтобы получить фактическое значение, мы просто должны проверить, действительно ли текущая строка в маске содержит 0 или ненулевое значение:
if((unsigned int)mask.at<uchar>(maskRow))
// store match or keypoints or points somewhere where you can access them later