Khludenkov
Пользователи-
Количество публикаций
79 -
Зарегистрирован
-
Посещение
-
Days Won
1
Все публикации пользователя Khludenkov
-
Здравствуйте. Продолжаю вникать в OpenCV. Скажите, есть ли смысл применять OpenMP? Приведёт ли это к ускорению работы? Должны ли библиотеки *.lib быть перекомпилированы отдельно для поддержки ОpenMP как например для Cuda?
-
Спасибо. А либы надо будет пересобирать? Если для с++?
-
Сделал программу получения видео в камеры и поиска на видео заданного объекта. По образцу с оф. сайта openCV. int main( int argc, char** argv ) { VideoCapture cap(1); // Открыть камеру (устройство 1). Для открытия встроенной камеры вызывать 0 устройство. if(!cap.isOpened()) // Проверка корректности отработки { string message = "Проверьте камеру или укажите другой номер устройства в коде"; // readme(message); return -1; } //Mat img_object = imread("D:\\005.jpg", CV_LOAD_IMAGE_GRAYSCALE); Mat img_object = imread("D:\\feat\\iiL2.jpg", CV_LOAD_IMAGE_GRAYSCALE ); for(;; ) { Mat frame; cap >> frame; // Получить очередной фрейм из камеры Mat img_scene = frame; // Mat img_scene = imread("D:\\feat\\iiR.jpg", CV_LOAD_IMAGE_GRAYSCALE ); // Mat img_object = imread("D:\\stereoImg\\iL.jpg", CV_LOAD_IMAGE_GRAYSCALE ); // Mat img_scene = imread("D:\\stereoImg\\iR.jpg", CV_LOAD_IMAGE_GRAYSCALE ); if( !img_object.data || !img_scene.data ) { std::cout<< " --(!) Error reading images " << std::endl; return -1; } // Detect the keypoints using SURF Detector int minHessian = 400; SurfFeatureDetector detector( minHessian ); std::vector<KeyPoint> keypoints_object, keypoints_scene; detector.detect( img_object, keypoints_object ); detector.detect( img_scene, keypoints_scene ); //-- Step 2: Calculate descriptors (feature vectors) SurfDescriptorExtractor extractor; Mat descriptors_object, descriptors_scene; extractor.compute( img_object, keypoints_object, descriptors_object ); extractor.compute( img_scene, keypoints_scene, descriptors_scene ); //-- Step 3: Matching descriptor vectors using FLANN matcher FlannBasedMatcher matcher; std::vector< DMatch > matches; matcher.match( descriptors_object, descriptors_scene, matches ); double max_dist = 0; double min_dist = 100; // Quick calculation of max and min distances between keypoints for( int i = 0; i < descriptors_object.rows; i++ ) { double dist = matches[i].distance; if( dist < min_dist ) min_dist = dist; if( dist > max_dist ) max_dist = dist; } printf("-- Max dist : %f \n", max_dist ); printf("-- Min dist : %f \n", min_dist ); //-- Draw only "good" matches (i.e. whose distance is less than 3 * min_dist ) std::vector< DMatch > good_matches; for( int i = 0; i < descriptors_object.rows; i++ ) { if( matches[i].distance < 3 * min_dist ) { good_matches.push_back( matches[i]); } } Mat img_matches; drawMatches( img_object, keypoints_object, img_scene, keypoints_scene, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); //-- Localize the object std::vector<Point2f> obj; std::vector<Point2f> scene; for(int i = 0; i < good_matches.size(); i++) { // Get the keypoints from the good matches // if( (keypoints_object[good_matches[i].queryIdx].pt.x - keypoints_object[good_matches[i].queryIdx].pt.x) > 0) { obj.push_back( keypoints_object[good_matches[i].queryIdx].pt ); scene.push_back( keypoints_scene[good_matches[i].trainIdx].pt ); /* printf("p1.x = %f\tp2.x = %f\tdx = %f\r\n", keypoints_object[good_matches[i].queryIdx].pt.x, keypoints_scene[ good_matches[i].trainIdx ].pt.x, keypoints_object[good_matches[i].queryIdx].pt.x - keypoints_scene[ good_matches[i].trainIdx ].pt.x); */ } } Mat H = findHomography( obj, scene, CV_RANSAC ); //-- Get the corners from the image_1 ( the object to be "detected" ) std::vector<Point2f> obj_corners(4); obj_corners[0] = cvPoint(0,0); obj_corners[1] = cvPoint( img_object.cols, 0 ); obj_corners[2] = cvPoint( img_object.cols, img_object.rows ); obj_corners[3] = cvPoint( 0, img_object.rows ); std::vector<Point2f> scene_corners(4); perspectiveTransform( obj_corners, scene_corners, H); //-- Draw lines between the corners (the mapped object in the scene - image_2 ) line( img_matches, scene_corners[0] + Point2f( img_object.cols, 0), scene_corners[1] + Point2f( img_object.cols, 0), Scalar(0, 255, 0), 4 ); line( img_matches, scene_corners[1] + Point2f( img_object.cols, 0), scene_corners[2] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 ); line( img_matches, scene_corners[2] + Point2f( img_object.cols, 0), scene_corners[3] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 ); line( img_matches, scene_corners[3] + Point2f( img_object.cols, 0), scene_corners[0] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 ); //-- Show detected matches imshow( "Good Matches & Object detection", img_matches ); H.release(); img_matches.release(); waitKey(20); } return 0; } Постоянно "вылетает" по memory exception. Я думаю из-за того что постоянно выделяю ресурсы и не освобождаю их. Скажите, что надо освобождать (release), а что должно само освобождаться?
-
Утечка памяти. Что надо освобождать.
Khludenkov replied to Khludenkov's topic in Обсуждение общих вопросов
Если можно, ещё вопрос. Есть Cortex A8 с установленным линуксом и opencv. opencv используется для сшивки трёх кадров примерно по 900х600. Итоговое 1500х500. Сшивает за 35 секунд. Основное время занимает warp (25 секунд). Можно ли как-то убыстрить этот процесс? -
Утечка памяти. Что надо освобождать.
Khludenkov replied to Khludenkov's topic in Обсуждение общих вопросов
То есть распберри к примеру не потянет? -
Здравствуйте. Скажите, в каком виде внутри opencv представляется матрица гомографии? Есть ли функции для того, что получить из неё вращение, сдвиг, растяжение? Нечто вроде float dy = get_dy_from_Homography(H); float dx = get_dx_from_Homography(H); float angle = get_angle_from_Homography(H);
-
Сложный вопрос. Что в примерах было то и взял. Сейчас делаю так (фильтр по примерно одинаковой высоте точек): for(int i = 0; i < matchSize; ++i) { float dx = keypoints1[matches[i].queryIdx].pt.x - keypoints2[matches[i].trainIdx].pt.x; float dy = keypoints1[matches[i].queryIdx].pt.y - keypoints2[matches[i].trainIdx].pt.y; if( (fabs(dy) > imgCol1.rows/10) ) { Point2f t = keypoints2[matches[i].trainIdx].pt; t.x += imgCol1.cols; cv::circle(summIm, keypoints1[matches[i].queryIdx].pt, 3, CV_RGB(0, 0, 255), 1); cv::circle(summIm, t, 3, CV_RGB(0, 255, 0), 1); cv::line(summIm, keypoints1[matches[i].queryIdx].pt, t, CV_RGB(0, 64, 64)); printf("%d: dx = %.1f, dy = %.1f\r\n", i, keypoints1[matches[i].queryIdx].pt.x - keypoints2[matches[i].trainIdx].pt.x, keypoints1[matches[i].queryIdx].pt.y - keypoints2[matches[i].trainIdx].pt.y); } } Не очень разбираюсь в отличиях.
-
Утечка памяти. Что надо освобождать.
Khludenkov replied to Khludenkov's topic in Обсуждение общих вопросов
Спасибо, попробуем. Убрал везде release(). Работает, спасибо. -
Утечка памяти. Что надо освобождать.
Khludenkov replied to Khludenkov's topic in Обсуждение общих вопросов
Сижу в визуал студии 2010. Пробовал посмотреть стек вызовов. Не показывает. А если в цикле показывать одно и то же окно через imshow. Его надо периодически уничтожать через destroy? -
Прошу помощи. Как переписать матчер? Пардон, даже его исходников не нашёл. Или потом уже найденные пары просматривать? Хорошо бы сразу проверять... Вот class CV_EXPORTS_W FlannBasedMatcher : public DescriptorMatcher описан в features2fd.hpp, а в features2fd.cpp t его функций нету. И где их искать...
-
Лучше конечно самому отсеивать. Если опыта достаточно и сами код подправить можете. Потому как лучше не усреднять, а именно отсеивать. К примеру, стереоснимки: мы знаем что точки примерно на одной высоте расположены. Если одна сверху, другая много ниже, то явно ошибочно нашли.
-
А может ещё с матчингом поможете? Выходные параметры не совсем ясны. Вот это: FlannBasedMatcher matcher; std::vector< DMatch > matches; matcher.match( descriptors_object, descriptors_scene, matches ); И исходные коды его в сорсах не нашёл. Я хочу подправить матчер. К примеру, чтобы точки одного изображения всегда имели большее значение по X чем другого.
-
Спасибо. Сделал. Но наверное каждая новая строка должна начинаться с *(data + stride) Я так понимаю? Это здесь хорошо, данные по 8 байт, выравнивать не надо. // H - это матрица оптимального перспективного преобразования от img1 к img2 Mat H = findHomography(pt1, pt2, RANSAC, 10); double aM = H.at<double>(0); printf("aM = %lf\r\n", aM); double bM = H.at<double>(1); printf("bM = %lf\r\n", bM); double cM = H.at<double>(2); printf("cM = %lf\r\n", cM); double dM = H.at<double>(3); printf("dM = %lf\r\n", dM); double eM = H.at<double>(4); printf("eM = %lf\r\n", eM); double fM = H.at<double>(5); printf("fM = %lf\r\n", fM); double gM = H.at<double>(6); printf("gM = %lf\r\n", gM); double hM = H.at<double>(7); printf("hM = %lf\r\n", hM); double iM = H.at<double>(8); printf("iM = %lf\r\n", iM); double fi = atan(bM / aM); printf("fi = %lf\r\n", fi * 57); printf("sizeof double = %d\r\n", sizeof(double)); printf("sizeof float = %d\r\n", sizeof(float));
-
Сделал: for (int i = 0; i < 9; ++i) { printf("el = %lf\r\n", H.at<double>(i)); } И результаты похожие: последний элемент = 1.
-
Сделал printf("size = %d\r\n", H.elemSize()); На 32-х битном ХР выдаёт 8 (байт?). Это тип dоuble значит?
-
Что-то вроде А = H[2][1];
-
Я к тому что в документации не указано, в каком виде представлена матрица гомографии. То ли это float, то ли ещё что. Честно смотрел http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html?highlight=findhomography То есть каким образом вытащить значения элементов этой матрицы?
-
Спасибо. А в opencv доступ к элементам матрицы такой же? Построчно? Везде матрицы для изображений приводятся...
-
Здравствуйте. Как говорится, дальше в лес, больше дров. Продолжаю разбирать OpenCV. Написал такой код. int main( int argc, char** argv ) { string imName[2] = {"D:\\feat\\imL.jpg", "D:\\feat\\imR.jpg"}; Ptr<FeaturesFinder> finder; //finder = new SurfFeaturesFinder(); finder = new OrbFeaturesFinder(); Mat full_img, img; vector<ImageFeatures> features(2); vector<Mat> images(2); vector<Size> full_img_sizes(2); double seam_work_aspect = 1; #pragma region Find Features for (int i = 0; i < 2; ++i) { full_img = imread(imName[i], CV_LOAD_IMAGE_GRAYSCALE); full_img_sizes[i] = full_img.size(); (*finder) (full_img, features[i]); features[i].img_idx = i; for(int j = 0; j < features[i].keypoints.size(); ++j){ circle(full_img, features[i].keypoints[j].pt, 3, 255, 1, 8, 0 ); } imshow(imName[i], full_img); waitKey(0); } finder->collectGarbage(); full_img.release(); img.release(); #pragma endregion #pragma region Pairwise matching vector<MatchesInfo> pairwise_matches; BestOf2NearestMatcher matcher(false, 0.3f); matcher(features, pairwise_matches); matcher.collectGarbage(); #pragma endregion return 0; } Даю ему фотографии. Получаю особые точки. Глобальная цель: найти матрицу преобразования, которая максимально похоже переводит один снимок во второй. Делаю матчинг полученных особых точек. matcher(features, pairwise_matches); А дальше не знаю что делать... То есть есть структура pairwise_matches. Не совсем понял что такое: query descriptor index, train descriptor index, train image index, and distance between descriptors. В инете есть много примеров, но что-то они не компилируются. В частности: // Загружаем изображения: Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE); // Находим особые точки на каждом изображении // Вычисляем их дескрипторы: Ptr<Feature2D> surf=Algorithm::create<Feature2D>("Feature2D.SURF"); vector<KeyPoint> keypoints1, keypoints2; Mat descriptors1, descriptors2; surf->operator()(img1, Mat(), keypoints1, descriptors1); surf->operator()(img2, Mat(), keypoints2, descriptors2); // Находим наилучшее соответствие между особыми точками // на изображениях vector<DMatch> matches; BFMatcher(NORM_L2, true).match(descriptors1, descriptors2, matches); // Находим оптимальное преобразование, // согласующееся с большинством пар точек. vector<Point2f> pt1, pt2; for( size_t i = 0; i < matches.size(); i++ ) { pt1.push_back(keypoints1[matches[i].queryIdx].pt); pt2.push_back(keypoints2[matches[i].trainIdx].pt); } // H – это матрица оптимального перспективного // преобразования от img1 к img2 Mat H = findHomography(pt1, pt2, RANSAC, 10); Не может создать "Feature2D.SURF" детектор.
-
Спасибо. К примеру, есть матрица гомографии: Mat H = findHomography(pt1, pt2, RANSAC, 10); Можно ли её разложить собственно на сдвиг по x и y, поворот и сжатие/растяжение? В частности для случая аффинного преобразования? Скажите, как переписать матчер?
-
Если можно, ещё одну тему в продолжение. Неожиданно узнал, что SURF - nonfree. И в стандартной поставке opencv его нет. Я правильно понял? Есть только ORB. Скажите, насколько он хорошо работает при поиске особых точек и матчинге если объекты сильно повёрнуты? Если объекты просто сдвинуты и слегка (примерно 5 градусов) повернуты?
-
Вот, получилось. int main( int argc, char** argv ) { // Загружаем изображения: Mat img1 = imread("D:\\feat\\imL.jpg", CV_LOAD_IMAGE_GRAYSCALE); Mat img2 = imread("D:\\feat\\imR.jpg", CV_LOAD_IMAGE_GRAYSCALE); Mat i3 = imread("D:\\feat\\imL.jpg"); Mat i4 = imread("D:\\feat\\imL.jpg"); // Находим особые точки на каждом изображении. Вычисляем их дескрипторы: Ptr<Feature2D> surf=Algorithm::create<Feature2D>("Feature2D.ORB"); vector<KeyPoint> keypoints1, keypoints2; Mat descriptors1, descriptors2; surf->operator()(img1, Mat(), keypoints1, descriptors1); surf->operator()(img2, Mat(), keypoints2, descriptors2); // Находим наилучшее соответствие между особыми точками на изображениях vector<DMatch> matches; BFMatcher(NORM_L2, true).match(descriptors1, descriptors2, matches); // Находим оптимальное преобразование, согласующееся с большинством пар точек. vector<Point2f> pt1, pt2; for( size_t i = 0; i < matches.size(); i++ ) { pt1.push_back(keypoints1[matches[i].queryIdx].pt); pt2.push_back(keypoints2[matches[i].trainIdx].pt); } // H – это матрица оптимального перспективного преобразования от img1 к img2 Mat H = findHomography(pt1, pt2, RANSAC, 10); warpPerspective(i3, i4, H, i4.size()); imshow("3", i3); imshow("4", i4); waitKey(0); return 0; }
-
Гм. Сделал "Feature2D.ORB", заработало... Это значит, SURF не установлен?
-
Определение расстояния до объекта по двум фотографиям
Khludenkov добавил тему в Обсуждение общих вопросов
Здравствуйте. Скажите, есть ли в opencv стандартная последовательность (pipeline) определения расстояния до объекта? Объект присутствует на двух фотографиях, снятых на расстоянии (база) 1м друг от друга. Смотрел в гугле, попадались проекты. Но они больше какие-то "самодельные". -
Определение расстояния до объекта по двум фотографиям
Khludenkov replied to Khludenkov's topic in Обсуждение общих вопросов
Выдаёт изображение в чёрно-былом (не сером) виде. Градаций серого нет. Что можно сделать? Какое примерно расстояние должно быть?