3 //--- Please read help() below: ---
7 #include <opencv2/core/core_c.h>
8 #include <opencv2/calib3d/calib3d_c.h>
9 #include <opencv2/imgproc.hpp>
10 #include <opencv2/highgui.hpp>
11 #include <opencv2/legacy/compat.hpp>
13 #if defined WIN32 || defined _WIN32 || defined WINCE
22 #include <OpenGL/gl.h>
32 cout << "\nThis demo demonstrates the use of the Qt enhanced version of the highgui GUI interface\n"
33 " and dang if it doesn't throw in the use of of the POSIT 3D tracking algorithm too\n"
34 "It works off of the video: cube4.avi\n"
35 "Using OpenCV version %s\n" << CV_VERSION << "\n\n"
36 " 1). This demo is mainly based on work from Javier Barandiaran Martirena\n"
37 " See this page http://code.opencv.org/projects/opencv/wiki/Posit.\n"
38 " 2). This is a demo to illustrate how to use **OpenGL Callback**.\n"
39 " 3). You need Qt binding to compile this sample with OpenGL support enabled.\n"
40 " 4). The features' detection is very basic and could highly be improved \n"
41 " (basic thresholding tuned for the specific video) but 2).\n"
42 " 5) THANKS TO Google Summer of Code 2010 for supporting this work!\n" << endl;
45 #define FOCAL_LENGTH 600
48 static void renderCube(float size)
52 glNormal3f( 0.0f, 0.0f, 1.0f);
53 glVertex3f( 0.0f, 0.0f, 0.0f);
54 glVertex3f( size, 0.0f, 0.0f);
55 glVertex3f( size, size, 0.0f);
56 glVertex3f( 0.0f, size, 0.0f);
58 glNormal3f( 0.0f, 0.0f,-1.0f);
59 glVertex3f( 0.0f, 0.0f, size);
60 glVertex3f( 0.0f, size, size);
61 glVertex3f( size, size, size);
62 glVertex3f( size, 0.0f, size);
64 glNormal3f( 0.0f, 1.0f, 0.0f);
65 glVertex3f( 0.0f, size, 0.0f);
66 glVertex3f( size, size, 0.0f);
67 glVertex3f( size, size, size);
68 glVertex3f( 0.0f, size, size);
70 glNormal3f( 0.0f,-1.0f, 0.0f);
71 glVertex3f( 0.0f, 0.0f, 0.0f);
72 glVertex3f( 0.0f, 0.0f, size);
73 glVertex3f( size, 0.0f, size);
74 glVertex3f( size, 0.0f, 0.0f);
76 glNormal3f( 1.0f, 0.0f, 0.0f);
77 glVertex3f( size, 0.0f, 0.0f);
78 glVertex3f( size, 0.0f, size);
79 glVertex3f( size, size, size);
80 glVertex3f( size, size, 0.0f);
82 glNormal3f(-1.0f, 0.0f, 0.0f);
83 glVertex3f( 0.0f, 0.0f, 0.0f);
84 glVertex3f( 0.0f, size, 0.0f);
85 glVertex3f( 0.0f, size, size);
86 glVertex3f( 0.0f, 0.0f, size);
91 static void on_opengl(void* param)
93 //Draw the object with the estimated pose
95 glScalef( 1.0f, 1.0f, -1.0f);
96 glMultMatrixf( (float*)param );
97 glEnable( GL_LIGHTING );
98 glEnable( GL_LIGHT0 );
100 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
101 renderCube( CUBE_SIZE );
103 glDisable( GL_LIGHTING );
106 static void initPOSIT(std::vector<CvPoint3D32f> *modelPoints)
108 //Create the model pointss
109 modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, 0.0f)); //The first must be (0,0,0)
110 modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, CUBE_SIZE));
111 modelPoints->push_back(cvPoint3D32f(CUBE_SIZE, 0.0f, 0.0f));
112 modelPoints->push_back(cvPoint3D32f(0.0f, CUBE_SIZE, 0.0f));
115 static void foundCorners(vector<CvPoint2D32f> *srcImagePoints, const Mat& source, Mat& grayImage)
117 cvtColor(source, grayImage, COLOR_RGB2GRAY);
118 GaussianBlur(grayImage, grayImage, Size(11,11), 0, 0);
119 normalize(grayImage, grayImage, 0, 255, NORM_MINMAX);
120 threshold(grayImage, grayImage, 26, 255, THRESH_BINARY_INV); //25
122 vector<vector<Point> > contours;
123 vector<Vec4i> hierarchy;
124 findContours(grayImage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
127 vector<CvPoint2D32f> srcImagePoints_temp(4,cvPoint2D32f(0,0));
129 if (contours.size() == srcImagePoints_temp.size())
132 for(size_t i = 0 ; i<contours.size(); i++ )
137 for(size_t j = 0 ; j<contours[i].size(); j++ )
140 srcImagePoints_temp.at(i)=cvPoint2D32f(float(p.x)/contours[i].size(),float(p.y)/contours[i].size());
143 //Need to keep the same order
151 for(size_t i = 1 ; i<srcImagePoints_temp.size(); i++ )
153 if (srcImagePoints_temp.at(i).y > srcImagePoints_temp.at(index).y)
156 srcImagePoints->at(0) = srcImagePoints_temp.at(index);
160 for(size_t i = 1 ; i<srcImagePoints_temp.size(); i++ )
162 if (srcImagePoints_temp.at(i).x > srcImagePoints_temp.at(index).x)
165 srcImagePoints->at(1) = srcImagePoints_temp.at(index);
169 for(size_t i = 1 ; i<srcImagePoints_temp.size(); i++ )
171 if (srcImagePoints_temp.at(i).x < srcImagePoints_temp.at(index).x)
174 srcImagePoints->at(2) = srcImagePoints_temp.at(index);
178 for(size_t i = 1 ; i<srcImagePoints_temp.size(); i++ )
180 if (srcImagePoints_temp.at(i).y < srcImagePoints_temp.at(index).y)
183 srcImagePoints->at(3) = srcImagePoints_temp.at(index);
185 Mat Msource = source;
187 for(size_t i = 0 ; i<srcImagePoints_temp.size(); i++ )
190 circle(Msource,srcImagePoints->at(i),5,Scalar(0,0,255));
191 putText(Msource,ss.str(),srcImagePoints->at(i),FONT_HERSHEY_SIMPLEX,1,Scalar(0,0,255));
194 //new coordinate system in the middle of the frame and reversed (camera coordinate system)
195 srcImagePoints->at(i) = cvPoint2D32f(srcImagePoints_temp.at(i).x-source.cols/2,source.rows/2-srcImagePoints_temp.at(i).y);
201 static void createOpenGLMatrixFrom(float *posePOSIT,const CvMatr32f &rotationMatrix, const CvVect32f &translationVector)
205 //coordinate system returned is relative to the first 3D input point
206 for (int f=0; f<3; f++)
208 for (int c=0; c<3; c++)
210 posePOSIT[c*4+f] = rotationMatrix[f*3+c]; //transposed
216 posePOSIT[12] = translationVector[0];
217 posePOSIT[13] = translationVector[1];
218 posePOSIT[14] = translationVector[2];
225 VideoCapture video("cube4.avi");
226 CV_Assert(video.isOpened());
228 Mat source, grayImage;
232 namedWindow("original", WINDOW_AUTOSIZE | WINDOW_FREERATIO);
233 namedWindow("POSIT", WINDOW_AUTOSIZE | WINDOW_FREERATIO);
234 displayOverlay("POSIT", "We lost the 4 corners' detection quite often (the red circles disappear). This demo is only to illustrate how to use OpenGL callback.\n -- Press ESC to exit.", 10000);
236 float OpenGLMatrix[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
237 setOpenGlDrawCallback("POSIT",on_opengl,OpenGLMatrix);
239 vector<CvPoint3D32f> modelPoints;
240 initPOSIT(&modelPoints);
242 //Create the POSIT object with the model points
243 CvPOSITObject* positObject = cvCreatePOSITObject( &modelPoints[0], (int)modelPoints.size() );
245 CvMatr32f rotation_matrix = new float[9];
246 CvVect32f translation_vector = new float[3];
247 CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 100, 1.0e-4f);
249 vector<CvPoint2D32f> srcImagePoints(4,cvPoint2D32f(0,0));
252 while(waitKey(33) != 27)
255 imshow("original",source);
257 foundCorners(&srcImagePoints, source, grayImage);
258 cvPOSIT( positObject, &srcImagePoints[0], FOCAL_LENGTH, criteria, rotation_matrix, translation_vector );
259 createOpenGLMatrixFrom(OpenGLMatrix,rotation_matrix,translation_vector);
261 imshow("POSIT",source);
263 if (video.get(CAP_PROP_POS_AVI_RATIO) > 0.99)
264 video.set(CAP_PROP_POS_AVI_RATIO, 0);
268 cvReleasePOSITObject(&positObject);