Виталий 6 Жалоба Опубликовано February 9, 2011 Задача: по изображению с камеры определить направление смотрения. снимок получается с вебкамеры, лицо подсвечивается одним мощным светодиодом. пример в прикрепленном файле. По снимку нужно определить относительное смещение зрачка и отражения( в координатах рисунка). 1) Определение отражения. Использованные свойства: отражение наиболее яркое, круглое и находится на темном фоне. после вычитания фона легко находиттся. Средняя ошибка около одного пиксела (при разрешении 640*480) 2) Определение координат зрачка Использованные свойства: находится недалеко от отражения, круглый, наиболее темный. Помехи: отражение светодиода(решается закрашиванием), ресницы. Придумал несколько способов как это сделать: -пороговое преобразование с предварительным размытием. Выделение происходит очень нестабильно из-за близкорасположенных ресниц. Пробовал с различными уровнями размытия и порога и относительно часто происходит сбой алгоритма. -использование встроенного детектора окружностей с предварительной обработкой. метод работает, но слишком часто выдает много окружностей или совсем не выдает. Интересующая нас окружность детектируется с большой погрешностью и не всегда. -детектор канни при некоторых параметрах размытия и значений порогов выдает приемлемые границы зрачка. Как лучше отфильтровать нужную границу и получить из нее примерный центр зрачка? -использовать какие-либо функции слежения за зрачком и близлежащей радужной оболочкой. Пока не реализовывал. Интересует Ваше мнение как можно более точно и устойчиво к помехам определить координаты центра зрачка? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано February 10, 2011 Окружности можно находить по-разному. Например, так: int main() { IplImage *img = cvLoadImage("d:\\eye.PNG"); IplImage *bin_img = cvCreateImage(cvGetSize(img), 8, 1); cvCvtColor(img, bin_img, CV_RGB2GRAY); cvEqualizeHist(bin_img, bin_img); cvCanny(bin_img, bin_img, 50, 150); CvMemStorage *storage = cvCreateMemStorage(0); CvContourScanner traverse = cvStartFindContours(bin_img, storage, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE); for (CvSeq *contour = cvFindNextContour(traverse); contour; contour = cvFindNextContour(traverse)) { if (contour->total > 6) { CvBox2D box = cvFitEllipse2(contour); CvPoint center = cvPointFrom32f(box.center); CvSize size = cvSize(cvRound(box.size.width * 0.5), cvRound(box.size.height * 0.5)); // Проверка на окружность if ((double)box.size.width / (double)box.size.height > 0.9) cvEllipse(img, center, size, -box.angle, 0, 360, CV_RGB(0, 0, 255), 1, CV_AA, 0); } } cvEndFindContours(&traverse); cvReleaseMemStorage(&storage); cvShowImage("1", img); cvShowImage("2", bin_img); for (; { if (cvWaitKey(10) > 0) break; } cvReleaseImage(&bin_img); cvReleaseImage(&img); return 0; }[/code] В результате есть и ложные сработки, но их можно отфильтровать по "вторичным половым признакам": 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Виталий 6 Жалоба Опубликовано February 11, 2011 Спасибо за код, особенно за функцию cvFitEllipse2 - я хотел ее в ручную писать. Вставил подкорректированный кусок кода в свою прогу - работает нормально. Чаще всего элипс находится, как надо, иногда граница зрачка определяется как 2 контура, иногда элипс получается вытянутым. Сейчас попробую перейти от детектора канни к адаптивному порогу. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано February 11, 2011 Для лучшего выделения контуров ещё можно усилить контрастность в определённом диапазоне яркостей. Не знаю на счёт OpenCV (есть в Фотошопе), но и самому реализовать довольно просто: 1. если яркость пикселя I[x, y] ниже некоторого нижнего порога t, то I[x, y] = k * I[x, y], где 0 > k < 1; 2. если яркость пикселя I[x, y] выше некоторого верхнего порога T, то I[x, y] = min(255, K * I[x, y]), где 1 > k < 2; 3. 0 < t < T < 255. Подбирая нижний и верхний пороги, а также коэффициенты усиления и ослабления можно добиться неплохого выделения исходного объекта, если тот находится на фоне с другой яркостью. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано February 11, 2011 Написал и самому стало интересно - будет ли оно работать. Набросал кусочек, попробуй вставить его вместо cvEqualizeHist: unsigned char t = 10; unsigned char T = 20; double k = 0.2; double K = 1.5; for (unsigned char *pbuf = (unsigned char *)bin_img->imageData, *stop = (unsigned char *)(bin_img->imageData + bin_img->imageSize); pbuf < stop; ++pbuf) { if (pbuf[0] < t) { pbuf[0] = (unsigned char)(k * (double)pbuf[0]); } else if (pbuf[0] > T) { pbuf[0] = (unsigned char)std::min(255., K * (double)pbuf[0]); } } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Виталий 6 Жалоба Опубликовано February 13, 2011 Я понял,что ты имел ввиду, Nuzhny. Такое преобразование должно быть непрерывным. В твоем случае получится разрыв с уровнем по яркости t и T, поэтому появится лишняя граница по этому уровню Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Виталий 6 Жалоба Опубликовано February 14, 2011 сделал немного по-другому. Все, что выше определенного порога приравнял к порогу тресхолдом, тк интересует только темная граница. Далее канни и проверка окружности на вшивость. Стало более стабильно работать. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Виталий 6 Жалоба Опубликовано February 15, 2011 эксперименты с алгоритмами к более лучшему результату не превели. Теперь есть другая задача: имеется некоторое отображение точек из одной плоскости в другую. мы знаем координаты образа и прообраза нескольких точек. Как по этим данным найти наиболее точное отображение? Наверняка есть некоторые функции opencv, но какие? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано February 15, 2011 cvFindHomography Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Виталий 6 Жалоба Опубликовано February 15, 2011 опять в точку. эта именно эта функция. иду изучать ее. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано February 24, 2011 Случайно наткнулся на достаточно новую статью по теме: "REAL-TIME CALIBRATION-FREE AUTONOMOUS EYE TRACKER" Klefenz, Husar, Krenzer, Hess Там подход посложнее рассматривается. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Виталий 6 Жалоба Опубликовано March 3, 2011 Там используется пороговое преобразование зрачка. у меня данный метод не прокатил - самые яркие пиксели зрачка ярче темных пикселей роговицы. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
flacs 0 Жалоба Опубликовано March 9, 2011 Здраствуйте. Интересует следующий вопрос. Реально ли с помощью функций opencv, задетектить поворот головы, поворот зрачка в определнную сторону (вправо, влево, вверх вниз). Если да, то можно ли определить угол поворота головы/зрачка, отталкиваясь от фронтального вида ?? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано March 10, 2011 Реально. Но необходимо хорошее освещение. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
flacs 0 Жалоба Опубликовано March 11, 2011 Уже хорошо. А какие API функции opncv вы порекомендовали бы использовать для реализации данной задачи? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано March 11, 2011 Сначала должен быть алгоритм, хотя бы в общих чертах, а функции это дело третье. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
flacs 0 Жалоба Опубликовано March 12, 2011 Вот вкратце, что я хотел бы видеть и как я это себе представляю. В этой сфере я новичок, поэтому прошу сильно не пинать. Что я хочу получить в итоге: При повороте головы (в конечном варианте - зрачка), моя программа должна выполнять некие действия. Возможные положения (влево, вправо, вверх, вниз). Главное условия, чтобы программа четко детектировала данные положения головы (зрачка), без ошибок, ну или с в большей степенью вероятности (не меньше 80%) Как я себе это представляю. Примерный алгоритм. 1) Получаю снимок с камеры, выделяю лицо каскадами хаара. Кстати есть более надежные методы? 2) Выделенный паттерн лица, распознать методами (EigenFace, Hide-Mark-Model). К примеру имеется в базе имеется 4 паттерна (т.е. для различных положений головы). В базе есть сл. паттерны. а) Фронтальный вид лица. б) Где лицо чуть повернуто влево (не в профиль) в) Где лицо чуть повернуто вправо (не в профиль) г) Лицо повернуто вверх д) Лицо повернуто вниз Распознать и выделить паттерн, который наиболее совпадает. Тем самым в дальнейшем интерпретировать картинки -> в действия. Вот как я себе это представляю. А теперь вопросы. Насколько это будет надежно? Есть более продвинутые методы? (слышал о технологии трехмерной модели головы). Какие функции opencv можно было бы использовать для настройки резкости изображения, удаления шумов, и т.п. В конечном итоге я бы хотел, чтобы данная система надежно детектировала заданные положения, и желательно без ошибок. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано March 13, 2011 Недавно обсуждалось определение положение зрачка. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах