mrgloom 242 Жалоба Опубликовано May 29, 2013 есть код для получения 1 пары. MatchesInfo get_pair(Mat& im1, Mat& im2) { MatchesInfo info; double surf_param=100; // чем меньше значение тем больше точек SurfFeaturesFinder finder(surf_param); ImageFeatures features1; ImageFeatures features2; finder(im1,features1); finder(im2,features2); finder.collectGarbage(); match_flann(features1,features2,info); Mat affine; string method="translation"; //string method="translation+rotation"; //string method="affine"; int thres=3; std::vector<DMatch> inliners; double score= ransac(features1.keypoints, features2.keypoints, info.matches, affine,inliners,thres,method); info.num_inliers= inliners.size(); Mat M= affine.reshape(1,2); info.H= M; info.confidence= (double)inliners.size()/(8+0.3*info.matches.size());// по пейперу Lowe return info; } есть код для всех, который хочеться распараллелить. например с помощью boost. как это правильно сделать? составить список пар заранее? (непонятно надо ли копировать отдельно изображения или несколько тредов могут читать из одной памяти?) vector<MatchesInfo> GetSURFCorrespondences(vector<Mat>& vec_im) { vector<MatchesInfo> vec; int k=0; for(int i=0;i<vec_im.size();++i) { ++k; for(int j=k;j<vec_im.size();++j) { MatchesInfo info= get_pair(vec_im[i], vec_im[j]); info.src_img_idx= i; info.dst_img_idx= j; vec.push_back(info); } } return vec; } основную часть времени съедает именно матчинг, немного меньше детектирование фич+экстракция дескрипторов. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 29, 2013 Можно распараллелить при помощи openmp-ишной директивы #pragma omp parallel for выглядит обычно так: #ifdef _OPENMP #pragma omp parallel for for (int i = 0; i < ferns.size(); i++) { } #else нераспараллеленая реализация #endif [/code] Чтобы это работало надо включить заголовок #include <omp.h> и разрешить использование openmp в опциях проекта (options -> C++ -> Language -> поставить галку OpenMP support). Что касается кода, то явно будут проблемы с vec.push_back(info); Тут лучше выделить каждому потоку свой кусок памяти. Хорошее руководство тут: http://msdn.microsoft.com/ru-ru/library/dd335940.aspx 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано May 30, 2013 #pragma omp parallel { printf("Hello World\n"); } так выводит 2 раза cvSetNumThreads(2); int nthreads = cvGetNumThreads(); но nthreads почему то =1 кстати говоря если заранее выделить память, то пишут что безопасно класть. http://stackoverflow.com/questions/9269097/openmp-and-stl-vector Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано May 30, 2013 попробовал распараллелить внутренний цикл int n=8; int c=0; for(int i=n-1;i>=0;--i) c+=i; int k=0; vector<pair<int,int>> vec(c); c=0; for(int i=0;i<n;++i) { ++k; cout<<"k= "<<k<<endl; #pragma omp parallel for for(int j=k;j<n;++j) { //вычисление чего нибудь и присваивание vec[c]= make_pair(i,j); // так неправильно #pragma omp critical { //vec[c]= make_pair(i,j); //так правильно cout<<"i= "<<i<<" j= "<<j<<endl; cout<<"c= "<<c<<endl; ++c; } } } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано May 30, 2013 vector<MatchesInfo> GetSURFCorrespondences(vector<Mat>& vec_im) { vector<MatchesInfo> vec; #ifndef _OPENMP int k=0; for(int i=0;i<vec_im.size();++i) { ++k; for(int j=k;j<vec_im.size();++j) { MatchesInfo info= get_pair(vec_im[i], vec_im[j]); info.src_img_idx= i; info.dst_img_idx= j; vec.push_back(info); } } #else int c=0; int n= vec_im.size(); for(int i=n-1;i>=0;--i) c+=i; int k=0; vec.resize(c); c=0; for(int i=0;i<n;++i) { ++k; //cout<<"k= "<<k<<endl; #pragma omp parallel for for(int j=k;j<n;++j) { MatchesInfo info= get_pair(vec_im[i], vec_im[j]); info.src_img_idx= i; info.dst_img_idx= j; vec[c]= info; #pragma omp critical { /*cout<<"i= "<<i<<" j= "<<j<<endl; cout<<"c= "<<c<<endl;*/ ++c; // должно быть в крит секции } } } #endif return vec; } судя по времени выполнения код вообще не ускоряется Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано May 30, 2013 так тоже работает int k=0; for(int i=0;i<vec_im.size();++i) { ++k; #pragma omp parallel for for(int j=k;j<vec_im.size();++j) { MatchesInfo info= get_pair(vec_im[i], vec_im[j]); info.src_img_idx= i; info.dst_img_idx= j; #pragma omp critical { cout<<"i= "<<i<<" j= "<<j<<endl; vec.push_back(info); } } } проблема была в том, что тестировал в релизе и забыл там включить openmp, а так ускорение где в 1.7 раз получилось(на 2 процессорном). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано May 31, 2013 class CTask { public: int id1; int id2; Mat m1; Mat m2; }; vector<CTask> vec_task; int k=0; for(int i=0;i<vec_im.size();++i) { ++k; for(int j=k;j<vec_im.size();++j) { CTask t; t.id1= i; t.id2= j; t.m1= vec_im[i]; t.m2= vec_im[j]; vec_task.push_back(t); } } #pragma omp parallel for for(int i=0;i<vec_task.size();++i) { MatchesInfo info= get_pair(vec_task[i].m1, vec_task[i].m2); info.src_img_idx= vec_task[i].id1; info.dst_img_idx= vec_task[i].id2; #pragma omp critical { vec.push_back(info); } } попробовал всё в 1 цикл, ускорения не получил, хотя думал будет, т.к. в предыдущей реализации были нечётные циклы. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 31, 2013 Так критическая секция, а данном случае, из параллельного кода последовательный делает. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано June 3, 2013 Так критическая секция, а данном случае, из параллельного кода последовательный делает. да вообще то нет, код в крит. секции выполняется быстро относительно основных вычислений, так что норм., я имею ввиду что я не получил дополнительного относительно 1.7. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 4, 2013 1.7 это близко к пределу для 2-х ядер. Большее ускорение вряд ли получится выжать. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано June 5, 2013 Не о распараллеливании конечно, но думаю что здесь будет уместно упомянуть: http://code.opencv.org/issues/1498 When using CvInvert with SVD method, OpenCV 2.3 is 3x slower than OpenCV 2.2 Исправлять, по плану, собираются только к 3-ей версии (примерно через 3 месяца). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано June 5, 2013 1.7 это близко к пределу для 2-х ядер. Большее ускорение вряд ли получится выжать. вопрос не в том, 1.3,1.5 или 1.7, а в том, что в предыдущей версии были циклы нечетной длины и я предполагал, что 1 остаточная итерация в таком цикле делается на 1 процессоре, что видимо неверно. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах