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

iamx4nd3r

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

    3
  • Зарегистрирован

  • Посещение

Репутация

0 Новичек

О iamx4nd3r

  • Звание
    Новичок
  1. Трекинг точек на лице

    Спасибо за ответы! Обязательно изучу предложенные варианты работы, но позже. Сейчас все же стоит задача доделать трекинг точек на имеющихся видеозаписях. Посему я стал разбираться с оптическим потоком, и пока имею некоторые сложности. Правильно ли я понимаю схему использования оптического потока? (ниже) //берем первый кадр frame = cvQueryFrame(capture); //инициализация нужных массивов и переменных //... cvGoodFeaturesToTrack(imgThresh, eig_image, tmp_image, cornersA, &corner_count, 0.01, 1); cvFindCornerSubPix( imgThresh, cornersA, corner_count, cvSize( win_size, win_size ), cvSize( -1, -1 ), cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03 ) ); //цикл для обработки последующих кадров while(true){ frame = cvQueryFrame(capture); //доп инициализации //.. cvCalcOpticalFlowPyrLK( imgPrev, imgCurr, pyrA, pyrB, cornersA, cornersB, corner_count, cvSize(win_size,win_size), 5, features_found, 0, cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03 ), 0 ); CV_SWAP( tmp_image, imgThresh, swap_temp ); CV_SWAP( pyrA, pyrB, swap_temp ); CV_SWAP( cornersA, cornersB, swap_points ); }
  2. Трекинг точек на лице

    Расскажите, пожалуйста, чуточку подробнее про параметрическую модель, мне кажется, есть целесообразность использовать ее.
  3. Трекинг точек на лице

    Добрый день! Решаю следующую задачу: на вход программе подается видеофайл, на котором актер с нарисованными синим маркером на лице 64 точками говорит что-то, изображая одну из эмоций(злость, грусть, радость и т.д.). Необходимо сделать трэкинг этих точек и на выходе дать файл с координатами каждой точки в каждом кадре. На данный момент имею следующее: //03.04.13 #include <OpenCV/highgui.h> #include <OpenCV/cv.h> #include <stdio.h> #include <iostream> #include <stdlib.h> char * itoa( int value, char * str, int base ) { char * rc; char * ptr; char * low; // Check for supported base. if ( base < 2 || base > 36 ) { *str = '\0'; return str; } rc = ptr = str; // Set '-' for negative decimals. if ( value < 0 && base == 10 ) { *ptr++ = '-'; } // Remember where the numbers start. low = ptr; // The actual conversion. do { // Modulo is negative for negative value. This trick makes abs() unnecessary. *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + value % base]; value /= base; } while ( value ); // Terminating the string. *ptr-- = '\0'; // Invert the numbers. while ( low < ptr ) { char tmp = *low; *low++ = *ptr; *ptr-- = tmp; } return rc; } // задаём ROI int x = 85; int y = 5; int width = 170; int height = 185; // добавочная величина int add = 00; // устанавливаем ROI // cvSetImageROI(frame, cvRect(x,y,width,height)); // сбрасываем ROI // cvResetImageROI(frame); /*CvScalar s; s=cvGet2D(imgThresh,centerX,centerY); // get the (i,j) pixel value s.val[0]=180; s.val[1]=100; s.val[2]=100; cvSet2D(imgThresh,centerX,centerY,s); // set the (i,j) pixel value */ //cvScalar(75,0,50), cvScalar(150,165,195) //This function threshold the ROI of HSV image and create a binary image IplImage* GetThresholdedImage(IplImage* imgHSV){ IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1); cvZero(imgThresh); cvSetImageROI(imgHSV, cvRect(x,y,width,height)); cvSetImageROI(imgThresh, cvRect(x,y,width,height)); cvInRangeS(imgHSV, cvScalar(75,5,50), cvScalar(150,165,195), imgThresh);//(src, lower[3], upper[3]) cvResetImageROI(imgThresh); cvResetImageROI(imgHSV); return imgThresh; } void GetCentralPoints(CvSeq* contours){ CvSeq *contour; CvMoments moments; double M00, M01, M10; int centerX, centerY, pointnum; contour = contours; //Now contour points to the first contour in the list pointnum = 1; while(contour){ cvMoments(contour,&moments); M00 = cvGetSpatialMoment(&moments,0,0); M10 = cvGetSpatialMoment(&moments,1,0); M01 = cvGetSpatialMoment(&moments,0,1); centerX = (int)(M10/M00); centerY = (int)(M01/M00); std::cout << "point№" << pointnum << "\n"; //printf("X=", centerX); std::cout << "X=" << centerX << " "; //printf("\n"); std::cout << "Y=" << centerY << "\n"; //printf("Y=", centerY); //printf("\n"); contour = (CvSeq *)(contour->h_next); pointnum = pointnum+1; } } int main(){ CvCapture* capture =0; //capture = cvCaptureFromCAM(0); capture = cvCaptureFromAVI("/Users/agortinskiy/Downloads/AudioVisualClip/DC/a1.avi"); CvMemStorage* g_storage = NULL; CvSeq* contours = 0; if(!capture){ printf("Capture failure\n"); return -1; } IplImage* frame=0; frame = cvQueryFrame(capture); if(!frame) return -1; cvNamedWindow("Original"); cvNamedWindow("Contour"); cvNamedWindow("Binary"); //iterate through each frames of the video while(true){ frame = cvQueryFrame(capture); if(!frame) break; frame=cvCloneImage(frame); //cvSmooth(frame, frame, CV_BILATERAL,3,3,0.1,0.1); //smooth the original image using Gaussian kernel cvSmooth(frame, frame, CV_GAUSSIAN, 3, 3); IplImage* imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3); cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV IplImage* imgThresh = GetThresholdedImage(imgHSV); //cvSmooth(imgThresh, imgThresh, CV_BILATERAL, 3, 3, 0.1, 0.1); //smooth the binary image using Gaussian kernel cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN, 3, 3); if( g_storage==NULL ) { g_storage = cvCreateMemStorage(0); } else { cvClearMemStorage( g_storage ); } cvShowImage("Binary", imgThresh); cvFindContours( imgThresh, g_storage,&contours,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0)); GetCentralPoints(contours); cvZero( imgThresh ); // для отметки контуров CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0); char buf[128]; int counter=0; /* if( contours ){ cvDrawContours( imgThresh, contours, cvScalarAll(255), cvScalarAll(255), 100 ); // выводим его номер CvPoint2D32f point; float rad; cvMinEnclosingCircle(contours,&point,&rad); // получим окружность содержащую контур cvPutText(imgThresh, itoa(++counter, buf, 10), cvPointFrom32f(point), &font, CV_RGB(255,255,255)); } */ // нарисуем контуры изображения if(contours){ for(CvSeq* seq0 = contours;seq0!=0;seq0 = seq0->h_next){ // рисуем контур cvDrawContours(imgThresh, seq0, cvScalarAll(255), cvScalarAll(255), 0, 1, 8); // выводим его номер CvPoint2D32f point; float rad; cvMinEnclosingCircle(seq0,&point,&rad); // получим окружность содержащую контур cvPutText(imgThresh, itoa(++counter, buf, 10), cvPointFrom32f(point), &font, cvScalarAll(255)); } } cvShowImage("Contour", imgThresh); cvShowImage("Original", frame); //Clean up used images cvReleaseImage(&imgHSV); cvReleaseImage(&imgThresh); cvReleaseImage(&frame); //Wait 50mS int c = cvWaitKey(10); //If 'ESC' is pressed, break the loop if((char)c==27 ) break; } cvDestroyAllWindows() ; cvReleaseCapture(&capture); return 0; } Программа уже преобразует изображение в бинарное с выбранным порогом в hsv цветовой палитре, затем выделяются контуры, считаются моменты для вычисления центров контуров(и есть координаты искомые мной), ну и нумеруются точки. Проблемы 2: 1. Т.к. поиск контуров производится на каждом кадре независимо от предыдущего кадра, то и точки нумеруются в разном порядке, что неверно в условиях моей задачи. Каким образом можно закрепить порядок следования точек от кадра к кадру? 2. Ошибочно детектируются глаза на некоторых кадрах. Видимо, при некоторых положениях головы актера цветовые параметры глаза укладываются в диапозон, заданный для отбора синих точек. Как можно исключить глаза?
×