Фруктовый 0 Report post Posted May 24, 2016 Добрый день, Пробую реализовать указанный здесь метод на Java. Столкнулся с тем, что при инициализации дескриптора типа FREAK выдает ошибку об ошибочном параметре функции create(). Посмотрел в исходники features2d_manual.hpp оказалось что там данный метод закоменчен и не реализован. Вопрос, что делать? можно заменить его на ORB и получить такой же результат? что тогда надо делать при матчинге? или действия такие же? Share this post Link to post Share on other sites
Фруктовый 0 Report post Posted May 25, 2016 Получился вот такой результат. Почему объект не обводится прямоугольником? что может идти не так при локализации объекта? полностью повторил код из этого туториала с детектором FAST, дескриптором ORB, матчером BRUTEFORCE_HAMMING Код локализации на Java: //-- Localize the object Point obj_point[] = new Point[good_matches.size()]; Point scene_point[] = new Point[good_matches.size()]; List<KeyPoint> keypoints_object = keypointsImageTemple.toList(); List<KeyPoint> keypoints_scene = keypointsImage.toList(); for( int i = 0; i < good_matches.size(); i++ ) { //-- Get the keypoints from the good matches obj_point[i]=keypoints_object.get(good_matches.get(i).queryIdx).pt; scene_point[i]=keypoints_scene.get(good_matches.get(i).trainIdx).pt; } MatOfPoint2f obj = new MatOfPoint2f(obj_point); MatOfPoint2f scene = new MatOfPoint2f(scene_point); Mat H = Calib3d.findHomography( obj, scene, RANSAC,1); //-- Get the corners from the image_1 ( the object to be "detected" ) Point obj_corners[]= new Point[4]; obj_corners[0] = new Point(0,0); obj_corners[1] = new Point(ImageTemple.cols(), 0 ); obj_corners[2] = new Point(ImageTemple.cols(), ImageTemple.rows()); obj_corners[3] = new Point(0, ImageTemple.rows()); MatOfPoint2f obj_corners_m = new MatOfPoint2f(obj_corners); MatOfPoint2f scene_corners_m = new MatOfPoint2f(); Core.perspectiveTransform(obj_corners_m,scene_corners_m, H); Share this post Link to post Share on other sites
Smorodov 578 Report post Posted May 25, 2016 Ну, очевидно Вы просто не рисуете прямоугольник. Share this post Link to post Share on other sites
Фруктовый 0 Report post Posted May 25, 2016 Рисую, вон получается маленькая зеленая форма "песочных часов" почему то точки в scene_corners_m после Core.perspectiveTransform(obj_corners_m,scene_corners_m, H); определяются близко к друг другу. может у меня Calib3d.findHomography( obj, scene, RANSAC,1); неправильно выдает результат? Share this post Link to post Share on other sites
Фруктовый 0 Report post Posted May 25, 2016 Попробовал заменить Core.perspectiveTransform на ручной способ указанный тут // Находим трансформацию между исходным изображением и с тем, которое // ищем if( !cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 )) return 0; // По полученному значению трансформации (в матрицу _h) находим // координаты четырёхугольника, характеризующего объект for( i = 0; i < 4; i++ ) { double x = src_corners[i].x, y = src_corners[i].y; double Z = 1./(h[6]*x + h[7]*y + h[8]); double X = (h[0]*x + h[1]*y + h[2])*Z; double Y = (h[3]*x + h[4]*y + h[5])*Z; dst_corners[i] = cvPoint(cvRound(X), cvRound(Y)); } получились дурацкие координаты опять же, грешу на findHomography как проверить адекватность получаемого этой функцией результата? Share this post Link to post Share on other sites
Smorodov 578 Report post Posted May 25, 2016 Въезжать сейчас особо некогда, но проверьте, не нужно ли обратить матрицу гомографии. Share this post Link to post Share on other sites
Фруктовый 0 Report post Posted May 26, 2016 Обращение результатов в нужную сторону не дало. Вот лучшее чего добился при снижении количества сравниваемых пар и повышение порога RANSAC до 10. При увеличении количества пар, итоговые точки контура сбиваются в одну точку. Как это можно объяснить? Судя по тому как сравнены особенности, дело видимо в матчере. В документации на 3.1. я не нашел как его настраивать. Share this post Link to post Share on other sites
Фруктовый 0 Report post Posted May 26, 2016 Вообщем, видимо я что-то не так делаю при создании детекторов. Вот код объявления: // Инициалищация класса детектора особенностей FeatureDetector detector = FeatureDetector.create(FAST); //Инициалищация класса десриптора особенностей DescriptorExtractor extractor = DescriptorExtractor.create(ORB); //Инициалищация класса матчера особенностей DescriptorMatcher matcher = DescriptorMatcher.create(BRUTEFORCE_HAMMING); Вот результат срабатывания: Цитата keypointsImageTemple= 1x2670 keypointsImage= 1x1977 descriptorsImageTemple= 32x2226 descriptorsImage= 32x1939 matches= 1x2226 На объекте детектируется больше точек чем на сцене, и если я правильно понимаю сопоставление пар происходит не однозначно. Как быть? Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted May 26, 2016 Для начала использовать более надёжные точки и дескрипторы. Например, SURF или AKAZE. Share this post Link to post Share on other sites
BeS 53 Report post Posted May 27, 2016 У вас точки матчатся как попало. Попробуйте сначала SIFT детектор/дескриптор и поматчить по L2. Share this post Link to post Share on other sites
Фруктовый 0 Report post Posted May 30, 2016 Решение проблемы: Перед вызовом match() надо дергать метод train() Итого работа матчера на Java: //Инициалищация класса матчера особенностей DescriptorMatcher matcher = DescriptorMatcher.create(BRUTEFORCE_HAMMING); //сравнение особенностей matcher.train(); matcher.match(descriptorsImageTemple, descriptorsImage, matches); При этом более приемлемый "боевой" результат получился на версии OpenCV.2.4.13 чем на OpenCV.3.1. в виду большей поддержки типов детекторов\дескрипторов. Удалось подобрать сочетание с лучшей производительностью. Всем спасибо! Share this post Link to post Share on other sites