#java #opencv #feature-detection #orb
#java #opencv #обнаружение функций #orb
Вопрос:
Я использую детектор объектов ORB для поиска совпадений между двумя изображениями, используя этот код:
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);;
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
// First photo
Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGB2GRAY);
Mat descriptors1 = new Mat();
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
descriptor.compute(img1, keypoints1, descriptors1);
// Second photo
Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGB2GRAY);
Mat descriptors2 = new Mat();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector.detect(img2, keypoints2);
descriptor.compute(img2, keypoints2, descriptors2);
// Matching
MatOfDMatch matches = new MatOfDMatch();
MatOfDMatch filteredMatches = new MatOfDMatch();
matcher.match(descriptors1, descriptors2, matches);
// Linking
Scalar RED = new Scalar(255,0,0);
Scalar GREEN = new Scalar(0,255,0);
List<DMatch> matchesList = matches.toList();
Double max_dist = 0.0;
Double min_dist = 100.0;
for(int i = 0;i < matchesList.size(); i ){
Double dist = (double) matchesList.get(i).distance;
if (dist < min_dist)
min_dist = dist;
if ( dist > max_dist)
max_dist = dist;
}
LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
for(int i = 0;i < matchesList.size(); i ){
if (matchesList.get(i).distance <= (1.5 * min_dist))
good_matches.addLast(matchesList.get(i));
}
// Printing
MatOfDMatch goodMatches = new MatOfDMatch();
goodMatches.fromList(good_matches);
System.out.println(matches.size() " " goodMatches.size());
Mat outputImg = new Mat();
MatOfByte drawnMatches = new MatOfByte();
Features2d.drawMatches(img1, keypoints1, img2, keypoints2, goodMatches, outputImg, GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);
Highgui.imwrite("matches.png", outputImg);
Моя проблема в том, что я не могу найти способ фильтровать совпадения так, чтобы они совпадали только тогда, когда у них похожие позиции на фотографиях. Я всегда получаю несколько совпадений для одной ключевой точки, даже если они находятся очень далеко по местоположению.
Есть ли способ отфильтровать их лучше?
Ответ №1:
Чтобы получить лучшие результаты сопоставления, вы должны включить эти методы фильтрации в заданном порядке.
-
Выполните сопоставление в двух направлениях, т. е. для каждой точки на первом изображении найдите наилучшее соответствие на втором изображении и наоборот.
-
Выполните тест соотношения (ratio test евклидовых расстояний) между совпадениями, чтобы исключить неоднозначные совпадения.
- Выполните проверку RANSAC: это алгоритм подбора модели, который находит наилучшие данные, которые соответствуют модели, и удаляет выбросы.
- Выполните гомографию: это алгоритм проецирования изображения.
Вы можете получить все подробности описанных выше методов в главе 9 «Кулинарная книга по программированию приложений Computer vision». В нем также есть пример кода для реализации этих методов фильтрации. Это очень легко понять. (Примечание: Код в этой книге написан на C , но как только вы поймете, его можно легко реализовать и на JAVA)
Ответ №2:
После прочтения книги Роберта Ланганьера. Я пришел к выводу, что есть способ. Это делается для удаления совпадений с дальнейшими расстояниями. В Java это выглядит следующим образом
Collections.sort(bestMatches,new Comparator<DMatch>() {
@Override
public int compare(DMatch o1, DMatch o2) {
if(o1.distance<o2.distance)
return -1;
if(o1.distance>o2.distance)
return 1;
return 0;
}
});
if(bestMatches.size()>3){
bestMatches = bestMatches.subList(0,3);
}
Комментарии:
1. Привет, спасибо за ответ, я также использую этот способ, после получения необработанных совпадений из метода .match (.., .., ..) я сортирую их по возрастанию и просто выбираю 10 лучших, 30 или что мне подходит. мой вопрос в том, может ли сортировка совпадений, возвращенных методом .match (.., .., …) в порядке возрастания, быть заменой порогового значения? потому что, как я видел во многих примерах, когда используется пороговое значение, кажется, что это еще один способ получить наилучшие соответствия, и использование опубликованного вами алгоритма сортировки может быть заменой .. пожалуйста, посоветуйте.
2. Я думаю, что это больше подходит для добавления в качестве дополнения к пороговому значению, которое отфильтровывает лучшие совпадения из хороших совпадений.
3. но поскольку у меня расстояния отсортированы по возрастанию, это означает, что первые 10 или 15 будут иметь меньшие расстояния среди остальных, что означает, что я выбираю хорошие .. пожалуйста, посоветуйте
4. В своей книге он не использовал пороговое значение. Но для деталей мне также нужно узнать больше, поскольку я сам все еще не очень хорошо понимаю раздел «Как это работает» этого решения. Я хотел бы быть вашей помощью, когда я знаю лучше.
Ответ №3:
Сопоставление выполняется путем определения кратчайшего расстояния Хэмминга между двумя дескрипторами. Таким образом, вы всегда будете получать соответствие между обнаруженными функциями.
Вам следует изменить пороговое значение вашего детектора СФЕР. Таким образом, вы уменьшите вероятность обнаружения объектов на фоне (т. Е. шума), поэтому большинство обнаруженных вами объектов будут исходить от интересующего вас объекта.