Перейти к содержимому
Compvision.ru

Nuzhny

Пользователи
  • Количество публикаций

    1 427
  • Зарегистрирован

  • Посещение

  • Days Won

    176

Все публикации пользователя Nuzhny

  1. Можно и Вин-треды сделать. Там тоже несложно. Сделай parallel_barrel как unsigned __stdcall parallel_barrel(void *pArguments) (pArguments - это и есть указатель на структуру с входными параметрами). Входные данные для неё упакуй в одну структуру и передавай в функцию _beginthreadex. Все хендлы потоков складывай в массив, который подавай в функцию ожидания завершения всех потоков WaitForMultipleObjects. Чуть сложнее и более громоздко чем буст.
  2. Ага. А ещё, кроме неумелого оператора, не хватает дополнительных микрофонов в зале. В России культура видеолекций пока не развита.
  3. Вот код с бустом: #include <cstdlib> #include <iostream> #include <deque> #include <boost/bind.hpp> #include <boost/smart_ptr.hpp> #include <boost/thread.hpp> #include <cv.h> #include <highgui.h> //////////////////////////////////////////////////////////////////////////// void parallel_barrel(float* pbufx, float* pbufy, int Y, int w, int H, float kx, float ky, int Cx, int Cy) { //через указатели (может хватит точности float?) float через указатели не работает for (int y = Y; y < Y+H; y++) { int ty= y-Cy; for (int x = 0; x < w; x++) { int tx= x-Cx; int rt= tx*tx+ty*ty; *pbufx = (float)(tx*(1+kx*rt)+Cx); ++pbufx; } } for (int y = Y;y < Y+H; y++) { int ty= y-Cy; for (int x = 0; x < w; x++) { int tx= x-Cx; int rt= tx*tx+ty*ty; *pbufy = (float)(ty*(1+ky*rt)+Cy); ++pbufy; } } } //////////////////////////////////////////////////////////////////////////// int _tmain(int argc, _TCHAR* argv[]) { argc; argv; //распаралеливаем по mapx mapy IplImage* img= cvLoadImage("1.PNG"); IplImage* mapx= cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 ); IplImage* mapy= cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 ); int w= img->width; int h= img->height; int Cx= w/2; int Cy= h/2; const float kx= 3.8E-7; const float ky= 3.8E-7; float* pbufx = (float*)mapx->imageData; float* pbufy = (float*)mapy->imageData; //parallel section //вместо цикла поставить разделение на треды int N = 4; //кол-во тредов int H= h / N; int y = 0; boost::thread_group threads; for (int i = 0; i < N; ++i) { threads.add_thread(new boost::thread(boost::bind(parallel_barrel, pbufx, pbufy, y, w, H, kx, ky, Cx, Cy))); //parallel_barrel(pbufx, pbufy, y, w, H, kx, ky, Cx, Cy); if (i != N - 1) { pbufx += H * w; pbufy += H * w; } y += H; } //end parallel section threads.join_all(); IplImage* temp = cvCloneImage(img); cvRemap(temp, img, mapx, mapy); cvReleaseImage(&temp); cvReleaseImage(&mapx); cvReleaseImage(&mapy); cvSaveImage("out.png",img); return 0; } Как видишь, пользоваться бустовскими потоками очень просто, код практически не изменился. У меня дома комп - старенький Core 2 Duo, поэтому ускорения не заметил никакого.
  4. Распознавание лиц

    В самой последней верссии алгоритмы разбиты по разным dll. Поэтому для разных программ разная комплектация. P.S. А в чём вообще трудность? Возьми тот же Far и посмотри, из каких dll импортирует функции твоя программа.
  5. Работа с контурами

    Чтобы не закрашивать всё изображение. Он не обязателен.
  6. Работа с контурами

    Если точек для проверки много, то можно поступить следующим образом: закрасить лежащую снаружи контура область изображения одним цветом, нарисовать контур другим, а внутренность контура - третьим. И просто брать значение пикселя по координатам точек. То есть: 1. Создать одноканальное изображение размеров с исходное, закрасить его нулями (cvSet). 2. Найти описывающий прямоугольник для контура, увеличить его размеры на 1, нарисовать на изображении белым цветом. 3. Нарисовать контур цветом, скажем, 128. 4. В точке bounding_rect.x + 1 и bounding_rect.y + 1 вызвать функцию cvFloodFill с белым цветом. 5. Для каждой интересующей точки проверить значение пикселя. Этот метод будет немного затратным вначале, но зато с очень простой и быстрой проверкой на вхождение точек.
  7. Распознавание лиц

    Для какой версии OpenCV?
  8. Распознавание лиц

    В версии 2.2 новые варианты dll. Они остались только в 2.1.
  9. 1. Создать большую матрицу. 2. Скопировать по указателю на её данные первую матрицу через обычный memcpy. 3. Сдвинуть указатель и скопировать данные второй матрицы.
  10. Надо пробовать
  11. Распознавание лиц

    Вся прелесть QT как раз в том, что он кроссплатформенный. Но как знаешь. В opencv 2.2 не может быть cv100.dll, так как она из верси opencv 1.0
  12. remap задействована в самом внутреннем цикле. Значит, можно разделить изображение по высоте на число потоков и отдавать каждому из них свою "полоску" исходного изображения. Можно предложить такое решение: void block_warpPerspective(int y_from, int y_to) { for( y = y_from; y < y_to; y += bh0 ) { for( x = 0; x < width; x += bw0 ) { int bw = std::min( bw0, width - x); int bh = std::min( bh0, height - y); Mat _XY(bh, bw, CV_16SC2, XY), matA; Mat dpart(dst, Rect(x, y, bw, bh)); for( y1 = 0; y1 < bh; y1++ ) { short* xy = XY + y1*bw*2; double X0 = M[0]*x + M[1]*(y + y1) + M[2]; double Y0 = M[3]*x + M[4]*(y + y1) + M[5]; double W0 = M[6]*x + M[7]*(y + y1) + M[8]; if( interpolation == INTER_NEAREST ) for( x1 = 0; x1 < bw; x1++ ) { double W = W0 + M[6]*x1; W = W ? 1./W : 0; int X = saturate_cast<int>((X0 + M[0]*x1)*W); int Y = saturate_cast<int>((Y0 + M[3]*x1)*W); xy[x1*2] = (short)X; xy[x1*2+1] = (short)Y; } else { short* alpha = A + y1*bw; for( x1 = 0; x1 < bw; x1++ ) { double W = W0 + M[6]*x1; W = W ? INTER_TAB_SIZE/W : 0; int X = saturate_cast<int>((X0 + M[0]*x1)*W); int Y = saturate_cast<int>((Y0 + M[3]*x1)*W); xy[x1*2] = (short)(X >> INTER_BITS); xy[x1*2+1] = (short)(Y >> INTER_BITS); alpha[x1] = (short)((Y & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (X & (INTER_TAB_SIZE-1))); } } } if( interpolation == INTER_NEAREST ) remap( src, dpart, _XY, Mat(), interpolation, borderType, borderValue ); else { Mat matA(bh, bw, CV_16U, A); remap( src, dpart, _XY, matA, interpolation, borderType, borderValue ); } } } } void parallel_warpPerspective( const Mat& src, Mat& dst, const Mat& M0, Size dsize, int flags, int borderType, const Scalar& borderValue ) { dst.create( dsize, src.type() ); CV_Assert( dst.data != src.data ); const int BLOCK_SZ = 32; short XY[BLOCK_SZ*BLOCK_SZ*2], A[BLOCK_SZ*BLOCK_SZ]; double M[9]; Mat matM(3, 3, CV_64F, M); int interpolation = flags & INTER_MAX; if( interpolation == INTER_AREA ) interpolation = INTER_LINEAR; CV_Assert( (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 3 && M0.cols == 3 ); M0.convertTo(matM, matM.type()); if( !(flags & WARP_INVERSE_MAP) ) invert(matM, matM); int x, y, x1, y1, width = dst.cols, height = dst.rows; int bh0 = std::min(BLOCK_SZ/2, height); int bw0 = std::min(BLOCK_SZ*BLOCK_SZ/bh0, width); bh0 = std::min(BLOCK_SZ*BLOCK_SZ/bw0, height); // Число потоков int num_threads = 4; for (i = 0; i < num_threads; ++i) { // Типа старт потока с функцией block_warpPerspective и двумя её аргументами y_from, y_to start_thread(block_warpPerspective, (i * height) / num_threads, ((i + 1) * height) / num_threads); } } Вместо warpPerspective вызывать parallel_warpPerspective. Функции start_thread и block_warpPerspective - условные, необходимо заменить на конкретную реализацию. Надеюсь, что моя мысль ясна, но могу пояснить или набросать компилирующийся параллельный код с бустовскими потоками (только мне нужен какой-нибудь рабочий последовательный).
  13. msyuv.dll

    Ну да. Поставь k-lite codeck pack. В нём, кстати, есть graphstudio.exe. Попробуй захват и отображение в ней сделать: будет ли нормально работать.
  14. Работа с контурами

    Выкладывай свой код, поможем конечно.
  15. Распознавание лиц

    QT умеет с базами работать.
  16. msyuv.dll

    Она используется при декомпрессии видео. Можешь поставить в качестве эксперимента другие кодеки.
  17. Здесь Кто-нибудь собирается участвовать?
  18. Ну и как? Есть участники этого форума среди выступающих? Мы с другом в команде Кенты-параноики болтаемся где-то в первой двадцатке.
  19. Солдатов С.А., Стрельников К.Н., Ватолин Д.С. "Быстрое и надежное определение глобального движения в видеопоследовательностях"
  20. Thread + MinGW + OpenCV

    Ты же в QT Creator'е работаешь? У него должна быть возможность посмотреть стек (call stack или stack browser).
  21. Thread + MinGW + OpenCV

    Я бы посмотрел стек вызовов внутри OpenCV в момент падения.
  22. 3D реконструкция

    То есть тебе надо сделать что-то подобное?
  23. Контуры, представленные координатами точек, кодируются разными способами: 1. код Фримена; 2. полигональное кодирование; 3. кодирование проекциями на оси координат; 4. кодирование комплексными числами; 5. ... Пункт 4 подразумевает представление контура в виде последовательности элементарных векторов, каждый из которых представляется в виде комплексного числа. Эту последовательность интерпретируют как сигнал, используют весь инструментарий цифровой обработки сигналов: преобразование Фурье, цифровые фильтры и т.д. (см. книгу "Введение в контурный анализ"). А сигналы и нейросети уже давно подружили между собой. Возможно, что удобно будет подавать на вход результат преобразования косинусов. Или вейвлет преобразования. Как-то так.
  24. Объединились. Что дальше?

    Есть такая библиотека IVT У них есть пример Undistortion / rectification - можно скачать по ссылке. Так вот, rectification - выравнивание изображения. Очень похоже, что тебе надо каждую фотографию сначала выровнять, а после уже склеивать. В IVT это делается, кажется, по матрице калибровки. Я видел подходы с поиском вертикальных или горизонтальных линий и выравнивания уже по ним. Посмотри пример - возможно именно такой подход позволит улучшить качество.
  25. Поиск особых точек.

    Да, есть такой пример в OpenCV: OpenCV\samples\c\find_object.exe
×