bool VisualOdometry::EstimateLastFrame() { // -------------- Add landmarks std::vector<cv::Point3f> points3d; std::vector<cv::Point2f> points2d; std::vector<int> points_index; if (!map_.PrepareEstimateLastFramePoseData(points3d, points2d, points_index)) { std::cerr << "Error: Points match from last two frames not available.\n"; return false; } // Find out the the portion of landmarks used in pnp are seen in last second const int last_second_frame_id = map_.num_frame() - 2; const double seen_percent = ((double)points3d.size()) / (double)map_.num_landmarks_in_frame(last_second_frame_id); std::cout << points3d.size() << " / " << map_.num_landmarks_in_frame(last_second_frame_id) << " points are re-seen.\n"; if (seen_percent > 0.5 && tracking_or_matching_ == 1) { std::cout << "Skipped a frame, overlap > 50%.\n"; return false; } std::vector<bool> inliers; cv::Mat R; cv::Mat t; if (!pnp_estimator_->EstimatePose(points2d, points3d, camera_model_->K(), inliers, R, t)) { std::cerr << "Error: PnP estimation.\n"; return false; } map_.SetLastFramePose(R, t); // Add new landmarks std::vector<cv::Vec2d> kp0, kp1; FramePose pose0, pose1; if (!map_.PrepareUninitedPointsFromLastTwoFrames(kp0, kp1, pose0, pose1)) { return false; } std::vector<cv::Point3f> new_points3d; std::vector<bool> new_points3d_mask; int num_good_points = TriangulatePoints(kp0, kp1, camera_model_->K(), pose0.R, pose0.t, pose1.R, pose1.t, new_points3d, new_points3d_mask); if ((double)num_good_points / kp0.size() < 0.4) { std::cout << "Skipped a frame, good triangulated point percentage < 40%.\n"; return false; } if (num_good_points < 30) { std::cerr << "Not enough good triangulated points.\n"; return false; } if (!map_.AddInitedPoints(new_points3d, new_points3d_mask)) return false; return true; }
/* ------------------------------------------------------------------------- */ void MainWindow::on_PB_Reconstruction_clicked() { on_PB_Sift_clicked(); cv::Mat_<double> rvec(1,3); vector<KeyPoint> imgpts1_tmp; vector<KeyPoint> imgpts2_tmp; imgpts.resize(filelist.size()); reconstruct_first_two_view(); cv::Mat_<double> t = (cv::Mat_<double>(1,3) << Pmats[1](0,3), Pmats[1](1,3), Pmats[1](2,3)); cv::Mat_<double> R = (cv::Mat_<double>(3,3) << Pmats[1](0,0), Pmats[1](0,1), Pmats[1](0,2), Pmats[1](1,0), Pmats[1](1,1), Pmats[1](1,2), Pmats[1](2,0), Pmats[1](2,1), Pmats[1](2,2)); cv::Matx34d P_0; cv::Matx34d P_1; P_0 = cv::Matx34d(1,0,0,0, 0,1,0,0, 0,0,1,0); int img_prev; for( int img_now = 2; img_now<filelist.size(); img_now++) { cout << endl << endl << endl <<endl; cout << "dealing with " << filelist.at(img_now).fileName().toStdString() << endl; cout << endl; img_prev = img_now - 1; descriptors1.release(); descriptors1 = descriptors2; QString ymlFile; ymlFile = ymlFileDir; ymlFile.append(filelist.at(img_now).fileName()).append(".yml"); restore_descriptors_from_file(ymlFile.toStdString(),imgpts[img_now],descriptors2); matches_prev.clear(); matches_prev = matches_new; matches_new.clear(); //matching matching_fb_matcher(descriptors1,descriptors2,matches_new); matching_good_matching_filter(matches_new); outCloud_prev = outCloud_new; outCloud_new.clear(); vector<cv::Point3f> tmp3d; vector<cv::Point2f> tmp2d; for (unsigned int i=0; i < matches_new.size(); i++) { int idx_in_prev_img = matches_new[i].queryIdx; for (unsigned int pcldp=0; pcldp<outCloud_prev.size(); pcldp++) { if(idx_in_prev_img == outCloud_prev[pcldp].imgpt_for_img[img_prev]) { tmp3d.push_back(outCloud_prev[pcldp].pt); tmp2d.push_back(imgpts[img_now][matches_new[i].trainIdx].pt); break; } } } bool pose_estimated = FindPoseEstimation(rvec,t,R,tmp3d,tmp2d); if(!pose_estimated) { cout << "error"<<endl; } //store estimated pose Pmats[img_now] = cv::Matx34d (R(0,0),R(0,1),R(0,2),t(0), R(1,0),R(1,1),R(1,2),t(1), R(2,0),R(2,1),R(2,2),t(2)); cout << "Pmats:" << endl << Pmats[img_now] << endl; imgpts1_tmp.clear(); imgpts2_tmp.clear(); GetAlignedPointsFromMatch(imgpts[img_prev], imgpts[img_now], matches_new, imgpts1_tmp, imgpts2_tmp); std::vector<cv::KeyPoint> correspImg1Pt; double mean_proj_err = TriangulatePoints(imgpts1_tmp, imgpts2_tmp, K, Kinv,distcoeff, Pmats[img_prev], Pmats[img_now], outCloud, correspImg1Pt); std::vector<CloudPoint> outCloud_tmp; outCloud_tmp.clear(); for (unsigned int i=0; i<outCloud.size(); i++) { if(outCloud[i].reprojection_error <= 5){ //cout << "surving" << endl; outCloud[i].imgpt_for_img.resize(filelist.size()); for(int j = 0; j<filelist.size();j++) { outCloud[i].imgpt_for_img[j] = -1; } outCloud[i].imgpt_for_img[img_now] = matches_new[i].trainIdx; outCloud_tmp.push_back(outCloud[i]); } } outCloud.clear(); outCloud= outCloud_tmp; for(unsigned int i=0;i<outCloud.size();i++) { outCloud_all.push_back(outCloud[i]); } outCloud_new = outCloud; } GetRGBForPointCloud(outCloud_all,pointCloudRGB); ui->widget->update(getPointCloud(), getPointCloudRGB(), getCameras()); }
/* ------------------------------------------------------------------------- */ void MainWindow::on_method2_clicked() { int index_prev; int index_now; QString ymlFile; vector<KeyPoint> imgpts1_tmp; vector<KeyPoint> imgpts2_tmp; imgpts.resize(filelist.size()); on_PB_Sift_clicked(); cout << endl << endl << endl << "Using Method 2:" <<endl; vector<DMatch> matches; cv::Matx34d P_0; cv::Matx34d P_1; P_0 = cv::Matx34d(1,0,0,0, 0,1,0,0, 0,0,1,0); cv::Mat_<double> t_prev = (cv::Mat_<double>(3,1) << 0, 0, 0); cv::Mat_<double> R_prev = (cv::Mat_<double>(3,3) << 0, 0, 0, 0, 0, 0, 0, 0, 0); cv::Mat_<double> R_prev_inv = (cv::Mat_<double>(3,3) << 0, 0, 0, 0, 0, 0, 0, 0, 0); cv::Mat_<double> t_now = (cv::Mat_<double>(3,1) << 0, 0, 0); cv::Mat_<double> R_now = (cv::Mat_<double>(3,3) << 0, 0, 0, 0, 0, 0, 0, 0, 0); cv::Mat_<double> t_new = (cv::Mat_<double>(3,1) << 0, 0, 0); cv::Mat_<double> R_new = (cv::Mat_<double>(3,3) << 0, 0, 0, 0, 0, 0, 0, 0, 0); reconstruct_first_two_view(); std::cout << "Pmat[0] = " << endl << Pmats[0]<<endl; std::cout << "Pmat[1] = " << endl << Pmats[1]<<endl; for(index_now = 2; index_now<filelist.size(); index_now++) { cout << endl << endl << endl <<endl; cout << "dealing with " << filelist.at(index_now).fileName().toStdString() << endl; cout << endl; index_prev = index_now - 1; descriptors1.release(); descriptors1 = descriptors2; descriptors2.release(); ymlFile = ymlFileDir; ymlFile.append(filelist.at(index_now).fileName()).append(".yml"); restore_descriptors_from_file(ymlFile.toStdString(),imgpts[index_now],descriptors2); matches.clear(); //matching matching_fb_matcher(descriptors1,descriptors2,matches); matching_good_matching_filter(matches); imggoodpts1.clear(); imggoodpts2.clear(); P_0 = cv::Matx34d(1,0,0,0, 0,1,0,0, 0,0,1,0); P_1 = cv::Matx34d(1,0,0,0, 0,1,0,0, 0,0,1,0); outCloud.clear(); if(FindCameraMatrices(K,Kinv,distcoeff, imgpts[index_prev],imgpts[index_now], imggoodpts1,imggoodpts2, P_0,P_1, matches, outCloud)) {//if can find camera matries R_prev(0,0) = Pmats[index_prev](0,0); R_prev(0,1) = Pmats[index_prev](0,1); R_prev(0,2) = Pmats[index_prev](0,2); R_prev(1,0) = Pmats[index_prev](1,0); R_prev(1,1) = Pmats[index_prev](1,1); R_prev(1,2) = Pmats[index_prev](1,2); R_prev(2,0) = Pmats[index_prev](2,0); R_prev(2,1) = Pmats[index_prev](2,1); R_prev(2,2) = Pmats[index_prev](2,2); t_prev(0) = Pmats[index_prev](0,3); t_prev(1) = Pmats[index_prev](1,3); t_prev(2) = Pmats[index_prev](2,3); R_now(0,0) = P_1(0,0); R_now(0,1) = P_1(0,1); R_now(0,2) = P_1(0,2); R_now(1,0) = P_1(1,0); R_now(1,1) = P_1(1,1); R_now(1,2) = P_1(1,2); R_now(2,0) = P_1(2,0); R_now(2,1) = P_1(2,1); R_now(2,2) = P_1(2,2); t_now(0) = P_1(0,3); t_now(1) = P_1(1,3); t_now(2) = P_1(2,3); invert(R_prev, R_prev_inv); t_new = t_prev + R_prev * t_now ; R_new = R_now * R_prev; // //store estimated pose Pmats[index_now] = cv::Matx34d (R_new(0,0),R_new(0,1),R_new(0,2),t_new(0), R_new(1,0),R_new(1,1),R_new(1,2),t_new(1), R_new(2,0),R_new(2,1),R_new(2,2),t_new(2)); cout << "Pmats[index_now]:" << endl << Pmats[index_now] << endl; } else { break; } } cout << endl; cout << endl; cout << endl; //visualization imgpts.clear(); imgpts.resize(filelist.size()); for( index_now = 1; index_now<filelist.size(); index_now++) { index_prev = index_now - 1; descriptors1.release(); descriptors2.release(); ymlFile = ymlFileDir; ymlFile.append(filelist.at(index_prev).fileName()).append(".yml"); cout << ymlFile.toStdString()<< endl; restore_descriptors_from_file(ymlFile.toStdString(),imgpts[index_prev],descriptors1); ymlFile = ymlFileDir; ymlFile.append(filelist.at(index_now).fileName()).append(".yml"); cout << ymlFile.toStdString()<< endl; restore_descriptors_from_file(ymlFile.toStdString(),imgpts[index_now],descriptors2); matches.clear(); //matching matching_fb_matcher(descriptors1,descriptors2,matches); matching_good_matching_filter(matches); imgpts1_tmp.clear(); imgpts2_tmp.clear(); GetAlignedPointsFromMatch(imgpts[index_prev], imgpts[index_now], matches, imgpts1_tmp, imgpts2_tmp); cout << imgpts1_tmp.size() << endl; cout << imgpts1_tmp.size() << endl; outCloud.clear(); std::vector<cv::KeyPoint> correspImg1Pt; double mean_proj_err = TriangulatePoints(imgpts1_tmp, imgpts2_tmp, K, Kinv,distcoeff, Pmats[index_prev], Pmats[index_now], outCloud, correspImg1Pt); std::vector<CloudPoint> outCloud_tmp; outCloud_tmp.clear(); for (unsigned int i=0; i<outCloud.size(); i++) { if(outCloud[i].reprojection_error <= 3){ //cout << "surving" << endl; outCloud[i].imgpt_for_img.resize(filelist.size()); for(int j = 0; j<filelist.size();j++) { outCloud[i].imgpt_for_img[j] = -1; } outCloud[i].imgpt_for_img[index_now] = matches[i].trainIdx; outCloud_tmp.push_back(outCloud[i]); } } outCloud.clear(); outCloud= outCloud_tmp; cout << outCloud_tmp.size() << endl; for(unsigned int i=0;i<outCloud.size();i++) { outCloud_all.push_back(outCloud[i]); } outCloud_new = outCloud; } for( int i = 0; i<filelist.size(); i++) Pmats[i](1,3) =0; GetRGBForPointCloud(outCloud_all,pointCloudRGB); ui->widget->update(getPointCloud(), getPointCloudRGB(), getCameras()); cout << "finished" <<endl <<endl; }
void MainWindow::reconstruct_first_two_view() { QString ymlFile; cv::Matx34d P_first; cv::Matx34d P_second; P_first = cv::Matx34d(1,0,0,0, 0,1,0,0, 0,0,1,0); Pmats[0] = P_first; int first_view = 0; int second_view =1; imggoodpts1.clear(); imggoodpts2.clear(); descriptors1.release(); descriptors2.release(); ymlFile = ymlFileDir; ymlFile.append(filelist.at(first_view).fileName()).append(".yml"); cout<<ymlFile.toStdString()<<endl; restore_descriptors_from_file(ymlFile.toStdString(),imgpts[first_view],descriptors1); ymlFile = ymlFileDir; ymlFile.append(filelist.at(second_view).fileName()).append(".yml"); cout<<ymlFile.toStdString()<<endl; restore_descriptors_from_file(ymlFile.toStdString(),imgpts[second_view],descriptors2); //matching matching_fb_matcher(descriptors1,descriptors2,matches_new); matching_good_matching_filter(matches_new); //estimating and reconstruction FindCameraMatrices(K,Kinv,distcoeff, imgpts[first_view],imgpts[second_view], imggoodpts1,imggoodpts2, P_first,P_second, matches_new, outCloud); Pmats[1] = P_second; outCloud.clear(); std::vector<cv::KeyPoint> correspImg1Pt; TriangulatePoints(imggoodpts1, imggoodpts2, K, Kinv,distcoeff, P_first, P_second, outCloud, correspImg1Pt); for (unsigned int i=0; i<outCloud.size(); i++) { //cout << "surving" << endl; outCloud[i].imgpt_for_img.resize(filelist.size()); for(int j = 0; j<filelist.size();j++) { outCloud[i].imgpt_for_img[j] = -1; } outCloud[i].imgpt_for_img[1] = matches_new[i].trainIdx; } for(unsigned int i=0;i<outCloud.size();i++) { outCloud_all.push_back(outCloud[i]); } outCloud_new = outCloud; }