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

Доска почета

  1. Smorodov

    Smorodov

    Главные администраторы


    • Баллы

      532

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

      3 720


  2. mrgloom

    mrgloom

    Пользователи


    • Баллы

      242

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

      2 301


  3. Nuzhny

    Nuzhny

    Пользователи


    • Баллы

      216

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

      1 316


  4. BeS

    BeS

    Пользователи


    • Баллы

      53

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

      349



Popular Content

Showing most liked content since 03.12.2010 во всех областях

  1. 4 points
    Вышла еще одна книжка (см. №3) и я решил для удобства собрать эти книжки вместе: 1)"Learning OpenCV. Computer Vision in C++ with the OpenCV Library. 2nd Edition" http://shop.oreilly.com/product/0636920022497.do Благородная попытка перевода ее на русский язык первого издания этой книги: http://locv.ru/wiki/%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0 2)"OpenCV 2 Computer Vision Application Programming Cookbook" ссылка на исходный код на сайте http://www.laganiere.name/opencvCookbook/ 3)"Mastering OpenCV with Practical Computer Vision Projects" очень интересные проекты с исходниками. http://www.packtpub.com/cool-projects-with-opencv/book исходники здесь: https://github.com/MasteringOpenCV/code Еще одна книжка с opensouce исходниками: Practical OpenCV By Samarth Brahmbhatt Список книг по Opencv от opencv.org: http://opencv.org/books.html Еще бесплатная книжка: "Modern Robotics with OpenCV" здесь: http://www.sciencepublishinggroup.com/book/B-978-1-940366-12-8.aspx
  2. 4 points
    Кому интересно, написал довольно шуструю вычиталку фона(пока только последовательная версия, до распараллеливания пока руки не дошли) основанную на алгоритме VIBE с оберткой для использования в OpenCV. Оригинальная статья: http://orbi.ulg.ac.be/bitstream/2268/145853/1/Barnich2011ViBe.pdf Мои исходные коды: https://github.com/BelBES/VIBE
  3. 4 points
    Привет всем! Вот, попытался сделать пример вывода видео на форму. И, думаю, получилось Для того, что-бы скопировать IplImage в объект .NET типа Image, достаточно всего лишь одной строки: #include <opencv/cv.h> #include <opencv/highgui.h> ... using namespace System; using namespace System::Windows::Forms; using namespace System::Drawing::Imaging; using namespace System::Drawing; ... IplImage *iplImg; ... // Копирование IplImage в объект .NET типа Image Image ^image = gcnew Bitmap(iplImg->width, iplImg->height, iplImg->widthStep, PixelFormat::Format24bppRgb, IntPtr(iplImg->imageData)); ... или, с использованием класса Mat: cv::Mat imgMat; // Копирование cv::Mat в объект .NET типа Image Image ^img = gcnew Bitmap(imgMat.cols, imgMat.rows, imgMat.step, PixelFormat::Format24bppRgb, IntPtr(imgMat.data)); Чтобы вывести изображение на компоненту PictureBox, достаточно следующей строки в одном из методов вашей формы: this->pictureBox1->Image = image; Если вам нужен HBITMAP, то получить его можно следующим образом: Bitmap ^image = gcnew Bitmap(iplImg->width, iplImg->height, iplImg->widthStep, PixelFormat::Format24bppRgb, IntPtr(iplImg->imageData)); HBITMAP hb = (HBITMAP)image->GetHbitmap().ToPointer(); У меня вышеприведенные примеры отлично работают с OpenCV 2.2 в Visual Studio 2008/2010. К сообщению прилагаю проект простого видео плеера, написанного с помощью OpenCV 2.2 в Visual Studio 2008. Он может воспроизводить все типы видео, которые берет OpenCV и видео, захваченное с видеокамеры. Не судите строго за возможные несовершенства в коде Просто, я старался, что бы были основные функции плеера. Пояснения к проекту. Компиляция: Чтобы успешно скомпилировать проект, достаточно в опциях Visual Studio установить пути на OpenCV в следующем виде: %OPENCV_HOME%\include и %OPENCV_HOME%\lib Например, так: C:\OpenCV2.2\include и C:\OpenCV2.2\lib Другое: При создании проекта использовались следующие опции и установки. .NET Framework 3.5. General/Common Language Runtime Support: Common Language Runtime Support (/clr) C/C++/Advanced/Disable Specific Warnings: 4996;4793 Linker/Input/Additional Dependencies: opencv_core220d.lib opencv_highgui220d.lib opencv_imgproc220d.lib opencv_objdetect220d.lib Для версии Release: без "d" после 220. В компоненте PictureBox свойство SizeMode имеет значение Zoom, что позволяет сохранить оригинальное соотношение сторон кадра. Для визуализации кадров используется Tick таймера. При двойном щелчке по области отображения, происходит переход в полноэкранный режим и обратно. Надеюсь, пример кому-нибудь пригодится VideoOnForm.zip
  4. 4 points
    Здравствуйте, решил заняться переводом книги "Learning OpenCV", перевёл уже 37 глав. Присоединяйтесь будем переводить вместе! - http://locv.ru
  5. 3 points
    проект здесь: FaceDetect.rar дополнительные классификаторы (нос, глаза, рот, тело):HaarClassifiers.rar здесь еще куча каскадов: Каскады хаара
  6. 3 points
    Самокодный вариант AdaBoost. (Виолы и Джонса там нет , только AdaBoost ) Надеюсь оформлю статью по нему, но и в листинге старался разместить побольше комментариев. AdaBoost.cpp И ссылка на мою презентацию по детекту лиц там тоже есть немного пояснений по теме: http://www.compvision.ru/forum/index.php?app=core&module=attach&section=attach&attach_id=369
  7. 3 points
    Наконец-то дошли руки Оптимизации не делал, просто проверил идею. Пример кода максимизирует расстояние между средним цветом внутри и снаружи прямоугольной области. Максимизирует он это расстояние при помощи подбора параметров этого прямоугольника (методом градиентного спуска). Вот что я имел ввиду, когда говорил непонятные вещи Результат работы программы (изображение может быть и цветным): #include "opencv2/opencv.hpp" #include <vector> using namespace std; using namespace cv; //---------------------------------------------------------- // Это и есть вычисление расстояния между средними цветами //---------------------------------------------------------- double getLikelihood(Mat& img,cv::RotatedRect& rr) { double likelihood=0; Mat mask=Mat::zeros(img.size(),CV_8UC1); // rotated rectangle Point2f rect_points[4]; rr.points( rect_points ); vector<cv::Point> pts(4); for(int i=0;i<4;++i) { pts[i]=rect_points[i]; } cv::fillConvexPoly(mask,pts,Scalar::all(255)); imshow("mask",255-mask); Scalar cc1,cc2; cc1=cv::mean(img,mask); cc2=cv::mean(img,255-mask); likelihood=norm(cc1,cc2,cv::NORM_L2); return likelihood; } //---------------------------------------------------------- // Градиент, чтобы знать куда менять параметры //---------------------------------------------------------- void getLikelihoodGradient(Mat& img,cv::RotatedRect& rr,cv::RotatedRect& drr) { cv::RotatedRect rrdx=rr; rrdx.center.x+=1; cv::RotatedRect rrdy=rr; rrdy.center.y+=1; cv::RotatedRect rrdw=rr; rrdw.size.width+=1; cv::RotatedRect rrdh=rr; rrdh.size.height+=1; cv::RotatedRect rrdang=rr; rrdang.angle+=1; cv::RotatedRect rrdxn=rr; rrdxn.center.x-=1; cv::RotatedRect rrdyn=rr; rrdyn.center.y-=1; cv::RotatedRect rrdwn=rr; rrdwn.size.width-=1; cv::RotatedRect rrdhn=rr; rrdhn.size.height-=1; cv::RotatedRect rrdangn=rr; rrdangn.angle-=1; float l0=getLikelihood(img,rr); cout << l0 << endl; float dlx=getLikelihood(img,rrdx)-getLikelihood(img,rrdxn); float dly=getLikelihood(img,rrdy)-getLikelihood(img,rrdyn); float dlw=getLikelihood(img,rrdw)-getLikelihood(img,rrdwn); float dlh=getLikelihood(img,rrdh)-getLikelihood(img,rrdhn); float dlang=getLikelihood(img,rrdang)-getLikelihood(img,rrdangn); float scale=sqrt(dlx*dlx+dly*dly+dlw*dlw+dlh*dlh+dlang*dlang); dlx/=scale; dly/=scale; dlw/=scale; dlh/=scale; dlang/=scale; drr.center.x=dlx; drr.center.y=dly; drr.size.width=dlw; drr.size.height=dlh; drr.angle=dlang; } //---------------------------------------------------------- // Генерируем тестовое зашумленное изображение //---------------------------------------------------------- void generateTestImage(Mat& img) { img=Mat(512,512,CV_8UC3); cv::RotatedRect rr(cv::Point2f(200,300),Size(140,180),67); img=Scalar::all(0); // rotated rectangle Point2f rect_points[4]; rr.points( rect_points ); vector<cv::Point> pts(4); for(int i=0;i<4;++i) { pts[i]=rect_points[i]; } cv::fillConvexPoly(img,pts,Scalar(255,255,255)); for(int i=0;i<100000;++i) { int x=rand()%512; int y=rand()%512; img.at<Vec3b>(y,x)=Vec3b(255,255,255); } for(int i=0;i<105000;++i) { int x=rand()%512; int y=rand()%512; img.at<Vec3b>(y,x)=Vec3b(0,0,0); } } //---------------------------------------------------------- // //---------------------------------------------------------- int main(int argc, char* argv[]) { Mat img,img_cpy; generateTestImage(img); imshow("testimg",img); cv::waitKey(0); cv::RotatedRect rr(cv::Point2f((float)img.cols/2.0,(float)img.rows/2.0),Size(img.cols-100,img.rows-100),0); cv::RotatedRect drr; while(1) { img_cpy=img.clone(); getLikelihoodGradient(img,rr,drr); // Меняем параметры в сторону увеличения расстояния между средними цветами rr.center+=drr.center; rr.size+=drr.size; rr.angle+=drr.angle; // rotated rectangle Point2f rect_points[4]; rr.points( rect_points ); for( int j = 0; j < 4; j++ ) { line( img_cpy, rect_points[j], rect_points[(j+1)%4], Scalar(0,255,0), 2, CV_AA ); } imshow("img_cpy",img_cpy); waitKey(10); } cv::destroyAllWindows(); return 0; }
  8. 3 points
    2 Nuzhny Результаты сравнения по скорости собирал 4-2 года назад (потом стало лень) на этой странице (смотреть от где-то от середины и все постскрипты). Сравнивал с пятью чужими программами (вернее, с опубликованными в печати или в интернете временами расчётов - исходник-то был доступен всего для одной из этих 5 программ). Сравнивал ориентировочно - с учётом прикидок о разнице в быстродействии моего и других процессоров. Исходников не открываю, демку где-то в те годы на сайте предложил сделать-дать только тому, кто придёт с тяжёлым проектом и гарантирует отдачу проекта в мои руки после того, как демка всё заявленное (как скорость, так и просто надёжность-работоспособность) продемонстрирует. По потреблению памяти - у меня на копейки больше, т.к. все данные обрабатываемого примера (именно одного текущего примера) и внутренние сигналы/веса сети оптимально раскладываются с учётом выравнивания блоков данных на границу параграфа. Ну и в коде 1.5 ноу-хау - одно чисто моё (на удивление - почему-то нигде и никем ранее не опубликованное) о самом шустром варианте распараллеливания обучения нейросети (вообще без синхронизаций потоков на уровне операционной системы), второе - об аппроксимированном вычислении нелинейности нейрона (которое опубликовано, но почему-то никто об этом не знает и на практике не применяет). И сейчас реализованы пара канонических вариантов свёрточных сеток (ЛеКуновский и Симардовский), а также другие её клоны (от Эндрю Нг, Свена Бенке) - вернее, из разных слоёв-кубиков можно собирать свой/новый вариант. Также у нейронов можно ставить полиномиальные сумматоры - не на всех слоях свёрточной сети это помогает/полезно, но если помогает - то точность растёт. Я так даже самого Хинтона опроверг - он в прошлом году говорил, что на задаче MNIST на обычном персептроне никто никогда не опустился ниже 1.6% ошибок, а я таки постановкой полиномиальных сумматоров только на вых.слой получил точность лучше (см последний абзац тут) (хотя сам Хинтон в 1986г в двухтомнике PDP описывал формулы обратного распространения ошибки в том числе и для полиномиальных сумматоров - но вот почему-то сам не пользуется сейчас сигма-пи нейронами в своих сетях, может быть, зря).
  9. 3 points
    покопавшись в исходниках можно найти для себя несколько заготовок, таких как построение 3d модели лица, его трекинг и даже ( на начальном этапе ) вычисление значения фильтров габора в ключевых точках этой модели. может кому пригодиться... трекинг работает весьма быстро для одного человека, но я по быстрому переделал под свои цели для двоих. в основе детектирования ключевых точек - Flandmark_detector, трекинга - headtracker-master. (лиценция которых GNU GPL, для тех кого это вообще интересует). должно даже собраться и заработать (под ubuntu писалось) Написано на С++, есть куски на С. для работы нужна opencv2.4.4 lndmark.tar.gz
  10. 3 points
    Соорудил быстрый и маленький кусочно-аффинный варпер (перенос фрагмента изображения из одной сетки треугольников в другую): WarpAffine.rar
  11. 3 points
    Слайды одной из моих лекций. Детектор лиц на основе метода Виолы-Джонса.rar
  12. 3 points
    Так случилось, что я активно использую Delphi в своей работе (программирование по работе, собственные открытые и закрытые проекты) и вот мне понадобилось написать программу, использующую открытую библиотеку компьютерного зрения OpenCV. Что же делать, ведь официально OpenCV использовать в Delphi невозможно, а перебираться на C ради одной программы слишком долго. Но нет ничего невозможного… Немного поискав в интернете, я нашел несколько проектов по использованию OpenCV в Delphi. Первый, второй, третий и наиболее свежий и удачный — четвертый, который я и взял за основу. Проект на github мне показался интересным, реализовано много функций OpenCV, есть много примеров на Delphi, но проект заброшен автором и пришлось взяться за свой. Все текущие наработки я выложил на code.google.com/p/opencv-delphi-new/ В настоящий момент сделано: 1. Поддержка RAD Studio XE3. 2. Добавлены новые функции: cvFlip, cvClearMemStorage, cvCreateChildMemStorage, cvRectangle, cvRetrieveFrame, cvIntegral, cvGetPerspectiveTransform, cvWarpPerspective, cvCreateMat, cv2DRotationMatrix, cvWarpAffine, cvFindContours, cvHaarDetectObjects. 3. Добавлено 6 новых примеров: FaceDetect — Пример детектирования лица в видеопотоке с использованием преобразования Хафа. FindContours — Нахождение контуров изображения. Integral — Интегральное изображение. WarpAffine — Трансформация изображения — аффинные преобразования (Поворот изображения на произвольный угол). WrapPrespective — Трансформация изображения — гомография (Перспективная трансформация). MatchShapes — Поиск объекта на изображении по шаблону (Сравнение объектов по моментам их контуров). В добавленных примерах я постарался подробно расписать все манипуляции для достяжения нужного результата. Если кому-то будет интересна тема использования OpenCV в Delphi, то пишите мне на email или оставляйте комментарии. Если тематика использования OpenCV в принципе интересна, то могу написать несколько статей, только напишите, какое направление использования OpenCV Вас интересует.
  13. 3 points
    Полезный сайт по теории: http://courses.graphicon.ru/ Материал по ASM и AAM: http://courses.graphicon.ru/files/courses/smisa/2008/lectures/lecture10.pdf
  14. 3 points
    И еще проект ( активные контуры (ASM) переделанный (на чистый OpenCV 2.X) мной проект одного китайца, который переделал его из STASM ): В архиве конвертер моделей STASM в файл с матрицами OpenCV, и солюшн для студии с двумя проектами: библиотекой и демкой. Надеюсь на дальнейшее развитие проекта. ASMCompvisionEdition.rar
  15. 3 points
    Где-то есть деление на ноль. Смотри свои данные.
  16. 3 points
    Привет. В общем вот выкладываю перевод с БИЛДЕРА на ВИЖУАЛ (кстати недавно совсем переводил), "Создание APIшного битмапа из интеловского RGB изображения" присутствует. Смотри, разбирайся. Если, что не пойдет пиши - разберемся. [Прикрепленный файл был потерян при откате форума]
  17. 3 points
    Здравствуйте, RinOS. Рекомендую все-таки использовать cvStereoRectify() т.к. результат его работы более точен, а cvStereoRectifyUncalibrated() лучше использовать когда существуют значительные непараллельности в оптических осях камер, насколько я понимаю. Критерием правильности калибровки стерео может служить правильное число в векторе T (который означает расстояние между оптическими осями по оси x, y и z) камер. У меня, при расстоянии между камерами 12 см, и 29 калибровочных пар изображений 640х480 в оттенках серого (изображения я сохраняю предварительно в bmp, чтобы каждый раз не мучаться с их показом камерам) величина составляет: цитирую xml содержимое <data>-1.1886876922892217e-001 -7.8263643755714435e-004 -4.6620003758508491e-003</data>, (все величины в метрах - первая величина - это сдвиг по оси X, то есть расстояние между камерами). То есть 1.6 %, что может быть точнее измерянного мною расстояния. Чем шире расстояние между камерами, тем лучше будет восприятие на более дальних расстояниях, и тем хуже будет поле зрения камеры, при обзоре близких предметов. Для того чтобы величина вектора T содержала метрические величины, необходимо, чтобы вы правильно (в метрических единицах) указали размер клеточки при калибровке. В книге learning OpenCV, в примере стерео (стр 445), есть константа squareSize, у меня в коде примерно так (размер клетки 3 см): float chesbSquareSize = 0.030f; // 30 mm is a Square size for (size_t pair_idx = 0; pair_idx < boards_count; pair_idx++) { for (size_t i=pair_idx*board_n,j = 0;j < board_n; ++i,++j) { // Chessboard points CV_MAT_ELEM(*image_pointsL,float,i,0) = vCalibData[IMG_LEFT][pair_idx].vPoints[j].x; CV_MAT_ELEM(*image_pointsL,float,i,1) = vCalibData[IMG_LEFT][pair_idx].vPoints[j].y; CV_MAT_ELEM(*image_pointsR,float,i,0) = vCalibData[IMG_RIGHT][pair_idx].vPoints[j].x; CV_MAT_ELEM(*image_pointsR,float,i,1) = vCalibData[IMG_RIGHT][pair_idx].vPoints[j].y; // Linear space remapping points CV_MAT_ELEM(*object_points,float,i,0) = (float)(j/w) * chesbSquareSize; CV_MAT_ELEM(*object_points,float,i,1) = (float)(j%w) * chesbSquareSize; CV_MAT_ELEM(*object_points,float,i,2) = 0; }; CV_MAT_ELEM(*point_counts,UINT,pair_idx,0) = (UINT)board_n; }; Откалиброванные матрицы удобно сохранять в xml. Для того, чтобы калибровка была корректной, рекомендуют использовать "шахматную доску" с не одинаковым кол-вом клеток по ширине и высоте (я заметил вы такую и использовали). Для улучшения качества BlockMatcher'а, попробуйте BMState->uniquenessRatio = 0; Привожу мои рабочие параметры: BMState->preFilterSize = 17; BMState->preFilterCap = 31; BMState->SADWindowSize = 11; BMState->minDisparity = 13; BMState->numberOfDisparities = 256; BMState->textureThreshold = 35; BMState->uniquenessRatio = 0; Искомую матрицу репроекции Q вы можете заполнить вручную по формуле Q= стр 435 Learn OpenCV, используя ранее вычисленные матрицы: CameraMatrix и T, например.. но мне кажется это сложный путь, и ... некоторые величины (f, n) придется выдумывать. Вот набросал матрицу, которую вы можете использовать, подставив лишь расстояние между объективами камер: Но я не уверен, что она даст для вас точный и качественный результат. f можно уменьшить вовсе до 5 метров. Если вы вызовете cvStereoRectify() то наверняка ничего не потеряете, по книге инных вариантов не приводится. Матрицу Q нельзя извлечь из cvStereoRectifyUncalibrated() поскольку (стр 431): То есть, теоретически, если вы при калибровке, задавали реальные метрические координаты (с помощью размера) ваших клеточек, то на выходе ReprojectTo3D проекции получите реальные размеры и расстояния до объекта в метрах. Насколько я понимаю, disparityImage должен быть Float(существует быстрый вариант с Int). Подавать нужно disparityImage не нормализованный. Репроекцией еще сам не занимался, поэтому грабли раскрыть в этой теме пока не могу (может на этих выходных, тогда я бы отписался здесь). Прикрепляю свою шахматную доску (visio), может пригодится.
  18. 2 points
    Если там скрыта синусоида, то надо делать разложение в ряд Фурье. FFT даст пик на частоте синусоиды. Статейка с Хабра: https://habrahabr.ru/post/219337/ Имел дело с подобными кривыми когда измерителем пульса баловался: HartRateMeasure.zip Работа по которой делал: "Non-contact, automated cardiac pulse measurements using video imaging and blind source separation." легко гуглится.
  19. 2 points
    Хороший алгоритм. Если его правильно приготовить, то быстрый и очень точный. Надо добавить, что Szeliski только описал метод, его придумали ещё до него. А называется он... оптический поток Лукаса-Канаде! Да, именно так. Только применяется он не в привычном для всех виде для набора точек (или для одной точки), а к изображениям целиком. Правильный первоисточник называется Lucas-Kanade 20 Years On: A Unifying Framework. P.S. Кстати, охрененный метод для стабилизации видео, работает даже там, где ключевых точек нет и/или они смазаны motion blur. И быстрее, чем на основе fft, т.к. достаточная точность достигается уже на верхних уровнях пирамиды, не обязательно спускаться на уровень оригинального изображения.
  20. 2 points
    Спасибо! Именно это помогло! Кому нужно - в репозитории имеется около 3к идеально размеченных автоматом данных (больший объем пока не делал) А что с настройками обучения? Оставить все по дефолту? 40к итераций хватит? если у меня будет 10-30к изображений для тренировки? Как выявить наилучший результат при тренировке? https://github.com/Maxfashko/CamVid
  21. 2 points
    Статья о том как ускорить CPU Caffe и как использовать CPU+GPU. https://cs.stanford.edu/people/shadjis/CcT_DanaC.pdf http://arxiv.org/pdf/1504.04343.pdf https://github.com/HazyResearch/CaffeConTroll
  22. 2 points
    Выкладываю свои 9 лекций по машинному обучению это первая редакция, так что не судите строго Если заметите явные косяки - пишите. Lec1.pdf Lec2.pdf Lec3.pdf Lec4.pdf Lec5.pdf Lec6.pdf Lec7.pdf Lec8.pdf Lec9.pdf AdaBoost.pdf (может быть будет еще 4, если руки дойдут) Отличный курс тут (автор Н.Ю. Золотых): Машинное обучение.pdf Кому этого мало, поищите лекции Сергея Николенко и К.В. Воронцова. Если знаете английский, то лучше всего прочитать книгу: Christopher M. Bishop "Pattern Recognition and Machine Learning" и http://www-stat.stanford.edu/~tibs/ElemStatLearn/ Интересный блог по машинному обучению здесь: http://yaroslavvb.blogspot.com/ Очень хороший цикл видео лекций: http://www.youtube.com/user/aktoshik/videos?view=0 Лекции от mathematicalmonk: Много лекций по машинному обучению (англ.): https://alliance.seas.upenn.edu/~cis520/wiki/index.php?n=Lectures.Lectures
  23. 2 points
    Защитил диплом, забыл приложить финальный код, может кому пригодится. Большое спасибо Smorodov и всем отписавшимся. Считаются все необходимые параметры(коэффициент смещения колеса, делительная окружность, модуль колеса). При необходимости реализации масштаба, нужно домножить все параметры на коэффициент масштаба. #include "opencv2/opencv.hpp" #include <iostream> #include <vector> using namespace cv; using namespace std; int main(int ac, char** av) { vector<vector<Point> > contours; vector<Vec4i> hierarchy; vector<RotatedRect> minEllipse; vector<RotatedRect> minRect; string fname; float alpha = 20; if (ac > 1) { fname = av[1]; alpha = ::atof(av[2]); } else { cout << "Need filename!" << endl; cin.get(); return 0; } Mat frame = imread(fname); Mat drawing = frame.clone(); frame = 266 - frame; namedWindow("result"); cvtColor(frame, frame, cv::COLOR_BGR2GRAY); threshold(frame, frame, 1, 255, THRESH_BINARY); Mat thr = frame.clone(); /// Find contours findContours(frame, contours, hierarchy, cv::RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); vector<Point2f>center(contours.size()); vector<float>radius(contours.size()); vector<vector<Point> > contours_poly(contours.size()); for (int i = 0; i < contours.size(); i++) { approxPolyDP(Mat(contours[i]), contours_poly[i], 5, true); minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]); minRect.push_back(minAreaRect(Mat(contours[i]))); if (contours[i].size() > 5) { minEllipse.push_back(fitEllipse(Mat(contours[i]))); } } RNG rng(12345); for (int i = 0; i< contours.size(); i++) { Scalar color = Scalar(255, 0, 0); // contour drawContours(drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point()); // ellipse ellipse(drawing, minEllipse[i], color, 0, 8); // rotated rectangle Point2f rect_points[4]; minRect[i].points(rect_points); for (int j = 0; j < 4; j++) line(drawing, rect_points[j], rect_points[(j + 1) % 4], color, 1, 8); // окружность circle(drawing, center[i], cvRound(radius[i]), color, 1, 8, 0); // ÷ентр окружности line(drawing, cv::Point(center[i].x, 0), cv::Point(center[i].x, drawing.rows), Scalar(0, 0, 255)); line(drawing, cv::Point(0, center[i].y), cv::Point(drawing.cols, center[i].y), Scalar(0, 0, 255)); } // засемплим точки с окружности. float step = 0.001; float x = center[0].x; float y = center[0].y; float r = radius[0] * 0.9; Mat unrolled = Mat::zeros(100, CV_PI*2.0 / step, CV_8UC1); int i = 0; int tooth_thick = 0; vector<int> teeth; bool tooth = false; float normals[2][2]; for (float ang = 0; ang<CV_PI * 2; ang += step) { float xs = x + r*cos(ang); float ys = y + r*sin(ang); uchar c = thr.at<uchar>(ys, xs); drawing.at<Vec3b>(ys, xs) = Vec3b(0, 0, 255); if (c>128) { if (teeth.size() == 1 && tooth == false) { normals[0][0] = xs; normals[0][1] = ys; } tooth = true; tooth_thick++; line(unrolled, cv::Point(i, 0), cv::Point(i, unrolled.rows), Scalar::all(255),5); } else { if (tooth) { teeth.push_back(tooth_thick); tooth_thick = 0; //count++; if (teeth.size() == 1) { normals[1][0] = xs; normals[1][1] = ys; } } tooth = false; } ++i; } //do normals to surface of teeth //line(drawing, Point(normals[0][0], normals[0][1]), Point(800 * cos(alpha * 180 / CV_PI), normals[0][1] * sin(alpha * 180 / CV_PI)), Scalar(0, 255, 0), 1); //line(drawing, Point(normals[1][0], normals[1][1]), Point(800 * cos(alpha * 180 / CV_PI), normals[1][1] * sin(alpha * 180 / CV_PI)), Scalar(0, 255, 0), 1); float m = minRect[0].size.width/(teeth.size()+2);//модуль float d = m*teeth.size();//delitelnaya okrujnost float Db = d*::cos(alpha); float sb = (CV_PI*m) / 2; //tolshina po delitelnoy okrujnosti alpha = alpha * CV_PI / 180;//for invol (convert deg to radian) float X = ((normals[0][1] - normals[1][1]) - (Db*(sb / d + (tan(alpha)-alpha)))) / (2 * m*sin(alpha)); stringstream str; str << "d= " + to_string(minRect[0].size.width) << " "; str << "m= " + to_string(m) << " "; str << "x= " + to_string(X) << " "; //imshow("thr", thr); //imshow("unrolled", unrolled); Mat pic = cv::Mat::zeros(250, 250, CV_8UC3); putText(pic,str.str(), cv::Point(5, 10), CV_FONT_NORMAL, 0.3, Scalar::all(255), 1, 7, false); imshow("Результаты", pic); imshow("result", drawing); waitKey(0); destroyAllWindows(); return 0; }
  24. 2 points
    Ну чтобы не писать с нуля, вот начальная версия, делал давно, прилеплялку баннера так и не закончил: исходник: TILT.cpp Если что то улучшите, будет здорово. Юзаге: щелкаем левой кнопкой в одном углу начальной рамки затем в другом (ничего не отображается) затем жмем кнопку и ждем.
  25. 2 points
    Обзор методов обнаружения людей в кадре (некоторые исходники тоже присутствуют): http://rodrigob.github.io/
  26. 2 points
    Сам не люблю магию , я за интеллект. K-means хороший вариант. Вот еще самообучающийся алгоритм (главный параметр, это количество цветов int NrGMMComponents = 8 ): #include <opencv2/opencv.hpp> #include "opencv2/ml/ml.hpp" #include <vector> #include <list> #include <iostream> using namespace cv; using namespace std; void main(void) { // Количество кластеров (сколько разных цветов будет на конечном изображении) int NrGMMComponents = 8; // Имя исходного файла string fname="D:\\ImagesForTest\\passport.jpg"; cv::Mat SampleImg = imread(fname,1); cv::GaussianBlur(SampleImg,SampleImg,Size(3,3),1); int SampleImgHeight = SampleImg.rows; int SampleImgWidth = SampleImg.cols; // Набираем точки данных vector<Vec3d> ListSamplePoints; for (int y=0; y<SampleImgHeight; y++) { for (int x=0; x<SampleImgWidth; x++) { // Собираем точки с изображения Vec3b bgrPixel = SampleImg.at<Vec3b>(y, x); uchar b = bgrPixel.val[0]; uchar g = bgrPixel.val[1]; uchar r = bgrPixel.val[2]; if(rand()%25==0) // Берем не все точки подряд, а по равномерной выборке (примерно каждую 25-ую) { ListSamplePoints.push_back(Vec3d(b,g,r)); } } // for (x) } // for (y) // Формируем матрицу обучающих данных int NrSamples = ListSamplePoints.size(); Mat samples( NrSamples, 3, CV_64FC1 ); for (int s=0; s<NrSamples; s++) { Vec3d v = ListSamplePoints.at(s); samples.at<double>(s,0) = (float) v[0]; samples.at<double>(s,1) = (float) v[1]; samples.at<double>(s,2) = (float) v[2]; } // Напишем что нибудь по-английски. cout << "Learning to represent the sample distributions with " << NrGMMComponents << " gaussians." << endl; cout << "Started GMM training" << endl; cv::EM em_model; // Параметры алгоритма em_model.setInt("covMatType",cv::EM::COV_MAT_GENERIC); em_model.setInt("nclusters",NrGMMComponents); em_model.setInt("maxIters",1500); em_model.setDouble("epsilon",0.001); Mat labels(NrSamples,1,CV_32SC1); Mat logLikelihoods( NrSamples, 1, CV_64FC1 ); // Выполнение алгоритма обучения em_model.train( samples,logLikelihoods,labels); cout << "Finished GMM training" << endl; // Изображение, на котором будет отображаться результат Mat img = Mat::zeros( Size( SampleImgWidth, SampleImgHeight ), CV_8UC3 ); // Опрос классификатора для каждого пикселя Mat sample( 1, 3, CV_64FC1 ); Mat means; means=em_model.getMat("means"); for(int i = 0; i < img.rows; i++ ) { for(int j = 0; j < img.cols; j++ ) { Vec3b v=SampleImg.at<Vec3b>(i,j); sample.at<double>(0,0) = (float) v[0]; sample.at<double>(0,1) = (float) v[1]; sample.at<double>(0,2) = (float) v[2]; int response = cvRound(em_model.predict( sample )[1]); img.at<Vec3b>(i,j)[0]=means.at<double>(response,0); img.at<Vec3b>(i,j)[1]=means.at<double>(response,1); img.at<Vec3b>(i,j)[2]=means.at<double>(response,2); } } img.convertTo(img,CV_8UC3); imshow("result",img); waitKey(); // Сохраним в файл результат cv::imwrite("result.png", img); } [/code] Результат для 8 цветов: и для двух цветов: Дальше можно морфологию сделать (dilate, erode, см. выше) чтобы строчки слить в прямоугольные области. Затем найти контуры, габаритные прямоугольники и вынуть строки. Или сильно размываем ([code]cv::GaussianBlur(SampleImg,SampleImg,Size(3,3),1); заменяем на cv::GaussianBlur(SampleImg,SampleImg,Size(15,15),5);) затем кластеризуем (в примере 2 кластера), получим нечто в духе такого: И никакой магии
  27. 2 points
    Как и написано в пояснении темы SWT применяется для поиска произвольного текста на произвольном изображении. Алгоритм неплохо описан здесь (SWT on Nokia N900), там есть и исходники, и статья. В процессе изучения темы я немного "поиграл" с их исходниками, выделил весь SWT в один файлик, переписал на С++ OpenCV, в результате чего код стал намного компактней и капельку быстрей. Исходники в аттаче к сообщению. Также неплохой материал по SWT есть в статьях "Text Detection in Natural Scenes with Stroke Width Transform" Werner (2013) и "Detecting Text in Natural Scenes with Stroke Width Transform" Epshtein, Ofek, Wexler (2010). [off] Надо добавить, что SWT - это достаточно низкоуровневый алгоритм, который находит связные линии примерно одинаковой толщины. В разрабатываемой сейчас версии OpenCV 3.0 (вот оно) реализован более, ммм, высокоуровневый алгоритм (Class-specific Extremal Regions), находящий не отдельные символы, а регионы с текстом. Статьи гуглятся: 1. "Real-Time Scene Text Localization and Recognition" Neumann, Matas (2012) 2. "Multi-script Text Extraction from Natural Scenes" Gomez, Karatzas (2013) [/off] swt.zip
  28. 2 points
    Deep Neural Networks for Visual Pattern Recognition. Wednesday, August 6, 2014 9:00 AM - 10:00 AM PDT и 10 Billion Parameter Neural Networks in Your Basement Wednesday, August 20, 2014 9:00 AM - 10:00 AM PDT
  29. 2 points
    http://docs.opencv.org/trunk/modules/objdetect/doc/erfilter.html еще появилось недавно для детектирования текста Scene Text Detection
  30. 2 points
    Попробуй Intraface прикрутить: там 49 особых точек, остальные я думаю можно интерполяцией расставить. IntraFace предалагает либу для некоммерческого использования, есть демка, идет под винду и линукс, зависит от OpenCV. Когда-то на меня сильно произвел впечатление ролик . Но ничего подобного я сделать не мог и инструментная база была похуже.
  31. 2 points
    Скоро выложат запись и презентацию здесь: http://www.gputechconf.com/page/gtc-express-webinar.html В целом особенно нового ничего не было. Обзор ускоренных функций, сравнение с CPU и как преобразовать CPU-шную программу а GPU-шно ускоренную. Плюс перспективы распространения, CUDA на мобильные девайсы. Вопросы были в основном по мобильным чипам и "что почитать". Упоминали некую спецификацию OpenVX, я задал вопрос по документации а нее, но так ответа и не дождался нашел сам тут: http://www.khronos.org/openvx и тут: http://itseez.com/openvx
  32. 2 points
    AAM по инверсно-композитному алгоритму (octave и C++ исходники): https://code.google.com/p/octaam/ Интересные работы по AAM: http://www2.isr.uc.pt/~pedromartins/ 3D модель лица и некоторые заготовки: http://aifi.isr.uc.pt/Downloads.html Облачная распознавалка лиц: http://en.faceplusplus.com/
  33. 2 points
    Динамические ядра - это идущий из СССРовских времён синоним k-means Ну и переформулирую прошлый пост на ином языке. 1) У Вас есть N сэмплов 2) Кластеризуем их - получаем n кластеров, n<<N. Кластеризовать я советую онлайновым алгоритмом. 3) Для каждого кластера строим список из его нескольких ближайших соседей. Чтобы если при "боевой работе" придёт сэмпл с краю кластера - knn работал и с примерами соседнего кластера. Начинаем боевую работу 1) Приходит сэмпл - определяем, в какой кластер он попадает. Затрат - n вычислений длин векторов разностей. 2) Думаем - а не нужно ли взять какие-то соседние кластеры? Например, те, расстояние от сэмпла до центра которых сопоставимо с расстоянием от сэмпла до его кластера. В общем, тут можно придумать эмпирику, ради экономии вычислений берущую соседей только при достаточном удалении сэмпла от центра его кластера. 3) На сэмплах кластера (и, при необходимости, сэмплах его соседях) запускаем knn. Число примеров в этом одном или нескольких кластерах будет в разы меньше, чем N - во столько же раз и ускорится knn. Т.е. через пару-тройку десятков классификаций сэмплов - компенсируем время, затраченное на предварительную кластеризацию, и затем начинаем работать в плюс (по сравнению с постоянным запуском knn по всем N сэмплам)
  34. 2 points
    Реализовал решатель уравнения Пуассона для изображений. Если кратко, то по границе изображения и его градиентам восстанавливается исходное изображение. Применяется для различных манипуляций в пространстве градиентов (блендинг, фильтры, и т.д.). Например, реализовал на нем фильтр и блендер (в исходнике есть). Примеры работы: Смесь яблока апельсином: Фильтр обнуляющий слабые (меньше заданного порога) градиенты: (Порог 0.035) (Порог 0.045) Исходник: poisson_main.cpp ЗЫ: В качестве вспомогательных функций, реализованы прямое и обратное дискретное синусное преобразование изображения. ЗЫЗЫ: Очень интересный редактор (посмотрите видео работы) в пространстве градиентов с исходным кодом (GPU): http://graphics.cs.cmu.edu/projects/gradient-paint/ Хороший сайт с теорией и исходниками: http://www.umiacs.umd.edu/~aagrawal/ICCV2007Course/index.html
  35. 2 points
    Насколько я знаю, дескриптор - это некоторое описание точки изображения. То есть существует точка, координаты которой мы задаем произвольно или находим при помощи автоматического метода (например детектором Харриса). Но, нам нужно эту точку снабдить дополнительной биркой, по которой мы можем отличать ее от других аналогичных точек. Поэтому считаем дескриптор в этих координатах. Все дескрипторы использует окружение точки (соседние пиксели), но по-разному. Так вот HOG, это всего лишь способ вычисления дескриптора, по своей идее аналогичный SURF, SIFT, FAST и т.д. Гистограмма градиентов идет как дополнительная инфа к точке, а как Вы ее считаете (квадратиками или кружочками) дело уже третье. Почему это используется в детекторе? Потому что к яркости точки (1 параметр) добавляется еще описание контекста, в котором встречается эта точка (еще N параметров). Если дескриптор подобран правильно, то наличие дополнительных параметров (дополнительных измерений пространства параметров) существенно повышает наши шансы разделить классы. Вот тут еще почитайте: http://ru.wikipedia.org/wiki/%D0%93%D0%B8%D1%81%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0_%D0%BD%D0%B0%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B3%D1%80%D0%B0%D0%B4%D0%B8%D0%B5%D0%BD%D1%82%D0%BE%D0%B2 http://courses.graphicon.ru/files/courses/cg/2012/lectures/cg2012_04_recognition.pdf http://www.nada.kth.se/utbildning/grukth/exjobb/rapportlistor/2012/rapporter12/matute_arribas_victoria_12016.pdf PS: Есть еще T-HOG для детекта текстовых областей (pdf-ки и исходники на java): http://www.dainf.ct.utfpr.edu.br/~rminetto/projects/thog.html
  36. 2 points
    Погуглите GTSRB (соревнование german traffic sign recognition benchmark). Уже указанная тут статья Серманета и ЛеКуна - от людей, занявших в соревновании второе место (и в статье описавших дальнейшее улучшение точности распознавания). Также в инете есть и статья победителей. В общем, все лидеры использовали нейросетки (достаточно схожие между собой). Точность нейросеток оказалась лучше точности распознавания человеком. Т.е. если знак каким-то алгоритмом выделяется достаточно хорошо - то распознаваться затем он будет с почти 100% точностью (распознавалку можно будет сделать по описанным в статьях рецептам и натренировать на готовой базе).
  37. 2 points
    допустим для GetReal1D(CvArr*,int id1), выдает значение типа double, которое находиться по номеру id1 К примеру, IplImage* image = cvLoadImage("test.jpg", CV_8U); cvGetReal2D(image, 1, 1); выведет значение яркости в пикселе(1,1) 3D соответственно для трехмерного
  38. 2 points
    Соорудил пару функций для работы с дескрипторами Фурье. Первая функция, для контура вычисляет коэффициенты Фурье разложения (это и есть дескрипторы). Вторая функция по заданному количеству коэффициентов восстанавливает контур. Причем, если задать количество коэффициентов меньше полученного при разложении, то контур сглаживается, постепенно теряя мелкие детали. Здесь, для получения сглаженного контура, использовано только 20 комплексных коэффициентов из примерно 2000. FourierDescriptors.cpp Для получения контура использовался файл Contour.bmp (в архиве): Contour.zip
  39. 2 points
    Для начала от Стэнфорда: Machine Learning и Probabilistic Graphical Models. Там есть ещё (см. внизу страницы), но эти по нашей тематике. Кроме того, 20 февраля начинаются: PROGRAMMING A ROBOTIC CAR и BUILDING A SEARCH ENGINE Программировать надо будет на Питоне. Кто-нибудь записался? P.S. Жаль, что на всё не хватит ни времени, ни сил.
  40. 2 points
    так должно еще лучше получиться int64 t = cv::getTickCount(); //некий процесс t = cv::getTickCount() - t; qDebug() << "\tTime elapsed: " << t*1000/cv::getTickFrequency();
  41. 2 points
    Мне думается каскады Хаара не будут здесь хорошо работать. Они работают с серыми тонами, а Вы сами по серой фотке всегда легко определите где небо а где земля Детектор Хаара хорошо использовать там, где явно присутствует четкая форма объекта и можно выделить среднее изображение и его вариации. А у неба или земли среднее изображение одинаковые (серый фон). Так что можете попробовать, конечно, но думаю достаточной точности не добьетесь. Лучше уж текстурная сегментация (фильтрами Габора например). Я пробовал, траву в лесу сегментирует вполне сносно. Правая кнопка - помечаем кусочек одного класса, левая кнопка - помечаем кусочек другого класса, r - обучаем и сегментируем. Можно отделить обучение и сегментацию. Обучиьт SVM, сохранить её в файл, а затем когда надо сегментировать считать её и применить к картинке. GaborSegmentation.zip
  42. 2 points
    Сегментация изображения при помощи PCNN (Pulse-Coupled Neural Network) (на основе результатов исследования работы глаза морских свинок). Снимок результатов работы программы (при различных параметрах). закомментировал dilate, получилось что-то комиксоподобное ... double Beta=0.8; double alpha_theta=-2; double alpha_F=-0.9; double alpha_L=-0.1; double V_F=1; double V_L=1; ... Mat rect_12 = getStructuringElement(CV_SHAPE_RECT, Size(3,3) , Point(1,1)); erode(Y, Y, rect_12,Point(),1); //Mat rect_6 = getStructuringElement(CV_SHAPE_RECT, Size(3,3) , Point(1,1)); //dilate(Y,Y,rect_6,Point(),1);[/code] Если поэкспериментировать с параметрами, можно получать различные варианты сегментации. При реализации руководствовался книжкой: Lindblad J.M. Kinser "Image Processing Using Pulse-Coupled Neural Networks". Там можно прочитать теорию. Исходники: PCNN.RAR
  43. 2 points
    Не использовать глобальные переменные, использовать константные указатели для неизменяемых объектов и т.п. полезные рекомендации, которые помогают избегать непонятных глюков. Например: int SmoothTresholdFunc(const IplImage* image1, IplImage* image2) { cvSmooth(image1, image2, CV_MEDIAN, 3, 3, 0, 0); cvThreshold(image2, image2, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); cvSaveImage("test_crop2.jpg", image2, 0); return 1; } int main() { IplImage* src = cvLoadImage(path, CV_LOAD_IMAGE_GRAYSCALE); IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels); SmoothTresholdFunc(src, dst); cvSaveImage("test_crop.jpg", dst, 0); cvReleaseImage(&dst); cvReleaseImage(&src); return 0; }
  44. 2 points
    Алгоритмы распознавания видео http://compsciclub.ru/course/videorecognition Распознавание человека по лицу http://compsciclub.ru/node/1715 видео Распознавание человека по лицу http://video.yandex.ru/users/tswr2/view/12/'>http://video.yandex.ru/users/tswr2/view/12/ http://video.yandex.ru/users/tswr2/ http://www.lektorium.tv/course/?id=22847 Введение в компьютерное зрение Компьютерное зрение и библиотека OpenCV http://www.lektorium.tv/course/?id=22800
  45. 2 points
    Здравствуйте. Начав изучать OpenCV и заодно программирование столкнулся с рядом банальных (для программеров) проблем при решении задачи определения ориентации объекта в пространстве по его фотографии. Одной из основных было отсутствие материалов на русском (или неумение найти). Здесь приведено описание решения этой задачи. Просьба сильно не пинать т.к. прогер из меня аховый. Предполагается что читатель предварительно ознакомился с используемой математикой (например: Артем Конушин Геометрические свойства нескольких изображений), имеет установленную студию (у меня VS 2010) и OpenCV 2.2. Итак, краткое содержание предыдущей серии. Имеется мировая система координат (СК), имеется СК камеры. Переход между ними определяется матрицей внешнего ориентирования (иногда называют матрицей внешней калибровки) Е(4х4). Эти системы метрические, то есть координаты задаются в метрах, миллиметрах и т.д. Имеется также система координат кадра, координаты в которой задаются в пикселях. Переход из нее в СК камеры задается матрицей калибровки К(3х3). Постановка задачи: Дан объект. Известны координаты его некоторых точек (здесь и далее «особые точки») в мировой системе координат. Известны координаты изображения этих точек на снимке. Известна матрица калибровки камеры К. Надо найти. Матрицу ориентирования камеры Е в мировой СК. Она может быть представлена в виде матрицы поворота R и вектора переноса T камеры. Для начала представим данные в формате OpenCV. Подход следующий: создаем массив, и привязываем к нему создаваемую матрицу. Тогда любые изменения можно будет отслеживать в массиве или изменяя массив изменять саму матрицу (делаю так по причине незнания работы с матрицами). double Ktmp[9]={1, 0, 0, 0, 1,0, 0,0,1}; Mat K(3, 3, DataType<double>::type, Ktmp); // объявили матрицу и привязали к массиву В качестве К задана единичная диагональная матрица для упрощения проверки результатов. При такой калибровке 1 пиксель соответствует 1 единице длины (пусть будет миллиметр). Теперь зададим координаты точек объекта в мировой СК. Пусть это будет фрагмент шахматной доски, то есть координаты точек соединения квадратов. Например, 5 точек float modX[5]={0, 2, 4, 0, 2}; float modY[5]={0, 0, 0, 2, 2}; // массивы с координатами по осям float modZ[5]={0, 0, 0, 0, 0}; vector<Point3f> model_points; // массив «вектор» трехмерных точек. Сюда перепишем массивы. for (int i=0;i<5;i++) { model_points.push_back(Point3f(modX[i],modY[i],modZ[i]));// переписываем } Аналогично зададим координаты точек на изображении. Предположим наша камера не повернута относительно мировой СК, а только сдвинута вниз на 10 мм. Тогда координаты точек на картинке будут в 10 раз ближе к оптической оси камеры (которая в соответствии с заданной К находится в точке (0,0) кадра). float imX[5]={ 0, 0.2, 0.4, 0, 0.2}; float imY[5]={0, 0, 0, 0.2, 0,2}; vector<Point2f> image_points; for (int i=0;i<5;i++) { model_points.push_back(Point2f(imX[i],imY[i]));// переписываем } Теперь для функции надо указать еще и дисторсию, Но ее пока не учитываем Mat_<double> distCoeffs(1, 5); distCoeffs << 0.0, 0.0, 0., 0., 0.; // дисторсия по нулям Готовим переменные для выходнызх данных double rvectmp[3]={0.0};// сами переменные double tvectmp[3]={0.0}; Mat rvec(3, 1, DataType<double>::type, rvectmp); // привязываем матрицы (точнее вектор-столбцы) Mat tvec(3, 1, DataType<double>::type, tvectmp); Творим волшебство (Mat(image_points) видимо означает преобразование типа «вектор» к типу «Матрица» иначе компилятор ругается). solvePnP(Mat(model_points), Mat(image_points), K, distCoeffs, rvec, tvec, false); false – означает что расчеты ведутся с нуля, без начального приближения (см документацию) теперь что же делать с результатом? tvec, а вместе с ним и tvectmp теперь содержит координаты точки фокуса камеры в мировой СК. rvectmp содержит углы поворота СК камеры относительно мировой СК. Надо преобразовать в матрицу поворота R double Rtmp[9]={0.0}; Mat R(3, 3, DataType<double>::type, Rtmp); Rodrigues(rvec,R); //пересчет углов поворота в матрицу поворота Теперь Rtmp содержит коэффициенты матрицы поворота. Задача решена. Для текущих данных должно получаться: повороты по нулям, матрица поворота единичная диагональная, вектор переноса T=(0,0,-10) Текущий код не компилил, писал по памяти и по старому варианту, так что могут быть синтаксические ошибки. Но подход работал точно. Как сохранить решение и прочитать входные массивы (например из файла) уже даже чайник вроде меня должен сообразить. Спасибо за внимание. Ваши комменты.
  46. 2 points
    Конечно, помогаем! Первый шаг - отказ от Делфи. Двигаемся дальше?
  47. 2 points
    http://see.stanford.edu/see/courses.aspx Содержание того что там есть: Introduction to Computer Science ---------------------------- Programming Methodology Programming Abstractions Programming Paradigms Artificial Intelligence ---------------------------- Introduction to Robotics Natural Language Processing Machine LearningCS229 Linear Systems and Optimization ---------------------------- The Fourier Transform and its Applications Introduction to Linear Dynamical Systems Convex Optimization Convex Optimization Additional School of Engineering Courses ---------------------------- Programming Massively Parallel Processors iPhone Application Programming Seminars and Webinars
  48. 2 points
    Видеоиллюстрация работы адабуст:
  49. 2 points
    Мультибуст классификатор (AdaBoost для количества классов больше двух) (не opencv) :multiboost.tar.gz
  50. 2 points
    У меня программа вылетала с ошибкой "divizion by zero" на строчке: if( !cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 )) Стал искать причину, обнаружил, что функция naiveNearestNeighbor может возвращать одну и ту же точку сколько угодно раз. То есть, для примера, у нас найдено n особенностей для исходного изображения и 1 особенность для изображения с камеры, тогда эта одна точка почему-то будет считаться парой для всех n точек из шаблона. Скорее всего функция naiveNearestNeighbor не очень верно работает (я с ней особо не разбирался), возможно, необходимо добавить туда еще какой-то порог или изменить существующие параметры. Добавил в функцию findPairs вот такую заглушку: if( nearest_neighbor >= 0 && nearest_neighbor != last_neighbor) { ptpairs.push_back(i); ptpairs.push_back(nearest_neighbor); last_neighbor = nearest_neighbor; } Хотя, все равно иногда вылетает та же ошибка (может быть это проблема борландовского компилятора), так что надо туда просто повесить обработчик ошибок и забить. На всякий случай прикрепляю проект для borland builder 6, вдруг кому-то пригодится. OpenCV SURF.rar
×