sba.cpp
Go to the documentation of this file.
00001 
00005 #include "sba.hpp"
00006 
00007 void findRelevantIndices(vector<featureTrack>& tracks, vector<unsigned int>& triangulated, vector<unsigned int>& untriangulated, unsigned int last_index, unsigned int new_index) {
00008         
00009         //unsigned int min_sightings = max(0, (((int) new_index) - ((int) last_index)) / 2);
00010         
00011         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00012                 
00013                 if (tracks.at(iii).isTriangulated) {
00014                         triangulated.push_back(iii);
00015                         /*
00016                         unsigned int sightings = 0;
00017                         
00018                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00019                                 
00020                                 if (tracks.at(iii).locations.at(jjj).imageIndex <= new_index) {
00021                                         sightings++;
00022                                 }
00023                                 
00024                         }
00025                         * */
00026                         
00027                         /*
00028                         if (sightings >= min_sightings) {
00029                                 triangulated.push_back(iii);
00030                         }
00031                         * */
00032                 } else {
00033                         untriangulated.push_back(iii);
00034                 }
00035                 
00036 
00037                 
00038         }
00039         
00040         
00041 }
00042 
00043 void findIntermediatePoses(vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int image_idx_1, unsigned int image_idx_2, bool fixBothEnds) {
00044         
00045         printf("%s << ENTERED.\n", __FUNCTION__);
00046         
00047         vector<unsigned int> activeTrackIndices, fullSpanIndices, untriangulatedIndices;
00048         
00049         int subsequence_iters = 10;
00050                         
00051         getActiveTracks(activeTrackIndices, tracks, image_idx_1, image_idx_2);
00052         filterToCompleteTracks(fullSpanIndices, activeTrackIndices, tracks, image_idx_1, image_idx_2);
00053         
00054         reduceActiveToTriangulated(tracks, fullSpanIndices, untriangulatedIndices);
00055         
00056         vector<cv::Point2f> pts1, pts2;
00057         getPointsFromTracks(tracks, pts1, pts2, image_idx_1, image_idx_2);
00058         
00059         vector<cv::Point3d> ptsInCloud;
00060         //printf("%s << ptsInCloud.size() (pre-update) = %d\n", __FUNCTION__, ptsInCloud.size());
00061         getActive3dPoints(tracks, fullSpanIndices, ptsInCloud);
00062         //printf("%s << ptsInCloud.size() (post-update) = %d\n", __FUNCTION__, ptsInCloud.size());
00063                 
00064         int relativeIndex = image_idx_2 - image_idx_1;
00065                 
00066         SysSBA subsys;
00067         addPointsToSBA(subsys, ptsInCloud);
00068         
00069         addFixedCamera(subsys, camData, cameras[image_idx_1]);
00070         addFixedCamera(subsys, camData, cameras[image_idx_2]);
00071         
00072         addProjectionsToSBA(subsys, pts1, 0);   // keyframe_idx_1
00073         addProjectionsToSBA(subsys, pts2, 1);
00074         
00075         if (fixBothEnds) {
00076                 subsys.nFixed = 2;
00077         } else {
00078                 subsys.nFixed = 1;
00079         }
00080         
00081         
00082         for (int jjj = 1; jjj < relativeIndex; jjj++) {
00083                 
00084                 vector<cv::Point2f> latestPoints;
00085                 getCorrespondingPoints(tracks, pts1, latestPoints, image_idx_1, image_idx_1+jjj);
00086                 
00087                 
00088                 
00089                 vector<cv::Point3f> objectPoints;
00090                 cv::Point3f tmpPt;
00091                 
00092                 for (unsigned int kkk = 0; kkk < ptsInCloud.size(); kkk++) {
00093                         tmpPt = cv::Point3f((float) ptsInCloud.at(kkk).x, (float) ptsInCloud.at(kkk).y, (float) ptsInCloud.at(kkk).z);
00094                         objectPoints.push_back(tmpPt);
00095                 }
00096                 
00097                 cv::Mat t, R, Rvec;
00098                 
00099                 //printf("%s << Solving PnP... (%d) (oP.size() = %d; lP.size() = %d)\n", __FUNCTION__, jjj, objectPoints.size(), latestPoints.size());
00100                 
00101                 //solvePnPRansac(InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess=false, int iterationsCount=100, float reprojectionError=8.0, int minInliersCount=100, OutputArray inliers=noArray() );
00102                 solvePnPRansac(objectPoints, latestPoints, camData.K, camData.blankCoeffs, Rvec, t);
00103                 
00104                 Rodrigues(Rvec, R);
00105                 
00106                 //cout << __FUNCTION__ << " << [" << jjj << "] R = " << R << endl;
00107                 //cout << __FUNCTION__ << " << [" << jjj << "] t = " << t << endl;
00108                 
00109                 cv::Mat newCam;
00110                 composeTransform(R, t, newCam);
00111                 //compileTransform(newCam, R, t);
00112                 
00113                 // Inverting camera "learned" by PnP since it always seems to need to be inverted when passed to 
00114                 // and from SBA...
00115                 
00116                 cv::Mat newCamC;
00117                 projectionToTransformation(newCam, newCamC);
00118                 newCamC = newCamC.inv();
00119                 transformationToProjection(newCamC, newCam);
00120                 
00121                 addNewCamera(subsys, camData, newCam);
00122                 
00123                 addProjectionsToSBA(subsys, latestPoints, jjj+1);
00124                 
00125                 //avgError = optimizeSystem(subsys, 1e-4, 10);
00126                 //printf("%s << Progressive subsequence BA error = %f.\n", __FUNCTION__, avgError);
00127                 
00128                 //drawGraph2(subsys, camera_pub, points_pub, decimation, bicolor);
00129                 
00130         }
00131         
00132         printf("%s << About to optimize subsystem... (nFixed = %d)\n", __FUNCTION__, subsys.nFixed);
00133         //if (iii == 0) {
00134                 
00135         double avgError = optimizeSystem(subsys, 1e-4, subsequence_iters);
00136         
00137         if (0) {
00138                 //drawGraph2(subsys, camera_pub, points_pub, decimation, bicolor);
00139         }
00140         
00141         if (avgError < 0.0) {
00142                 printf("%s << ERROR! Subsystem optimization failed to converge..\n", __FUNCTION__);
00143         }
00144         
00145         printf("%s << Subsystem optimized\n", __FUNCTION__);
00146         
00147         
00148                 
00149                 
00150         
00151         retrieveCameraPose(subsys, 0, cameras[image_idx_1]);
00152         retrieveCameraPose(subsys, 1, cameras[image_idx_2]);
00153         
00154         for (unsigned int ttt = 1; ttt < image_idx_2-image_idx_1; ttt++) {
00155                 retrieveCameraPose(subsys, ttt+1, cameras[image_idx_1+ttt]);
00156         }
00157         
00158         ptsInCloud.clear();
00159         retrieveAllPoints(ptsInCloud, subsys);
00160         
00161         updateTriangulatedPoints(tracks, fullSpanIndices, ptsInCloud);  
00162 }
00163 
00164 double getFeatureMotion(vector<featureTrack>& tracks, vector<unsigned int>& indices, unsigned int idx_1, unsigned int idx_2) {
00165 
00166         vector<double> distances, distances_x, distances_y;
00167 
00168         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00169                 
00170                 for (unsigned int jjj = 0; jjj < tracks.at(indices.at(iii)).locations.size()-1; jjj++) {
00171                         
00172                         if (tracks.at(indices.at(iii)).locations.at(jjj).imageIndex == int(idx_1)) {
00173                                 
00174                                 for (unsigned int kkk = jjj+1; kkk < tracks.at(indices.at(iii)).locations.size(); kkk++) {
00175                                         
00176                                         if (tracks.at(indices.at(iii)).locations.at(kkk).imageIndex == int(idx_2)) {
00177                                                 
00178                                                 double dist = distanceBetweenPoints(tracks.at(indices.at(iii)).locations.at(jjj).featureCoord, tracks.at(indices.at(iii)).locations.at(kkk).featureCoord);
00179                                                 
00180                                                 double dist_x = tracks.at(indices.at(iii)).locations.at(jjj).featureCoord.x - tracks.at(indices.at(iii)).locations.at(kkk).featureCoord.x;
00181                                                 double dist_y = tracks.at(indices.at(iii)).locations.at(jjj).featureCoord.y - tracks.at(indices.at(iii)).locations.at(kkk).featureCoord.y;
00182                                                                                                 
00183                                                 distances_x.push_back(dist_x);
00184                                                 distances_y.push_back(dist_y);
00185                                                 distances.push_back(dist);
00186                                                 
00187                                         }
00188                                         
00189                                 }
00190                                 
00191                         }
00192                         
00193                         
00194                 }
00195                 
00196         }
00197         
00198         double mean_dist = 0.00, std_dev = 0.00, mean_x = 0.00, mean_y = 0.00, std_x = 0.00, std_y = 0.00;
00199         
00200         for (unsigned int iii = 0; iii < distances.size(); iii++) {
00201                 mean_dist += (distances.at(iii) / ((double) distances.size()));
00202                 mean_x += (distances_x.at(iii) / ((double) distances.size()));
00203                 mean_y += (distances_y.at(iii) / ((double) distances.size()));
00204 
00205 
00206         }
00207         
00208         for (unsigned int iii = 0; iii < distances.size(); iii++) {
00209                 std_dev += pow(distances.at(iii) - mean_dist, 2.0);
00210                 std_x += pow(distances_x.at(iii) - mean_x, 2.0);
00211                 std_y += pow(distances_y.at(iii) - mean_y, 2.0);                
00212         }
00213                 
00214         std_dev /= distances.size();
00215         std_x /= distances.size();
00216         std_y /= distances.size();
00217 
00218         pow(std_dev, 0.5);
00219         pow(std_x, 0.5);
00220         pow(std_y, 0.5);
00221 
00222         
00223         //printf("%s << (%f, %f, %f) : (%f, %f, %f)\n", __FUNCTION__, mean_dist, mean_y, mean_x, std_dev, std_x, std_y);
00224         
00225         // Need to have some variation in x OR y translation, otherwise it could just be a homography
00226         return ((std_x + std_y) / 2.0);
00227         
00228         return mean_dist;
00229         
00230 }
00231 
00232 void removePoorTracks(vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int start_cam, unsigned int finish_cam) {
00233 
00234         //return;
00235         
00236         printf("%s << Entered.\n", __FUNCTION__);
00237 
00238         // go through each 3D point and find projection to each camera, if the projection is too far off
00239         // then remove it
00240         
00241         
00242         
00243         SysSBA sys;
00244         
00245         for (unsigned int iii = 0; iii <= finish_cam; iii++) {
00246                 if (cameras[iii].rows < 3) {
00247                         addBlankCamera(sys, camData);
00248                 } else {
00249                         addNewCamera(sys, camData, cameras[iii]);
00250                         //cout << cameras[iii] << endl;
00251                 }
00252                 
00253                 
00254         }
00255         
00256         printf("%s << sys.nodes.size() = %d\n", __FUNCTION__, int(sys.nodes.size()));
00257         
00258         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00259                 if (tracks.at(iii).isTriangulated) {
00260                         
00261                         Vector4d point_3(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
00262                         
00263                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00264                                 
00265                                 unsigned int camIndex = tracks.at(iii).locations.at(jjj).imageIndex;
00266                                 
00267                                 //printf("%s << Checking (%d)(%d)(%d)...\n", __FUNCTION__, iii, jjj, camIndex);
00268                                 
00269                                 if ((camIndex >= start_cam) && (camIndex <= finish_cam)) {
00270                                         
00271                                         // Find 2d projection based on 3d point; compare with 2d loc stored in tracks structure
00272                                         
00273                                         Vector2d proj;
00274                                         
00275                                         //printf("%s << nodes(%d) trans = (%f, %f, %f)\n", __FUNCTION__, camIndex, sys.nodes.at(camIndex).trans.x(), sys.nodes.at(camIndex).trans.y(), sys.nodes.at(camIndex).trans.z());
00276                                         
00277                                         sys.nodes.at(camIndex).setProjection();
00278                                         
00279                                         
00280                                         //printf("%s << w2n = (%f, %f, %f; %f %f %f; ...)\n", __FUNCTION__, sys.nodes.at(camIndex).w2n(0,0), sys.nodes.at(camIndex).w2n(0,1), sys.nodes.at(camIndex).w2n(0,2), sys.nodes.at(camIndex).w2n(1,0), sys.nodes.at(camIndex).w2n(1,1), sys.nodes.at(camIndex).w2n(1,2));
00281                                         
00282                                         
00283                                         sys.nodes.at(camIndex).project2im(proj, point_3);
00284                                         
00285                                         //printf("%s << t(%d)c(%d) = (%f, %f) vs (%f, %f)\n", __FUNCTION__, iii, camIndex, proj.x(), proj.y(), tracks.at(iii).locations.at(jjj).featureCoord.x, tracks.at(iii).locations.at(jjj).featureCoord.y);
00286                                         
00287                                 }
00288                                 
00289                         }
00290                         
00291                 }
00292         }
00293         
00294 }
00295 
00296 void copySys(const SysSBA& src, SysSBA& dst) {
00297         
00298         dst.tracks.clear();
00299         dst.nodes.clear();
00300         
00301         for (unsigned int iii = 0; iii < src.tracks.size(); iii++) {
00302                 dst.tracks.push_back(src.tracks.at(iii));
00303         }
00304         
00305         for (unsigned int iii = 0; iii < src.nodes.size(); iii++) {
00306                 dst.nodes.push_back(src.nodes.at(iii));
00307         }
00308         
00309 }
00310 
00311 void rescaleSBA(SysSBA& sba, unsigned int idx1, unsigned int idx2) {
00312         
00313         // Find the distance from first to last camera
00314         double totalDist = pow(pow(sba.nodes.at(idx2).trans.x() - sba.nodes.at(idx1).trans.x(), 2.0) + pow(sba.nodes.at(idx2).trans.y() - sba.nodes.at(idx1).trans.y(), 2.0) + pow(sba.nodes.at(idx2).trans.z() - sba.nodes.at(idx1).trans.z(), 2.0), 0.5);
00315 
00316         printf("%s << totalDist = %f\n", __FUNCTION__, totalDist);
00317 
00318         // Scale ALL locations by the ratio of this distance to 1.0
00319         for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00320                 sba.tracks.at(iii).point.x() /= totalDist;
00321                 sba.tracks.at(iii).point.y() /= totalDist;
00322                 sba.tracks.at(iii).point.z() /= totalDist;
00323         }
00324         
00325         for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00326                 sba.nodes.at(iii).trans.x() /= totalDist;
00327                 sba.nodes.at(iii).trans.y() /= totalDist;
00328                 sba.nodes.at(iii).trans.z() /= totalDist;
00329         }
00330         
00331         printf("%s << Exiting...\n", __FUNCTION__);
00332 
00333 }
00334 
00335 void renormalizeSBA(SysSBA& sba, cv::Point3d& desiredCenter) {
00336         
00337         cv::Point3d centroid, stdDeviation;
00338         
00339         // Find current centroid
00340         findCentroid(sba, centroid, stdDeviation);
00341         
00342         double largestAxis = 4.0 * max(stdDeviation.x, stdDeviation.z);
00343         double lowestHeight = -2.0 * stdDeviation.y;
00344         
00345         // Move everything to center around point (0,0,0)
00346         for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00347                 sba.tracks.at(iii).point.x() -= centroid.x;
00348                 sba.tracks.at(iii).point.y() -= centroid.y;
00349                 sba.tracks.at(iii).point.z() -= centroid.z;
00350         }
00351         
00352         for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00353                 sba.nodes.at(iii).trans.x() -= centroid.x;
00354                 sba.nodes.at(iii).trans.y() -= centroid.y;
00355                 sba.nodes.at(iii).trans.z() -= centroid.z;
00356         }
00357         
00358         
00359         
00360         // Re-size to a good scale
00361         for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00362                 sba.tracks.at(iii).point.x() /= (largestAxis / 10.0);
00363                 sba.tracks.at(iii).point.y() /= (largestAxis / 10.0);
00364                 sba.tracks.at(iii).point.z() /= (largestAxis / 10.0);
00365         }
00366         
00367         for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00368                 sba.nodes.at(iii).trans.x() /= (largestAxis / 10.0);
00369                 sba.nodes.at(iii).trans.y() /= (largestAxis / 10.0);
00370                 sba.nodes.at(iii).trans.z() /= (largestAxis / 10.0);
00371         }
00372         
00373         // Shift up to mostly sit on top of plane
00374         for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00375                 sba.tracks.at(iii).point.y() += lowestHeight;
00376         }
00377         
00378         for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00379                 sba.nodes.at(iii).trans.y() += lowestHeight;
00380         }
00381         
00382         // Move everything to desired centroid
00383         for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00384                 sba.tracks.at(iii).point.x() += desiredCenter.x;
00385                 sba.tracks.at(iii).point.y() += desiredCenter.y;
00386                 sba.tracks.at(iii).point.z() += desiredCenter.z;
00387         }
00388         
00389         for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00390                 sba.nodes.at(iii).trans.x() += desiredCenter.x;
00391                 sba.nodes.at(iii).trans.y() += desiredCenter.y;
00392                 sba.nodes.at(iii).trans.z() += desiredCenter.z;
00393         }
00394         
00395         
00396 }
00397 
00398 void findCentroid(SysSBA& sba, cv::Point3d& centroid, cv::Point3d& stdDeviation) {
00399         
00400         printf("%s << sba.tracks.size() = %d\n", __FUNCTION__, int(sba.tracks.size()));
00401         
00402         centroid = cv::Point3d(0.0, 0.0, 0.0);
00403         stdDeviation = cv::Point3d(0.0, 0.0, 0.0);
00404         
00405         for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00406                 centroid.x += (sba.tracks.at(iii).point.x() / ((double) sba.tracks.size()));
00407                 centroid.y += (sba.tracks.at(iii).point.y() / ((double) sba.tracks.size()));
00408                 centroid.z += (sba.tracks.at(iii).point.z() / ((double) sba.tracks.size()));
00409         }
00410         
00411         for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00412                 stdDeviation.x += (pow((sba.tracks.at(iii).point.x() - centroid.x), 2.0) / ((double) sba.tracks.size()));
00413                 stdDeviation.y += (pow((sba.tracks.at(iii).point.y() - centroid.y), 2.0) / ((double) sba.tracks.size()));
00414                 stdDeviation.z += (pow((sba.tracks.at(iii).point.z() - centroid.z), 2.0) / ((double) sba.tracks.size()));
00415         }
00416         
00417         stdDeviation.x = pow(stdDeviation.x, 0.5);
00418         stdDeviation.y = pow(stdDeviation.y, 0.5);
00419         stdDeviation.z = pow(stdDeviation.z, 0.5);
00420         
00421 }
00422 
00423 void optimizeFullSystem(vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int last_index) {
00424         /*
00425         SysSBA fullsys;
00426         
00427         vector<unsigned int> camera_indices;
00428         for (unsigned int iii = 0; iii <= last_index; iii++) {
00429                 if (cameras[iii].rows == 4) {
00430                         camera_indices.push_back(iii);
00431                         
00432                         if (fullsys.nodes.size() == 0) {
00433                                 addFixedCamera(fullsys, camData, cameras[iii]);
00434                         } else {
00435                                 addNewCamera(fullsys, camData, cameras[iii]);
00436                         }
00437                 }
00438         }
00439         
00440         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00441                 
00442                 if (tracks.at(iii).isTriangulated) {
00443                         
00444                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00445                                 
00446                                 unsigned int cam_idx = tracks.at(iii).locations.at(jjj).imageIndex;
00447                                 
00448                                 for (unsigned int kkk = 0; kkk < 
00449                                 
00450                         }
00451                         
00452                         
00453                 }
00454                 
00455         }
00456         
00457         */
00458 }
00459 
00460 double keyframeBundleAdjustment(cameraParameters& camData, vector<featureTrack>& tracks, cv::Mat *cameras, vector<unsigned int>& indices, unsigned int iterations, bool allFree, bool allFixedExceptLast, unsigned int fixed_cams) {
00461         
00462         //printf("%s << Entered kBA (1)...\n", __FUNCTION__);
00463         
00464         if (indices.size() == 0) {
00465                 return -1.00;
00466         }
00467         
00468         //printf("%s << indices.size() = %d\n", __FUNCTION__, indices.size());
00469         
00470         vector<unsigned int> activeTrackIndices;
00471         
00472         SysSBA sys;
00473         sys.verbose = 0;
00474         
00475         unsigned int maxFixedIndex = std::max(1, ((int)indices.size()) - 1);
00476         
00477         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 0);
00478                 
00479         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00480                 
00481                 unsigned int img_idx = indices.at(iii);
00482                 
00483                 //printf("%s << indices.at(iii) = %d\n", __FUNCTION__, img_idx);
00484                 //cout << cameras[img_idx] << endl;
00485                 
00486                 if (iii < maxFixedIndex) {
00487                         addNewCamera(sys, camData, cameras[img_idx]);
00488                 } else {
00489                         addNewCamera(sys, camData, cameras[img_idx]);
00490                 }
00491 
00492         }
00493         
00494         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 1);
00495 
00496         if (allFree && allFixedExceptLast) {
00497                 // Bug to fix ALL points
00498                 sys.nFixed = sys.nodes.size();
00499         } else if (allFree) {
00500                 sys.nFixed = 1;
00501         } else if (allFixedExceptLast) {
00502                 sys.nFixed = sys.nodes.size()-1;
00503         } else if (fixed_cams != 0) {
00504                 sys.nFixed = fixed_cams;
00505         } else {
00506                 sys.nFixed = maxFixedIndex;
00507         }
00508         
00509         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 2);
00510         
00511         //printf("%s << sys.nodes.size() = %d\n", __FUNCTION__, sys.nodes.size());
00512         
00513         for (unsigned int iii = 0; iii < indices.size()-1; iii++) {
00514                 
00515                 //printf("%s << Defining kf indices...\n", __FUNCTION__);
00516                 unsigned int kf_ind_1 = indices.at(iii);
00517                 unsigned int kf_ind_2 = indices.at(iii+1);
00518                 
00519                 vector<unsigned int> tmp_indices, untriangulated;
00520                 
00521                 //printf("%s << About to get active tracks...\n", __FUNCTION__);
00522                 getActiveTracks(tmp_indices, tracks, kf_ind_1, kf_ind_2);
00523                 
00524                 //printf("%s << Reducing active to triangulated...\n", __FUNCTION__);
00525                 reduceActiveToTriangulated(tracks, tmp_indices, untriangulated  );
00526                 
00527                 //printf("%s << Adding unique to vector...\n", __FUNCTION__);
00528                 addUniqueToVector(activeTrackIndices, tmp_indices);
00529         }
00530         
00531         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 3);
00532         
00533         //printf("%s << activeTrackIndices.size() = %d\n", __FUNCTION__, activeTrackIndices.size());
00534         
00535         vector<cv::Point3d> cloud;
00536         getActive3dPoints(tracks, activeTrackIndices, cloud);
00537         
00538         //printf("%s << cloud.size() = %d\n", __FUNCTION__, cloud.size());
00539 
00540         addPointsToSBA(sys, cloud);
00541         
00542         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 4);
00543         
00544         for (unsigned int iii = 0; iii < activeTrackIndices.size(); iii++) {
00545                 // For each active track, see if it has a 2D location in each image
00546                 
00547                 for (unsigned int jjj = 0; jjj < indices.size(); jjj++) {
00548                         
00549                         // what is the image index that you're after?
00550                         unsigned int cam_idx_1 = indices.at(jjj);
00551                         
00552                         //printf("%s << Searching for projection in (%d)\n", __FUNCTION__, cam_idx_1);
00553                         
00554                         for (unsigned int kkk = 0; kkk < tracks.at(activeTrackIndices.at(iii)).locations.size(); kkk++) {
00555                                 
00556                                 if (tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).imageIndex == ((int) cam_idx_1)) {
00557                                         // Found a projection of track onto this camera
00558                                         
00559                                         if (iii == 0) {
00560                                                         //printf("%s << Adding projection (%f, %f) of track (%d) to camera (%d)...\n", __FUNCTION__, tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).featureCoord.x, tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).featureCoord.y, iii, kf_store.keyframes.at(validKeyframes.at(jjj)).idx); 
00561                                         }
00562                                         
00563                                         
00564                                         addProjectionToSBA(sys, tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).featureCoord, iii, jjj);
00565                                          
00566                                          
00567                                 } 
00568                         }
00569                         
00570                         
00571                         
00572                 }
00573 
00574                 
00575         }
00576         
00577         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 5);
00578         
00579         double avgError = optimizeSystem(sys, 1e-4, iterations);
00580         
00581         //rescaleSBA(sys, 0, sys.nodes.size()-1);
00582         
00583         //printf("%s << avgError = %f\n", __FUNCTION__, avgError);
00584 
00585         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 51);
00586         
00587         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00588                 
00589                 unsigned int img_idx = indices.at(iii);
00590                 
00591                 retrieveCameraPose(sys, iii, cameras[img_idx]);
00592         }
00593         
00594         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 6);
00595         
00596         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
00597                 
00598                 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
00599                 
00600                 //if (validKeyframes.size() == 2) {
00601                         // Hack to get it to reset locations on first go
00602                         tracks.at(activeTrackIndices.at(iii)).reset3dLoc(new3dLoc);
00603                 //} else {
00604                 //      tracks.at(activeTrackIndices.at(iii)).set3dLoc(new3dLoc);
00605                 //}
00606                 
00607         }
00608         
00609         //printf("%s << DEBUG (%02d)\n", __FUNCTION__, 7);
00610         
00611         return avgError;
00612 }
00613 
00614 
00615 double keyframeBundleAdjustment(cameraParameters& camData, vector<featureTrack>& tracks, keyframeStore& kf_store, cv::Mat *cameras, unsigned int kfIndex, unsigned int iterations) {
00616 
00617         //printf("%s << Entered kBA (2)...\n", __FUNCTION__);
00618 
00619         //unsigned int optIndex = kf_store.keyframes.at(kf_idx).idx;    // index of frame to be adjusted
00620         
00621         unsigned int kf_idx = kfIndex;
00622         
00623         vector<unsigned int> validConnections, validKeyframes;
00624         // Find all connected keyframes, and establish initial camera poses
00625         //kf_store.findStrongConnections(kf_idx, validConnections, kf_idx);
00626         
00627         for (unsigned int iii = 0; iii < kf_idx; iii++) {
00628                 validConnections.push_back(iii);
00629         }
00630         
00631         //printf("%s << validConnections.size() = %d\n", __FUNCTION__, validConnections.size());
00632         
00633         for (unsigned int iii = 0; iii < validConnections.size(); iii++) {
00634                 
00635                 //printf("%s << validConnections.at(%d) = (%d) (%d)\n", __FUNCTION__, iii, kf_store.connections.at(validConnections.at(iii)).idx1, kf_store.connections.at(validConnections.at(iii)).idx2);
00636                 
00637                 bool kf1added = false, kf2added = false;
00638                 
00639                 for (unsigned int jjj = 0; jjj < validKeyframes.size(); jjj++) {
00640                         
00641                         if (kf_store.connections.at(validConnections.at(iii)).idx1 == validKeyframes.at(jjj)) {
00642                                 kf1added = true;
00643                         } 
00644                         
00645                         if (kf_store.connections.at(validConnections.at(iii)).idx2 == validKeyframes.at(jjj)) {
00646                                 kf2added = true;
00647                         }
00648                         
00649                 }
00650                 
00651                 if (!kf1added) {
00652                         validKeyframes.push_back(kf_store.connections.at(validConnections.at(iii)).idx1);
00653                 }
00654                 
00655                 if (!kf2added) {
00656                         validKeyframes.push_back(kf_store.connections.at(validConnections.at(iii)).idx2);
00657                 }
00658                 
00659                 
00660         }
00661         
00662         //printf("%s << Valid keyframes size: %d\n", __FUNCTION__, validKeyframes.size());
00663         
00664         
00665         // For each connection, find any tracks that have been triangulated
00666         
00667         vector<unsigned int> activeTrackIndices;
00668         
00669         SysSBA sys;
00670         sys.verbose = 0;
00671         
00672         //printf("%s << Before 2-frame BA: \n", __FUNCTION__);
00673         
00674         for (unsigned int iii = 0; iii < validKeyframes.size(); iii++) {
00675                 
00676                 unsigned int img_idx = kf_store.keyframes.at(validKeyframes.at(iii)).idx;
00677                 
00678                 //Mat C_mat;
00679                 //printf("%s << validKeyframes.at(%d) = %d\n", __FUNCTION__, iii, validKeyframes.at(iii));
00680                 //(kf_store.keyframes.at(validKeyframes.at(iii)).pose).copyTo(C_mat);
00681 
00682                 
00683                 if (iii == validKeyframes.size()-1) {
00684                         addNewCamera(sys, camData, cameras[img_idx]);
00685                 } else {
00686                         addFixedCamera(sys, camData, cameras[img_idx]); // addFixedCamera(sys, camData, C_mat);
00687                         sys.nodes.at(iii).isFixed = true;
00688                         //addNewCamera(sys, camData, cameras[img_idx]);
00689                         
00690                         //printf("%s << sys.nFixed = %d\n", __FUNCTION__, sys.nFixed);
00691                 }
00692                 
00693                 
00694                 
00695                 if (int(iii) >= max(((int) 0), ((int) validKeyframes.size())-4)) {
00696                         //cout << __FUNCTION__ << " << C(" << img_idx << ") = " << endl << cameras[img_idx] << endl;
00697                 }
00698                 
00699                 
00700         }       
00701         
00702         int minUnfixed = 5;
00703         
00704         sys.nFixed = max(1, ((int) validKeyframes.size())-minUnfixed);
00705         
00706         
00707         for (unsigned int iii = 0; iii < validConnections.size(); iii++) {
00708                 
00709                 unsigned int kf_ind_1 = kf_store.connections.at(validConnections.at(iii)).idx1;
00710                 unsigned int kf_ind_2 = kf_store.connections.at(validConnections.at(iii)).idx2;
00711                 
00712                 vector<unsigned int> tmp_indices;
00713                 
00714                 //printf("%s << indexes = (%d, %d)\n", __FUNCTION__, kf_store.keyframes.at(kf_ind_1).idx, kf_store.keyframes.at(kf_ind_2).idx);
00715                 
00716                 getActiveTracks(tmp_indices, tracks, kf_store.keyframes.at(kf_ind_1).idx, kf_store.keyframes.at(kf_ind_2).idx);
00717                 
00718                 //printf("%s << active tracks for (%d, %d) = %d\n", __FUNCTION__, kf_store.keyframes.at(kf_ind_1).idx, kf_store.keyframes.at(kf_ind_2).idx, tmp_indices.size());
00719                 
00720                 vector<unsigned int> untriangulated;
00721                 reduceActiveToTriangulated(tracks, tmp_indices, untriangulated);
00722                 
00723                 //printf("%s << after triangulation (%d, %d) = %d\n", __FUNCTION__, kf_store.keyframes.at(kf_ind_1).idx, kf_store.keyframes.at(kf_ind_2).idx, tmp_indices.size());
00724                 // 193 have been triangulated...
00725                 
00726                 //vector<Point3d> cloud;
00727                 //getActive3dPoints(tracks, tmp_indices, cloud);
00728                 
00729 
00730                 
00731                 //addPointsToSBA(subsys, ptsInCloud);
00732                 //addProjectionsToSBA(subsys, pts1, 0);
00733                 
00734                 addUniqueToVector(activeTrackIndices, tmp_indices);
00735         }
00736         
00737         //printf("%s << activeTrackIndices.size() = %d\n", __FUNCTION__, activeTrackIndices.size());
00738                         
00739         //reduceActiveToTriangulated(tracks, activeTrackIndices);
00740         
00741         //printf("%s << triangulatedIndices.size() = %d\n", __FUNCTION__, activeTrackIndices.size());
00742         
00743         // Get projections and 3D locations for these tracks relative to the relevant cameras
00744         
00745         vector<cv::Point3d> cloud;
00746         getActive3dPoints(tracks, activeTrackIndices, cloud);
00747         
00748         //printf("%s << cloud.size() = %d (tracks.size() = %d; activeTrackIndices.size() = %d)\n", __FUNCTION__, cloud.size(), tracks.size(), activeTrackIndices.size());
00749         
00750         addPointsToSBA(sys, cloud);
00751         //drawGraph(sys, camera_pub, points_pub);
00752         
00753         for (unsigned int iii = 0; iii < activeTrackIndices.size(); iii++) {
00754                 // For each active track, see if it has a 2D location in each image
00755                 
00756                 for (unsigned int jjj = 0; jjj < validKeyframes.size(); jjj++) {
00757                         
00758                         // what is the image index that you're after?
00759                         unsigned int cam_idx_1 = kf_store.keyframes.at(validKeyframes.at(jjj)).idx;
00760                         
00761                         //printf("%s << Searching for projection in (%d)\n", __FUNCTION__, cam_idx_1);
00762                         
00763                         for (unsigned int kkk = 0; kkk < tracks.at(activeTrackIndices.at(iii)).locations.size(); kkk++) {
00764                                 
00765                                 if (tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).imageIndex == ((int) cam_idx_1)) {
00766                                         // Found a projection of track onto this camera
00767                                         
00768                                         if (iii == 0) {
00769                                                         //printf("%s << Adding projection (%f, %f) of track (%d) to camera (%d)...\n", __FUNCTION__, tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).featureCoord.x, tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).featureCoord.y, iii, kf_store.keyframes.at(validKeyframes.at(jjj)).idx); 
00770                                         }
00771                                         
00772                                         
00773                                         addProjectionToSBA(sys, tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).featureCoord, iii, jjj);
00774                                          
00775                                          
00776                                 } 
00777                         }
00778                         
00779                         
00780                         
00781                 }
00782 
00783                 
00784         }
00785         
00786         //sys.setupSys(1.0e-4);
00787         
00788         // Bundle adjust this system, with only the "kf_index" camera unfixed
00789                         // what about the 3D points? might it change some of their positions?
00790                                         // perhaps this will be handled by the overall BA....
00791                                         
00792         //printf("%s << Cameras (nodes): %d, Points: %d [iters = %d]\n", __FUNCTION__, (int)sys.nodes.size(), (int)sys.tracks.size(), iterations);
00793         
00794         double avgError = optimizeSystem(sys, 1e-4, iterations);
00795         //printf("%s << avgError = %f.\n", __FUNCTION__, avgError);
00796         
00797         //printf("%s << () sys.nFixed = %d\n", __FUNCTION__, sys.nFixed);
00798         
00799         // Then need to update locations of 3D points and location of camera
00800         
00801         //unsigned int img_idx = kf_store.keyframes.at(validKeyframes.size()-1).idx;
00802         
00803         //retrieveCamera(cameras[img_idx], sys, validKeyframes.size()-1);
00804         
00805         
00806         
00807         
00808         //retrieveCamera(kf_store.keyframes.at(validKeyframes.size()-1).pose, sys, validKeyframes.size()-1);
00809         
00810         //printf("%s << After 2-frame BA: \n", __FUNCTION__);
00811         //cout << P0 << endl;
00812         //cout << kf_store.keyframes.at(validKeyframes.size()-1).pose << endl;
00813         
00814         for (unsigned int iii = 0; iii < validKeyframes.size(); iii++) {
00815                 
00816                 unsigned int img_idx = kf_store.keyframes.at(iii).idx;
00817                 
00818                 retrieveCameraPose(sys, iii, cameras[img_idx]);
00819                 
00820                 if (int(iii) >= max(((int) 0), ((int) validKeyframes.size())-4)) {
00821                         //cout << __FUNCTION__ << " << C(" << img_idx << ") = " << endl << cameras[img_idx] << endl;
00822                 }
00823                 
00824                 
00825                 //cout << "C = " << endl << cameras[kf_store.keyframes.at(validKeyframes.at(iii)).idx] << endl;
00826         }
00827         
00828         
00829         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
00830                 
00831                 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
00832                 
00833                 if (validKeyframes.size() == 2) {
00834                         // Hack to get it to reset locations on first go
00835                         tracks.at(activeTrackIndices.at(iii)).reset3dLoc(new3dLoc);
00836                 } else {
00837                         tracks.at(activeTrackIndices.at(iii)).set3dLoc(new3dLoc);
00838                 }
00839                 
00840         }
00841         
00842         return avgError;
00843 }
00844 
00845 double distanceBetweenPoints(Eigen::Matrix<double, 4, 1>& pt1, Eigen::Matrix<double, 4, 1>& pt2) {
00846         
00847         double dist = 0.0;
00848         
00849         dist += pow(pt1.x() - pt2.x(), 2.0);
00850         dist += pow(pt1.y() - pt2.y(), 2.0);
00851         dist += pow(pt1.z() - pt2.z(), 2.0);
00852         
00853         dist = pow(dist, 0.5);
00854         
00855         return dist;
00856         
00857 }
00858 
00859 double determineSystemSize(SysSBA& sys) {
00860         
00861         double maxDist = 0.0;
00862         
00863         for (unsigned int iii = 0; iii < sys.nodes.size()-1; iii++) {
00864                 for (unsigned int jjj = iii+1; jjj < sys.nodes.size(); jjj++) {
00865                         double dist = distanceBetweenPoints(sys.nodes.at(iii).trans, sys.nodes.at(jjj).trans);
00866                         maxDist = max(maxDist, dist);
00867                 }
00868         }
00869         
00870         return maxDist;
00871 }
00872 
00873 void normalizeSystem(SysSBA& sys, double factor) {
00874         
00875         for (unsigned int iii = 0; iii < sys.nodes.size(); iii++) {
00876                 sys.nodes.at(iii).trans.x() *= factor;
00877                 sys.nodes.at(iii).trans.y() *= factor;
00878                 sys.nodes.at(iii).trans.z() *= factor;
00879         }
00880         
00881         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
00882                 sys.tracks.at(iii).point.x() *= factor;
00883                 sys.tracks.at(iii).point.y() *= factor;
00884                 sys.tracks.at(iii).point.z() *= factor;
00885         }
00886 }
00887 
00888 double predictiveBundleAdjustment(cameraParameters& camData, vector<featureTrack>& tracks, geometry_msgs::PoseStamped *keyframePoses, bool *keyframeTypes, unsigned int keyframeCount, geometry_msgs::PoseStamped& newPose, unsigned int iterations, bool debug, int mode, double err, int* triangulations, double *averagePointShift) {
00889         
00890         double avgError;
00891         vector<unsigned int> activeTrackIndices;
00892         
00893         SysSBA sys;
00894         debug ? sys.verbose = 1 : sys.verbose = 0;
00895         sys.nFixed = 0;
00896         
00897         for (unsigned int iii = 0; iii < keyframeCount; iii++) {
00898                 
00899                 cv::Mat C, R, t;
00900                 Eigen::Quaternion<double> Q;
00901                 t = cv::Mat::zeros(3, 1, CV_64FC1);
00902                 
00903                 convertPoseFormat(keyframePoses[iii].pose, t, Q);
00904                 quaternionToMatrix(Q, R);
00905                 composeTransform(R, t, C);
00906                                 
00907                 addFixedCamera(sys, camData, C);
00908                 
00909                 // was if (1) {
00910                 if (keyframeTypes[iii]) { //(iii == (keyframeCount-1)) { // (iii == 0) { // 
00911                         sys.nodes.at(iii).isFixed = true;
00912                         sys.nFixed++;
00913                 } else { sys.nodes.at(iii).isFixed = false; }
00914         }
00915         
00916         if (sys.nFixed == 0) {
00917                 // To deal with the special case of ALL keyframes being video-based...
00918                 //printf("%s << DEALING WITH SPECIAL CASE!\n", __FUNCTION__);
00919                 sys.nodes.at(0).isFixed = true;
00920                 sys.nFixed++;
00921         }
00922         
00923         cv::Mat C, R, t;
00924         
00925         Eigen::Quaternion<double> Q;
00926         t = cv::Mat::zeros(3, 1, CV_64FC1);
00927         
00928         convertPoseFormat(newPose.pose, t, Q);
00929         quaternionToMatrix(Q, R);
00930         composeTransform(R, t, C);
00931         addFixedCamera(sys, camData, C);
00932         sys.nodes.at(sys.nodes.size()-1).isFixed = false;
00933         
00934         
00935         if (0) { printf("%s << Cameras added = (%d) + 1\n", __FUNCTION__, (keyframeCount-1)); }
00936         
00937 
00938         unsigned int tracksAdded = 0, projectionsAdded = 0;
00939         
00940         vector<int> track_indices;
00941         
00942         if (0) { printf("%s << tracks provided = (%d).\n", __FUNCTION__, ((int)tracks.size())); }
00943         
00944         int triCount = 0;
00945         
00946         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00947                 
00948                 
00949                 
00950                 if (tracks.at(iii).isTriangulated) {
00951                         
00952                         unsigned int projectionCount = 0;
00953                         
00954                         vector<int> indices, camera_indices; 
00955                         
00956                         if (0) {printf("%s << tracks.at(%d).locations.size() = (%d)\n", __FUNCTION__, iii, ((int)tracks.at(iii).locations.size())); }
00957                         
00958                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00959                                 
00960                                 if (0) {printf("%s << [%d] [%d]\n", __FUNCTION__, iii, jjj); }
00961                                 if (0) {printf("%s << (%d)\n", __FUNCTION__, tracks.at(iii).locations.at(jjj).imageIndex); }
00962                                 
00963                                 bool indexAdded = false;
00964                                 
00965                                 for (unsigned int kkk = 0; kkk < keyframeCount; kkk++) {
00966                                         
00967                                         if (int(tracks.at(iii).locations.at(jjj).imageIndex) == int(keyframePoses[kkk].header.seq)) {
00968                                                 projectionCount++;
00969                                                 if (0) {printf("%s << A Adding index (%d)\n", __FUNCTION__, jjj); }
00970                                                 indices.push_back(jjj);
00971                                                 indexAdded = true;
00972                                                 camera_indices.push_back(kkk);
00973                                                 break;
00974                                         }
00975                                         
00976                                 }
00977                                 
00978                                 if (0) {printf("%s << Searching for presence in flexible camera... (%d, %d)\n", __FUNCTION__, iii, jjj); }
00979                                 if (0) {printf("%s << (%d)\n", __FUNCTION__, newPose.header.seq); }
00980                                 
00981                                 if (!indexAdded && (int(tracks.at(iii).locations.at(jjj).imageIndex) == int(newPose.header.seq))) {
00982                                         projectionCount++;
00983                                         if (0) {printf("%s << B Adding index (%d)\n", __FUNCTION__, jjj); }
00984                                         indices.push_back(jjj);
00985                                         camera_indices.push_back(sys.nodes.size()-1);
00986                                 }
00987                                 
00988                                 
00989                         }
00990                         
00991                         if (0) {printf("%s << [%d] Out of loop\n", __FUNCTION__, iii); }
00992                         
00993                         //printf("%s << projectionCount = (%d)\n", __FUNCTION__, projectionCount);
00994                         
00995                         if (projectionCount >= 2) {
00996                                 // add point
00997                                 //Vector4d temppoint(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
00998                                 Vector4d temppoint(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
00999                                 
01000                                 //printf("%s << Adding point (%d) (%f, %f, %f)\n", __FUNCTION__, tracksAdded, temppoint.x(), temppoint.y(), temppoint.z());
01001                                 sys.addPoint(temppoint);
01002                                 track_indices.push_back(iii);
01003                                 
01004                                 if (0) {printf("%s << [%d] Adding projections\n", __FUNCTION__, iii); }
01005                                 
01006                                 // add projections
01007                                 for (unsigned int jjj = 0; jjj < indices.size(); jjj++) {
01008                                         
01009                                         if (0) {printf("%s << Adding projection for index (%d)(%d)... camera_indices.size() = [%d] {%d}\n", __FUNCTION__, jjj, indices.at(jjj), ((int)camera_indices.size()), camera_indices.at(jjj)); }
01010                                         
01011                                         //addProjectionToSBA(sys, tracks.at(iii).locations.at(jjj).featureCoord, tracks.at(iii).locations.at(jjj)., unsigned int camNo) 
01012                                         
01013                                         if (0) {printf("%s << iii = (%d)\n", __FUNCTION__, iii); }
01014                                         if (0) {printf("%s << tracks.size() = (%d)\n", __FUNCTION__, ((int)tracks.size())); }
01015                                         if (0) {printf("%s << jjj = (%d)\n", __FUNCTION__, jjj); }
01016                                         if (0) {printf("%s << X tracks.at(%d).locations.size() = (%d); (%d)\n", __FUNCTION__, iii, ((int)tracks.at(iii).locations.size()), indices.at(jjj)); }
01017                                         
01018                                         // jjj value was too large to access that "location"
01019                                         Vector2d temp2d(tracks.at(iii).locations.at(indices.at(jjj)).featureCoord.x, tracks.at(iii).locations.at(indices.at(jjj)).featureCoord.y);
01020                                         if (0) {printf("%s << sys.nodes.size() = (%d)\n", __FUNCTION__, ((int)sys.nodes.size())); }
01021                                         sys.addMonoProj(camera_indices.at(jjj), tracksAdded, temp2d);
01022                                         //printf("%s << Adding projection (%f, %f) for track (%d) and camera (%d)\n", __FUNCTION__, temp2d.x(), temp2d.y(), tracksAdded, camera_indices.at(jjj));
01023                                         projectionsAdded++;
01024                                         
01025                                 }
01026                                 
01027                                 if (0) {printf("%s << [%d] Projections added.\n", __FUNCTION__, iii); }
01028                                 
01029                                 tracksAdded++;
01030                                 
01031                         }
01032                         
01033                         triCount++;
01034                 }
01035                 
01036                 //
01037                 
01038         }
01039         
01040         if (0) { printf("%s << triangulated count = (%d).\n", __FUNCTION__, triCount); }
01041         
01042         if ((tracksAdded < 8) || (projectionsAdded < 8)) {
01043                 if (debug) { printf("%s << ERROR! Insufficient tracks (%d) or projections (%d) added for bundle adjustment.\n", __FUNCTION__, ((int)sys.tracks.size()), sys.countProjs()); }
01044                 return -1.0;
01045         }
01046         
01047         
01048         if (debug) {
01049                 printf("%s << Total tracks/cams/projections = (%d, %d, %d)\n", __FUNCTION__, ((int)sys.tracks.size()), ((int)sys.nodes.size()), sys.countProjs());
01050                 sys.printStats();
01051         }
01052         
01053         // BUNDLE ADJUST!!
01054         //sys.setupSys(1.0e-4);
01055         
01056         //printf("%s << About to bundle adjust...\n", __FUNCTION__);
01057         
01058         double system_size = determineSystemSize(sys);
01059         
01060         // printf("%s << system_size = (%f)\n", __FUNCTION__, system_size);
01061         
01062         normalizeSystem(sys, 3.0/system_size);
01063         
01064         if (debug) { printf("%s << Number of points in system = (%d)\n", __FUNCTION__, sys.tracks.size()); }
01065         
01066         avgError = optimizeSystem(sys, err, iterations, debug, mode);
01067         
01068         normalizeSystem(sys, system_size/3.0);
01069         
01070         /*
01071         for (unsigned int iii = 0; iii < keyframeCount; iii++) {
01072                 retrieveCameraPose(sys, iii, keyframePoses[iii].pose);
01073         }
01074         */
01075         geometry_msgs::Pose tmpPose = newPose.pose;
01076         double cameraShift = retrieveCameraPose(sys, keyframeCount, tmpPose);
01077         
01078         if (debug) { printf("%s << cameraShift = (%f)\n", __FUNCTION__, cameraShift); }
01079         
01080         if (debug) { printf("%s << avgError = (%f)\n", __FUNCTION__, avgError); }
01081         
01082         //if (!overwritePoints(sys, track_indices, tracks, DEFAULT_MAX_DISPLACEMENT, debug)) return -1.0;
01083         
01084         bool ptsOverwritten = overwritePoints(sys, track_indices, tracks, DEFAULT_MAX_DISPLACEMENT, averagePointShift, debug); /*DEFAULT_MAX_DISPLACEMENT*/
01085         
01086         if (debug) {
01087                 if (ptsOverwritten) {
01088                         printf("%s << Some points were overwritten...\n", __FUNCTION__);
01089                 } else {
01090                         printf("%s << No points were overwritten...\n", __FUNCTION__);
01091                 }
01092         }
01093         
01094         *triangulations = projectionsAdded;
01095         
01096         if (cameraShift == 0.0) {
01097                 return -1.0;
01098         } else {
01099                 newPose.pose = tmpPose;
01100                 return avgError;
01101         }
01102         
01103         //printf("%s << Adjustment error = (%f), (%d) out of (%d) pts changed\n", __FUNCTION__, avgError, changedCount, sys.tracks.size());
01104         
01105 }
01106 
01107 double odometryBundleAdjustment(cameraParameters& camData, vector<featureTrack>& tracks, geometry_msgs::PoseStamped *keyframePoses, unsigned int keyframeCount, unsigned int iterations, bool debug) {
01108         
01109         double avgError;
01110         vector<unsigned int> activeTrackIndices;
01111         
01112         SysSBA sys;
01113         
01114         debug ? sys.verbose = 1 : sys.verbose = 0;
01115         
01116         sys.nFixed = 0;
01117         
01118         for (unsigned int iii = 0; iii < keyframeCount; iii++) {
01119                 
01120                 if (0) { printf("%s << keyframePoses[%d].header.seq = (%d)\n", __FUNCTION__, iii, keyframePoses[iii].header.seq); }
01121                 
01122                 cv::Mat C, R, t;
01123                 Eigen::Quaternion<double> Q;
01124                 t = cv::Mat::zeros(3, 1, CV_64FC1);
01125                 convertPoseFormat(keyframePoses[iii].pose, t, Q);
01126                 quaternionToMatrix(Q, R);
01127                 composeTransform(R, t, C);
01128                 addFixedCamera(sys, camData, C);
01129                 
01130                 if ( (iii == 0) || (iii == (keyframeCount-1)) ) {
01131                         sys.nodes.at(iii).isFixed = true;
01132                         sys.nFixed++;
01133                 } else { sys.nodes.at(iii).isFixed = false; }
01134         }       
01135         
01136         unsigned int tracksAdded = 0, projectionsAdded = 0;
01137         vector<int> track_indices;
01138         
01139         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01140                 if (tracks.at(iii).isTriangulated) {
01141                         
01142                         unsigned int projectionCount = 0;
01143                         vector<int> indices, camera_indices; 
01144                         
01145                         // Determine all cameras that have this feature in them..
01146                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
01147                                 
01148                                 if (0) { printf("%s << tracks.at(%d).locations.at(%d).imageIndex = (%d)\n", __FUNCTION__, iii, jjj, tracks.at(iii).locations.at(jjj).imageIndex); }
01149                                 
01150                                 for (unsigned int kkk = 0; kkk < keyframeCount; kkk++) {
01151                                         
01152                                         if (int(tracks.at(iii).locations.at(jjj).imageIndex) == int(keyframePoses[kkk].header.seq)) {
01153                                                 projectionCount++;
01154                                                 indices.push_back(jjj);
01155                                                 camera_indices.push_back(kkk);
01156                                                 if (0) { printf("%s << found in keyframePoses[%d].header.seq = (%d)\n", __FUNCTION__, kkk, keyframePoses[kkk].header.seq); }
01157                                                 break;
01158                                         }
01159                                         
01160                                 }
01161                                 
01162                         }
01163                         
01164                         if (projectionCount > 2) {
01165 
01166                                 Vector4d temppoint = Vector4d(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
01167 
01168                                 sys.addPoint(temppoint);
01169                                 track_indices.push_back(iii);
01170                                 
01171                                 for (unsigned int jjj = 0; jjj < indices.size(); jjj++) {
01172                                         Vector2d temp2d(tracks.at(iii).locations.at(indices.at(jjj)).featureCoord.x, tracks.at(iii).locations.at(indices.at(jjj)).featureCoord.y);
01173                                         sys.addMonoProj(camera_indices.at(jjj), tracksAdded, temp2d);
01174                                         if (0) { printf("%s << Adding projection (%f, %f) for track (%d) and camera (%d)\n", __FUNCTION__, temp2d.x(), temp2d.y(), tracksAdded, camera_indices.at(jjj)); }
01175                                         projectionsAdded++;
01176                                 }
01177                                 
01178                                 tracksAdded++;
01179                                 
01180                         }
01181                         
01182                         
01183                 }
01184         }
01185         
01186         if ((tracksAdded < 8) || (projectionsAdded == 8)) {
01187                 if (debug) { printf("%s << ERROR! Insufficient tracks (%d) or projections (%d) added for bundle adjustment.\n", __FUNCTION__, ((int)sys.tracks.size()), sys.countProjs()); }
01188                 return -1.0;
01189         }
01190         
01191         if (debug) {
01192                 sys.printStats();
01193         }
01194         
01195         avgError = optimizeSystem(sys, 1e-5, iterations, debug);
01196         
01197         if (0) { printf("%s << avgError = (%f)\n", __FUNCTION__, avgError); }
01198         
01199         double avePointShift;
01200         if (!overwritePoints(sys, track_indices, tracks, DEFAULT_MAX_DISPLACEMENT, &avePointShift, debug)) return -1.0;
01201         
01202         if (avgError < 1.0) {
01203                 /*
01204                 for (unsigned int iii = 0; iii < keyframeCount; iii++) {
01205                         double cameraShift = retrieveCameraPose(sys, iii, keyframePoses[iii].pose);
01206                         printf("%s << shifting camera (%d) by (%f)\n", __FUNCTION__, iii, cameraShift);
01207                 }
01208                 */
01209         }
01210         
01211         return avgError;
01212         
01213 }
01214 
01215 bool overwritePoints(const SysSBA& sys, const vector<int>& track_indices, vector<featureTrack>& tracks, double maxDisplacement, double *averagePointShift, bool debug) {
01216         
01217         unsigned int changedCount = 0, couldveCount = 0;
01218         
01219         *averagePointShift = 0.0;
01220         
01221         if (debug) { printf("%s << Overwriting points with constraint of (%f)\n", __FUNCTION__, maxDisplacement); }
01222         
01223         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
01224                 
01225                 cv::Point3d old3dLoc = tracks.at(track_indices.at(iii)).get3dLoc();
01226                 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
01227                 
01228                 double dist = distBetweenPts(old3dLoc, new3dLoc);
01229                 
01230                 if ( (dist < maxDisplacement) && (dist > 0.0) ) {
01231                         *averagePointShift += dist;
01232                         changedCount++;                 
01233                         tracks.at(track_indices.at(iii)).reset3dLoc(new3dLoc);
01234                 } else {
01235                         // printf("%s << Point not overwritten because (%f) !=! (%f, %f)\n", __FUNCTION__, dist, 0.0, maxDisplacement);
01236                 }
01237                 
01238                 if (dist > 0.0) {
01239                         couldveCount++;
01240                 }
01241                 
01242         }
01243         
01244         if (changedCount == 0) {
01245                 *averagePointShift = -1.0;
01246         } else {
01247                 *averagePointShift /= double(changedCount);
01248         }
01249         
01250 
01251         
01252         if (debug) { printf("%s << Changed a total of (%u) out of (%u / %u) 3D point locations (%f)\n", __FUNCTION__, changedCount, couldveCount, sys.tracks.size(), *averagePointShift); }
01253         
01254         if (changedCount > 0) { return true; } else { return false; }
01255         
01256 }
01257 
01258 void retrievePartialSystem(SysSBA& sys, cv::Mat *C, vector<featureTrack>& tracks, vector<unsigned int>& indices) {
01259 
01260         for (unsigned int iii = 0; iii < indices.size(); iii++) {
01261                 
01262                 if (C[indices.at(iii)].rows == 4) {
01263                         retrieveCameraPose(sys, iii, C[indices.at(iii)]);
01264                 }
01265                 
01266         }
01267         
01268         unsigned int trackIndex = 0;
01269         
01270         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
01271                 
01272                 while (!tracks.at(trackIndex).isTriangulated) {
01273                         trackIndex++;
01274                         
01275                         if (trackIndex >= tracks.size()) {
01276                                 break;
01277                         }
01278                 }
01279                 
01280                 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
01281                 tracks.at(trackIndex).reset3dLoc(new3dLoc);
01282                 
01283                 trackIndex++;
01284                 
01285                 if (trackIndex >= tracks.size()) {
01286                         break;
01287                 }
01288                 
01289         }
01290         
01291 }
01292 
01293 void getActiveCameras(cv::Mat *C, vector<unsigned int>& indices, unsigned int min_index, unsigned int max_index) {
01294         for (unsigned int iii = min_index; iii <= max_index; iii++) {
01295                 if (C[iii].rows == 4) {
01296                         indices.push_back(iii);
01297                 }
01298         }
01299 }
01300 
01301 void getActiveTracks(vector<featureTrack>& tracks, vector<unsigned int>& cameras, vector<unsigned int>& indices) {
01302         
01303         printf("%s << Entered.\n", __FUNCTION__);
01304         
01305         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01306                 
01307                 bool isAdded = false;
01308                 
01309                 if (tracks.at(iii).isTriangulated) {
01310                 
01311                         for (unsigned int jjj = 0; jjj < cameras.size(); jjj++) {
01312                                 
01313                                 for (unsigned int kkk = 0; kkk < tracks.at(iii).locations.size(); kkk++) {
01314                                         
01315                                         printf("%s << about to access tracks(%d / %d)(%d / %d) & cameras(%d / %d)\n", __FUNCTION__, int(iii), int(tracks.size()), int(kkk), int(tracks.at(iii).locations.size()), int(jjj), int(cameras.size()));
01316                                         if (tracks.at(iii).locations.at(kkk).imageIndex == int(cameras.at(jjj))) {
01317                                                 indices.push_back(iii);
01318                                                 isAdded = true;
01319                                                 break;
01320                                         }
01321                                         
01322                                 }
01323                                 
01324                                 if (isAdded) {
01325                                         break;
01326                                 }
01327                                 
01328                         }
01329                         
01330                 }
01331                 
01332         }
01333         
01334         printf("%s << Exiting.\n", __FUNCTION__);
01335         
01336 }
01337  
01338 void retrieveFullSystem(SysSBA& sys, cv::Mat *C, vector<featureTrack>& tracks, unsigned int start_cam, unsigned int final_cam) {
01339         
01340         //vector<unsigned int> camera_indices;
01341         
01342         
01343         for (unsigned int iii = 0; iii < sys.nodes.size(); iii++) {
01344                 
01345                 retrieveCameraPose(sys, iii, C[start_cam+iii]);
01346                 
01347         }
01348         
01349         
01350         /*
01351         for (unsigned int jjj = start_cam; jjj <= final_cam; jjj++) {
01352                 
01353                 if (C[jjj].rows == 4) {
01354                         retrieveCamera(C[camera_indices.size()], sys, jjj);
01355                         
01356                         camera_indices.push_back(jjj);
01357                 }
01358         
01359         }
01360         */
01361         
01362         // The way the tracks are being retrived is incorrect!!!
01363         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
01364                 
01365                 // Only want to retrieve relevant tracks!
01366                 
01367                 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
01368                 tracks.at(iii).reset3dLoc(new3dLoc);
01369         }
01370 }
01371 
01372 double optimizeSubsystem(cameraParameters& camData, cv::Mat *C, vector<unsigned int>& c_i, vector<featureTrack>& tracks, vector<unsigned int>& t_i, unsigned int iterations) {
01373 
01374         SysSBA sys;
01375         sys.verbose = 0;
01376         
01377         vector<cv::Point3d> cloud;
01378         
01379         getActive3dPoints(tracks, t_i, cloud);
01380 
01381         printf("%s << active points (%d) out of (%d) valid tracks..\n", __FUNCTION__, int(cloud.size()), int(t_i.size()));
01382 
01383         addPointsToSBA(sys, cloud);
01384         
01385         // Add first and last cameras as fixed
01386         printf("%s << Adding (%d) and (%d) as fixed cameras...\n", __FUNCTION__, c_i.at(0), c_i.at(c_i.size()-1));
01387         addFixedCamera(sys, camData, C[c_i.at(0)]);
01388         addFixedCamera(sys, camData, C[c_i.at(c_i.size()-1)]);
01389         
01390         for (unsigned int iii = 1; iii < c_i.size()-1; iii++) {
01391                 addNewCamera(sys, camData, C[c_i.at(iii)]);
01392         }
01393         
01394         for (unsigned int iii = 0; iii < c_i.size(); iii++) {
01395                 
01396                 //printf("%s << (%d) : %d\n", __FUNCTION__, iii, c_i.at(iii));
01397                 
01398                 // the node that corresponds to the camera
01399                 
01400                 unsigned int sysIndex;
01401                 
01402                 if (iii == 0) {
01403                         sysIndex = 0;
01404                 } else if (iii == c_i.size()-1) {
01405                         sysIndex = 1;
01406                 } else {
01407                         sysIndex = iii + 1;
01408                 }
01409 
01410 
01411                 
01412                 //cout << C[c_i.at(iii)] << endl;       
01413                 
01414                 for (unsigned int jjj = 0; jjj < t_i.size(); jjj++) {
01415                         
01416                         for (unsigned int kkk = 0; kkk < tracks.at(t_i.at(jjj)).locations.size(); kkk++) {
01417                                 
01418                                 if (tracks.at(t_i.at(jjj)).locations.at(kkk).imageIndex == ((int) c_i.at(iii))) {
01419                                         
01420                                         Vector2d proj;
01421                                         
01422                                         proj.x() = tracks.at(t_i.at(jjj)).locations.at(kkk).featureCoord.x;
01423                                         proj.y() = tracks.at(t_i.at(jjj)).locations.at(kkk).featureCoord.y;
01424         
01425                                         sys.addMonoProj(sysIndex, jjj, proj);
01426                                 }
01427                         }
01428                         
01429                 }
01430                 
01431                 
01432                 
01433         }       
01434         
01435         sys.nFixed = 2;
01436         
01437         unsigned int numFixed = sys.nFixed;
01438         
01439         printf("%s << nodes = %d; tracks = %d (nFixed = %d)\n", __FUNCTION__, int(sys.nodes.size()), int(sys.tracks.size()), int(numFixed));
01440         
01441         double avgError = optimizeSystem(sys, 1e-4, iterations);
01442         
01443         printf("%s << avgError = %f\n", __FUNCTION__, avgError);
01444         
01445         printf("%s << Retrieving 0 -> %d; and 1 -> %d\n", __FUNCTION__, c_i.at(0), c_i.at(c_i.size()-1));
01446         
01447         retrieveCameraPose(sys, 0, C[c_i.at(0)]);
01448         retrieveCameraPose(sys, 1, C[c_i.at(c_i.size()-1)]);
01449         
01450         for (unsigned int iii = 1; iii < c_i.size()-1; iii++) {
01451                 retrieveCameraPose(sys, iii+1, C[c_i.at(iii)]);
01452         }
01453         
01454         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
01455                 
01456                 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
01457                 
01458                 tracks.at(t_i.at(iii)).set3dLoc(new3dLoc);
01459         }
01460         
01461         
01462         return avgError;
01463         
01464 }
01465 
01466 double optimizeKeyframePair(vector<featureTrack>& tracks, cameraParameters& camData, int idx1, int idx2, cv::Mat *cameras) {
01467         
01468         vector<cv::Point2f> pts1, pts2;
01469         getPointsFromTracks(tracks, pts1, pts2, idx1, idx2);
01470         
01471         vector<cv::Point3d> cloud;
01472         vector<cv::Point2f> corresp;
01473         
01474         for (unsigned int iii = 0; iii < 10; iii++) {
01475                 //printf("%s << pt(%d) = (%f, %f) & (%f, %f)\n", __FUNCTION__, iii, pts1.at(iii).x, pts1.at(iii).y, pts2.at(iii).x, pts2.at(iii).y);
01476         }
01477         //if (debug) {
01478                 printf("%s << Before 2-frame BA: \n", __FUNCTION__);
01479                 cout << cameras[idx1] << endl;
01480                 cout << cameras[idx2] << endl;
01481         //}
01482         
01483         TriangulatePoints(pts1, pts2, camData.K, camData.K.inv(), cameras[idx1], cameras[idx2], cloud, corresp);
01484         
01485         double twoErr = twoViewBundleAdjustment(camData, cameras[idx1], cameras[idx2], cloud, pts1, pts2, 1000);
01486         
01487         //if (debug) {
01488                 printf("%s << After 2-frame BA: \n", __FUNCTION__);
01489                 cout << cameras[idx1] << endl;
01490                 cout << cameras[idx2] << endl;
01491         //}
01492         
01493         
01494         return twoErr;
01495         
01496 }
01497 
01498 void assignPartialSystem(SysSBA &sba, vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, vector<unsigned int>& indices, bool assignProjections) {
01499         
01500         sba.tracks.clear();
01501         sba.nodes.clear();
01502         
01503         vector<unsigned int> added_indices;
01504         
01505         for (unsigned int jjj = 0; jjj < indices.size(); jjj++) {
01506                         
01507                 if (cameras[indices.at(jjj)].rows == 4) {
01508                         if (jjj == 0) {
01509                                 addFixedCamera(sba, camData, cameras[indices.at(jjj)]);
01510                         } else {
01511                                 addNewCamera(sba, camData, cameras[indices.at(jjj)]);
01512                         }
01513                         added_indices.push_back(indices.at(jjj));
01514                 }
01515         
01516         }
01517         
01518         unsigned int addedTracks = -1;
01519         
01520         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01521                 
01522                 if (tracks.at(iii).isTriangulated) {
01523 
01524                         Vector4d temppoint(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
01525                         sba.addPoint(temppoint);
01526                         addedTracks++;  
01527                         
01528                         if (assignProjections) {
01529                                 
01530                                 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
01531                                         
01532                                         unsigned int cam_index = tracks.at(iii).locations.at(jjj).imageIndex;
01533                                         
01534                                         for (unsigned int kkk = 0; kkk < added_indices.size(); kkk++) {
01535                                                 
01536                                                 if (added_indices.at(kkk) == cam_index) {
01537                                                         //printf("%s << adding projection (%f, %f) to (cam: %d, track: %d)\n", __FUNCTION__, tracks.at(iii).locations.at(jjj).featureCoord.x, tracks.at(iii).locations.at(jjj).featureCoord.y, kkk, iii);
01538                                                         addProjectionToSBA(sba, tracks.at(iii).locations.at(jjj).featureCoord, addedTracks, kkk);
01539                                                         
01540                                                         break;
01541                                                 }
01542                                                 
01543                                         }
01544                                         
01545                                         
01546                                         
01547                                 }
01548                                                         
01549                         }               
01550                 }
01551                 
01552                 
01553                 
01554         }
01555         
01556         
01557         
01558 }
01559 
01560 double adjustFullSystem(vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int min_index, unsigned int max_index, unsigned int its) {
01561         SysSBA fullsys;
01562         
01563         cv::Mat eye4 = cv::Mat::eye(4, 4, CV_64FC1);
01564         
01565         for (unsigned int iii = 0; iii < max_index; iii++) {
01566                 if (cameras[iii].rows == 4) {
01567                         //estimatePoseFromKnownPoints(cameras[iii], camData, tracks, iii, eye4);
01568                 }
01569         }
01570         
01571         // Get active cameras
01572         vector<unsigned int> active_camera_indices;
01573         getActiveCameras(cameras, active_camera_indices, min_index, max_index);
01574         
01575         // Get active tracks
01576         vector<unsigned int> active_track_indices;
01577         getActiveTracks(tracks, active_camera_indices, active_track_indices);
01578         
01579         assignSystem(fullsys, tracks, camData, cameras, active_camera_indices, active_track_indices);
01580         
01581         double avgError;
01582         
01583         avgError = optimizeSystem(fullsys, 1e-4, its );
01584         //retrievePartialSystem(sys, ACM, featureTrackVector, keyframeIndices);
01585         
01586         retrieveSystem(fullsys, tracks, camData, cameras, active_camera_indices, active_track_indices);
01587         
01588         return avgError;
01589         
01590         
01591 }
01592 
01593 void retrieveSystem(SysSBA &sba, vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, vector<unsigned int>& camera_indices, vector<unsigned int>& track_indices) {
01594         
01595         for (unsigned int iii = 0; iii < camera_indices.size(); iii++) {
01596                 retrieveCameraPose(sba, iii, cameras[camera_indices.at(iii)]);
01597         }
01598         
01599         for (unsigned int iii = 0; iii < track_indices.size(); iii++) {
01600                 cv::Point3d new3dLoc(sba.tracks.at(iii).point.x(), sba.tracks.at(iii).point.y(), sba.tracks.at(iii).point.z());
01601                 tracks.at(track_indices.at(iii)).reset3dLoc(new3dLoc);
01602         }
01603         
01604 }
01605 
01606 void assignSystem(SysSBA &sba, vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, vector<unsigned int>& camera_indices, vector<unsigned int>& track_indices) {
01607         
01608         sba.tracks.clear();
01609         sba.nodes.clear();
01610         
01611         printf("%s << DEBUG [%d]\n", __FUNCTION__, 0);
01612         
01613         for (unsigned int iii = 0; iii < camera_indices.size(); iii++) {
01614                 if (sba.nodes.size() == 0) {
01615                         addFixedCamera(sba, camData, cameras[camera_indices.at(iii)]);
01616                 } else {
01617                         addNewCamera(sba, camData, cameras[camera_indices.at(iii)]);
01618                 }
01619         }
01620         
01621         printf("%s << DEBUG [%d]\n", __FUNCTION__, 1);
01622         
01623         for (unsigned int iii = 0; iii < track_indices.size(); iii++) {
01624                 
01625                 Vector4d temppoint(tracks.at(track_indices.at(iii)).get3dLoc().x, tracks.at(track_indices.at(iii)).get3dLoc().y, tracks.at(track_indices.at(iii)).get3dLoc().z, 1.0);
01626                 sba.addPoint(temppoint);
01627                 
01628                 for (unsigned int jjj = 0; jjj < tracks.at(track_indices.at(iii)).locations.size(); jjj++) {
01629                         
01630                         for (unsigned int kkk = 0; kkk < camera_indices.size(); kkk++) {
01631                                 if (int(camera_indices.at(kkk)) == tracks.at(track_indices.at(iii)).locations.at(jjj).imageIndex) {
01632                                         
01633                                         Vector2d proj;
01634                         
01635                                         proj.x() = tracks.at(track_indices.at(iii)).locations.at(jjj).featureCoord.x;
01636                                         proj.y() = tracks.at(track_indices.at(iii)).locations.at(jjj).featureCoord.y;
01637                                                                                 
01638                                         //printf("%s << Adding mono projection: (cam: %d / %d, track: %d / %d) = (%f, %f)\n", __FUNCTION__, tracks.at(iii).locations.at(jjj).imageIndex, sys.nodes.size(), sys.tracks.size()-1, sys.tracks.size(), proj.x(), proj.y());
01639                                         sba.addMonoProj(kkk, iii, proj);
01640                                 }
01641                         }
01642                         
01643                 }
01644 
01645                 
01646         }
01647         
01648         printf("%s << DEBUG [%d]\n", __FUNCTION__, 2);
01649         
01650 }
01651 
01652 void assignFullSystem(SysSBA &sba, vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int start_index, unsigned int finish_index, bool dummy) {
01653         
01654         sba.tracks.clear();
01655         sba.nodes.clear();
01656         
01657         vector<unsigned int> camera_indices;
01658         
01659         for (unsigned int jjj = start_index; jjj <= finish_index; jjj++) {
01660                 
01661                 if (cameras[jjj].rows == 4) {
01662                         if (sba.nodes.size() == 0) {
01663                                 addFixedCamera(sba, camData, cameras[jjj]);
01664                         } else {
01665                                 addNewCamera(sba, camData, cameras[jjj]);
01666                         }
01667                         
01668                         camera_indices.push_back(jjj);
01669                 }
01670         
01671         }
01672         
01673         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01674                 
01675                 if (tracks.at(iii).isTriangulated) {
01676 
01677                         Vector4d temppoint(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
01678                         sba.addPoint(temppoint);                        
01679         
01680                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
01681                                 
01682                                 // Only want to add projections for active nodes
01683                                 
01684                                 if (!dummy) {
01685                                         if ((((unsigned int) tracks.at(iii).locations.at(jjj).imageIndex) >= start_index) && (((unsigned int) tracks.at(iii).locations.at(jjj).imageIndex) <= (finish_index))) {
01686                                                 
01687                                                 for (unsigned int kkk = 0; kkk < camera_indices.size(); kkk++) {
01688                                                         
01689                                                         if (int(camera_indices.at(kkk)) == tracks.at(iii).locations.at(jjj).imageIndex) {
01690                                                                 Vector2d proj;
01691                                                 
01692                                                                 proj.x() = tracks.at(iii).locations.at(jjj).featureCoord.x;
01693                                                                 proj.y() = tracks.at(iii).locations.at(jjj).featureCoord.y;
01694                                                                                                         
01695                                                                 //printf("%s << Adding mono projection: (cam: %d / %d, track: %d / %d) = (%f, %f)\n", __FUNCTION__, tracks.at(iii).locations.at(jjj).imageIndex, sys.nodes.size(), sys.tracks.size()-1, sys.tracks.size(), proj.x(), proj.y());
01696                                                                 sba.addMonoProj(kkk, sba.tracks.size()-1, proj);
01697                                                         }
01698                                                         
01699                                                 }
01700                                                 
01701                                                 //printf("%s << Assembling projection (%d)(%d)\n", __FUNCTION__, iii, jjj);
01702                                         
01703                                                 
01704                                                 
01705                                         }
01706                                 }
01707                                 
01708                                 
01709                                 
01710                                 
01711                                 
01712                         }
01713                 
01714                 }
01715                 
01716         }
01717         
01718         
01719         
01720 }
01721 
01722 bool reconstructFreshSubsequencePair(vector<featureTrack>& tracks, vector<cv::Point3d>& ptCloud, vector<unsigned int>& triangulatedIndices, cv::Mat& real_C0, cv::Mat& real_C1, cameraParameters camData, int idx1, int idx2) {
01723         
01724         if ((camData.K.rows != 3) || (camData.K.cols != 3) || (camData.K_inv.rows != 3) || (camData.K_inv.cols != 3)) {
01725                 printf("%s << ERROR! Camera intrinsics dimensions are invalid.\n", __FUNCTION__);
01726                 return false;
01727         }
01728         
01729         
01730         //printf("%s << DEBUG [%d]\n", __FUNCTION__, 0);
01731         
01732         cv::Mat real_P0, real_P1; 
01733         
01734         vector<cv::Point2f> pts1_, pts2_, pts1, pts2;
01735         
01736         printf("%s << Getting pts from tracks: (%d), (%d, %d), (%d, %d)\n", __FUNCTION__, ((int)tracks.size()), ((int)pts1_.size()), ((int)pts2_.size()), idx1, idx2);
01737         getPointsFromTracks(tracks, pts1_, pts2_, idx1, idx2);
01738         
01739         //subselectPoints(pts1_, pts1, pts2_, pts2);
01740         pts1.insert(pts1.end(), pts1_.begin(), pts1_.end());
01741         pts2.insert(pts2.end(), pts2_.begin(), pts2_.end());
01742         
01743         printf("%s << Checking pts size... (%d)\n", __FUNCTION__, ((int)pts1.size()));
01744         
01745         if (pts1.size() < 8) {
01746                 printf("%s << ERROR! Too few corresponding points (%d)\n", __FUNCTION__, ((int)pts1.size()));
01747                 return false;
01748         }
01749         
01750         vector<unsigned int> activeTrackIndices, fullSpanIndices;
01751         getActiveTracks(activeTrackIndices, tracks, idx1, idx2);
01752         filterToCompleteTracks(fullSpanIndices, activeTrackIndices, tracks, idx1, idx2);
01753         
01754         //printf("%s << DEBUG [%d]\n", __FUNCTION__, 2);
01755         
01756         cv::Mat F, matchesMask_F_matrix;
01757         F = cv::findFundamentalMat(cv::Mat(pts1), cv::Mat(pts2), cv::FM_RANSAC, 1.00, 0.99, matchesMask_F_matrix);
01758 
01759         cv::Mat E = camData.K.t() * F * camData.K;      
01760         cv::Mat CX[4];
01761         findFourTransformations(CX, E, camData.K, pts1, pts2);
01762         
01763         //printf("%s << DEBUG [%d]\n", __FUNCTION__, 3);
01764         
01765         cv::Mat C;
01766         int validPts = findBestCandidate(CX, camData.K, pts1, pts2, C);
01767         
01768         if (validPts < ((int) (0.5 * ((double) pts1.size())))) {
01769                 printf("%s << ERROR! too few tracks (%d / %d) in best transform are in front of camera.\n", __FUNCTION__, ((int)validPts), ((int)pts1.size()));
01770                 return false;
01771         }
01772                 
01773         //printf("%s << DEBUG [%d]\n", __FUNCTION__, 4);
01774         
01775         cv::Mat P1, R1, t1, Rvec;
01776         transformationToProjection(C, P1);
01777         decomposeTransform(C, R1, t1);
01778         Rodrigues(R1, Rvec);
01779 
01780         //printf("%s << DEBUG [%d]\n", __FUNCTION__, 5);
01781         
01782         real_C1 = C * real_C0;  // real_C1 = C * real_C0;
01783         
01784         //real_C1 = C.inv() * real_C0;
01785         
01786         transformationToProjection(real_C0, real_P0);
01787         transformationToProjection(real_C1, real_P1);
01788         
01789         /*
01790         printf("%s << Putative camera poses (%d & %d)\n", __FUNCTION__, idx1, idx2);
01791         cout << "real_C0 = " << endl;
01792         cout << real_C0 << endl;
01793         cout << "real_C1 = " << endl;
01794         cout << real_C1 << endl;
01795         */
01796         
01797         //printf("%s << DEBUG [%d]\n", __FUNCTION__, 6);
01798         
01799         //cout << camData.K << endl;
01800         //cout << camData.K_inv << endl;
01801         
01802         vector<cv::Point2f> correspPoints;
01803         TriangulatePoints(pts1, pts2, camData.K, camData.K_inv, real_C0, real_C1, ptCloud, correspPoints);
01804         //TriangulatePoints(pts1_, pts2_, camData.K, camData.K_inv, real_C1.inv(), real_C0.inv(), ptCloud, correspPoints);
01805         //TriangulatePoints(pts1, pts2, camData.K, camData.K_inv, real_P0, real_P1, ptCloud, correspPoints);
01806         //printf("%s << %d points triangulated.\n", __FUNCTION__, ptsInCloud.size());
01807         
01808         //printf("%s << DEBUG [%d]\n", __FUNCTION__, 7);
01809         
01810         triangulatedIndices.clear();
01811         triangulatedIndices.insert(triangulatedIndices.end(), fullSpanIndices.begin(), fullSpanIndices.end());
01812         
01813         //printf("%s << triangulatedIndices.size() = %d\n", __FUNCTION__, triangulatedIndices.size());
01814         
01815         updateTriangulatedPoints(tracks, triangulatedIndices, ptCloud);
01816         
01817         //printf("%s << DEBUG [%d]\n", __FUNCTION__, 8);
01818         
01819         //real_C1 = real_C1.inv();
01820         
01821         return true;                    
01822 }
01823 
01824 void subselectPoints(const vector<cv::Point2f>& src1, vector<cv::Point2f>& dst1, const vector<cv::Point2f>& src2, vector<cv::Point2f>& dst2) {
01825         
01826         vector<cv::Point2f> new_src_1, new_src_2;
01827         new_src_1.insert(new_src_1.end(), src1.begin(), src1.end());
01828         new_src_2.insert(new_src_2.end(), src2.begin(), src2.end());
01829         
01830         int aimedPoints = 48;
01831         
01832         if (int(src1.size()) <= aimedPoints) {
01833                 dst1.insert(dst1.end(), src1.begin(), src1.end());
01834                 dst2.insert(dst2.end(), src2.begin(), src2.end());
01835                 
01836                 return;
01837         }
01838         
01839         // Find centroid
01840         cv::Point2f centroid_1, centroid_2;
01841         
01842         for (unsigned int iii = 0; iii < src1.size(); iii++) {
01843                 centroid_1.x += src1.at(iii).x / ((double) src1.size());
01844                 centroid_1.y += src1.at(iii).y / ((double) src1.size());
01845                 
01846                 centroid_2.x += src2.at(iii).x / ((double) src2.size());
01847                 centroid_2.y += src2.at(iii).y / ((double) src2.size());
01848         } 
01849         
01850         printf("%s << Centroids: (%f, %f) & (%f, %f)\n", __FUNCTION__, centroid_1.x, centroid_1.y, centroid_2.x, centroid_2.y);
01851         
01852         // First add most central point
01853         int mostCentralIndex = -1;
01854         float bestDistance = 9e99;
01855         
01856         for (unsigned int iii = 0; iii < src1.size(); iii++) {
01857                 
01858                 float dist = distanceBetweenPoints(src1.at(iii), centroid_1) + distanceBetweenPoints(src2.at(iii), centroid_2);
01859                 
01860                 if ((dist < bestDistance) || (iii == 0)) {
01861                         bestDistance = dist;
01862                         mostCentralIndex = iii;
01863                 }
01864                 
01865         }
01866         
01867         if (mostCentralIndex < 0) {
01868                 
01869                 dst1.insert(dst1.end(), src1.begin(), src1.end());
01870                 dst2.insert(dst2.end(), src2.begin(), src2.end());
01871                 
01872                 return;
01873                 
01874         }
01875         
01876         dst1.push_back(new_src_1.at(mostCentralIndex));
01877         dst2.push_back(new_src_2.at(mostCentralIndex));
01878         
01879         // Correct centroid by removing contribution of removed point, multiplying by old size divided by new size
01880         centroid_1.x -= new_src_1.at(mostCentralIndex).x / ((double) src1.size());
01881         centroid_1.x *= ((double) src1.size()) / ((double) new_src_1.size());
01882         
01883         centroid_2.x -= new_src_2.at(mostCentralIndex).x / ((double) src2.size());
01884         centroid_2.x *= ((double) src2.size()) / ((double) new_src_2.size());
01885         
01886         new_src_1.erase(new_src_1.begin() + mostCentralIndex);
01887         new_src_2.erase(new_src_2.begin() + mostCentralIndex);
01888         
01889         printf("%s << Most central index: %d\n", __FUNCTION__, mostCentralIndex);
01890         
01891         for (int iii = 0; iii < aimedPoints-1; iii++) {
01892                 
01893                 cv::Point2f centroid_1, centroid_2;
01894                 
01895                 float largestDist;
01896                 unsigned int largestIndex;
01897         
01898                 for (unsigned int jjj = 0; jjj < new_src_1.size(); jjj++) {
01899 
01900                         float dist = distanceBetweenPoints(new_src_1.at(jjj), centroid_1) + distanceBetweenPoints(new_src_2.at(jjj), centroid_2);
01901                         
01902                         if ((jjj == 0) || (dist > largestDist)) {
01903                                 largestDist = dist;
01904                                 largestIndex = jjj;
01905                         }
01906                         
01907                 }
01908                 
01909                 centroid_1.x -= new_src_1.at(largestIndex).x / ((double) new_src_1.size());
01910                 centroid_1.x *= ((double) new_src_1.size()) / ((double) new_src_1.size() - 1);
01911         
01912                 centroid_2.x -= new_src_2.at(mostCentralIndex).x / ((double) new_src_2.size());
01913                 centroid_2.x *= ((double) new_src_2.size()) / ((double) new_src_2.size() - 1);
01914                 
01915                 dst1.push_back(new_src_1.at(largestIndex));
01916                 dst2.push_back(new_src_2.at(largestIndex));
01917                 
01918                 new_src_1.erase(new_src_1.begin() + largestIndex);
01919                 new_src_2.erase(new_src_2.begin() + largestIndex);
01920                 
01921         }
01922         
01923         //dst1.insert(dst1.end(), src1.begin(), src1.end());
01924         //dst2.insert(dst2.end(), src2.begin(), src2.end());
01925         
01926 }
01927 
01928 int estimatePoseBetweenCameras(cameraParameters& camData, vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, cv::Mat& C) {
01929         cv::Mat F, matchesMask_F_matrix;
01930         
01931         F = cv::findFundamentalMat(cv::Mat(pts1), cv::Mat(pts2), cv::FM_RANSAC, 1.00, 0.99, matchesMask_F_matrix);
01932         
01933         cv::Mat E = camData.K.t() * F * camData.K;      
01934         
01935         cv::Mat CX[4];
01936         
01937         findFourTransformations(CX, E, camData.K, pts1, pts2);
01938         
01939         int validPts = findBestCandidate(CX, camData.K, pts1, pts2, C);
01940         
01941         return validPts;
01942 }
01943 
01944 double testKeyframePair(vector<featureTrack>& tracks, cameraParameters& camData, double *scorecard[], int idx1, int idx2, double *score, cv::Mat& pose, bool evaluate, bool debug) {
01945         
01946         //printf("%s << Entered.\n", __FUNCTION__);
01947         
01948         //if (debug) {
01949                 //printf("%s << Testing frames (%d) & (%d)\n", __FUNCTION__, idx1, idx2);
01950         //}
01951         
01952         double keyframeScore;
01953         
01954         for (unsigned int iii = 0; iii < 5; iii++) {
01955                 score[iii] = -1.0;
01956         }
01957         
01958         vector<cv::Point2f> pts1_, pts2_, pts1, pts2;
01959         getPointsFromTracks(tracks, pts1, pts2, idx1, idx2);
01960         
01961         //printf("%s << A: pts1.size() = %d; pts2.size() = %d\n", __FUNCTION__, pts1.size(), pts2.size());
01962         
01963         subselectPoints(pts1_, pts1, pts2_, pts2);
01964         
01965         pts1.insert(pts1.end(), pts1_.begin(), pts1_.end());
01966         pts2.insert(pts2.end(), pts2_.begin(), pts2_.end());
01967         
01968         //printf("%s << B: pts1.size() = %d; pts2.size() = %d\n", __FUNCTION__, pts1.size(), pts2.size());
01969         
01970         unsigned int min_pts = std::min(pts1.size(), pts2.size());
01971         
01972         if (min_pts < 16) {
01973                 printf("%s << Returning with (-1); insufficient points.\n", __FUNCTION__);
01974                 return -1.00;
01975         }
01976         
01977         cv::Mat matchesMask_F_matrix, matchesMask_H_matrix;
01978         
01979         cv::Mat F = cv::findFundamentalMat(cv::Mat(pts1), cv::Mat(pts2), cv::FM_RANSAC, 1.00, 0.99, matchesMask_F_matrix);
01980         cv::Mat H = cv::findHomography(cv::Mat(pts1), cv::Mat(pts2), cv::FM_RANSAC, 1.00, matchesMask_H_matrix);
01981         
01982         //int inliers_H = countNonZero(matchesMask_H_matrix);
01983         //int inliers_F = countNonZero(matchesMask_F_matrix);
01984         
01985         //double new_F_score = calcInlierGeometryDistance(pts1, pts2, F, matchesMask_F_matrix, SAMPSON_DISTANCE);
01986         //double new_H_score = calcInlierGeometryDistance(pts1, pts2, H, matchesMask_H_matrix, LOURAKIS_DISTANCE);
01987         
01988         //double geometryScore = calcGeometryScore(inliers_H, inliers_F, new_H_score, new_F_score);
01989         
01990         // gric score
01991         double fGric, hGric;
01992         double gricScore = normalizedGRICdifference(pts1, pts2, F, H, matchesMask_F_matrix, matchesMask_H_matrix, fGric, hGric);
01993         gricScore = fGric / hGric;
01994         //double gricIdeal = 2.0, gricMax = 10.0, gricMin = 1.0;
01995         double nGRIC = asymmetricGaussianValue(gricScore, scorecard[1][0], scorecard[1][2], scorecard[1][2]);
01996         //printf("%s << SCORES: geom (%f), conv (%f), gric (%f / [%d / %d]), pts (%f)\n", __FUNCTION__, geometryScore, twoErr, gricScore, (int) fGric, (int) hGric, infrontScore);
01997         
01998         score[1] = gricScore;
01999         
02000         //else if (geometryScore < 1.00) {
02001                 // geometryScore = -1.00;
02002         //}
02003         
02004         if (nGRIC == 0.00) {
02005                 if (!evaluate) {
02006                         printf("%s << Returning with (0); nGric = 0.00.\n", __FUNCTION__);
02007                         return 0.00;
02008                 }
02009         }
02010 
02011         cv::Mat E = camData.K.t() * F * camData.K;      
02012         cv::Mat CX[4], C;
02013         findFourTransformations(CX, E, camData.K, pts1, pts2);
02014         int validPts = findBestCandidate(CX, camData.K, pts1, pts2, C);
02015         
02016         // infrontScore
02017         //double infrontIdeal = 1.00, infrontMax = 1.00, infrontMin = 0.90;
02018         double infrontScore = ((double) validPts) / ((double) pts1.size());
02019         double nIFS = asymmetricGaussianValue(infrontScore, scorecard[2][0], scorecard[2][2], scorecard[2][1]);
02020         
02021         score[2] = infrontScore;
02022         
02023         // Now correct if amt in front is greater than mean:
02024         if (infrontScore >= scorecard[2][0]) {
02025                 nIFS = 1.00;
02026         }
02027         
02028         if (nIFS == 0) {
02029                 if (!evaluate) {
02030                         printf("%s << Returning with (0); nIFS = 0.00.\n", __FUNCTION__);
02031                         return 0.00;
02032                 }
02033         }
02034         
02035         cv::Mat absolute_C0, P0, P1;
02036         absolute_C0 = cv::Mat::eye(4, 4, CV_64FC1);
02037         
02038         transformationToProjection(absolute_C0, P0);
02039         transformationToProjection(C, P1);
02040         //pose.copyTo(P1);
02041         
02042         vector<cv::Point3d> cloud;
02043         vector<cv::Point2f> corresp;
02044         
02045         if (debug) {
02046                 /*
02047                 printf("%s << Before triangulation: \n", __FUNCTION__);
02048                 cout << P0 << endl;
02049                 cout << P1 << endl;
02050                 */
02051         }
02052         
02053         TriangulatePoints(pts1, pts2, camData.K, camData.K.inv(), P0, P1, cloud, corresp);
02054         
02055         //printf("%s << Before 2-frame BA: \n", __FUNCTION__);
02056         //cout << P0 << endl;
02057         //cout << P1 << endl;
02058         
02059         if (debug) {
02060                 /*
02061                 printf("%s << Before 2-frame BA: \n", __FUNCTION__);
02062                 cout << P0 << endl;
02063                 cout << P1 << endl;
02064                 */
02065         }
02066         
02067         // convergence
02068         //double convIdeal = 0.30, convMax = 0.80, convMin = 0.10;
02069         double twoErr = twoViewBundleAdjustment(camData, P0, P1, cloud, pts1, pts2, 10);
02070         
02071         score[0] = twoErr;
02072         
02073         if (debug) {
02074                 /*
02075                 printf("%s << After 2-frame BA: \n", __FUNCTION__);
02076                 cout << P0 << endl;
02077                 cout << P1 << endl;
02078                 */
02079                 for (unsigned int iii = 0; iii < 10; iii++) {
02080                         //printf("%s << pt(%d) = (%f, %f) & (%f, %f)\n", __FUNCTION__, iii, pts1.at(iii).x, pts1.at(iii).y, pts2.at(iii).x, pts2.at(iii).y);
02081                 }
02082         }
02083         
02084         double nCONV = asymmetricGaussianValue(twoErr, scorecard[0][0], scorecard[0][2], scorecard[0][1]);
02085         
02086         if (nCONV == 0.00) {
02087                 if (!evaluate) {
02088                         printf("%s << Returning with (0); nCONV = 0.00.\n", __FUNCTION__);
02089                         return 0.00;
02090                 }
02091         }
02092         
02093         projectionToTransformation(P1, C);
02094         
02095         // break it down to get Z component and angle...
02096         cv::Mat R, t;
02097         decomposeTransform(C, R, t);
02098         
02099         // translation score
02100         //double transIdeal = 3.00, transMax = 5.00, transMin = 1.00;
02101         double tScore = (abs(t.at<double>(0,0)) + abs(t.at<double>(1,0))) / abs(t.at<double>(2,0));
02102         
02103         score[3] = tScore;
02104         
02105         double nTRN = asymmetricGaussianValue(tScore, scorecard[3][0], scorecard[3][2], scorecard[3][1]);
02106         
02107         if (nTRN == 0.00) {
02108                 if (!evaluate) {
02109                         return 0.00;
02110                 }
02111         }
02112         
02113         // angle score
02114         //double angleIdeal = 10.0, angleMax = 15.0, angleMin = 5.0;
02115         double dScore = getRotationInDegrees(R);
02116         
02117         score[4] = dScore;
02118         
02119         double nANG = asymmetricGaussianValue(dScore, scorecard[4][0], scorecard[4][2], scorecard[4][1]);
02120         
02121         if (nANG == 0.00) {
02122                 if (!evaluate) {
02123                         printf("%s << Returning with (0); nANG = 0.00.\n", __FUNCTION__);
02124                         return 0.00;
02125                 }
02126         }
02127         
02128         //double homographyScore = 0.00;        // later this will be replaced by a method for determining FOV change / rot angle
02129         
02130         // Followed by checks to set homography score to be less than zero (not enough view change, H-score too low etc)
02131         
02132         
02133         
02134         
02135         
02136         
02137         
02138         //cout << t << endl;
02139         
02140         //printf("%s << Convergence score = %f\n", __FUNCTION__, twoErr);
02141         
02142         unsigned int numTerms = 5;
02143         keyframeScore = pow(nCONV * nGRIC * nIFS * nTRN * nANG, 1.0 / ((double) numTerms));
02144         
02145         //if (debug) {
02146                 printf("%s << [%f]: conv (%1.2f, %1.2f), gric (%1.2f, %1.2f), if (%1.2f, %1.2f), trans (%1.2f, %1.2f), ang (%02.1f, %1.2f)\n", __FUNCTION__, keyframeScore, twoErr, nCONV, gricScore, nGRIC, infrontScore, nIFS, tScore, nTRN, dScore, nANG);
02147         //}
02148         
02149         
02150         P1.copyTo(pose);
02151         
02152         //printf("%s << Exiting.\n", __FUNCTION__);
02153         
02154         return keyframeScore;
02155         
02156 }
02157 
02158 
02159 //double testKeyframePair(vector<featureTrack>& tracks, cameraParameters& camData, int idx1, int idx2, double *score, Mat& pose, bool evaluate, bool debug) {
02160         
02161         //printf("%s << Entered.\n", __FUNCTION__);
02162         
02164                 //printf("%s << Testing frames (%d) & (%d)\n", __FUNCTION__, idx1, idx2);
02166         
02167         //double keyframeScore;
02168         
02169         //for (unsigned int iii = 0; iii < 5; iii++) {
02170                 //score[iii] = -1.0;
02171         //}
02172         
02173         //vector<Point2f> pts1_, pts2_, pts1, pts2;
02174         //getPointsFromTracks(tracks, pts1, pts2, idx1, idx2);
02175         
02176         //printf("%s << A: pts1.size() = %d; pts2.size() = %d\n", __FUNCTION__, pts1.size(), pts2.size());
02177         
02178         //subselectPoints(pts1_, pts1, pts2_, pts2);
02179         
02180         //pts1.insert(pts1.end(), pts1_.begin(), pts1_.end());
02181         //pts2.insert(pts2.end(), pts2_.begin(), pts2_.end());
02182         
02183         //printf("%s << B: pts1.size() = %d; pts2.size() = %d\n", __FUNCTION__, pts1.size(), pts2.size());
02184         
02185         //unsigned int min_pts = std::min(pts1.size(), pts2.size());
02186         
02187         //if (min_pts < 16) {
02188                 //return -1.00;
02189         //}
02190         
02191         //Mat matchesMask_F_matrix, matchesMask_H_matrix;
02192         
02193         //Mat F = findFundamentalMat(Mat(pts1), Mat(pts2), FM_RANSAC, 1.00, 0.99, matchesMask_F_matrix);
02194         //Mat H = findHomography(Mat(pts1), Mat(pts2), FM_RANSAC, 1.00, matchesMask_H_matrix);
02195         
02198         
02201         
02203         
02205         //double fGric, hGric;
02206         //double gricScore = normalizedGRICdifference(pts1, pts2, F, H, matchesMask_F_matrix, matchesMask_H_matrix, fGric, hGric);
02207         //gricScore = fGric / hGric;
02208         //double gricIdeal = 2.0, gricMax = 10.0, gricMin = 1.0;
02209         //double nGRIC = asymmetricGaussianValue(gricScore, gricIdeal, gricMin, gricMax);
02211         
02215         
02216         //if (nGRIC == 0.00) {
02217                 //if (!evaluate) {
02218                         //return 0.00;
02219                 //}
02220         //}
02221 
02222         //Mat E = camData.K.t() * F * camData.K;        
02223         //Mat CX[4], C;
02224         //findFourTransformations(CX, E, camData.K, pts1, pts2);
02225         //int validPts = findBestCandidate(CX, camData.K, pts1, pts2, C);
02226         
02228         //double infrontIdeal = 1.00, infrontMax = 1.00, infrontMin = 0.90;
02229         //double infrontScore = ((double) validPts) / ((double) pts1.size());
02230         //double nIFS = asymmetricGaussianValue(infrontScore, infrontIdeal, infrontMin, infrontMax);
02231         
02232         //if (nIFS == 0) {
02233                 //if (!evaluate) {
02234                         //return 0.00;
02235                 //}
02236         //}
02237         
02238         //Mat absolute_C0, P0, P1;
02239         //absolute_C0 = Mat::eye(4, 4, CV_64FC1);
02240         
02241         //transformationToProjection(absolute_C0, P0);
02242         //transformationToProjection(C, P1);
02244         
02245         //vector<Point3d> cloud;
02246         //vector<Point2f> corresp;
02247         
02248         //if (debug) {
02250                 //printf("%s << Before triangulation: \n", __FUNCTION__);
02251                 //cout << P0 << endl;
02252                 //cout << P1 << endl;
02253                 //*/
02254         //}
02255         
02256         //TriangulatePoints(pts1, pts2, camData.K, camData.K.inv(), P0, P1, cloud, corresp);
02257         
02261         
02262         //if (debug) {
02264                 //printf("%s << Before 2-frame BA: \n", __FUNCTION__);
02265                 //cout << P0 << endl;
02266                 //cout << P1 << endl;
02267                 //*/
02268         //}
02269         
02271         //double convIdeal = 0.30, convMax = 0.80, convMin = 0.10;
02272         //double twoErr = twoViewBundleAdjustment(camData, P0, P1, cloud, pts1, pts2, 10);
02273         
02274         
02275         
02276         //if (debug) {
02278                 //printf("%s << After 2-frame BA: \n", __FUNCTION__);
02279                 //cout << P0 << endl;
02280                 //cout << P1 << endl;
02281                 //*/
02282                 //for (unsigned int iii = 0; iii < 10; iii++) {
02284                 //}
02285         //}
02286         
02287         //double nCONV = asymmetricGaussianValue(twoErr, convIdeal, convMin, convMax);
02288         
02289         //if (nCONV == 0.00) {
02290                 //if (!evaluate) {
02291                         //return 0.00;
02292                 //}
02293         //}
02294         
02295         //projectionToTransformation(P1, C);
02296         
02298         //Mat R, t;
02299         //decomposeTransform(C, R, t);
02300         
02302         //double transIdeal = 3.00, transMax = 5.00, transMin = 1.00;
02303         //double tScore = (abs(t.at<double>(0,0)) + abs(t.at<double>(1,0))) / abs(t.at<double>(2,0));
02304         //double nTRN = asymmetricGaussianValue(tScore, transIdeal, transMin, transMax);
02305         
02306         //if (nTRN == 0.00) {
02307                 //if (!evaluate) {
02308                         //return 0.00;
02309                 //}
02310         //}
02311         
02313         //double angleIdeal = 10.0, angleMax = 15.0, angleMin = 5.0;
02314         //double dScore = getRotationInDegrees(R);
02315         //double nANG = asymmetricGaussianValue(dScore, angleIdeal, angleMin, angleMax);
02316         
02317         //if (nANG == 0.00) {
02318                 //if (!evaluate) {
02319                         //return 0.00;
02320                 //}
02321         //}
02322         
02324         
02326         
02327         //score[0] = twoErr;
02328         //score[1] = gricScore;
02329         //score[2] = infrontScore;
02330         //score[3] = tScore;
02331         //score[4] = dScore;
02332         
02334         
02336         
02337         //unsigned int numTerms = 5;
02338         //keyframeScore = pow(nCONV * nGRIC * nIFS * nTRN * nANG, 1.0 / ((double) numTerms));
02339         
02341                 //printf("%s << [%f]: conv (%1.2f, %1.2f), gric (%1.2f, %1.2f), if (%1.2f, %1.2f), trans (%1.2f, %1.2f), ang (%02.1f, %1.2f)\n", __FUNCTION__, keyframeScore, twoErr, nCONV, gricScore, nGRIC, infrontScore, nIFS, tScore, nTRN, dScore, nANG);
02343         
02344         
02345         //P1.copyTo(pose);
02346         
02347         //printf("%s << Exiting.\n", __FUNCTION__);
02348         
02349         //return keyframeScore;
02350         
02351 //}
02352 
02353 
02354 double optimizeSystem(SysSBA &sba, double err, int iterations, bool debug, int mode) {
02355         
02356         if (0) { printf("%s << ENTERED.\n", __FUNCTION__); }
02357         
02358         double error = -1.0, prevError = 9e99;
02359         
02360         unsigned int groupsize = min(50, iterations/10);
02361         
02362         if (debug) {
02363                 sba.verbose = 1;
02364         } else {
02365                 sba.verbose = 0;
02366         }
02367         
02368         // Filtering...?
02369         //sba.reduceTracks();
02370         //sba.reduceLongTracks();
02371         //sba.remExcessTracks();
02372         //sba.removeBad();
02373         
02374         
02375         //printf("%s << Bad points [pre] = (%d)\n", __FUNCTION__, sba.numBadPoints());
02376         
02377         
02378         
02379         
02380         //printf("%s << DEBUG (%d)\n", __FUNCTION__, 0);
02381         
02382         for (unsigned int iii = 0; iii < iterations/groupsize; iii++) {
02383                 
02384                 //printf("%s << DEBUG (%d)(%d) : (%d, %d)\n", __FUNCTION__, iii, 0, sba.nodes.size(), sba.tracks.size());
02385                 
02386                 if (debug) { printf("%s << About to attempt SBA (%d) / (%d)\n", __FUNCTION__, ((int)iii), iterations/groupsize); }
02387                 
02388                 int actualIts = sba.doSBA(groupsize, err, mode);
02389                 
02390                 if (actualIts == 0) {
02391                         if (debug) { printf("%s << SBA did not iterate... (%f)\n", __FUNCTION__, sba.calcAvgError()); }
02392                         break;
02393                         //return 9e99;
02394                 }
02395                 if (debug) { printf("%s << SBA completed with (%d) iterations.\n", __FUNCTION__, actualIts); }
02396                 
02397                 //printf("%s << DEBUG (%d)(%d)\n", __FUNCTION__, iii, 1);
02398                 
02399                 error = sba.calcAvgError();
02400                 if (debug) { printf("%s << current error = (%f)\n", __FUNCTION__, error); }
02401                 
02402                 //printf("%s << DEBUG (%d)(%d)\n", __FUNCTION__, iii, 2);
02403                 
02404                 if (error >= prevError) {
02405                         break; // return error;
02406                 } else {
02407                         prevError = error;
02408                 }
02409                 
02410                 //printf("%s << DEBUG (%d)(%d)\n", __FUNCTION__, iii, 3);
02411                 //printf("%s << error(%d) = %f\n", __FUNCTION__, iii, error);
02412         }
02413         
02414         //printf("%s << DEBUG (%d)\n", __FUNCTION__, 1);
02415         
02416         //int iterationsPerformed = sba.doSBA(iterations, err, SBA_SPARSE_CHOLESKY);
02417         //printf("%s << its performed = %d\n", __FUNCTION__, iterationsPerformed);
02418 
02419         if (debug) { printf("%s << Bad points [post] = (%d)\n", __FUNCTION__, sba.numBadPoints()); }
02420 
02421         // sba.doSBA(iterations, err, SBA_SPARSE_CHOLESKY);
02422         //constrainDodgyPoints(sba);
02423         
02424         //printf("%s << Bad points [final] = (%d)\n", __FUNCTION__, sba.numBadPoints());
02425         
02426         if (debug) { printf("%s << EXITING.\n", __FUNCTION__); }
02427         
02428         return error;
02429 }
02430 
02431 double twoViewBundleAdjustment(cameraParameters cam_data, cv::Mat& cam1, cv::Mat& cam2, vector<cv::Point3d>& cloud, vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, int iterations) {     
02432         
02433         SysSBA sys;
02434         
02435         sys.verbose = 0;
02436         
02437         addFixedCamera(sys, cam_data, cam1);
02438         addNewCamera(sys, cam_data, cam2);
02439         
02440         addPointsToSBA(sys, cloud);
02441         
02442         addProjectionsToSBA(sys, pts1, 0);
02443         addProjectionsToSBA(sys, pts2, 1);
02444         
02445         // printf("%s << nodes = %d; tracks = %d\n", __FUNCTION__, sys.nodes.size(), sys.tracks.size());
02446         
02447         double avgError = optimizeSystem(sys, 1e-4, iterations);
02448         
02449         retrieveCameraPose(sys, 1, cam2);
02450         cloud.clear();
02451         retrieveAllPoints(cloud, sys);
02452         
02453         return avgError;
02454         
02455 }
02456 
02457 void addPointsToSBA(SysSBA& sba, vector<cv::Point3d>& cloud) {
02458         
02459         //Vector2d proj;
02460         
02461         for (unsigned int iii = 0; iii < cloud.size(); iii++) {
02462                 
02463                 Vector4d temppoint(cloud.at(iii).x, cloud.at(iii).y, cloud.at(iii).z, 1.0);
02464                 
02465                 sba.addPoint(temppoint);
02466                 
02467                 /*
02468                 proj.x() = loc1.at(iii).x;
02469                 proj.y() = loc1.at(iii).y;
02470                 
02471                 sba.addMonoProj(idx0, iii, proj);
02472                 
02473                 proj.x() = loc2.at(iii).x;
02474                 proj.y() = loc2.at(iii).y;
02475                 
02476                 sba.addMonoProj(idx1, iii, proj);
02477                 * */
02478         }       
02479 }
02480 
02481 void addProjectionToSBA(SysSBA& sba, cv::Point2f& loc, unsigned int trackNo, unsigned int camNo) {
02482         
02483         Vector2d proj;
02484         proj.x() = loc.x;
02485         proj.y() = loc.y;
02486         sba.addMonoProj(camNo, trackNo, proj);
02487 }
02488 
02489 void addProjectionsToSBA(SysSBA& sba, vector<cv::Point2f>& loc, int idx) {
02490         
02491         Vector2d proj;
02492         
02493         // printf("%s << ENTERED.\n", __FUNCTION__);
02494         
02495         for (unsigned int iii = 0; iii < loc.size(); iii++) {
02496                 
02497                 if (iii >= sba.tracks.size()) {
02498                         printf("%s << WARNING! provided locations exceed number of tracks in system...\n", __FUNCTION__);
02499                         break;
02500                 }
02501                 
02502                 //printf("%s << it(%d)\n", __FUNCTION__, iii);
02503                 proj.x() = loc.at(iii).x;
02504                 proj.y() = loc.at(iii).y;
02505                 
02506                 //printf("%s << Adding projection... (%d / %d) : (%d / %d)\n", __FUNCTION__, iii, sba.tracks.size(), idx, sba.nodes.size());
02507                 sba.addMonoProj(idx, iii, proj);
02508                 
02509                 //printf("%s << Projection added. (%d)\n", __FUNCTION__, iii);
02510         }
02511         
02512         printf("%s << EXITING.\n", __FUNCTION__);
02513 }
02514 
02515 void extractPointCloud(const SysSBA &sba, pcl::PointCloud<pcl::PointXYZ>& point_cloud) {
02516         
02517         for (unsigned int kkk = 0; kkk < sba.tracks.size(); kkk++) {
02518                         
02519                         Vector4d pt = sba.tracks[kkk].point;
02520                         
02521                         pcl::PointXYZ pclPt(pt(2), -pt(0), -pt(1));                             
02522                         point_cloud.points.push_back(pclPt);
02523                         //printf("%s << cloud_pt(%d) = (%f, %f, %f)\n", __FUNCTION__, kkk, pointCloud.at(kkk).x, pointCloud.at(kkk).y, pointCloud.at(kkk).z);
02524                 }
02525 }
02526 
02527 void extractCameras(const SysSBA &sba, visualization_msgs::MarkerArray& cameraArray, visualization_msgs::Marker& marker_path) {
02528         
02529         uint32_t shape = visualization_msgs::Marker::ARROW;
02530         
02531         cameraArray.markers.clear();
02532         
02533         visualization_msgs::Marker marker;
02534         marker.header.frame_id = "/pgraph";
02535         marker.ns = "cameras";
02536         marker.type = shape;
02537         marker.action = visualization_msgs::Marker::ADD;
02538         marker.scale.x = 0.5;
02539         marker.scale.y = 0.5;
02540         marker.scale.z = 0.5;
02541         
02542         // And adjust path...
02543         
02544         marker_path.points.clear();
02545         
02546         marker_path.header.frame_id = "/pgraph";
02547         marker_path.header.stamp = ros::Time();
02548         marker_path.ns = "camera_path";
02549         marker_path.id = 0;
02550         marker_path.type = visualization_msgs::Marker::LINE_STRIP;
02551         marker_path.action = visualization_msgs::Marker::ADD;
02552         
02553         marker_path.pose.position.x = 0.0;
02554         marker_path.pose.position.y = 0.0;
02555         marker_path.pose.position.z = 0.0;
02556         
02557         marker_path.pose.orientation.x = 0.0;
02558         marker_path.pose.orientation.y = 0.0;
02559         marker_path.pose.orientation.z = 0.0;
02560         marker_path.pose.orientation.w = 1.0;
02561         
02562         marker_path.scale.x = 0.02;
02563         
02564         marker_path.color.a = 1.0;
02565         marker_path.color.r = 0.0;
02566         marker_path.color.g = 0.0;
02567         marker_path.color.b = 1.0;
02568         
02569         marker_path.lifetime = ros::Duration();
02570         
02571         geometry_msgs::Point p;
02572         
02573         for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
02574                 
02575                 printf("%s << Adding node #%d\n", __FUNCTION__, iii);
02576                 marker.header.stamp = ros::Time();
02577                 marker.id = iii;
02578                 
02579                 
02580                 
02581                 marker.pose.position.x = sba.nodes.at(iii).trans.x();
02582                 marker.pose.position.y = sba.nodes.at(iii).trans.y();
02583                 marker.pose.position.z = sba.nodes.at(iii).trans.z();
02584                 
02585                 p.x = sba.nodes.at(iii).trans.x();
02586                 p.y = sba.nodes.at(iii).trans.y();
02587                 p.z = sba.nodes.at(iii).trans.z();
02588                 
02589                 printf("%s << New co-ordinates = [%f, %f, %f]\n", __FUNCTION__, p.x, p.y, p.z);
02590                 
02591                 marker.pose.orientation.x = sba.nodes.at(iii).qrot.x();
02592                 marker.pose.orientation.y = sba.nodes.at(iii).qrot.y();
02593                 marker.pose.orientation.z = sba.nodes.at(iii).qrot.z();
02594                 marker.pose.orientation.w = 1.0;
02595                 
02596                 printf("%s << New rotations are = [%f, %f, %f]\n", __FUNCTION__, marker.pose.orientation.x, marker.pose.orientation.y, marker.pose.orientation.z);
02597                 
02598                 marker_path.points.push_back(p);
02599                 
02600                 cameraArray.markers.push_back( marker );
02601         }
02602 
02603 }
02604 
02605 void initializeFrameCamera(frame_common::CamParams& cam_params, const cv::Mat& newCamMat, int& maxx, int& maxy, const cv::Size& cameraSize) {
02606     
02607     cam_params.fx = newCamMat.at<double>(0,0); // Focal length in x
02608     cam_params.fy = newCamMat.at<double>(1,1); // Focal length in y
02609     cam_params.cx = newCamMat.at<double>(0,2); // X position of principal point
02610     cam_params.cy = newCamMat.at<double>(1,2); // Y position of principal point
02611     cam_params.tx = 0;   // Baseline (no baseline since this is monocular)
02612 
02613     // Define dimensions of the image.
02614     maxx = cameraSize.width;
02615     maxy = cameraSize.height;
02616 }
02617 
02618 void drawKeyframes(const ros::Publisher &camera_pub, const geometry_msgs::PoseStamped *keyframePoses, unsigned int keyframeCount) {
02619 
02620         visualization_msgs::Marker camera_marker;
02621         camera_marker.header.frame_id = "/world";
02622         camera_marker.header.stamp = ros::Time::now();
02623         camera_marker.ns = "world";
02624         camera_marker.id = 0;
02625         camera_marker.action = visualization_msgs::Marker::ADD;
02626         camera_marker.pose.position.x = 0;
02627         camera_marker.pose.position.y = 0;
02628         camera_marker.pose.position.z = 0;
02629         camera_marker.pose.orientation.x = 0.0;
02630         camera_marker.pose.orientation.y = 0.0;
02631         camera_marker.pose.orientation.z = 0.0;
02632         camera_marker.pose.orientation.w = 1.0;
02633         camera_marker.scale.x = 0.02;
02634         camera_marker.scale.y = 0.02;
02635         camera_marker.scale.z = 0.02;
02636         camera_marker.color.r = 1.0f;
02637         camera_marker.color.g = 0.0f;
02638         camera_marker.color.b = 0.0f;
02639         camera_marker.color.a = 1.0f;
02640         camera_marker.lifetime = ros::Duration();
02641         camera_marker.type = visualization_msgs::Marker::LINE_LIST;
02642         
02643         int num_cameras = keyframeCount;
02644         
02645         camera_marker.points.resize(num_cameras*6);
02646         camera_marker.colors.resize(num_cameras*6);
02647 
02648         double y_length = 0.02, x_length = 0.05, z_length = 0.10;
02649 
02650 
02651         //double maxCam = 0.00, maxCam2 = 0.00;
02652         //double maxOpt = 0.00, maxOpt2 = 0.00;
02653 
02654 
02655 
02656         for (int i=0, ii=0; i < num_cameras; i++)
02657          {
02658                  
02659                  float rv = ((float) (((float) i) / ((float) num_cameras)) * 1.0f);
02660                  float bv = ((float) (((float) (num_cameras - i)) / ((float) num_cameras)) * 1.0f);
02661                  
02662            //const Node &nd = sba.nodes[i];
02663            //Node nd(sba.nodes[i]);
02664            
02665            //q1 = Quaterniond(keyframePoses[cameraIndex1].pose.orientation.w, keyframePoses[cameraIndex1].pose.orientation.x, keyframePoses[cameraIndex1].pose.orientation.y, keyframePoses[cameraIndex1].pose.orientation.z);
02666           //v1 = Eigen::Vector4d(keyframePoses[cameraIndex1].pose.position.x, keyframePoses[cameraIndex1].pose.position.y, keyframePoses[cameraIndex1].pose.position.z, 1.0);
02667                         
02668            Matrix<double,3,4> tr;
02669            Vector3d  opt;
02670            
02671            //printf("%s << keyframePoses[(%d)].pose.orientation = (%f, %f, %f, %f)\n", __FUNCTION__, i, keyframePoses[i].pose.orientation.w, keyframePoses[i].pose.orientation.x, keyframePoses[i].pose.orientation.y, keyframePoses[i].pose.orientation.z);
02672            
02673            Eigen::Quaterniond q(keyframePoses[i].pose.orientation.w, keyframePoses[i].pose.orientation.x, keyframePoses[i].pose.orientation.y, keyframePoses[i].pose.orientation.z);
02674            Matrix<double,4,1> t;
02675            
02676            t(0,0) = keyframePoses[i].pose.position.x;
02677            t(1,0) = keyframePoses[i].pose.position.y;
02678            t(2,0) = keyframePoses[i].pose.position.z;
02679            t(3,0) = 1.0;
02680            
02681            transformF2W(tr,t,q);
02682            
02683            camera_marker.colors[ii].r = rv;
02684            camera_marker.colors[ii].b = bv;
02685 
02686            camera_marker.points[ii].x = keyframePoses[i].pose.position.x;
02687            camera_marker.points[ii].y = keyframePoses[i].pose.position.y;
02688            camera_marker.points[ii++].z = keyframePoses[i].pose.position.z;
02689 
02690                 camera_marker.colors[ii].r = rv;
02691            camera_marker.colors[ii].b = bv;
02692            
02693            opt = tr*Vector4d(0,0,z_length,1);
02694            
02695            camera_marker.points[ii].x = opt.x();
02696            camera_marker.points[ii].y = opt.y();
02697            camera_marker.points[ii++].z = opt.z();
02698 
02699                 camera_marker.colors[ii].r = rv;
02700            camera_marker.colors[ii].b = bv;
02701            
02702            camera_marker.points[ii].x = keyframePoses[i].pose.position.x;
02703            camera_marker.points[ii].y = keyframePoses[i].pose.position.y;
02704            camera_marker.points[ii++].z = keyframePoses[i].pose.position.z;
02705            
02706                 camera_marker.colors[ii].r = rv;
02707            camera_marker.colors[ii].b = bv;
02708            
02709            opt = tr*Vector4d(x_length,0,0,1);
02710            
02711            camera_marker.points[ii].x = opt.x();
02712            camera_marker.points[ii].y = opt.y();
02713            camera_marker.points[ii++].z = opt.z();
02714            
02715            
02716                  camera_marker.colors[ii].r = rv;
02717            camera_marker.colors[ii].b = bv;
02718 
02719 
02720            camera_marker.points[ii].x = keyframePoses[i].pose.position.x;
02721            camera_marker.points[ii].y = keyframePoses[i].pose.position.y;
02722            camera_marker.points[ii++].z = keyframePoses[i].pose.position.z;
02723            
02724            camera_marker.colors[ii].r = rv;
02725            camera_marker.colors[ii].b = bv;
02726            
02727            opt = tr*Vector4d(0,y_length,0,1);
02728            
02729            
02730            
02731            camera_marker.points[ii].x = opt.x();
02732            camera_marker.points[ii].y = opt.y();
02733            camera_marker.points[ii++].z = opt.z();
02734 
02735          }
02736          
02737          //printf("%s << Publishing keyframe markers (%d, %d)\n", __FUNCTION__, camera_marker.points.size(), camera_marker.colors.size());
02738          camera_pub.publish(camera_marker);
02739 }
02740 
02741 void drawGraph2(const SysSBA &sba, const ros::Publisher &camera_pub,
02742                 const ros::Publisher &point_pub, const ros::Publisher &path_pub, int decimation, int bicolor, double scale)
02743  {
02744    int num_points = sba.tracks.size();
02745    int num_cameras = sba.nodes.size();
02746    if (num_points == 0 && num_cameras == 0) return;
02747    
02748    visualization_msgs::Marker camera_marker, point_marker, path_marker;
02749    camera_marker.header.frame_id = "/pgraph";
02750    camera_marker.header.stamp = ros::Time::now();
02751    camera_marker.ns = "pgraph";
02752    camera_marker.id = 0;
02753    camera_marker.action = visualization_msgs::Marker::ADD;
02754    camera_marker.pose.position.x = 0;
02755    camera_marker.pose.position.y = 0;
02756    camera_marker.pose.position.z = 0;
02757    camera_marker.pose.orientation.x = 0.0;
02758    camera_marker.pose.orientation.y = 0.0;
02759    camera_marker.pose.orientation.z = 0.0;
02760    camera_marker.pose.orientation.w = 1.0;
02761    camera_marker.scale.x = 0.02;
02762    camera_marker.scale.y = 0.02;
02763    camera_marker.scale.z = 0.02;
02764    camera_marker.color.r = 1.0f;
02765    camera_marker.color.g = 0.0f;
02766    camera_marker.color.b = 0.0f;
02767    camera_marker.color.a = 1.0f;
02768    camera_marker.lifetime = ros::Duration();
02769    camera_marker.type = visualization_msgs::Marker::LINE_LIST;
02770  
02771    point_marker = camera_marker;
02772    point_marker.color.r = 0.5f;
02773    point_marker.color.g = 0.5f;
02774    point_marker.color.b = 1.0f;
02775    point_marker.color.a = 1.0f; // 0.5f
02776    point_marker.scale.x = scale;
02777    point_marker.scale.y = scale;
02778    point_marker.scale.z = scale;
02779    point_marker.type = visualization_msgs::Marker::POINTS;
02780    
02781    path_marker = point_marker;
02782    path_marker.color.r = 0.0f;
02783    path_marker.color.g = 0.5f;
02784    path_marker.color.b = 0.0f;
02785    path_marker.color.a = 1.0f;
02786    path_marker.scale.x = 0.03;
02787    path_marker.type = visualization_msgs::Marker::LINE_STRIP;
02788    
02789    
02790    double maxPt = 0.00, maxPt2 = 0.00;
02791         
02792    // draw points, decimated
02793    point_marker.points.resize((int)(num_points/(double)decimation + 0.5));
02794    point_marker.colors.resize((int)(num_points/(double)decimation + 0.5));
02795    for (int i=0, ii=0; i < num_points; i += decimation, ii++)
02796      {
02797        //const Vector4d &pt = sba.tracks[i].point;
02798        Vector4d pt(sba.tracks[i].point);
02799        //point_marker.colors[ii].r = 1.0f;
02800        //if (bicolor > 0 && i >= bicolor)
02801          //point_marker.colors[ii].g = 1.0f;
02802        //else
02803          //point_marker.colors[ii].g = 0.0f;
02804        //point_marker.colors[ii].b = 0.0f;
02805 
02806                 maxPt = max(maxPt, abs(pt(2)));
02807                 maxPt = max(maxPt, abs(pt(1)));
02808                 maxPt = max(maxPt, abs(pt(0)));
02809        
02810        if (abs(pt(2)) > MAX_RVIZ_DISPLACEMENT) {
02811                    pt(2) = 0.0;
02812            }
02813            
02814            if (abs(pt(0)) > MAX_RVIZ_DISPLACEMENT) {
02815                    pt(0) = 0.0;
02816            }
02817            
02818            if (abs(pt(1)) > MAX_RVIZ_DISPLACEMENT) {
02819                    pt(1) = 0.0;
02820            }
02821            
02822            maxPt2 = max(maxPt2, abs(pt(2)));
02823                 maxPt2 = max(maxPt2, abs(pt(1)));
02824                 maxPt2 = max(maxPt2, abs(pt(0)));
02825            
02826        point_marker.points[ii].x = pt(2);
02827        point_marker.points[ii].y = -pt(0);
02828        point_marker.points[ii].z = -pt(1);
02829        
02830        point_marker.colors[ii].r = 0.0;
02831        point_marker.colors[ii].g = 0.0;
02832        point_marker.colors[ii].b = 0.0;
02833        point_marker.colors[ii].a = 1.0;
02834        
02835      }
02836      
02837    //hajmig
02838    //printf("%s << maxPt = (%f, %f)\n", __FUNCTION__, maxPt, maxPt2);
02839  
02840    // draw cameras
02841    camera_marker.points.resize(num_cameras*6);
02842    camera_marker.colors.resize(num_cameras*6);
02843    
02844    double y_length = 0.00, x_length = 0.00, z_length = 0.30;
02845    
02846    
02847   double maxCam = 0.00, maxCam2 = 0.00;
02848   double maxOpt = 0.00, maxOpt2 = 0.00;
02849 
02850    
02851    
02852    for (int i=0, ii=0; i < num_cameras; i++)
02853      {
02854                  
02855                  float rv = ((float) (((float) i) / ((float) num_cameras)) * 1.0f);
02856                  float bv = ((float) (((float) (num_cameras - i)) / ((float) num_cameras)) * 1.0f);
02857                  
02858        //const Node &nd = sba.nodes[i];
02859        Node nd(sba.nodes[i]);
02860        Vector3d  opt;
02861        Matrix<double,3,4> tr;
02862        transformF2W(tr,nd.trans,nd.qrot);
02863        
02864        maxCam = max(maxCam, abs(nd.trans.z()));
02865        maxCam = max(maxCam, abs(nd.trans.x()));
02866        maxCam = max(maxCam, abs(nd.trans.y()));
02867        
02868        if (abs(nd.trans.z()) > MAX_RVIZ_DISPLACEMENT) {
02869                    nd.trans.z() = 0.0;
02870            }
02871            
02872            if (abs(nd.trans.x()) > MAX_RVIZ_DISPLACEMENT) {
02873                    nd.trans.x() = 0.0;
02874            }
02875            
02876            if (abs(nd.trans.y()) > MAX_RVIZ_DISPLACEMENT) {
02877                    nd.trans.y() = 0.0;
02878            }
02879            
02880            maxCam2 = max(maxCam2, abs(nd.trans.z()));
02881        maxCam2 = max(maxCam2, abs(nd.trans.x()));
02882        maxCam2 = max(maxCam2, abs(nd.trans.y()));
02883        
02884        camera_marker.colors[ii].r = rv;
02885        camera_marker.colors[ii].b = bv;
02886  
02887        camera_marker.points[ii].x = nd.trans.z();
02888        camera_marker.points[ii].y = -nd.trans.x();
02889        camera_marker.points[ii++].z = -nd.trans.y();
02890        
02891         camera_marker.colors[ii].r = rv;
02892        camera_marker.colors[ii].b = bv;
02893        
02894        opt = tr*Vector4d(0,0,z_length,1);
02895        
02896        maxOpt = max(maxOpt, abs(opt.z()));
02897        maxOpt = max(maxOpt, abs(opt.x()));
02898        maxOpt = max(maxOpt, abs(opt.y()));
02899        
02900        if (abs(opt.z()) > MAX_RVIZ_DISPLACEMENT) {
02901                    opt.z() = 0.0;
02902            }
02903            
02904            if (abs(opt.x()) > MAX_RVIZ_DISPLACEMENT) {
02905                    opt.x() = 0.0;
02906            }
02907            
02908            if (abs(opt.y()) > MAX_RVIZ_DISPLACEMENT) {
02909                    opt.y() = 0.0;
02910            }
02911        
02912                 maxOpt2 = max(maxOpt2, abs(opt.z()));
02913        maxOpt2 = max(maxOpt2, abs(opt.x()));
02914        maxOpt2 = max(maxOpt2, abs(opt.y()));
02915        
02916        
02917        camera_marker.points[ii].x = opt.z();
02918        camera_marker.points[ii].y = -opt.x();
02919        camera_marker.points[ii++].z = -opt.y();
02920  
02921         camera_marker.colors[ii].r = rv;
02922        camera_marker.colors[ii].b = bv;
02923        
02924        camera_marker.points[ii].x = nd.trans.z();
02925        camera_marker.points[ii].y = -nd.trans.x();
02926        camera_marker.points[ii++].z = -nd.trans.y();
02927        
02928         camera_marker.colors[ii].r = rv;
02929        camera_marker.colors[ii].b = bv;
02930        
02931        opt = tr*Vector4d(x_length,0,0,1);
02932        
02933        if (abs(opt.z()) > MAX_RVIZ_DISPLACEMENT) {
02934                    opt.z() = 0.0;
02935            }
02936            
02937            if (abs(opt.x()) > MAX_RVIZ_DISPLACEMENT) {
02938                    opt.x() = 0.0;
02939            }
02940            
02941            if (abs(opt.y()) > MAX_RVIZ_DISPLACEMENT) {
02942                    opt.y() = 0.0;
02943            }
02944            
02945        camera_marker.points[ii].x = opt.z();
02946        camera_marker.points[ii].y = -opt.x();
02947        camera_marker.points[ii++].z = -opt.y();
02948        
02949        
02950          camera_marker.colors[ii].r = rv;
02951        camera_marker.colors[ii].b = bv;
02952  
02953         
02954        camera_marker.points[ii].x = nd.trans.z();
02955        camera_marker.points[ii].y = -nd.trans.x();
02956        camera_marker.points[ii++].z = -nd.trans.y();
02957        
02958        camera_marker.colors[ii].r = rv;
02959        camera_marker.colors[ii].b = bv;
02960        
02961        opt = tr*Vector4d(0,y_length,0,1);
02962        
02963        if (abs(opt.z()) > MAX_RVIZ_DISPLACEMENT) {
02964                    opt.z() = 0.0;
02965            }
02966            
02967            if (abs(opt.x()) > MAX_RVIZ_DISPLACEMENT) {
02968                    opt.x() = 0.0;
02969            }
02970            
02971            if (abs(opt.y()) > MAX_RVIZ_DISPLACEMENT) {
02972                    opt.y() = 0.0;
02973            }
02974            
02975        camera_marker.points[ii].x = opt.z();
02976        camera_marker.points[ii].y = -opt.x();
02977        camera_marker.points[ii++].z = -opt.y();
02978 
02979        
02980      }
02981      
02982     //hajmig
02983     // printf("%s << maxCam = (%f, %f)\n", __FUNCTION__, maxCam, maxCam2);
02984     // printf("%s << maxOpt = (%f, %f)\n", __FUNCTION__, maxOpt, maxOpt2);
02985      
02986      // Draw path
02987      path_marker.points.resize(num_cameras);
02988      path_marker.colors.resize(num_cameras);
02989      
02990      //Matrix<double,3,4> pr;
02991      
02992      for (int ii=0; ii < num_cameras; ii++)
02993      {
02994                  
02995                  float rv = ((float) (((float) ii) / ((float) num_cameras)) * 1.0f);
02996                  float bv = ((float) (((float) (num_cameras - ii)) / ((float) num_cameras)) * 1.0f);
02997 
02998        const Node &nd = sba.nodes[ii];
02999        Vector3d opt;
03000        Matrix<double,3,4> tr;
03001        transformF2W(tr,nd.trans,nd.qrot);
03002  
03003        path_marker.points[ii].x = nd.trans.z();
03004        path_marker.points[ii].y = -nd.trans.x();
03005        path_marker.points[ii].z = -nd.trans.y();
03006        
03007        path_marker.colors[ii].r = rv;
03008        path_marker.colors[ii].b = bv;
03009        
03010      }
03011  
03012    // draw point-plane projections
03013    //int num_tracks = sba.tracks.size();
03014    //int ii = camera_marker.points.size();
03015  
03016  /*
03017    for (int i=0; i < num_tracks; i++)
03018      {
03019        const ProjMap &prjs = sba.tracks[i].projections;
03020        for (ProjMap::const_iterator itr = prjs.begin(); itr != prjs.end(); itr++)
03021          {
03022            const Proj &prj = (*itr).second;
03023            if (prj.pointPlane)   // have a ptp projection
03024              {
03025                camera_marker.points.resize(ii+2);
03026                sba::Point pt0 = sba.tracks[i].point;
03027                Vector3d plane_point = prj.plane_point;
03028                Vector3d plane_normal = prj.plane_normal;
03029                Eigen::Vector3d w = pt0.head<3>()-plane_point;
03030                //              Eigen::Vector3d projpt = plane_point+(w.dot(plane_normal))*plane_normal;
03031                Eigen::Vector3d projpt = pt0.head<3>() - (w.dot(plane_normal))*plane_normal;
03032                //              Vector3d pt1 = pt0.head<3>()+0.1*plane_normal;
03033                Vector3d pt1 = projpt;
03034                    
03035                camera_marker.points[ii].x = pt0.z();
03036                camera_marker.points[ii].y = -pt0.x();
03037                camera_marker.points[ii++].z = -pt0.y();
03038                camera_marker.points[ii].x = pt1.z();
03039                camera_marker.points[ii].y = -pt1.x();
03040                camera_marker.points[ii++].z = -pt1.y();
03041              }
03042          } 
03043      }
03044  */
03045  
03046    path_pub.publish(path_marker);
03047    camera_pub.publish(camera_marker);
03048    point_pub.publish(point_marker);
03049  }
03050 
03051 void finishTracks(vector<featureTrack>& tracks, vector<cv::Point2f>& pts, double retainProp, unsigned int maxOccurrences) {
03052         
03053         if (maxOccurrences == 0) {
03054                 return;
03055         }
03056         
03057         if (tracks.size() == 0) {
03058                 return;
03059         }
03060         
03061         if (pts.size() == 0) {
03062                 return;
03063         }
03064         
03065         vector<unsigned char> invalidFlags;
03066         
03067         for (unsigned int jjj = 0; jjj < tracks.size(); jjj++) {
03068                 
03069                 if (tracks.at(jjj).locations.size() >= maxOccurrences) {
03070                         
03071                         for (unsigned int iii = 0; iii < pts.size(); iii++) {
03072                 
03073                                 cout << pts.at(iii) << endl;
03074                                 cout << tracks.at(jjj).locations.size() << endl;
03075                                 cout << tracks.at(jjj).locations.at(tracks.at(jjj).locations.size()-1).featureCoord.x << endl;
03076                                 
03077                                 if (pts.at(iii) == tracks.at(jjj).locations.at(tracks.at(jjj).locations.size()-1).featureCoord) {
03078                                         printf("%s << Found feature! (%d, %d)\n", __FUNCTION__, iii, jjj);
03079                                         
03080                                         invalidFlags.push_back(iii);
03081                                         
03082                                         
03083                                 }
03084                                 
03085                         }
03086                 }
03087                 
03088         }
03089         
03090         if (invalidFlags.size() == 0) {
03091                 return;
03092         }
03093         
03094         double origSize = ((double) pts.size());
03095         
03096         while (((double) pts.size()) > (retainProp * origSize)) {
03097                 
03098                 unsigned int index = rand() % invalidFlags.size();
03099                 
03100                 pts.erase(pts.begin() + invalidFlags.at(index));
03101                 invalidFlags.erase(invalidFlags.begin() + index);
03102                 
03103         }
03104 
03105         
03106 }


thermalvis
Author(s): Stephen Vidas
autogenerated on Sun Jan 5 2014 11:38:45