Wildcat 2 Жалоба Опубликовано December 5, 2011 Пытаюсь переписать распознавание по PCA на новый OpenCv 2.3. Там есть класс РСА, с помощью которого можно реализовать это. Вот что у меня получилось по коду: #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/gpu/gpu.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/features2d/features2d.hpp> #include <vector> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { ArgParser parser(argc, argv); char filelist[200]; try { if (!parser.queryFilename("filelist", filelist)) { printf("Filelist not specified.\n"); _getch(); return -1; } } catch (char* str) { printf("%s\n", str); _getch(); return -1; } FilelistProcessor flP(filelist); const unsigned numpics = 100; vector <cv::Mat> img_tr; for (unsigned i = 0; i < numpics; i++) { cv::Mat itmp = cv::imread(flP.getfile(i), 0); img_tr.push_back(itmp); } unsigned imsize = img_tr[0].rows*img_tr[0].cols; cv::Mat mat_tr(numpics, imsize, img_tr[0].type()); for (unsigned i = 0; i < numpics; i++) { cv::Mat matRow = mat_tr.row(i); memcpy(matRow.data, img_tr[i].data, imsize*sizeof(unsigned char)); } const unsigned maxComponents = 60; cv::PCA eigenvectorsCompute(mat_tr, cv::Mat(), CV_PCA_DATA_AS_ROW, maxComponents); cv::Mat newImg = cv::imread(flP.getfile(numpics + 1), 0); cv::Mat newImgTr(1, imsize, img_tr[0].type()); { cv::Mat matRow = newImgTr.row(0); memcpy(matRow.data, newImg.data, imsize*sizeof(unsigned char)); } cv::Mat coeffs; coeffs.create(1, maxComponents, CV_32F); eigenvectorsCompute.project(newImgTr, coeffs); return 0; } FilelistProcessor - читает список файлов с изображениями лица. Файлов больше 100, поэтому ошибки в количестве векторов быть не может. Проблема в том, что полученные на выходе coeffs - нулевые. Что может быть не так? 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Wildcat 2 Жалоба Опубликовано December 6, 2011 Нашла в чем проблема - изображения, по которым строится РСА должны быть приведены к типу CV_32FC1. Тогда все строится вполне корректно. Хотя в процессе поиска ошибки все переписала заново, код стал другим. Может еще есть какие-то неточности. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
diana87 0 Жалоба Опубликовано May 21, 2012 А вы бы могли, эту программу сбросить на электронный ящик diana87@mail.by , т.к. я не могу ее скачать.... Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 21, 2012 ok, скинул. Оба варианта, с начала темы и с этой страницы. PS: Не скачиваться может из-за менеджеров загрузки. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 25, 2012 С марковскими моделями не стал разбираться, а с PCA сразу с ходу пошло дело. Неплохо работает! Мануал на английском тема) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 25, 2012 Есть вопрос, подскажите пожалуйста! Я нахожу в кадре лицо каскадами Хаара. Затем выделяю найденную область(как в примере прямоугольником). Как мне найденную область фотографии сохранить в JPG и сделать строго определенного размера? Например 100х100 пикселей. Спасибо. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 25, 2012 Если в С, то через ROI http://nashruddin.com/OpenCV_Region_of_Interest_(ROI) если в с++, то img(Rect(x,y,w,h)).copyTo(img1); а затем Resize http://linuxconfig.org/resize-an-image-with-opencv-cvresize-function Вот кусок из одной программы подобного назначения: CvRect * pFaceRect = (CvRect*)cvGetSeqElem(pRectSeq, 0); cvSetImageROI(pImg, *pFaceRect); IplImage * pFaceImg = cvCreateImage( STD_SIZE, IPL_DEPTH_8U, 1 ); cvResize(pImg, pFaceImg, CV_INTER_AREA ); [/code] 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 26, 2012 Спасибо большое! Применил cvSetImageROI, все прекрасно работает под C++/cli. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 27, 2012 Еще вопросик есть по этой теме. Для распознавания лица методом главных компонент обязательно преобразовывать цветное изображение в градации серого? Как в этом ПРИМЕРЕ . И если обязательно, то как это сделать? Наверняка есть какая то встроенная функция, но поискав я нашел только работу с каналами RGB. Пробовал копировать 3-х канальное изображение в созданное вот таким методом cvCreateImage( STD_SIZE, IPL_DEPTH_8U, 1 ), сразу вылезает ошибка. Я так понял что нельзя запихнуть автоматом цветное изображение в черно-белое. Как быть? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 27, 2012 Как конвертировать нашел. Функция cvCvtColor(img, im2, CV_BGR2GRAY). Но про необходимость этого конвертирования вопрос актуален) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано May 28, 2012 можно сразу грузить в грей, конвертировать скорее надо т.к. полезной информации в 3-х каналах не так много(опять же цвет волос) или можно по 3-м каналам отдельно смотреть. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 29, 2012 Нужен совет! Последния два дня меня убивает непонятная вещь, а именно виснет приложение, которое фотографирует, находит лицо ресайзит его и записывает в БД на компьютере. Причем оно виснет оно самым странным образом. 1)Запускаю приложение. При этом сразу отображается видео с камеры на форму. 2)Нажимаю кнопку сфотографировать. 3)Находит лицо. 4)Фотографирует, ресайзит и сохраняет в БД все успешно. 5)Видео продолжает отображаться и вроде все впорядке. Можно даже нажать "Закрыть" и все закроется как надо. НО 6) Если взять окно и попробовать перетащить его, сразу же "Завершена работа программы.." и "Widows ищет поиск решения данной проблемы.." Еще одно - на ноутбуке все работает замечательно, ничего подобного не происходит. Практически всё идентично: ОС Windows 7, MS Visual Studio 2010, MS SQL 2008, разве что на ноутбуке стоит 64-х разрядная система. Думал, что может из-за веб камеры. Но поставил камеру с компьютера на ноутбук, там и с этой камерой все работает прекрасно. К тому же иногда работает все прекрасно и на компьютере. В связи с чем такое может быть, куда смотреть, что делать даж не знаю. Может у кого то были подобные проблемы? Спасибо за ваши ответы! Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 29, 2012 А если скомпилировать под х64, работает ? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 29, 2012 Если не секрет, как это сделать?) На компьютере где висне стоит ОС 32 разрядная. На ноуте 64-х. Где именно копилировать надо? И как поменять настойки сборки, чтобы это сделать. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 29, 2012 Перетрудился я сегодня, тупить начал )). А он и в отладочной и в релизной версии одинаково глючит? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 29, 2012 Нет, в отладочной версии еще при запуске "Возникла точка останова" и на ноуте и на компе. Но я отладочную версю запускал с библиотеками OpenCV для релизной версии. Может из-за этого? Я еще думал что мож из-за фреймворка такое может быть каким то образом? Хотя и на ноутбуке и на компьютере ставился новый 4,5 вроде со студией. Приложение я пытаюсь сделать на 3-м фреймворке. Реально уже не знаю, что придумать. Еще есть такое, что без нахождения лица работает стабильно. Может слишком много дейсвий при нажатии кнопки происходит и 32-х разрядная система не справляется? Хотя вроде ересь. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 29, 2012 Может. Если отладочную версию с релизными библиотеками запускать, GUI-шные функции глючат по-черному. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 29, 2012 Эх, а что ж делать с моим багом при релизной версии? Может туплю п острашному. Нашел еще один момент. Для того чтоб получить при фотографировании картинку качества получше, увеличиваю разрешение считываемого кадра, т.к. видео с камеры отображается в миниатюрном окошке, если убрать это изменение кадра, то все работает, но фото конечно отстойного качества. Может надо как то оптимизировать эту задачу? Хотя все тоже - на ноуте работает с любыми настройками. timer1->Stop();// Counter = 0; //счетчик времени для показа "Данные записаны в БД" //BuffCount =0; cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1280); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 1024); frame = cvQueryFrame( capture ); //-------/возврат к миниатюрному изображению/-----------// cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, WidthFrame); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, HieghtFrame); Спасибо еще раз, за ваши ответы! Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 30, 2012 Сильно похоже на переполнение стека, у Вас таймер останавливается на время вывода кадра? timer1->Stop(); - это остановка таймера вызывающего функцию или это профилировка ? Просто ситуация может быть такая: Таймер вызывает функцию с интервалом времени, почти точно равным времени выполнения этой функции. Когда дергаете окно мышью, сообщения таймера задерживаются, и при первой возможности идут пачкой с короткими интервалами. Функция вызывается много раз, и стек переполняется, или возникают проблемы с потоками. Резюме: Попробуйте останавливать таймер в функции обратного вызова, увеличьте интервал таймера, или уменьшите время выполнения функции обратного вызова. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
JoQeR 0 Жалоба Опубликовано May 30, 2012 timer1->Stop(); <-- это у меня остановка таймера, который отвечает за воспроизведение кадров в pictureBox. Спаибо за ответ, очень похоже что у меня как раз эта проблема. Но т.к. я еще новичек в этом деле, особенно с таймерами. Что есть функция обратного вызова у таймера Windows Forms? У системного таймера есть такая функция. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Flame 1 Жалоба Опубликовано May 31, 2012 Smorodov, А почему количество векторов базиса это количество изображений - 1 ? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 31, 2012 2JoQeR: Функция обратного вызова, это та функция, которая вызывается таймером по истечении заданного интервала времени, то есть та самая функция, в которой Вы пишите что должно произойти по таймеру. 2Flame: Теоретически количество векторов базиса может быть любым, в пределах ненулевых собственных значений. количество изображений - 1 - это, как мне думается, такая opencv-шная фишка (ранних версий), в 2.4 я считал собственные векторы, этого ограничения нет http://www.compvision.ru/forum/index.php?showtopic=852&st=20 (пост №37). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано May 31, 2012 нет -1 это от матана\линала такая фишка(http://www.cognotics.com/opencv/servo_2007_series/part_4/page_2.html ), что когда проецируем можем спроецировать на n-1 измерение, я так понимаю, можем и на меньшее кол-во ,а на большее не можем. The PCA Subspace However, the number of principal components we can find is also limited by the number of data points. To see why that is, think of a dataset that consists of just one point. What's the direction of maximum separation for this dataset? There isn't one, because there's nothing to separate. Now consider a dataset with just two points. The line connecting these two points is the first principal component. But there's no second principal component, because there's nothing more to separate: both points are fully on the line. We can extend this idea indefinitely. Three points define a plane, which is a 2D object, so a dataset with three data points can never have more than two principal components, even if it's in a 3D, or higher, coordinate system. And so on. In eigenface, each 50x50 face image is treated as one data point (in a 2,500 dimensional "space"). So the number of principal components we can find will never be more than the number of face images minus one. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано May 31, 2012 А, ну да, это идет от экономного способа поиска матрицы ковариации. http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=calccovarmatrix#cv.CalcCovarMatrix Там перемножаются транспонированные матрицы точек, результат имеет размерность NxN, где N количество изображений. Есть и другой (стандартный) способ, без транспонирования, там матрица ковариации получается размерностью MxM, где M размерность вектора (кол-во точек в изображении). Прикол в том, что максимальные собственные векторы в этих двух случаях совпадают. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Flame 1 Жалоба Опубликовано June 1, 2012 А кто нибудь реализовывал порог отсечения левых лиц в этой проге? по статье на хабре там порог 2.2 у него а у меня что то расстояния редко больше 2х получаются... или в данном коде for (i=0; i < nEigens; i++) { float d_i = projectedTestFace[i] - coeffs[iTrain][i]; distSq += d_i * d_i/EigenVals->data.fl[i]; } считается эвклидово расстояние? а в статье я так понял расстояние Махаланобиса. Кто знает как его посчитать? Я так понял что по PCA проще сделать порог отсечения, чем по марковским моделям Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах