In his post, OpenCV solvePnP was used in order to calculate fundamental matrix that can be used to map 3D points in model to 2D point in images. But I found OpenCV also provides POSIT implementation and very nice POSIT tutorial at http://opencv.willowgarage.com/wiki/Posit. So I decide to use "Roy" data and apply to POSIT function of OpenCV.
#include <cxcore.h> #include <cv.h> #include <highgui.h> using namespace std; using namespace cv; #define FOCAL_LENGTH 1000 #define CUBE_SIZE 10 static const char* IMAGE_DATA_PATH = "/Users/mhrinc/Desktop/image_data/"; #define IMAGE_EXTENSION ".jpeg" #define DATA_EXTENSION ".txt" std::vector<CvPoint3D32f> modelPoints; std::vector<CvPoint3D32f> glassesPoints; void getImagePath(char* result,const char* imageFileName) { sprintf(result,"%s%s%s", IMAGE_DATA_PATH, imageFileName,IMAGE_EXTENSION); } void getDataPath(char* result,const char* dataFileName) { sprintf(result,"%s%s%s", IMAGE_DATA_PATH, dataFileName,DATA_EXTENSION); } vector<const char* > listOfImages() { vector<const char* > arrayOfImages; //Man arrayOfImages.push_back("man/barack_obama_1"); arrayOfImages.push_back("man/barack_obama_2"); arrayOfImages.push_back("man/bill-gates_1"); arrayOfImages.push_back("man/bill-gates_2"); arrayOfImages.push_back("man/david_beckham_1"); arrayOfImages.push_back("man/david_beckham_2"); arrayOfImages.push_back("man/nguyen_tan_dung_1"); arrayOfImages.push_back("man/nguyen_tan_dung_2"); arrayOfImages.push_back("man/bill_clinton_1"); arrayOfImages.push_back("man/bill_clinton_2"); //Woman arrayOfImages.push_back("woman/britney_spears_1"); arrayOfImages.push_back("woman/cheryl_cole_2"); arrayOfImages.push_back("woman/jang_nara_1"); arrayOfImages.push_back("woman/kim_tae_hee_2"); arrayOfImages.push_back("woman/britney_spears_2"); arrayOfImages.push_back("woman/harry_clinton_1"); arrayOfImages.push_back("woman/jang_nara_2"); arrayOfImages.push_back("woman/michelle_obama_1"); arrayOfImages.push_back("woman/cheryl_cole_1"); arrayOfImages.push_back("woman/harry_clinton_2"); arrayOfImages.push_back("woman/kim_tae_hee_1"); arrayOfImages.push_back("woman/michelle_obama_2"); arrayOfImages.push_back("woman/Angelina_Jolie_0002"); arrayOfImages.push_back("woman/Angelina_Jolie_0003"); arrayOfImages.push_back("woman/Angelina_Jolie_0004"); arrayOfImages.push_back("woman/Angelina_Jolie_0005"); arrayOfImages.push_back("woman/Angelina_Jolie_0006"); arrayOfImages.push_back("woman/Angelina_Jolie_0007"); arrayOfImages.push_back("woman/Angelina_Jolie_0008"); return arrayOfImages; } void loadNext(CvPOSITObject* positObject, const char* imageFileName) { int _w, _h; char buf[256] = {0}; getDataPath(&buf[0], imageFileName); cout << "Data:"<< buf << endl; vector<CvPoint2D32f > points; FILE* f; f = fopen(buf,"r"); fscanf(f,"%i",&_w); fscanf(f,"%i",&_h); cout << "widht:"<<_w<<",height:"<<_h<<endl; float _width = _w/2.0; float _height = _h/2.0; for(int i=0;i<7;i++) { int x,y; fscanf(f,"%d",&x); fscanf(f,"%d",&y); cout << x<<","<<y<<","; points.push_back(cvPoint2D32f(-_width+x,_height - y)); } cout << endl; fclose(f); getImagePath(&buf[0], imageFileName); cout << "Image:"<< buf << endl; Mat img = imread(buf); for(unsigned int i=0;i<points.size();i++) { CvPoint2D32f p = cvPoint2D32f(points[i].x+_width,_height-points[i].y); circle(img,p,2,Scalar(255,0,255),CV_FILLED); } //Estimate the pose CvMatr32f rotation_matrix = new float[9]; CvVect32f translation_vector = new float[3]; CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 100, 1.0e-4f); cvPOSIT( positObject, &points[0], FOCAL_LENGTH, criteria, rotation_matrix, translation_vector ); cout << "\n-.- SOURCE IMAGE POINTS -.-\n"; for ( size_t p=0; p<points.size(); p++ ) cout << points[p].x << ", " << points[p].y << " \n"; cout << "\n-.- ESTIMATED ROTATION\n"; for ( size_t p=0; p<3; p++ ) cout << rotation_matrix[p*3] << " | " << rotation_matrix[p*3+1] << " | " << rotation_matrix[p*3+2] << "\n"; cout << "\n-.- ESTIMATED TRANSLATION\n"; cout << translation_vector[0] << " | " << translation_vector[1] << " | " << translation_vector[2] << "\n"; //Project the model points with the estimated pose std::vector<CvPoint2D32f> projectedPoints; for ( size_t p=0; p<glassesPoints.size(); p++ ) { CvPoint3D32f point3D; point3D.x = rotation_matrix[0] * glassesPoints[p].x + rotation_matrix[1] * glassesPoints[p].y + rotation_matrix[2] * glassesPoints[p].z + translation_vector[0]; point3D.y = rotation_matrix[3] * glassesPoints[p].x + rotation_matrix[4] * glassesPoints[p].y + rotation_matrix[5] * glassesPoints[p].z + translation_vector[1]; point3D.z = rotation_matrix[6] * glassesPoints[p].x + rotation_matrix[7] * glassesPoints[p].y + rotation_matrix[8] * glassesPoints[p].z + translation_vector[2]; CvPoint2D32f point2D = cvPoint2D32f( 0.0, 0.0 ); if ( point3D.z != 0 ) { point2D.x = FOCAL_LENGTH * point3D.x / point3D.z; point2D.y = FOCAL_LENGTH * point3D.y / point3D.z; } projectedPoints.push_back( point2D ); } cout << "\n-.- PROJECTED POINTS -.-\n"; for ( size_t p=0; p<projectedPoints.size(); p++ ) cout << projectedPoints[p].x << ", " << projectedPoints[p].y << " \n"; for(unsigned int i=0;i<projectedPoints.size();i++) { CvPoint2D32f p = cvPoint2D32f(projectedPoints[i].x+_width,_height-projectedPoints[i].y); circle(img,p,2,Scalar(255,0,0),CV_FILLED); } delete rotation_matrix; delete translation_vector; imshow("1", img); cvWaitKey(0); } int main(int argc, char** argv) { cout << "OpenCV POSIT tutorial" << endl; cout << "by Javier Barandiaran(jbarandiaran@gmail.com)" << endl; //Create the model pointss float xOffset = 36.9522f; float yOffset = -39.3518f; float zOffset = -47.1217f; modelPoints.push_back(cvPoint3D32f(xOffset+-36.9522f,yOffset+39.3518f,zOffset+47.1217f)); //l eye modelPoints.push_back(cvPoint3D32f(xOffset+35.446f,yOffset+38.4345f,zOffset+47.6468f)); //r eye modelPoints.push_back(cvPoint3D32f(xOffset+-0.0697709f,yOffset+18.6015f,zOffset+87.9695f)); //nose modelPoints.push_back(cvPoint3D32f(xOffset+-27.6439f,yOffset+-29.6388f,zOffset+73.8551f)); //l mouth modelPoints.push_back(cvPoint3D32f(xOffset+28.7793f,yOffset+-29.2935f,zOffset+72.7329f)); //r mouth float xx,yy; xx = 20, yy = 15; glassesPoints.push_back(cvPoint3D32f(xOffset+-36.9522f - xx,yOffset+39.3518f + yy,zOffset+47.1217f)); //l eye glassesPoints.push_back(cvPoint3D32f(xOffset+-36.9522f - xx,yOffset+39.3518f - yy,zOffset+47.1217f)); //l eye glassesPoints.push_back(cvPoint3D32f(xOffset+35.446f + xx,yOffset+38.4345f + yy,zOffset+47.6468f)); //r eye glassesPoints.push_back(cvPoint3D32f(xOffset+35.446f + xx,yOffset+38.4345f - yy,zOffset+47.6468f)); //r eye // modelPoints.push_back(Point3f(-87.2155f,15.5829f,-45.1352f)); //l ear // modelPoints.push_back(Point3f(85.8383f,14.9023f,-46.3169f)); //r ear cout << "\n-.- SOURCE MODEL POINTS -.-\n"; for ( size_t p=0; p<modelPoints.size(); p++ ) cout << modelPoints[p].x << ", " << modelPoints[p].y << ", " << modelPoints[p].z << "\n"; //Create the POSIT object with the model points CvPOSITObject* positObject; positObject = cvCreatePOSITObject( &modelPoints[0], (int)modelPoints.size() ); //Do processing int imageIndex = 0; vector<const char* > images = listOfImages(); while (imageIndex < images.size()) { const char* imageFileName = images.at(imageIndex); loadNext(positObject, imageFileName); imageIndex++; } cvReleasePOSITObject(&positObject); return 0; }