Dmti 0 Жалоба Опубликовано October 24, 2014 Извините, что задаю много вопросов, но по ходу здесь самый авторитетный форум по Opencv. В своём проекте для панорамной камеры вся задача решалась легко, брал кадр, потом из него вычитал второй, полученный с задержкой, и смотрел построчно, что осталось. Рассчитывал средние арифметическое и посылал в порт. И так два раза в секунду. Пришлось поработать с Ардуинкой, чтобы не дергалась на шумы и поворачивалась в нужную точку, но это всё легко. А повис, когда захотел, чтобы вторая камера не только записывала то, что видит, а ещё и пыталась определить - попало или нет лицо в кадр. Взял готовый урок http://recog.ru/blog/opencv/62.html ,чуток переделал по своему пониманию, но не смог преодолеть несколько ошибок. Вот кусок, пока работает с фотками // Читаем изображения и присваиваем им номера (на каждого человека) vector<Mat> images; vector<int> labels; images.push_back(imread("1.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("2.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(2); images.push_back(imread("3.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(3); Mat testSample( imread("4.jpg", CV_LOAD_IMAGE_GRAYSCALE)); int testLabel = 1; // get width and height int height = images[0].rows; // Строится Fisherfaces model для тренировки Ptr<FaceRecognizer> model = createFisherFaceRecognizer(); //тренируем модель model->train(images, labels); // Тестируем к какому изображению относится модель int predicted = model->predict(testSample); получаю ошибку при вызове model->train и int predicted. Пробовал переустановить" libopencv_contrib249d.dll.a" думал, может криво поставил (не помогло). Перечитал весь хелп, но вот пришел с поклоном ПОМОГИТЕ определить ошибку. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 25, 2014 Система обычно такая: 1) Находим лицо в кадре. Этим занимается обычно детектор, и чаще всего, это детектор Виолы-Джонса (ака детектор Хаара). На выходе прямоугольная область, содержащая лицо. 2) Масштабируем найденное лицо (часто еще и выравниваем, выравниваем гистограмму, и т.д.), в соответствии с теми изображениями на которых учился распознаватель (классификатор, если правильно). Ибо классификатор образов умеет разбираться только в векторах той размерности на которой учился. 3) Подаем подготовленное лицо на классификатор. 4) Получаем и отображаем ответ. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 26, 2014 Я читал, что Виолы детектор более современный, чем Хаара, но выбор пал в связи больших примеров и описаний. Трудно что-то изучать, если везде написаны только теории и мало примеров с описаловом. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 26, 2014 Посмотрите мою лекцию по детектору Виолы-Джонса, может понятнее станет. Лекция см. аттач пост №111. И еще, то, что называют детектором Вилы-Джонса и детектором Хаара, это одно и то же. Но правильно первое, так как признаки Хаара, это только часть детектора. Здесь еще материал по Ада Буст: http://www.compvision.ru/forum/index.php/topic/543-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80-adaboost/?hl=%D0%B8%D0%BB%D0%BB%D1%8E%D1%81%D1%82%D1%80%D0%B0%D1%86%D0%B8%D1%8F#entry4012 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 26, 2014 За два дня столько теорий начитался, что во всёй этой воде тону. Короче, всё это откинул, и для начала нашел действующий пример http://docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html#cascade-classifier . Там используется другой метод, //-- Detect faces face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) ); по крайней мере он работает. Вот теперь и буду пробовать теории, но уже на практике. Но по-моему, этот метод сильно медленный, или я ошибаюсь. (Мне не надо распознать лицо, мне надо зафиксировать: было или нет лицо в кадре.) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 26, 2014 Это и есть метод Виолы-Джонса, (если загружает каскады Хаара, есть еще метод основанный на LBP). Это самый быстрый метод на сегодня. Для того чтобы работало быстрее добавьте ключик CV_HAAR_FIND_BIGGEST_OBJECT будет искать только наибольший объект. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 26, 2014 Тут в начале программы есть переменная.RNG rng(400); объявлена, и не где не используется. Я так понимаю, какое-то случайное число, а зачем надо, не где найти не могу. CV_HAAR_FIND_BIGGEST_OBJECT несильно ускорило. Запустил домашнюю вебку в VCL-player она и там притормаживает видео с задержкой в пол секунды. Буду разбираться с дровиной. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 26, 2014 RNG - это генератор случайных чисел. Если не используется, можно попробовать убрать. Существенно ускорить можно уменьшив изображение в несколько раз. Все равно поиск лиц обучен на шаблонах 24х24. Так что если лицо крупнее, можно пробовать уменьшать. Только надо в параметрах детектора поменять значения минимального размера искомого объекта. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 26, 2014 Почитал про свою вебку. Задержка - это норм. время обработки кодака. Есть где - нибудь вразумительное описание на русском? А то за эти два дня словарь изрядно поистрепался. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 26, 2014 Попробовал разрешение камеры уменьшить, убрал все авто, ничего не помогло. На самом деле работать будет на компе побыстрей, но и камера 600х800, плюс ещё одна панорамная тоже 600х800. Потом попробую разделить на потоки,чтобы параллельно работали, но пока разбираюсь с алгоритмами. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 26, 2014 Есть где - нибудь вразумительное описание на русском? А то за эти два дня словарь изрядно поистрепался. Метод Виолы-Джонса есть на хабре, например: http://habrahabr.ru/post/133826/ Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 26, 2014 Такое описание и искал. СПАСИБО. И ещё, я заметил, что чем дольше программа работает, тем больше отставание картинки во времени. Может, можно как - то сделать, чтобы не каждый кадр просчитывался, а тот, который на данный момент снимает камера. Предполагаю, что Capture надо как - то очищать. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 26, 2014 Да по идее то, камера (если в драйвере чего-нибудь чуднОго не накрутили) ничего не буферизирует, просто программа периодически забирает текущий кадр и обрабатывает его. Отставать может из-за того что захваченный кадр долго кодируется/декодируется. То есть захватил кадр, посекунды кодировал, потом переслал еще полсекунды раскодировал, вот и получили задержку в секунду. Если сильно замедляется посмотрите память, пожираемую процессом, может быть есть утечка. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 26, 2014 Метод Виолы-Джонса есть на хабре, например: http://habrahabr.ru/post/133826/ Я где - то эту статью на буржуйском уже читал. Интересно перечитывать на нормальном русском, сколько я при переводе упустил, и больше половины было непонятно. Спасибо. А с памятью уже проверяю, задержка нарастёт - память сравню. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 26, 2014 Проверка показала, что память грузится первых 10 мин., а потом стабилизируется. (с 560000 поднимается до 850000 приблизительно), а дескрипторы так и продолжают расти примерно 4 в сек.(прыгает туда - сюда, поэтому тоже приблизительно). А сколько по - нормальному должна занимать прога, я и приблизительно не знаю: сравнить не с чем. И ещё, почему после того, как я выхожу из цикла, там остаётся только Return 0; а окна, оба, не закрываются. if( capture ){while( true ){ // направляем поток в вектор frame = cvQueryFrame( capture ); if( (char)waitKey(1) == 'c' ) { cvReleaseCapture( &capture ); cvDestroyWindow(window_name); break; } } . . . return 0; Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 26, 2014 Я так обычно делаю: #include "opencv2/opencv.hpp" #include <iostream> #include <vector> #include <stdio.h> using namespace cv; using namespace std; int main(int ac, char** av) { VideoCapture capture0(0); namedWindow("Cam0"); Mat frame0; int k=0; while(k!=27) { capture0 >> frame0; // Здесь делаем что нибудь умное. .. .. // Отображаем результат imshow("Cam0",frame0); k=waitKey(20); } destroyAllWindows(); return 0; } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 27, 2014 Как вариант красиво смотрится, на целую проверку меньше операций. И ещё, есть какая - нибудь разница в скорости в двух блоках: 1. CvCapture* capture; Mat frame; capture = cvCaptureFromCAM( 0 ); {while( true ){ frame = cvQueryFrame( capture ); 2. VideoCapture capture0(0); namedWindow("Cam0"); Mat frame0; while(true) { capture0 >> frame0; в уроках встречаются оба варианта, а какой новее или быстрее - пока не разобрался. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 27, 2014 Первый, это старый C-шный интерфейс, второй C++ ный. Скорее всего есть потеря времени на преобразовании IplImage* в cv::Mat при присвоении в первом варианте т.к. IplImage* cvQueryFrame(CvCapture* capture) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Dmti 0 Жалоба Опубликовано October 27, 2014 Спасибо, я уже попробовал и увидел заметное ускорение, но со временем задержка все равно накапливается, и в конечном итоге задержка прежняя. В борланде я бы опрашивал каждую камеру не в цикле, а использовал бы класс TTimer, чтобы разнести по потокам. Чем лучше воспользоваться в Qt консольном приложении? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 27, 2014 Я как то юзал код отсюда: https://code.google.com/p/qt-opencv-multithreaded/ Правда оно не консольное. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах