5 #include "PnPProblem.h"
6 #include "RobustMatcher.h"
7 #include "ModelRegistration.h"
10 #include <opencv2/core/core.hpp>
11 #include <opencv2/imgproc/imgproc.hpp>
12 #include <opencv2/calib3d/calib3d.hpp>
13 #include <opencv2/features2d/features2d.hpp>
14 #include <opencv2/nonfree/features2d.hpp>
17 * Set up the images paths
20 // COOKIES BOX [718x480]
21 std::string img_path = "../Data/resized_IMG_3875.JPG"; // f 55
24 std::string ply_read_path = "../Data/box.ply";
27 std::string write_path = "../Data/cookies_ORB.yml";
32 << "--------------------------------------------------------------------------" << std::endl
33 << "This program shows how to create your 3D textured model. " << std::endl
34 << "Usage:" << std::endl
35 << "./pnp_registration " << std::endl
36 << "--------------------------------------------------------------------------" << std::endl
40 // Boolean the know if the registration it's done
41 bool end_registration = false;
44 * Set up the intrinsic camera parameters: CANON
46 double f = 45; // focal length in mm
47 double sx = 22.3, sy = 14.9;
48 double width = 2592, height = 1944;
49 double params_CANON[] = { width*f/sx, // fx
55 // Setup the points to register in the image
56 // In the order of the *.ply file and starting at 1
58 int pts[] = {1, 2, 3, 4, 5, 6, 7, 8}; // 3 -> 4
61 * Set up some basic colors
63 cv::Scalar red(0, 0, 255);
64 cv::Scalar green(0,255,0);
65 cv::Scalar blue(255,0,0);
66 cv::Scalar yellow(0,255,255);
69 * CREATE MODEL REGISTRATION OBJECT
74 ModelRegistration registration;
77 PnPProblem pnp_registration(params_CANON);
80 // Mouse events for model registration
81 static void onMouseModelRegistration( int event, int x, int y, int, void* )
83 if ( event == cv::EVENT_LBUTTONUP )
85 int n_regist = registration.getNumRegist();
86 int n_vertex = pts[n_regist];
88 cv::Point2f point_2d = cv::Point2f(x,y);
89 cv::Point3f point_3d = mesh.getVertex(n_vertex-1);
91 bool is_registrable = registration.is_registrable();
94 registration.registerPoint(point_2d, point_3d);
95 if( registration.getNumRegist() == registration.getNumMax() ) end_registration = true;
105 int main(int argc, char *argv[])
110 // load a mesh given the *.ply file path
111 mesh.load(ply_read_path);
114 int numKeyPoints = 10000;
116 //Instantiate robust matcher: detector, extractor, matcher
117 RobustMatcher rmatcher;
118 cv::FeatureDetector * detector = new cv::OrbFeatureDetector(numKeyPoints);
119 rmatcher.setFeatureDetector(detector);
122 * GROUND TRUTH OF THE FIRST IMAGE
124 * by the moment it is the reference image
127 // Create & Open Window
128 cv::namedWindow("MODEL REGISTRATION", cv::WINDOW_KEEPRATIO);
130 // Set up the mouse events
131 cv::setMouseCallback("MODEL REGISTRATION", onMouseModelRegistration, 0 );
133 // Open the image to register
134 cv::Mat img_in = cv::imread(img_path, cv::IMREAD_COLOR);
135 cv::Mat img_vis = img_in.clone();
138 std::cout << "Could not open or find the image" << std::endl;
142 // Set the number of points to register
143 int num_registrations = n;
144 registration.setNumMax(num_registrations);
146 std::cout << "Click the box corners ..." << std::endl;
147 std::cout << "Waiting ..." << std::endl;
149 // Loop until all the points are registered
150 while ( cv::waitKey(30) < 0 )
152 // Refresh debug image
153 img_vis = img_in.clone();
155 // Current registered points
156 std::vector<cv::Point2f> list_points2d = registration.get_points2d();
157 std::vector<cv::Point3f> list_points3d = registration.get_points3d();
159 // Draw current registered points
160 drawPoints(img_vis, list_points2d, list_points3d, red);
162 // If the registration is not finished, draw which 3D point we have to register.
163 // If the registration is finished, breaks the loop.
164 if (!end_registration)
167 int n_regist = registration.getNumRegist();
168 int n_vertex = pts[n_regist];
169 cv::Point3f current_poin3d = mesh.getVertex(n_vertex-1);
171 drawQuestion(img_vis, current_poin3d, green);
172 drawCounter(img_vis, registration.getNumRegist(), registration.getNumMax(), red);
177 drawText(img_vis, "END REGISTRATION", green);
178 drawCounter(img_vis, registration.getNumRegist(), registration.getNumMax(), green);
183 cv::imshow("MODEL REGISTRATION", img_vis);
189 * COMPUTE CAMERA POSE
193 std::cout << "COMPUTING POSE ..." << std::endl;
195 // The list of registered points
196 std::vector<cv::Point2f> list_points2d = registration.get_points2d();
197 std::vector<cv::Point3f> list_points3d = registration.get_points3d();
199 // Estimate pose given the registered points
200 bool is_correspondence = pnp_registration.estimatePose(list_points3d, list_points2d, cv::ITERATIVE);
201 if ( is_correspondence )
203 std::cout << "Correspondence found" << std::endl;
205 // Compute all the 2D points of the mesh to verify the algorithm and draw it
206 std::vector<cv::Point2f> list_points2d_mesh = pnp_registration.verify_points(&mesh);
207 draw2DPoints(img_vis, list_points2d_mesh, green);
210 std::cout << "Correspondence not found" << std::endl << std::endl;
214 cv::imshow("MODEL REGISTRATION", img_vis);
216 // Show image until ESC pressed
222 * COMPUTE 3D of the image Keypoints
227 // Containers for keypoints and descriptors of the model
228 std::vector<cv::KeyPoint> keypoints_model;
231 // Compute keypoints and descriptors
232 rmatcher.computeKeyPoints(img_in, keypoints_model);
233 rmatcher.computeDescriptors(img_in, keypoints_model, descriptors);
235 // Check if keypoints are on the surface of the registration image and add to the model
236 for (unsigned int i = 0; i < keypoints_model.size(); ++i) {
237 cv::Point2f point2d(keypoints_model[i].pt);
239 bool on_surface = pnp_registration.backproject2DPoint(&mesh, point2d, point3d);
242 model.add_correspondence(point2d, point3d);
243 model.add_descriptor(descriptors.row(i));
244 model.add_keypoint(keypoints_model[i]);
248 model.add_outlier(point2d);
252 // save the model into a *.yaml file
253 model.save(write_path);
256 img_vis = img_in.clone();
258 // The list of the points2d of the model
259 std::vector<cv::Point2f> list_points_in = model.get_points2d_in();
260 std::vector<cv::Point2f> list_points_out = model.get_points2d_out();
262 // Draw some debug text
263 std::string num = IntToString(list_points_in.size());
264 std::string text = "There are " + num + " inliers";
265 drawText(img_vis, text, green);
267 // Draw some debug text
268 num = IntToString(list_points_out.size());
269 text = "There are " + num + " outliers";
270 drawText2(img_vis, text, red);
272 // Draw the object mesh
273 drawObjectMesh(img_vis, &mesh, &pnp_registration, blue);
275 // Draw found keypoints depending on if are or not on the surface
276 draw2DPoints(img_vis, list_points_in, green);
277 draw2DPoints(img_vis, list_points_out, red);
280 cv::imshow("MODEL REGISTRATION", img_vis);
282 // Wait until ESC pressed
285 // Close and Destroy Window
286 cv::destroyWindow("MODEL REGISTRATION");
288 std::cout << "GOODBYE" << std::endl;