Распознавание образов для программистов

ВНИМАНИЕ! БЛОГ ПЕРЕЕХАЛ ПО АДРЕСУ
RECOG.RU

18 Февраль 2011

Особенности и стереозрение

написано в рубрике: Стереозрение — Кручинин Александр @ 2:26 ПП

Статья про применение особенностей в стереозрении:

http://www.isr.uc.pt/~urbano/WorkIROS09/images/PDF/WorkIROS09-RobustFeature.pdf

Annalisa Milella, Bruno Nardelli, Donato Di Paola, and Grazia Cicirelli

Robust Feature Detection and Matching for Vehicle Localization in Uncharted Environments

Вообщем то, что делал я (чуть позже, не зная этой работы) на модели

http://blog.vidikon.com/?p=267

Они опробывали на роботе

stereo_1

16 Февраль 2011

Трекинг лица 2

написано в рубрике: OpenCV, Распознавание образов — Кручинин Александр @ 6:11 ПП

Наклон головы и виртуальное нажатие кнопок движения клавиатуры

2 Февраль 2011

37. Реализация трекинга лица

написано в рубрике: OpenCV — Кручинин Александр @ 12:52 ПП

В предыдущей записи (http://blog.vidikon.com/?p=461) был приведён ролик трекинга лица, полученный с помощью средств OpenCV. Здесь будет описано, как добиться такого результата за короткое время.

Алгоритм использует следующие технологии:

1) детектируется лицо (http://blog.vidikon.com/?p=34);

2) на лице выделяются точки для трекинга и затем осуществляется их мониторинг (http://blog.vidikon.com/?p=277).

Я не стану приводить код и того и другого, поскольку используются вещи из стандартных примеров, описанных в частности в приведённых ссылках. После детектирования лица нам известен CvRect, который передаём в функцию cvSetImageROI для текущего изображения с Web-камеры. Ниже приведён пример инициализации точек:

IplImage* eig = cvCreateImage( cvGetSize(grey), 32, 1 );

IplImage* temp = cvCreateImage( cvGetSize(grey), 32, 1 );

double quality = 0.01;

double min_distance = 10;

cvSetImageROI(grey,RectFace);

count = MAX_COUNT;

cvGoodFeaturesToTrack( grey, eig, temp, points[1], &count,

quality, min_distance, 0, 3, 0, 0.04 );

cvFindCornerSubPix( grey, points[1], count,

cvSize(win_size,win_size), cvSize(-1,-1),

cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));

cvResetImageROI(grey);

Листинг 37.1. Инициализация точек трекинга

Если какие-то параметры непонятные, то посмотрите пример OpenCV по трекингу – я их имена не менял. Но возникает резонный вопрос: а зачем вообще использовать трекинг, если можно постоянно детектировать лицо? Ответ: без использования пакета распараллеливания процедура детектирования лица полностью занимает ресурсы современного персонального компьютера, причём так, что не успевают обрабатываться все кадры. А при трекинге – на средненьком компьютере Core 2 Duo 2.2 ГГц затрачиваются не более 5% ресурсов центрального процессора.

Для определения положения лица и его наклона будем оперировать двумя переменными: Point1 и Point2. В следующем листинге показано их начальное определение после детектирования лица:

Point1.x=0;

Point1.y=0;

Point2.x=0;

Point2.y=0;

int pp=0;

for(i=0;i<count;i++){

points[1][i].x+=RectFace.x;

points[1][i].y+=RectFace.y;

//Здесь также необходимо считать средние точки

Point1.x+=points[1][i].x;

Point1.y+=points[1][i].y;

point_status[i]=0;

if (points[1][i].y<CenterFace.y)

{

point_status[i]=1;

Point2.x+=points[1][i].x;

Point2.y+=points[1][i].y;

pp++;

}

}

Point1.x/=count;

Point1.y/=count;

Point2.x/=pp;

Point2.y/=pp;

Листинг 37.2. Определение точек Point1 и Point2

Первоначально точки обнуляются. Затем перебираются все точки трекинга, к которым прибавляется смещение CvRect лица – RectFace. В Point1 суммируются все точки – эта точка будет нам показывать, где центр лица. Для определения наклона используется довольно простое соображение – первоначально считается, что лицо расположено прямо (можно было в принципе сразу определить наклон по детектированным глазам), и выделяются все точки, которые выше центра лица – CenterFace. Этим точкам устанавливается специальный статус. После завершения цикла вычисляются средние значения точек. Собственно, проведя линию между Point1 и Point2, мы получаем наклон оси.

При осуществлении трекинга необходимо обновлять значения точек Point1 и Point2, точка Point1 – это средняя всех точек, а точка Point2 – это средняя точка всех точек со статусом point_status.

Для вывода другого лица поверх своего (у нас это лицо вождя мирового пролетариата) необходимо получение координаты точки вывода и наклона лица. В листинге 37.3 показано, как это делается

double angle;

if (CenterFace.y-CenterE.y!=0) angle=atan((double)(CenterFace.x-CenterE.x)/(CenterFace.y-CenterE.y));

else angle=0;

double angle_=angle*180/PI;

CvSize Size1=cvGetSize(image_1);

//ещё угол

double angle1=atan((double)Size1.width/Size1.height);

Mat image_11=image_1;

Mat image_12=rotateImage(image_11,angle_);

IplImage image_2=image_12;

CvSize Size=cvGetSize(&image_2);

CvRect Rect;

double x=Size.width;

double y=Size.height;

Rect.x=CenterFace.x-x/2;Rect.y=CenterFace.y-y/2;

Rect.height=Size.height;

Rect.width=Size.width;

cvSetImageROI(image,Rect);

IplImage* image_2m=cvCreateImage(cvGetSize(&image_2), 8, 1);

cvCvtColor( &image_2,image_2m, CV_BGR2GRAY );

if (Rect.x>=0 && Rect.y>=0 && Rect.x+Rect.width<=639 && Rect.y+Rect.height<=479)

cvCopy(&image_2,image,image_2m);

cvResetImageROI( image);

cvReleaseImage(&image_2m);

Листинг 37.3. Вычисление координаты, угла и вывод изображения на экран

Первоначально вычисляется угол наклона angle, CenterFace до этого выражается через Point1, а CenterE – через Point2. Вычисляется размер изображения Вождя – Size1. Дальше происходит поворот изображения (http://blog.vidikon.com/?p=468) и установление прозрачного цвета (http://blog.vidikon.com/?p=466). Ну и собственно вывод изображения на экран.

Конечно, это только подход, и немного оптимизировав его можно добиться более серьёзных результатов. Но на это надо уже больше времени.

Работает на WordPress