reconstruction.cpp
Go to the documentation of this file.
00001 
00005 #include "reconstruction.hpp"
00006 
00007 void summarizeTransformation(const cv::Mat& C, char *summary) {
00008 
00009         cv::Mat P, R, Rv, t;
00010         transformationToProjection(C, P);
00011         decomposeTransform(C, R, t);
00012         Rodrigues(R, Rv);
00013         
00014         double unitsDist, degreesRot;
00015         unitsDist = getDistanceInUnits(t);
00016         degreesRot = getRotationInDegrees(R);
00017         
00018         sprintf(summary, "%f units (%f, %f, %f); %f degrees", unitsDist, t.at<double>(0,0), t.at<double>(1,0), t.at<double>(2,0), degreesRot);
00019         
00020 }
00021 
00022 int findBestCandidate(const cv::Mat *CX, const cv::Mat& K, const vector<cv::Point2f>& pts1, const vector<cv::Point2f>& pts2, cv::Mat& C) {
00023         
00024         int bestScore = 0, bestCandidate = 0;
00025 
00026         for (int kkk = 0; kkk < 4; kkk++) {
00027 
00028                 int validPts = pointsInFront(CX[kkk], K, pts1, pts2);
00029                 
00030                 if (validPts > bestScore) {
00031                         bestScore = validPts;
00032                         bestCandidate = kkk;
00033                 }
00034                 
00035                 //printf("%s << validPts(%d) = %d\n", __FUNCTION__, kkk, validPts);
00036         }
00037         
00038         CX[bestCandidate].copyTo(C);
00039         
00040         return bestScore;
00041 }
00042 
00043 void reverseTranslation(cv::Mat& C) {
00044         
00045         for (unsigned int iii = 0; iii < 3; iii++) {
00046                 C.at<double>(iii,3) = -C.at<double>(iii,3);
00047         }
00048         
00049 }
00050 
00051 
00052 
00053 void findFeaturesForPoints(vector<featureTrack>& tracks, vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, vector<cv::Point3d>& pts3d, int idx1, int idx2) {
00054 
00055         // For each 3d point, find the track that contains it, then find the projections...
00056         for (unsigned int jjj = 0; jjj < pts3d.size(); jjj++) {
00057                 
00058                 //printf("%s << jjj = %d (%f, %f, %f)\n", __FUNCTION__, jjj, pts3d.at(jjj).x, pts3d.at(jjj).y, pts3d.at(jjj).z);
00059                 
00060                 for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00061 
00062                         //printf("%s << iii = %d\n", __FUNCTION__, iii);
00063                         
00064                         // MONKEY!!
00065                         if (tracks.at(iii).get3dLoc() == pts3d.at(jjj)) {
00066                                 
00067                                 //printf("%s << MATCH! (%d, %d)\n", __FUNCTION__, jjj, iii);
00068                                 
00069                                 for (unsigned int kkk = 0; kkk < tracks.at(iii).locations.size(); kkk++) {
00070                                         
00071                                         //printf("%s << kkk = %d (%d, %d)\n", __FUNCTION__, kkk, tracks.at(iii).locations.at(kkk).imageIndex, tracks.at(iii).locations.at(kkk).imageIndex);
00072                         
00073                                         if (((int)tracks.at(iii).locations.at(kkk).imageIndex) == idx1) {
00074                                                 
00075                                                 pts1.push_back(tracks.at(iii).locations.at(kkk).featureCoord);
00076                                                 
00077                                         } else if (((int)tracks.at(iii).locations.at(kkk).imageIndex) == idx2) {
00078                                                 
00079                                                 pts2.push_back(tracks.at(iii).locations.at(kkk).featureCoord);
00080                                                 
00081                                         }
00082                                         
00083                                 }
00084                                 
00085                         }
00086                         
00087                 }
00088                 
00089                 
00090         }
00091         
00092 }
00093 
00094 int countTriangulatedTracks(const vector<featureTrack>& tracks) {
00095         
00096         int triangulatedCount = 0;
00097         
00098         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00099                 
00100                 if (tracks.at(iii).isTriangulated) {
00101                         triangulatedCount++;
00102                 }
00103         }
00104         
00105         return triangulatedCount;
00106         
00107 }
00108 
00109 int countActiveTriangulatedTracks(vector<unsigned int>& indices, vector<featureTrack>& tracks) {
00110         
00111         int triangulatedCount = 0;
00112         
00113         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00114                 
00115                 if (tracks.at(indices.at(iii)).isTriangulated) {
00116                         triangulatedCount++;
00117                 }
00118                 
00119         }
00120         
00121         return triangulatedCount;
00122         
00123 }
00124 
00125 void getIndicesForTriangulation(vector<unsigned int>& dst, vector<unsigned int>& src, vector<unsigned int>& already_triangulated) {
00126         
00127         dst.clear();
00128         
00129         for (unsigned int iii = 0; iii < src.size(); iii++) {
00130                 
00131                 bool triangulated = false;
00132                 
00133                 for (unsigned int jjj = 0; jjj < already_triangulated.size(); jjj++) {
00134                         
00135                         if (already_triangulated.at(jjj) == src.at(iii)) {
00136                                 triangulated = true;
00137                                 continue;
00138                         }
00139 
00140                         
00141                 }
00142                 
00143                 if (!triangulated) {
00144                         
00145                         dst.push_back(src.at(iii));
00146                         
00147                 }
00148 
00149                 
00150         }
00151         
00152 }
00153 
00154 void reconstructSubsequence(vector<featureTrack>& tracks, vector<cv::Point3d>& ptCloud, int idx1, int idx2) {
00155         
00156 }
00157 
00158 void removeShortTracks(vector<featureTrack>& tracks, int idx1, int idx2) {
00159         
00160         int minLength = (idx2 - idx1) / 2;
00161         
00162         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00163                 int trackLength = tracks.at(iii).locations.size();
00164                 if (trackLength < minLength) {
00165                         int final_image = tracks.at(iii).locations.at(trackLength-1).imageIndex;
00166                         
00167                         if ((final_image >= idx1) && (final_image < idx2)) {
00168                                 tracks.erase(tracks.begin() + iii);
00169                                 iii--;
00170                         }
00171                         
00172                 }
00173         }
00174         
00175 }
00176 
00177 void updateSystemTracks(SysSBA& sys, vector<featureTrack>& tracks, unsigned int start_index) {
00178         
00179         //sys = SysSBA();
00180         
00181         sys.tracks.clear();
00182 
00183         
00184         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00185                 
00186                 //printf("%s << Checking track (%d) (size = %d)\n", __FUNCTION__, iii, tracks.at(iii).locations.size());
00187                 
00188                 if (tracks.at(iii).isTriangulated) {
00189 
00190                         
00191                         //printf("%s << Track is triangulated\n", __FUNCTION__);
00192                         
00193                         Vector4d temppoint(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
00194                         sys.addPoint(temppoint);
00195                         
00196                         //printf("%s << Point added; nodes = %d\n", __FUNCTION__, sys.nodes.size());
00197                         //printf("%s << sys.tracks.size() = %d\n", __FUNCTION__, sys.tracks.size());
00198                         
00199                         // sys.tracks.size()-1
00200                         
00201         
00202                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00203                                 
00204                                 // Only want to add projections for active nodes
00205                                 
00206                                 if ((((unsigned int) tracks.at(iii).locations.at(jjj).imageIndex) >= start_index) && (((unsigned int) tracks.at(iii).locations.at(jjj).imageIndex) < (start_index+sys.nodes.size()))) {
00207                                         //printf("%s << Assembling projection (%d)(%d)\n", __FUNCTION__, iii, jjj);
00208                                 
00209                                         Vector2d proj;
00210                                         
00211                                         proj.x() = tracks.at(iii).locations.at(jjj).featureCoord.x;
00212                                         proj.y() = tracks.at(iii).locations.at(jjj).featureCoord.y;
00213                                         
00214                                         //printf("%s << Adding projection (track: %d)(loc: %d) node #: [%d]\n", __FUNCTION__, iii, jjj, tracks.at(iii).locations.at(jjj).imageIndex);
00215                                         
00216                                         //printf("%s << vec size (tracks: %d, nodes for this track: %d)\n", __FUNCTION__, tracks.size(), tracks.at(iii).locations.size());
00217                                         //printf("%s << sys size (tracks: %d, nodes: %d)\n", __FUNCTION__, sys.tracks.size(), sys.nodes.size());
00218                                         
00219                                         // If you only have 30 nodes, then how are you adding a track that has an image index of 53?
00220                                         
00221                                         //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());
00222                                         sys.addMonoProj(tracks.at(iii).locations.at(jjj).imageIndex-start_index, sys.tracks.size()-1, proj);
00223                                         
00224                                         //printf("%s << Added.\n", __FUNCTION__);
00225                                         
00226                                         // 0, 53, proj
00227                                 }
00228                                 
00229                                 
00230                                 
00231                         }
00232                         
00233                         //printf("%s << Projections added\n", __FUNCTION__);
00234                 
00235                 }
00236                 
00237         }
00238         
00239 }
00240 
00241 void updateTriangulatedPoints(vector<featureTrack>& tracks, vector<unsigned int>& indices, vector<cv::Point3d>& cloud) {
00242         
00243         if (cloud.size() != indices.size()) {
00244                 printf("%s << ERROR! Cloud size and index list size don't match (%d vd %d)\n", __FUNCTION__, ((int)cloud.size()), ((int)indices.size()));
00245         }
00246         
00247         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00248                 
00249                 if (tracks.at(indices.at(iii)).isTriangulated) {
00250                         //printf("%s << (%d) is triangulated; moving from (%f, %f, %f) to (%f, %f, %f)\n", __FUNCTION__, iii, tracks.at(indices.at(iii)).get3dLoc().x, tracks.at(indices.at(iii)).get3dLoc().y, tracks.at(indices.at(iii)).get3dLoc().z, cloud.at(iii).x, cloud.at(iii).y, cloud.at(iii).z);
00251                 }
00252                 
00253                 tracks.at(indices.at(iii)).set3dLoc(cloud.at(iii));
00254                 
00255                 
00256                 
00257         }
00258         
00259 }
00260 
00261 void reduceActiveToTriangulated(vector<featureTrack>& tracks, vector<unsigned int>& indices, vector<unsigned int>& untriangulated) {
00262         
00263         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00264                 
00265                 if (!tracks.at(indices.at(iii)).isTriangulated) {
00266                         untriangulated.push_back(indices.at(iii));
00267                         indices.erase(indices.begin() + iii);
00268                         iii--;
00269                 }
00270                 
00271         }
00272         
00273 }
00274 
00275 void filterToActivePoints(vector<featureTrack>& tracks, vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, vector<unsigned int>& indices, int idx1, int idx2) {
00276 
00277         pts1.clear();
00278         pts2.clear();
00279         
00280         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00281                 
00282                 for (unsigned int jjj = 0; jjj < tracks.at(indices.at(iii)).locations.size()-1; jjj++) {
00283                         
00284                         if (((int)tracks.at(indices.at(iii)).locations.at(jjj).imageIndex) == idx1) {
00285                                 
00286                                 pts1.push_back(tracks.at(indices.at(iii)).locations.at(jjj).featureCoord);
00287                                 
00288                                 for (unsigned int kkk = jjj+1; kkk < tracks.at(indices.at(iii)).locations.size(); kkk++) {
00289                                         
00290                                         if (((int)tracks.at(indices.at(iii)).locations.at(kkk).imageIndex) == idx2) {
00291                                                 
00292                                                 pts2.push_back(tracks.at(indices.at(iii)).locations.at(kkk).featureCoord);
00293                                                 
00294                                                 continue;
00295                                         }
00296                                         
00297                                 }
00298                                 
00299                                 continue;
00300                                 
00301                         }
00302                         
00303                 }
00304 
00305         }
00306         
00307         
00308 }
00309 
00310 void getActive3dPoints(vector<featureTrack>& tracks, vector<unsigned int>& indices, vector<cv::Point3d>& cloud) {
00311         
00312         cloud.clear();
00313         
00314         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00315                 cloud.push_back(tracks.at(indices.at(iii)).get3dLoc());
00316         }
00317         
00318 }
00319 
00320 void filterToCompleteTracks(vector<unsigned int>& dst, vector<unsigned int>& src, vector<featureTrack>& tracks, int idx1, int idx2) {
00321         
00322         dst.clear();
00323         
00324         for (unsigned int iii = 0; iii < src.size(); iii++) {
00325                 
00326                 if (tracks.at(src.at(iii)).locations.size() >= (idx2 - idx1)) {
00327                         
00328                         for (unsigned int jjj = 0; jjj < tracks.at(src.at(iii)).locations.size()-(idx2-idx1); jjj++) {
00329                                 
00330                                 //printf("%s << DEBUG [%d][%d]\n", __FUNCTION__, iii, jjj);
00331                         
00332                                 if (((int)tracks.at(src.at(iii)).locations.at(jjj).imageIndex) == idx1) {
00333                                         
00334                                         //printf("%s << DEBUG [%d][%d] X\n", __FUNCTION__, iii, jjj);
00335                                         
00336                                         for (unsigned int kkk = jjj+1; kkk < tracks.at(src.at(iii)).locations.size(); kkk++) {
00337                                                 
00338                                                 //printf("%s << DEBUG [%d][%d][%d]\n", __FUNCTION__, iii, jjj, kkk);
00339                                                 
00340                                                 if (((int)tracks.at(src.at(iii)).locations.at(kkk).imageIndex) == idx2) {
00341                                                         
00342                                                         //printf("%s << DEBUG [%d][%d][%d] X\n", __FUNCTION__, iii, jjj, kkk);
00343                                                         
00344                                                         dst.push_back(src.at(iii));
00345                                                         
00346                                                 }
00347                                                 
00348                                         }
00349                                         
00350                                 }
00351                                 
00352                                 
00353                         }
00354                         
00355                 }
00356                 
00357         }
00358         
00359 }
00360 
00361 void getActiveTracks(vector<unsigned int>& indices, vector<featureTrack>& tracks, int idx1, int idx2) {
00362         
00363         //printf("%s << Entered.\n", __FUNCTION__);
00364         
00365         // Should only consider a track active if it contains at least two projections in the subsequence
00366         
00367         indices.clear();
00368         
00369         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00370                 
00371                 //printf("%s << DEBUG [%d]\n", __FUNCTION__, iii);
00372                 
00373                 if (tracks.at(iii).locations.size() < 2) {
00374                         continue;
00375                 }
00376                 
00377                 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size()-1; jjj++) {
00378                         
00379                         //printf("%s << DEBUG [%d][%d]\n", __FUNCTION__, iii, jjj);
00380                 
00381                         if ((((int)tracks.at(iii).locations.at(jjj).imageIndex) >= idx1) && (((int)tracks.at(iii).locations.at(jjj).imageIndex) <= idx2)) {
00382                                 
00383                                 for (unsigned int kkk = jjj+1; kkk < tracks.at(iii).locations.size(); kkk++) {
00384                                         
00385                                         if ((((int)tracks.at(iii).locations.at(kkk).imageIndex) >= idx1) && (((int)tracks.at(iii).locations.at(kkk).imageIndex) <= idx2)) {
00386                                                 indices.push_back(iii);
00387                                                 break;
00388                                         }
00389                                         
00390                                 }
00391                                 
00392                                 break;
00393                         }
00394                         
00395                         
00396                 }
00397                 
00398                 
00399                 
00400                 
00401                 
00402         }
00403         
00404         //printf("%s << Exiting.\n", __FUNCTION__);
00405         
00406 }
00407 
00408 bool estimatePoseFromKnownPoints(cv::Mat& dst, cameraParameters camData, vector<featureTrack>& tracks, unsigned int index, const cv::Mat& guide, unsigned int minAppearances, unsigned int iterCount, double maxReprojErr, double inliersPercentage, double *reprojError, double *pnpInlierProp, bool debug) {
00409         
00410         vector<cv::Point3f> points_3d;
00411         vector<cv::Point2f> points_2d;
00412         
00413         unsigned int triangulatedCount = 0;
00414         *reprojError = 0.0;
00415         *pnpInlierProp = 0.0;
00416         
00417         if (debug) { printf("%s << minAppearances = (%d)\n", __FUNCTION__, minAppearances); }
00418         
00419         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00420                 
00421                 //printf("%s << DEBUG [%d]\n", __FUNCTION__, iii);
00422                 
00423                 if (!tracks.at(iii).isTriangulated) {
00424                         continue;
00425                 }
00426                 
00427                 triangulatedCount++;
00428                 
00429                 if (tracks.at(iii).locations.size() < minAppearances) {
00430                         printf("%s << Error! size() = (%d) < (%d)\n", __FUNCTION__, tracks.at(iii).locations.size(), minAppearances);
00431                         continue;
00432                 }
00433                 
00434                 bool pointAdded = false;
00435                 
00436                 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00437                         
00438                         //printf("%s << DEBUG [%d][%d]\n", __FUNCTION__, iii, jjj);
00439                 
00440                         if (tracks.at(iii).locations.at(jjj).imageIndex == index) {
00441                                 
00442                                 points_2d.push_back(tracks.at(iii).locations.at(jjj).featureCoord);
00443                                 cv::Point3f tmp_pt = cv::Point3f(((float) tracks.at(iii).get3dLoc().x), ((float) tracks.at(iii).get3dLoc().y), ((float) tracks.at(iii).get3dLoc().z));
00444                                 points_3d.push_back(tmp_pt);
00445                                 pointAdded = true;
00446                                 break;
00447                         }
00448                 }
00449                 
00450                 /*
00451                 if (!pointAdded) {
00452                         printf("%s << Error! Pt (%d) was not found in current view (%d)\n", __FUNCTION__, iii, index);
00453                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00454                                 printf("%s << Index (%d)...\n", __FUNCTION__, tracks.at(iii).locations.at(jjj).imageIndex);
00455                         }
00456                         
00457                 }
00458                 */
00459                 
00460         }
00461         
00462         unsigned int utilizedPointsCount = points_3d.size();
00463         
00464         cv::Mat Rvec, R, t;
00465         bool guided = false;
00466         
00467         cv::Mat guide_copy;
00468         
00469         guide_copy = guide.inv();
00470         
00471         if (guide_copy.rows > 0) {
00472                 decomposeTransform(guide_copy, R, t);
00473                 Rodrigues(R, Rvec);
00474                 guided = true;
00475         }
00476         
00477         //cv::Mat inlierPts;
00478         vector<int> inlierPts;
00479         
00480         if (points_2d.size() < 8) {
00481                 if (debug) { printf("%s << PnP Failed: Insufficient pts: (%d) < (%d) : [%d, %d, %d]\n", __FUNCTION__, ((int)points_2d.size()), 8, utilizedPointsCount, triangulatedCount, ((int)tracks.size())); }
00482                 guide.copyTo(dst);
00483                 return false;
00484         }
00485         
00486         solvePnPRansac(points_3d, points_2d, camData.K, camData.blankCoeffs, Rvec, t, guided, iterCount, maxReprojErr, ((unsigned int) ((double) points_2d.size()) * inliersPercentage), inlierPts, CV_EPNP); // ITERATIVE, CV_P3P
00487         
00488         
00489         //if ( ((unsigned int) inlierPts.size()) < ((unsigned int) (((double) points_2d.size()) * inliersPercentage)) ) {
00490         if ( inlierPts.size() < 8 ) {
00491                 if (debug) { printf("%s << PnP Failed:  Insufficient inliers: (%d) / (%d) : [%d, %d, %d]\n", __FUNCTION__, (int)inlierPts.size(), points_2d.size(), utilizedPointsCount, triangulatedCount, ((int)tracks.size())); }
00492                 guide.copyTo(dst);
00493                 return false;
00494         }
00495         
00496         if (debug) { printf("%s << PnP Succeeded:  Inliers: (%d) / (%d) : [%d, %d, %d]\n", __FUNCTION__, (int)inlierPts.size(), points_2d.size(), utilizedPointsCount, triangulatedCount, ((int)tracks.size())); }
00497         
00498         *pnpInlierProp = double(inlierPts.size()) / double(points_2d.size());
00499         
00500         Rodrigues(Rvec, R);
00501         cv::Mat P;
00502         findP1Matrix(P, R, t);                  
00503         projectionToTransformation(P, dst);
00504         dst = dst.inv();
00505         
00506         // Obtain some kind of error
00507         
00508         //printf("%s << points3d.size() = (%d); guided.size() = (%d)\n", __FUNCTION__, points_3d.size(), guided.size());
00509         //double reprojError = 0.0;
00510         
00511         //printf("%s << debug (%d)\n", __FUNCTION__, 0);
00512         
00513         cv::vector<cv::Point3f> validPts;
00514         for (unsigned int iii = 0; iii < inlierPts.size(); iii++) {
00515                 validPts.push_back(points_3d.at(inlierPts.at(iii)));
00516         }
00517         
00518         //printf("%s << debug (%d)\n", __FUNCTION__, 1);
00519         cv::vector<cv::Point2f> point_2f;
00520         projectPoints(validPts, Rvec, t, camData.K, camData.blankCoeffs, point_2f);
00521         
00522         //printf("%s << debug (%d)\n", __FUNCTION__, 2);
00523         
00524         for (unsigned int iii = 0; iii < inlierPts.size(); iii++) {
00525                 //printf("%s << points_2d.at(%d) = (%f, %f), point_2f.at(%d) = (%f, %f)\n", __FUNCTION__, iii, points_2d.at(inlierPts.at(iii)).x, points_2d.at(inlierPts.at(iii)).y, iii, point_2f.at(iii).x, point_2f.at(iii).y);
00526                 *reprojError += distBetweenPts2f(points_2d.at(inlierPts.at(iii)), point_2f.at(iii));
00527         
00528         }
00529         
00530         if (inlierPts.size() > 0) {
00531                 *reprojError /= double(inlierPts.size());
00532         } else {
00533                 *reprojError = -1.0;
00534         }
00535         
00536         //cout << "guide = " << guide << endl;
00537         //cout << "dst = " << dst << endl;
00538         
00539         return true;
00540         
00541 }
00542 
00543 
00544 
00545 void getCorrespondingPoints(vector<featureTrack>& tracks, const vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, int idx0, int idx1) {
00546         
00547         printf("%s << Entered X.\n", __FUNCTION__);
00548         
00549         // For each track
00550         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00551                 
00552                 if (tracks.at(iii).locations.size() < 2) {
00553                         continue;
00554                 }
00555                 //printf("%s << Debug (%d)\n", __FUNCTION__, iii);
00556                 // For each projection in the track
00557                 for (unsigned int kkk = 0; kkk < tracks.at(iii).locations.size()-1; kkk++) {
00558                 
00559                         //printf("%s << Debug (%d)(%d)\n", __FUNCTION__, iii, kkk);
00560                         
00561                         // If the camera of the projection matches the aim (idx0)
00562                         if (((int)tracks.at(iii).locations.at(kkk).imageIndex) == idx0) {
00563                                 // Found a feature that exists in the first image
00564                                 
00565                                 //printf("%s << Debug (%d)(%d) 2\n", __FUNCTION__, iii, kkk);
00566                                 
00567                                 // For each of the first set of points
00568                                 for (unsigned int jjj = 0; jjj < pts1.size(); jjj++) {
00569                                 
00570                                         //printf("%s << Debug (%d)(%d)(%d)\n", __FUNCTION__, iii, kkk, jjj);
00571                                 
00572                                         // If the projection location matches the first point at this point 
00573                                         if ((tracks.at(iii).locations.at(kkk).featureCoord.x == pts1.at(jjj).x) && (tracks.at(iii).locations.at(kkk).featureCoord.y == pts1.at(jjj).y)) {
00574                                                 
00575                                                 //printf("%s << Debug (%d)(%d)(%d) 2\n", __FUNCTION__, iii, kkk, jjj);
00576                                                 
00577                                                 // For each of the later projections on that track
00578                                                 for (unsigned int ppp = kkk; ppp < tracks.at(iii).locations.size(); ppp++) {
00579                                                         
00580                                                         //printf("%s << Debug (%d)(%d)(%d)(%d)\n", __FUNCTION__, iii, kkk, jjj, ppp);
00581                                                         
00582                                                         // If this later projection matches the second aimed index
00583                                                         if (((int)tracks.at(iii).locations.at(ppp).imageIndex) == idx1) {
00584                                                                 
00585                                                                 //printf("%s << Debug (%d)(%d)(%d)(%d) 2\n", __FUNCTION__, iii, kkk, jjj, ppp);
00586                                                                 
00587                                                                 // If the first projec....?
00588                                                                 if (jjj != pts2.size()) {
00589                                                                         printf("%s << ERROR! Vectors are not syncing (jjj = %d), pts2.size() = %d\n", __FUNCTION__, jjj, ((int)pts2.size()));
00590                                                                 } else {
00591                                                                         pts2.push_back(tracks.at(iii).locations.at(ppp).featureCoord);
00592                                                                 }
00593 
00594                                                                 
00595                                                         }
00596         
00597                                                         
00598                                                 }
00599                                                 
00600                                                 break;
00601                                         }
00602                                         
00603                                 }
00604                                 
00605                                 
00606                                 break;
00607                         }
00608                         
00609                 }
00610         }
00611                 
00612         printf("%s << Exiting.\n", __FUNCTION__);
00613         
00614 }
00615 
00616 void getTriangulatedFullSpanPoints(vector<featureTrack>& tracks, vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, int idx1, int idx2, vector<cv::Point3f>& points3) {
00617         
00618         pts1.clear();
00619         pts2.clear();
00620         points3.clear();
00621         
00622         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00623                 
00624                 for (unsigned int kkk = 0; kkk < tracks.at(iii).locations.size()-1; kkk++) {
00625                         
00626                         // If the track extends between the two images of interest
00627                         if (((int)tracks.at(iii).locations.at(kkk).imageIndex) == idx1) {
00628                                 
00629                                 for (unsigned int jjj = kkk+1; jjj < tracks.at(iii).locations.size(); jjj++) {
00630                                         
00631                                         if (((int)tracks.at(iii).locations.at(jjj).imageIndex) == idx2) {
00632                                                 
00633                                                 if (tracks.at(iii).isTriangulated) {
00634                                                         
00635                                                         pts1.push_back(tracks.at(iii).locations.at(kkk).featureCoord);
00636                                                         pts2.push_back(tracks.at(iii).locations.at(jjj).featureCoord);
00637                                                         
00638                                                         points3.push_back(cv::Point3f(((float) tracks.at(iii).get3dLoc().x), ((float) tracks.at(iii).get3dLoc().y), ((float) tracks.at(iii).get3dLoc().z)));
00639                                                         
00640                                                         break;
00641                                                 }
00642                                                 
00643                                                 
00644                                                 
00645                                         }
00646                                 }
00647                                 
00648                         }
00649                 }
00650         }
00651         
00652 }
00653 
00654 void findTriangulatableTracks(vector<featureTrack>& tracks, vector<unsigned int>& indices, vector<unsigned int>& cameras, unsigned int min_length) {
00655         
00656         unsigned int insuffAppeared = 0;
00657         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00658                 
00659                 if (tracks.at(iii).locations.size() < min_length) {
00660                         continue;
00661                 }
00662                 
00663                 unsigned int appearanceCount = 0;
00664                 unsigned int progressIndex = 0;
00665                 
00666                 for (unsigned int kkk = 0; kkk < cameras.size(); kkk++) {
00667                         
00668                         while (progressIndex < tracks.at(iii).locations.size()) {
00669                                 if (tracks.at(iii).locations.at(progressIndex).imageIndex == cameras.at(kkk) ) {
00670                                         appearanceCount++;
00671                                         progressIndex++;
00672                                         break;
00673                                 }
00674                                 progressIndex++;
00675                         }
00676                         
00677                 }
00678                 
00679                 if (appearanceCount >= min_length) {
00680                         indices.push_back(iii);
00681                 } else {
00682                         insuffAppeared++;
00683                         
00684                 }
00685                 
00686         }
00687         
00688         //printf("%s << insuffAppeared = (%d)\n", __FUNCTION__, insuffAppeared);
00689         
00690 }
00691 
00692 void findTriangulatableTracks3(vector<featureTrack>& tracks, vector<unsigned int>& indices, int latest_index, unsigned int min_length) {
00693         
00694         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00695                 
00696                 if (latest_index == -1) {
00697                         if (tracks.at(iii).locations.size() >= min_length) {
00698                                 indices.push_back(iii);
00699                         }
00700                 } else {
00701                         
00702                         unsigned int appearanceCount = 0;
00703                         
00704                         for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00705                                 if (tracks.at(iii).locations.at(jjj).imageIndex <= ((unsigned int) latest_index)) {
00706                                         appearanceCount++;
00707                                 }
00708                                 
00709                                 if (appearanceCount >= min_length) {
00710                                         indices.push_back(iii);
00711                                         break;
00712                                 }
00713                         }
00714                 }
00715                 
00716         }
00717         
00718 }
00719 
00720 void getTranslationBetweenCameras(cv::Mat& C1, cv::Mat& C2, double *translations) {
00721         
00722         cv::Mat CD = C2 - C1;
00723         
00724         translations[0] = CD.at<double>(0,3);
00725         translations[1] = CD.at<double>(1,3);
00726         translations[2] = CD.at<double>(2,3);
00727 
00728 }
00729 
00730 int initialTrackTriangulationDummy(vector<featureTrack>& tracks, vector<unsigned int>& indices, cameraParameters& cameraData, geometry_msgs::PoseStamped *keyframePoses, unsigned int keyframeCount, double minSeparation, double maxSeparation, int minEstimates, double maxStandardDev, bool handedness, int xCode) {
00731         
00732         int lim = 10; // 10
00733         
00734         cv::Point2f dummyPoints1[10], dummyPoints2[10];
00735         
00736         // far
00737         if (0) {
00738                 dummyPoints1[0].x = 200.5;
00739                 dummyPoints1[0].y = 143.5;
00740                 dummyPoints2[0].x = 180.5;
00741                 dummyPoints2[0].y = 143.5;
00742                 
00743         } else {
00744         
00745                 dummyPoints1[0].x = 225.5;
00746                 dummyPoints1[0].y = 163.5;
00747                 dummyPoints2[0].x = 115.5;
00748                 dummyPoints2[0].y = 163.5;
00749                 
00750                 dummyPoints1[1].x = 235.5;
00751                 dummyPoints1[1].y = 143.5;
00752                 dummyPoints2[1].x = 125.5;
00753                 dummyPoints2[1].y = 143.5;
00754                 
00755                 dummyPoints1[2].x = 235.5;
00756                 dummyPoints1[2].y = 123.5;
00757                 dummyPoints2[2].x = 125.5;
00758                 dummyPoints2[2].y = 123.5;
00759                 
00760                 dummyPoints1[3].x = 265.5;
00761                 dummyPoints1[3].y = 163.5;
00762                 dummyPoints2[3].x = 155.5;
00763                 dummyPoints2[3].y = 163.5;
00764                 
00765                 dummyPoints1[4].x = 255.5;
00766                 dummyPoints1[4].y = 143.5;
00767                 dummyPoints2[4].x = 145.5;
00768                 dummyPoints2[4].y = 143.5;
00769                 
00770                 dummyPoints1[5].x = 255.5;
00771                 dummyPoints1[5].y = 123.5;
00772                 dummyPoints2[5].x = 145.5;
00773                 dummyPoints2[5].y = 123.5;
00774                 
00775                 // near
00776                 dummyPoints1[6].x = 245.5;
00777                 dummyPoints1[6].y = 163.5;
00778                 dummyPoints2[6].x = 95.5;
00779                 dummyPoints2[6].y = 163.5;
00780                 
00781                 dummyPoints1[7].x = 255.5;
00782                 dummyPoints1[7].y = 123.5;
00783                 dummyPoints2[7].x = 105.5;
00784                 dummyPoints2[7].y = 123.5;
00785                 
00786                 dummyPoints1[8].x = 285.5;
00787                 dummyPoints1[8].y = 163.5;
00788                 dummyPoints2[8].x = 135.5;
00789                 dummyPoints2[8].y = 163.5;
00790                 
00791                 dummyPoints1[9].x = 275.5;
00792                 dummyPoints1[9].y = 123.5;
00793                 dummyPoints2[9].x = 125.5;
00794                 dummyPoints2[9].y = 123.5;
00795         }
00796         
00797         vector<cv::Point3f> testPt_3d;
00798         cv::Point3f tmp;
00799         tmp.x = 1.5;
00800         tmp.y = 1.5;
00801         tmp.z = 2.0;
00802         testPt_3d.push_back(tmp);
00803         
00804         /*
00805         cv::Mat testPt_3d(3, 1, CV_64FC1);
00806         testPt_3d.at<double>(0,0) = 1.5;
00807         testPt_3d.at<double>(1,0) = 1.5;
00808         testPt_3d.at<double>(2,0) = 1.0;
00809         */
00810         
00811         vector<cv::Point2f> testPts_2d;
00812         
00813         cv::Mat rvec, tvec, cameraMatrix, distCoeffs;
00814         tvec = cv::Mat::zeros(3, 1, CV_64FC1);
00815         rvec = cv::Mat::zeros(3, 1, CV_64FC1);
00816         cameraMatrix = cv::Mat::eye(3, 3, CV_64FC1);
00817         distCoeffs = cv::Mat::zeros(5, 1, CV_64FC1);;
00818         
00819         // projectPoints(InputArray objectPoints, InputArray rvec, InputArray tvec, InputArray cameraMatrix, InputArray distCoeffs, OutputArray imagePoints, OutputArray jacobian=noArray(), double aspectRatio=0 );
00820                 
00821         tvec.at<double>(0,0) = 0.0;
00822         tvec.at<double>(1,0) = 0.0;
00823         tvec.at<double>(2,0) = 0.0;
00824         projectPoints(testPt_3d, rvec, tvec, cameraMatrix, distCoeffs, testPts_2d);
00825         //printf("%s << Point (%f, %f, %f) projected to (%f, %f) and (%f, %f)\n", __FUNCTION__, testPt_3d.at<double>(0,0), testPt_3d.at<double>(1,0), testPt_3d.at<double>(2,0), testPts_2d.at(0).x, testPts_2d.at(0).y);
00826         printf("%s << Point (%f, %f, %f) projected to (%f, %f) for cam (%f, %f, %f)\n", __FUNCTION__, testPt_3d.at(0).x, testPt_3d.at(0).y, testPt_3d.at(0).z, testPts_2d.at(0).x, testPts_2d.at(0).y, tvec.at<double>(0,0), tvec.at<double>(1,0), tvec.at<double>(2,0));
00827         
00828         tvec.at<double>(0,0) = -1.5;
00829         tvec.at<double>(1,0) = -1.5;
00830         tvec.at<double>(2,0) = 0.0;
00831         
00832         projectPoints(testPt_3d, rvec, tvec, cameraMatrix, distCoeffs, testPts_2d);
00833         //printf("%s << Point (%f, %f, %f) projected to (%f, %f) and (%f, %f)\n", __FUNCTION__, testPt_3d.at<double>(0,0), testPt_3d.at<double>(1,0), testPt_3d.at<double>(2,0), testPts_2d.at(0).x, testPts_2d.at(0).y);
00834         printf("%s << Point (%f, %f, %f) projected to (%f, %f) for cam (%f, %f, %f)\n", __FUNCTION__, testPt_3d.at(0).x, testPt_3d.at(0).y, testPt_3d.at(0).z, testPts_2d.at(0).x, testPts_2d.at(0).y, tvec.at<double>(0,0), tvec.at<double>(1,0), tvec.at<double>(2,0));
00835         
00836         tvec.at<double>(0,0) = -3.0;
00837         tvec.at<double>(1,0) = -3.0;
00838         tvec.at<double>(2,0) = 0.0;
00839         
00840         projectPoints(testPt_3d, rvec, tvec, cameraMatrix, distCoeffs, testPts_2d);
00841         //printf("%s << Point (%f, %f, %f) projected to (%f, %f) and (%f, %f)\n", __FUNCTION__, testPt_3d.at<double>(0,0), testPt_3d.at<double>(1,0), testPt_3d.at<double>(2,0), testPts_2d.at(0).x, testPts_2d.at(0).y);
00842         printf("%s << Point (%f, %f, %f) projected to (%f, %f) for cam (%f, %f, %f)\n", __FUNCTION__, testPt_3d.at(0).x, testPt_3d.at(0).y, testPt_3d.at(0).z, testPts_2d.at(0).x, testPts_2d.at(0).y, tvec.at<double>(0,0), tvec.at<double>(1,0), tvec.at<double>(2,0));
00843         
00844         tvec.at<double>(0,0) = 0.0;
00845         tvec.at<double>(1,0) = -1.5;
00846         tvec.at<double>(2,0) = 0.0;
00847         
00848         projectPoints(testPt_3d, rvec, tvec, cameraMatrix, distCoeffs, testPts_2d);
00849         //printf("%s << Point (%f, %f, %f) projected to (%f, %f) and (%f, %f)\n", __FUNCTION__, testPt_3d.at<double>(0,0), testPt_3d.at<double>(1,0), testPt_3d.at<double>(2,0), testPts_2d.at(0).x, testPts_2d.at(0).y);
00850         printf("%s << Point (%f, %f, %f) projected to (%f, %f) for cam (%f, %f, %f)\n", __FUNCTION__, testPt_3d.at(0).x, testPt_3d.at(0).y, testPt_3d.at(0).z, testPts_2d.at(0).x, testPts_2d.at(0).y, tvec.at<double>(0,0), tvec.at<double>(1,0), tvec.at<double>(2,0));
00851         
00852         tvec.at<double>(0,0) = -1.5;
00853         tvec.at<double>(1,0) = 0.0;
00854         tvec.at<double>(2,0) = 0.0;
00855         
00856         projectPoints(testPt_3d, rvec, tvec, cameraMatrix, distCoeffs, testPts_2d);
00857         //printf("%s << Point (%f, %f, %f) projected to (%f, %f) and (%f, %f)\n", __FUNCTION__, testPt_3d.at<double>(0,0), testPt_3d.at<double>(1,0), testPt_3d.at<double>(2,0), testPts_2d.at(0).x, testPts_2d.at(0).y);
00858         printf("%s << Point (%f, %f, %f) projected to (%f, %f) for cam (%f, %f, %f)\n", __FUNCTION__, testPt_3d.at(0).x, testPt_3d.at(0).y, testPt_3d.at(0).z, testPts_2d.at(0).x, testPts_2d.at(0).y, tvec.at<double>(0,0), tvec.at<double>(1,0), tvec.at<double>(2,0));
00859         
00860         vector<cv::Point3d> estimatedLocations;
00861         for (int iii = 0; iii < lim; iii++) {
00862                 
00863                 cv::Mat R1, t1, temp_C1, temp_P1;
00864                 Quaterniond q1;
00865                 Eigen::Vector4d v1;
00866                 
00867                 
00868                 q1 = Quaterniond(1.0, 0.0, 0.0, 0.0);
00869                 //q1 = Quaterniond(0.70711, 0.0, -0.70711, 0.0); // trying to get projection matrix of identity..
00870                 v1 = Eigen::Vector4d(1.3, 1.5, 0.0, 1.0);
00871                 
00872                 quaternionToMatrix(q1, R1, handedness);
00873                 convertVec4dToMat(v1, t1);
00874                 composeTransform(R1, t1, temp_C1);
00875                 
00876                 
00877                 cv::Mat R2, t2, temp_C2, temp_P2;
00878                 Quaterniond q2;
00879                 Eigen::Vector4d v2;
00880                 q2 = Quaterniond(1.0, 0.0, 0.0, 0.0);
00881                 //q2 = Quaterniond(0.70711, 0.0, -0.70711, 0.0); // trying to get projection matrix of identity..
00882                 v2 = Eigen::Vector4d(1.7, 1.5, 0.0, 1.0);
00883                 
00884                 
00885                 quaternionToMatrix(q2, R2, handedness);
00886                 convertVec4dToMat(v2, t2);
00887                 composeTransform(R2, t2, temp_C2);
00888                 
00889                 cv::Point2f pt1_, pt2_;
00890                 cv::Point3d pt3d_;
00891                 
00892                 pt1_ = dummyPoints1[iii]; // left camera, point further to right
00893                 pt2_ = dummyPoints2[iii];
00894                 
00895                 temp_C1 = temp_C1.inv();
00896                 temp_C2 = temp_C2.inv();
00897                 
00898                 cout << "temp_C1 = " << temp_C1 << endl;
00899                 cout << "temp_C2 = " << temp_C2 << endl;
00900                 
00901                 Triangulate_1(pt1_, pt2_, cameraData.K, cameraData.K_inv, temp_C1, temp_C2, pt3d_, true);
00902                 
00903                 //pt3d_ = pt3d_;        // HACK!
00904                 
00905                 printf("%s << Triangulated (%f, %f) & (%f, %f) to (%f, %f, %f)\n", __FUNCTION__, pt1_.x, pt1_.y, pt2_.x, pt2_.y, pt3d_.x, pt3d_.y, pt3d_.z);
00906                 
00907                 estimatedLocations.push_back(pt3d_);
00908                 
00909                 tracks.at(indices.at(iii)).set3dLoc(pt3d_);
00910         }
00911         
00912         return lim;
00913         
00914 }
00915 
00916 void filterNearPoints(vector<featureTrack>& featureTrackVector, double x, double y, double z, double limit) {
00917         
00918         for (unsigned int iii = 0; iii < featureTrackVector.size(); iii++) {
00919                 
00920                 if (featureTrackVector.at(iii).isTriangulated) {
00921                         cv::Point3d pt3d = cv::Point3d(x, y, z);
00922                         cv::Point3d pt3d_ = featureTrackVector.at(iii).get3dLoc();
00923                         if (distBetweenPts(pt3d, pt3d_) < limit) {
00924                                 featureTrackVector.at(iii).isTriangulated = false;
00925                         }
00926                 }
00927                 
00928         }
00929         
00930 }
00931 
00932 int initialTrackTriangulation(vector<featureTrack>& tracks, vector<unsigned int>& indices, cameraParameters& cameraData, geometry_msgs::PoseStamped *keyframePoses, unsigned int keyframeCount, double minSeparation, double maxSeparation, int minEstimates, double maxStandardDev, double maxReprojectionDisparity) {
00933         
00934         cv::Point3d pt3d, mean3d(0.0, 0.0, 0.0), stddev3d(0.0, 0.0, 0.0);
00935         Quaterniond q0(1.0, 0.0, 0.0, 0.0); // corresponds to default projection matrix
00936         
00937         int minProjCount = 0, clusterFail = 0;
00938         vector<int> validPairs, tooClosePairs, tooFarPairs, tooNearPairs, inFrontPairs, withinDisparityPairs;
00939         
00940         
00941         int triangulatedCounter = 0;
00942         
00943         int minProjections_ = minProjections(minEstimates);
00944         
00945         for (unsigned int iii = 0; iii < indices.size(); iii++) {
00946                 
00947                 unsigned int ptsBehind = 0, ptsInfront = 0;
00948                 
00949                 int validPairs_ = 0, tooClosePairs_ = 0, tooFarPairs_ = 0, tooNearPairs_ = 0, inFrontPairs_ = 0, withinDisparityPairs_ = 0;
00950                 
00951                 if (tracks.size() <= indices.at(iii)) {
00952                         printf("%s << ERROR 1!\n", __FUNCTION__);
00953                         continue;
00954                 }
00955                 //if (tracks.at(iii).isTriangulated) continue;
00956                 
00957                 
00958                 if (((int)tracks.at(indices.at(iii)).locations.size()) < minProjections_) {
00959                         printf("%s << ERROR 2!\n", __FUNCTION__);
00960                         continue;
00961                 }
00962                 
00963                 //printf("%s << Continuing with (%d)...\n", __FUNCTION__, iii);
00964                 
00965                 vector<cv::Point3d> estimatedLocations;
00966                 vector<double> separationsVector;
00967                         
00968                 pt3d = cv::Point3d(0.0, 0.0, 0.0);
00969                 
00970                 int rrr, sss;
00971                 
00972                 // For each projection of interest (to make the FIRST one)
00973                 for (unsigned int jjj = 0; jjj < tracks.at(indices.at(iii)).locations.size()-1; jjj++) {
00974                         
00975                         //printf("%s << Here (%d) (jjj = %d)...\n", __FUNCTION__, iii, jjj);
00976                         
00977                         // Get the index of that image
00978                         rrr = tracks.at(indices.at(iii)).locations.at(jjj).imageIndex;
00979                         
00980                         // Check if you have that camera:
00981                         int cameraIndex1 = -1;
00982                         for (unsigned int kkk = 0; kkk < keyframeCount; kkk++) {
00983                                 if (((int)keyframePoses[kkk].header.seq) == rrr) {
00984                                         cameraIndex1 = kkk;
00985                                         break;
00986                                 }
00987                         }
00988                         
00989                         // If you don't, move to next projection
00990                         if (cameraIndex1 == -1) {
00991                                 //printf("%s << Error! missing camera 1.. (%d), (%d)\n", __FUNCTION__, rrr, cameraIndex1);
00992                                 continue;
00993                         }
00994                         
00995                         // Assign first camera to this matrix
00996                         cv::Mat R1, t1, temp_C1, temp_P1;
00997                         Quaterniond q1;
00998                         Eigen::Vector4d v1;
00999                         
01000                         q1 = Quaterniond(keyframePoses[cameraIndex1].pose.orientation.w, keyframePoses[cameraIndex1].pose.orientation.x, keyframePoses[cameraIndex1].pose.orientation.y, keyframePoses[cameraIndex1].pose.orientation.z);
01001                         v1 = Eigen::Vector4d(keyframePoses[cameraIndex1].pose.position.x, keyframePoses[cameraIndex1].pose.position.y, keyframePoses[cameraIndex1].pose.position.z, 1.0);
01002                         
01003                         quaternionToMatrix(q1, R1);
01004                         convertVec4dToMat(v1, t1);
01005                         composeTransform(R1, t1, temp_C1);
01006                         temp_C1 = temp_C1.inv();
01007                                 
01008                         transformationToProjection(temp_C1, temp_P1);
01009                         
01010                         for (unsigned int kkk = jjj+1; kkk < tracks.at(indices.at(iii)).locations.size(); kkk++) {
01011                                 
01012                                 //printf("%s << Here (%d) (kkk = %d)...\n", __FUNCTION__, iii, kkk);
01013                                 
01014                                 sss = tracks.at(indices.at(iii)).locations.at(kkk).imageIndex;
01015                                 
01016                                 // Check if you have that camera:
01017                                 int cameraIndex2 = -1;
01018                                 for (unsigned int mmm = 0; mmm < keyframeCount; mmm++) {
01019                                         if (((int)keyframePoses[mmm].header.seq) == sss) {
01020                                                 cameraIndex2 = mmm;
01021                                                 break;
01022                                         }
01023                                 }
01024                                 
01025                                 // If you don't, move to next projection
01026                                 if (cameraIndex2 == -1) {
01027                                         //printf("%s << Error! missing camera 2.. (%d), (%d)\n", __FUNCTION__, sss, cameraIndex2);
01028                                         continue;
01029                                 }
01030                                 
01031                                 //printf("%s << index (%d) is continuing...\n", __FUNCTION__, iii);
01032                                 
01033                                 validPairs_++;
01034                                                 
01035                                 // Assign second camera to this matrix
01036                                 cv::Mat R2, t2, temp_C2, temp_P2;
01037                                 Quaterniond q2;
01038                                 Eigen::Vector4d v2;
01039                                 
01040                                 q2 = Quaterniond(keyframePoses[cameraIndex2].pose.orientation.w, keyframePoses[cameraIndex2].pose.orientation.x, keyframePoses[cameraIndex2].pose.orientation.y, keyframePoses[cameraIndex2].pose.orientation.z);
01041                                 v2 = Eigen::Vector4d(keyframePoses[cameraIndex2].pose.position.x, keyframePoses[cameraIndex2].pose.position.y, keyframePoses[cameraIndex2].pose.position.z, 1.0);                               
01042                                 
01043                                 quaternionToMatrix(q2, R2);
01044                                 convertVec4dToMat(v2, t2);
01045                                 composeTransform(R2, t2, temp_C2);
01046                                 temp_C2 = temp_C2.inv();
01047                                 transformationToProjection(temp_C2, temp_P2);
01048                                 
01049                                 // Check whether separation is sufficient...
01050                                 double separation = pow(pow(v1.x() - v2.x(), 2.0) + pow(v1.y() - v2.y(), 2.0) + pow(v1.z() - v2.z(), 2.0), 0.5);
01051                                 
01052                                 if ( (separation < minSeparation) && (minSeparation != 0.0) ) {
01053                                         //printf("%s << Error! (%f) < (%f)\n", __FUNCTION__, separation, minSeparation);
01054                                         tooClosePairs_++;
01055                                         continue;
01056                                 } else if ( (separation > maxSeparation) && (maxSeparation != 0.0) ) {
01057                                         //printf("%s << Error! (%f) > (%f)\n", __FUNCTION__, separation , maxSeparation);
01058                                         tooFarPairs_++;
01059                                         continue;
01060                                 }
01061 
01062                                 cv::Point2f pt1_, pt2_;
01063                                 cv::Point3d pt3d_, pt3d_temp;
01064                                 
01065                                 pt1_ = tracks.at(indices.at(iii)).getCoord(rrr);
01066                                 pt2_ = tracks.at(indices.at(iii)).getCoord(sss);
01067                                 
01068                                 Triangulate_1(pt1_, pt2_, cameraData.K, cameraData.K_inv, temp_C1, temp_C2, pt3d_, true);
01069                         
01070                                 //printf("%s << Triangulated (%d) to (%f, %f, %f)...\n", __FUNCTION__, iii, pt3d_.x, pt3d_.y, pt3d_.z);
01071                         
01072                                 if (pointIsInFront(temp_C1, pt3d_) && pointIsInFront(temp_C2, pt3d_)) {
01073                                         
01074                                         inFrontPairs_++;
01075                                         
01076                                         vector<cv::Point3f> testPt_3d;
01077                                         testPt_3d.push_back(pt3d_);
01078                                         cv::Mat distCoeffs = cv::Mat::zeros(5, 1, CV_64FC1);
01079                                         
01080                                         cv::Mat t1x, r1x, R1_X;
01081                                         cv::Mat t2x, r2x, R2_X;
01082                                         decomposeTransform(temp_C1, R1_X, t1x);
01083                                         decomposeTransform(temp_C2, R2_X, t2x);
01084                                         Rodrigues(R1_X, r1x);
01085                                         Rodrigues(R2_X, r2x);
01086                                         
01087                                         
01088                                         /*
01089                                         
01090                                         cv::Mat t1x, r1x;
01091                                         cv::Mat t2x, r2x;
01092                                         t1x = -t1;
01093                                         t2x = -t2;
01094                                         
01095                                         Rodrigues(R1, r1x);
01096                                         Rodrigues(R2, r2x);
01097                                         r1x = -r1x;
01098                                         r2x = -r2x;
01099                                         */
01100                                         
01101                                         vector<cv::Point2f> testPts_2d_1, testPts_2d_2;
01102                                         
01103                                         projectPoints(testPt_3d, r1x, t1x, cameraData.K, distCoeffs, testPts_2d_1);
01104                                         double dist1 = pow(pow(testPts_2d_1.at(0).x - pt1_.x, 2.0) + pow(testPts_2d_1.at(0).y - pt1_.y, 2.0), 0.5);
01105                                         projectPoints(testPt_3d, r2x, t2x, cameraData.K, distCoeffs, testPts_2d_2);
01106                                         double dist2 = pow(pow(testPts_2d_2.at(0).x - pt2_.x, 2.0) + pow(testPts_2d_2.at(0).y - pt2_.y, 2.0), 0.5);
01107                                         
01108                                         //printf("%s << Track (%d):(%d,%d) from (%d,%d)/(%d,%d) to (%d,%d)/(%d,%d) for 3D (%3.1f, %3.1f, %3.1f)\n", __FUNCTION__, iii, jjj, kkk, int(pt1_.x), int(pt1_.y), int(pt2_.x), int(pt2_.y), int(testPts_2d_1.at(0).x), int(testPts_2d_1.at(0).y), int(testPts_2d_2.at(0).x), int(testPts_2d_2.at(0).y), testPt_3d.at(0).x, testPt_3d.at(0).y, testPt_3d.at(0).z);
01109                                         
01110                                         if ( ( (dist1 < maxReprojectionDisparity) && (dist2 < maxReprojectionDisparity) ) || (maxReprojectionDisparity == 0.0) ) {
01111                                                 withinDisparityPairs_++;
01112                                                 //printf("%s << And here (%d)...\n", __FUNCTION__, iii);
01113                                                 if ( (pt3d_.x != 0.0) && (pt3d_.y != 0.0) && (pt3d_.z != 0.0)) {
01114                                                         //printf("%s << And finally here (%d)...\n", __FUNCTION__, iii);
01115                                                         estimatedLocations.push_back(pt3d_);
01116                                                         separationsVector.push_back(separation);
01117                                                 }
01118                                         }
01119                                 } else {
01120                                         ptsBehind++;
01121                                 }
01122                         }
01123                 }
01124                 
01125                 
01126                 
01127                 validPairs.push_back(validPairs_);
01128                 tooClosePairs.push_back(tooClosePairs_);
01129                 tooFarPairs.push_back(tooFarPairs_);
01130                 tooNearPairs.push_back(tooNearPairs_);
01131                 inFrontPairs.push_back(inFrontPairs_);
01132                 withinDisparityPairs.push_back(withinDisparityPairs_);
01133                 
01134                 //printf("%s << (%d, %d, %d, %d, %d, %d)\n", __FUNCTION__, validPairs_, tooClosePairs_, tooFarPairs_, tooNearPairs_, inFrontPairs_, withinDisparityPairs_);
01135                 
01136                 if (((int)estimatedLocations.size()) < minEstimates) {
01137                         // printf("%s << Error! Insufficient estimates (%d) < (%d)\n", __FUNCTION__, ((int)estimatedLocations.size()) , minEstimates);
01138                         minProjCount++;
01139                         continue;
01140                 } else {
01141                         //printf("%s << Can continue..\n", __FUNCTION__);
01142                 }
01143                 
01144                 int mode = CLUSTER_MEAN_MODE; // DEFAULT_MEAN_MODE
01145                 bool validResult = findClusterMean(estimatedLocations, pt3d, mode, minEstimates, maxStandardDev);
01146                 
01147                 if (validResult) {
01148                         
01149                         //printf("%s << Clustering result is valid. (%f)\n", __FUNCTION__, maxStandardDev);
01150                         
01151                         /*
01152                         if (tracks.at(indices.at(iii)).isTriangulated) {
01153                                 cv::Point3d oldPt = tracks.at(indices.at(iii)).get3dLoc();
01154                                 double dist = distBetweenPts(oldPt, pt3d);
01155                                 if (dist < maxStandardDev) {
01156                                         printf("%s << Error! Dist is too low: (%f) < (%f)\n", __FUNCTION__, ((int)estimatedLocations.size()) , minEstimates);
01157                                         continue;
01158                                 }
01159                         }                       
01160                         */
01161                         
01162                         tracks.at(indices.at(iii)).set3dLoc(pt3d);
01163                         triangulatedCounter++;
01164                         
01165                 } else {
01166                         clusterFail++;
01167                         //printf("%s << error: clusterFail!\n", __FUNCTION__);
01168                 }
01169 
01170         }
01171         
01172         double validPairs_ave = 0.0, tooClosePairs_ave = 0.0, tooFarPairs_ave = 0.0, tooNearPairs_ave = 0.0, inFrontPairs_ave = 0.0, withinDisparityPairs_ave = 0.0;
01173         
01174         for (unsigned int iii = 0; iii < validPairs.size(); iii++) {
01175                 validPairs_ave += validPairs.at(iii);
01176                 tooClosePairs_ave += tooClosePairs.at(iii);
01177                 tooFarPairs_ave += tooFarPairs.at(iii);
01178                 tooNearPairs_ave += tooNearPairs.at(iii);
01179                 inFrontPairs_ave += inFrontPairs.at(iii);
01180                 withinDisparityPairs_ave += withinDisparityPairs.at(iii);
01181         }
01182         
01183         validPairs_ave /= double(validPairs.size());
01184         tooClosePairs_ave /= double(validPairs.size());
01185         tooFarPairs_ave /= double(validPairs.size());
01186         tooNearPairs_ave /= double(validPairs.size());
01187         inFrontPairs_ave /= double(validPairs.size());
01188         withinDisparityPairs_ave /= double(validPairs.size());
01189         
01190         // printf("%s << summ: (%f, %f, %f, %f, %f, %f)\n", __FUNCTION__, validPairs_ave, tooClosePairs_ave, tooFarPairs_ave, tooNearPairs_ave, inFrontPairs_ave, withinDisparityPairs_ave);
01191         
01192         //printf("%s << failed triangulations: minCOunt = (%d), cluster = (%d)\n", __FUNCTION__, minProjCount, clusterFail);
01193         
01194         return triangulatedCounter;
01195         
01196 }
01197 
01198 bool findClusterMean(const vector<cv::Point3d>& pts, cv::Point3d& pt3d, int mode, int minEstimates, double maxStandardDev) {
01199         
01200         cv::Point3d mean3d = cv::Point3d(0.0, 0.0, 0.0);
01201         cv::Point3d stddev3d = cv::Point3d(0.0, 0.0, 0.0);
01202         
01203         vector<cv::Point3d> estimatedLocations;
01204         estimatedLocations.insert(estimatedLocations.end(), pts.begin(), pts.end());
01205         vector<int> clusterCount;
01206         
01207         double outlierLimit = 3.0;
01208         
01209         if (mode == CLUSTER_MEAN_MODE) {
01210                 
01211                 
01212                 for (unsigned int iii = 0; iii < estimatedLocations.size(); iii++) {
01213                         clusterCount.push_back(1);
01214                         //printf("%s << pt(%d) = (%f, %f, %f)\n", __FUNCTION__, iii, estimatedLocations.at(iii).x, estimatedLocations.at(iii).y, estimatedLocations.at(iii).z);
01215                 }
01216                 
01217                 for (unsigned int iii = 0; iii < estimatedLocations.size()-1; iii++) {
01218                         
01219                         cv::Point3d basePt = estimatedLocations.at(iii);
01220                         
01221                         
01222                         
01223                         for (unsigned int jjj = iii+1; jjj < estimatedLocations.size(); jjj++) {
01224                                 
01225                                 double separation = pow(pow(basePt.x - estimatedLocations.at(jjj).x, 2.0) + pow(basePt.y - estimatedLocations.at(jjj).y, 2.0) + pow(basePt.z - estimatedLocations.at(jjj).z, 2.0), 0.5);
01226                                 
01227                                 if ( (separation < maxStandardDev) || (maxStandardDev == 0.0) ) {
01228                                         
01229                                         estimatedLocations.at(iii) *= double(clusterCount.at(iii));
01230                                         clusterCount.at(iii)++;
01231                                         estimatedLocations.at(iii) += estimatedLocations.at(jjj);
01232                                         estimatedLocations.at(iii).x /= double(clusterCount.at(iii));
01233                                         estimatedLocations.at(iii).y /= double(clusterCount.at(iii));
01234                                         estimatedLocations.at(iii).z /= double(clusterCount.at(iii));
01235                                         
01236                                         estimatedLocations.erase(estimatedLocations.begin() + jjj);
01237                                         clusterCount.erase(clusterCount.begin() + jjj);
01238                                         jjj--;
01239                                         
01240                                 }
01241                                 
01242                         }
01243                 }
01244                 
01245                 int maxClusterSize = 0, maxClusterIndex = -1;
01246                 
01247                 for (unsigned int iii = 0; iii < estimatedLocations.size(); iii++) {
01248 
01249                         if (clusterCount.at(iii) >= maxClusterSize) {
01250                                 maxClusterSize = clusterCount.at(iii);
01251                                 maxClusterIndex = iii;
01252                         }
01253 
01254                         //printf("%s << cluster(%d) = (%f, %f, %f) [%d]\n", __FUNCTION__, iii, estimatedLocations.at(iii).x, estimatedLocations.at(iii).y, estimatedLocations.at(iii).z, clusterCount.at(iii));
01255                 }
01256                 
01257                 if (maxClusterSize >= minEstimates) {
01258                         pt3d = estimatedLocations.at(maxClusterIndex);
01259                 } else {
01260                         return false;
01261                 }
01262                 
01263         } else {
01264                 //printf("%s << A; estimatedLocations.size() = (%d)\n", __FUNCTION__, estimatedLocations.size());
01265                 
01266                 for (unsigned int qqq = 0; qqq < estimatedLocations.size(); qqq++) {
01267                         
01268                         //printf("%s << pt(%d) = (%f, %f, %f)\n", __FUNCTION__, qqq, estimatedLocations.at(qqq).x, estimatedLocations.at(qqq).y, estimatedLocations.at(qqq).z); /* , separationsVector.at(qqq) */
01269                         
01270                         mean3d.x += (estimatedLocations.at(qqq).x / ((double) estimatedLocations.size()));
01271                         mean3d.y += (estimatedLocations.at(qqq).y / ((double) estimatedLocations.size()));
01272                         mean3d.z += (estimatedLocations.at(qqq).z / ((double) estimatedLocations.size()));
01273                         
01274                 }
01275                 
01276                 //printf("%s << mean = (%f, %f, %f)\n", __FUNCTION__, mean3d.x, mean3d.y, mean3d.z);
01277                 
01278                 //printf("%s << mean point = (%f, %f, %f)\n", __FUNCTION__, mean3d.x, mean3d.y, mean3d.z);
01279                 
01280                 // Calculate initial standard deviation
01281                 for (unsigned int qqq = 0; qqq < estimatedLocations.size(); qqq++) {
01282                         
01283                         stddev3d.x += (pow((estimatedLocations.at(qqq).x - mean3d.x), 2.0) / ((double) estimatedLocations.size()));
01284                         stddev3d.y += (pow((estimatedLocations.at(qqq).y - mean3d.y), 2.0) / ((double) estimatedLocations.size()));
01285                         stddev3d.z += (pow((estimatedLocations.at(qqq).z - mean3d.z), 2.0) / ((double) estimatedLocations.size()));
01286                         
01287                 }
01288                 
01289                 stddev3d.x = pow(stddev3d.x, 0.5);
01290                 stddev3d.y = pow(stddev3d.y, 0.5);
01291                 stddev3d.z = pow(stddev3d.z, 0.5);
01292                 
01293                 //printf("%s << stddev3d = (%f, %f, %f)\n", __FUNCTION__, stddev3d.x, stddev3d.y, stddev3d.z);
01294                 
01295                 //printf("%s << Point triangulated from (%d) view pairs: (%f, %f, %f) / (%f, %f, %f)\n", __FUNCTION__, estimatedLocations.size(), mean3d.x, mean3d.y, mean3d.z, stddev3d.x, stddev3d.y, stddev3d.z);
01296                 
01297                 // Reject projections that are more than X standard deviations away
01298                 for (int qqq = estimatedLocations.size()-1; qqq >= 0; qqq--) {
01299                         
01300                         double abs_diff_x = abs(estimatedLocations.at(qqq).x - mean3d.x);
01301                         double abs_diff_y = abs(estimatedLocations.at(qqq).y - mean3d.y); 
01302                         double abs_diff_z = abs(estimatedLocations.at(qqq).z - mean3d.z); 
01303                         
01304                         if ((abs_diff_x > outlierLimit*stddev3d.x) || (abs_diff_y > outlierLimit*stddev3d.y) || (abs_diff_z > outlierLimit*stddev3d.z)) {
01305                                 estimatedLocations.erase(estimatedLocations.begin() + qqq);
01306                         }
01307 
01308                 }
01309                 
01310                 //printf("%s << B: estimatedLocations.size() = (%d)\n", __FUNCTION__, estimatedLocations.size());
01311 
01312                 // Recalculate the standard deviation
01313                 stddev3d.x = 0.0;
01314                 stddev3d.y = 0.0;
01315                 stddev3d.z = 0.0;
01316                 
01317                 for (unsigned int qqq = 0; qqq < estimatedLocations.size(); qqq++) {
01318                         
01319                         stddev3d.x += (pow((estimatedLocations.at(qqq).x - mean3d.x), 2.0) / ((double) estimatedLocations.size()));
01320                         stddev3d.y += (pow((estimatedLocations.at(qqq).y - mean3d.y), 2.0) / ((double) estimatedLocations.size()));
01321                         stddev3d.z += (pow((estimatedLocations.at(qqq).z - mean3d.z), 2.0) / ((double) estimatedLocations.size()));
01322                         
01323                 }
01324                 
01325                 stddev3d.x = pow(stddev3d.x, 0.5);
01326                 stddev3d.y = pow(stddev3d.y, 0.5);
01327                 stddev3d.z = pow(stddev3d.z, 0.5);
01328                 
01329                 //printf("%s << stddev3d = (%f, %f, %f) [%d]\n", __FUNCTION__, stddev3d.x, stddev3d.y, stddev3d.z, minEstimates);
01330                 
01331                 // Reject track if the standard deviation is still too high, or not enough rays remain
01332                 if ( ((stddev3d.x > maxStandardDev) || (stddev3d.y > maxStandardDev) || (stddev3d.z > maxStandardDev) || (((int)estimatedLocations.size()) < minEstimates)) && (maxStandardDev != 0.0) ) { 
01333                         return false;
01334                 }
01335                 
01336                 //printf("%s << C: estimatedLocations.size() = (%d)\n", __FUNCTION__, estimatedLocations.size());
01337                 
01338                 // Final calculation of average point location
01339                 pt3d.x = 0.0;
01340                 pt3d.y = 0.0;
01341                 pt3d.z = 0.0;
01342                 
01343                 for (unsigned int qqq = 0; qqq < estimatedLocations.size(); qqq++) {
01344                                 
01345                         pt3d.x += (estimatedLocations.at(qqq).x / ((double) estimatedLocations.size()));
01346                         pt3d.y += (estimatedLocations.at(qqq).y / ((double) estimatedLocations.size()));
01347                         pt3d.z += (estimatedLocations.at(qqq).z / ((double) estimatedLocations.size()));
01348                         
01349                 }
01350         }
01351         
01352         return true;
01353 }
01354 
01355 void triangulateTracks(vector<featureTrack>& tracks, vector<unsigned int>& indices, cameraParameters& cameraData, cv::Mat *cameras, unsigned int earliest_index, unsigned int latest_index) {
01356         
01357         //return;
01358         
01359         //printf("%s << Entered.\n", __FUNCTION__);
01360         
01361         unsigned int minPairs = 10;
01362         
01363         // Should first check through camera pairs to see which ones can achive valid triangulations:
01364         
01365         //printf("%s << latest_index/earliest_index = (%d/%d)\n", __FUNCTION__, latest_index, earliest_index);
01366         unsigned int pair_width = latest_index - earliest_index + 1;
01367         cv::Mat validFramePairs = cv::Mat::zeros(pair_width, pair_width, CV_8UC1);
01368         
01369         double translations[3];
01370         
01371         for (unsigned int iii = earliest_index; iii < latest_index; iii++) {
01372                 for (unsigned int jjj = iii+1; jjj <= latest_index; jjj++) {
01373                         
01374                         if (cameras[iii].rows != 4) {
01375                                 continue;
01376                         }
01377                         
01378                         if (cameras[jjj].rows != 4) {
01379                                 continue;
01380                         }
01381                         
01382                         getTranslationBetweenCameras(cameras[iii], cameras[jjj], translations);
01383                         
01384                         //printf("%s << translations = (%f, %f, %f)\n", __FUNCTION__, translations[0], translations[1], translations[2]);
01385                         
01386                         //if ((abs(translations[0]) + abs(translations[1])) < 2.0*abs(translations[2])) {
01387                                 
01388                         
01389                                 
01390                         // Conditions for validity as a camera pair
01391                         if ((abs(translations[0] > 0.2)) || (abs(translations[1] > 0.2))) {     //  || (abs(translations[2] > 1.0))
01392                                 validFramePairs.at<unsigned char>(iii-earliest_index,jjj-earliest_index) = 1;
01393                         }
01394                 }
01395         }
01396                 
01397         unsigned int validCount = countNonZero(validFramePairs);
01398         
01399         //printf("%s << validCount = %d\n", __FUNCTION__, validCount);
01400         
01401         if (validCount < minPairs) {
01402                 return;
01403         }
01404         
01405         //printf("%s << Continuing.\n", __FUNCTION__);
01406         
01407         vector<cv::Point3d> estimatedLocations;
01408         
01409         cv::Point3d pt3d(0.0, 0.0, 0.0);
01410         cv::Point3d mean3d(0.0, 0.0, 0.0);
01411         cv::Point3d stddev3d(0.0, 0.0, 0.0);
01412         
01413         
01414         
01415         for (unsigned int iii = 0; iii < indices.size(); iii++) {
01416                 
01417                 //printf("%s << Track (%d) ...\n", __FUNCTION__, indices.at(iii));
01418                 
01419                 if (tracks.size() <= indices.at(iii)) {
01420                         return;
01421                 }
01422                 
01423                 if (tracks.at(indices.at(iii)).locations.size() < 2) {
01424                         continue;
01425                 }
01426                 
01427                 if (tracks.at(indices.at(iii)).isTriangulated) {
01428                         continue;
01429                 }
01430                 
01431                 //printf("%s << Track (%d) DEBUG [%d]\n", __FUNCTION__, indices.at(iii), 0);
01432                 
01433                 estimatedLocations.clear();
01434                         
01435                 pt3d = cv::Point3d(0.0, 0.0, 0.0);
01436                 mean3d = cv::Point3d(0.0, 0.0, 0.0);
01437                 stddev3d = cv::Point3d(0.0, 0.0, 0.0);
01438                 
01439                 unsigned int rrr, sss;
01440                 
01441                 for (unsigned int jjj = 0; jjj < tracks.at(indices.at(iii)).locations.size()-1; jjj++) {
01442                         
01443                         //printf("%s << Track (%d) jjj [%d]\n", __FUNCTION__, indices.at(iii), jjj);
01444                         
01445                         rrr = tracks.at(indices.at(iii)).locations.at(jjj).imageIndex;
01446                         
01447                         if ((rrr >= earliest_index) && (rrr <= latest_index)) {
01448                                 
01449                                 //printf("%s << Track (%d) jjj [%d] debug [%d]\n", __FUNCTION__, indices.at(iii), jjj, 0);
01450                         
01451                                 if (cameras[rrr].rows != 4) {
01452                                         //printf("%s << Breaking rrr (%d)...\n", __FUNCTION__, rrr);
01453                                         continue;
01454                                 }
01455                                 
01456                                 //printf("%s << Track (%d) jjj [%d] debug [%d]\n", __FUNCTION__, indices.at(iii), jjj, 1);
01457                         
01458                                 //printf("%s << rrr = %d\n", __FUNCTION__, rrr);
01459                                 
01460                                 cv::Mat temp_C0;
01461                                 cameras[rrr].copyTo(temp_C0);
01462                                 
01463                                 for (unsigned int kkk = jjj+1; kkk < tracks.at(indices.at(iii)).locations.size(); kkk++) {
01464                                         
01465                                         //printf("%s << Track (%d) kkk [%d]\n", __FUNCTION__, indices.at(iii), kkk);
01466                                         
01467                                         sss = tracks.at(indices.at(iii)).locations.at(kkk).imageIndex;
01468                                                                                 
01469                                         if ((sss >= earliest_index) && (sss <= latest_index)) {
01470                                                 
01471                                                 //printf("%s << Track (%d) kkk [%d] debug [%d]\n", __FUNCTION__, indices.at(iii), kkk, 0);
01472                                                 
01473                                                 //printf("%s << testing
01474                                                 
01475                                                 if (validFramePairs.at<unsigned char>(rrr-earliest_index,sss-earliest_index) == 0) {
01476                                                         continue;
01477                                                 }
01478                                         
01479                                                 if (cameras[sss].rows != 4) {
01480                                                         //printf("%s << Breaking sss (%d)...\n", __FUNCTION__, sss);
01481                                                         continue;
01482                                                 }
01483                                                 
01484                                                 //printf("%s << Track (%d) kkk [%d] debug [%d]\n", __FUNCTION__, indices.at(iii), kkk, 1);
01485 
01486                                                 
01487                                                 cv::Mat temp_C1;
01488                                                 cameras[sss].copyTo(temp_C1);
01489                                                 
01490                                                 // This should be a valid pair of projections to triangulate from for this point..
01491                                                 
01492                                                 // Check that the projections have enough translation:
01493                                                 
01494                                                 
01495                                                         
01496                                                 //}
01497                                                 
01498                                                 cv::Point2f pt1_, pt2_;
01499                                                 cv::Point3d pt3d_;
01500                                                 
01501                                                 pt1_ = tracks.at(indices.at(iii)).getCoord(rrr);
01502                                                 pt2_ = tracks.at(indices.at(iii)).getCoord(sss);
01503                                                 
01504                                                 Triangulate(pt1_, pt2_, cameraData.K, cameraData.K_inv, temp_C0, temp_C1, pt3d_, false);
01505                                                 
01506                                                 //if ((pointIsInFront(temp_C0, pt3d_)) && (pointIsInFront(temp_C1, pt3d_))) {
01507                                                         
01508                                                         estimatedLocations.push_back(pt3d_);
01509                                                         
01510                                                         /*
01511                                                         pt3d.x += pt3d_.x;
01512                                                         pt3d.y += pt3d_.y;
01513                                                         pt3d.z += pt3d_.z;
01514                                                         contribCount++;
01515                                                         */
01516                                                 //}
01517                                                 
01518                                                 if (jjj == 0) {
01519                                                         //printf("%s << Adding triangulation: (%f, %f, %f)\n", __FUNCTION__, pt3d_.x, pt3d_.y, pt3d_.z);
01520                                                 }
01521                                         }
01522                                 }
01523                         }
01524                         
01525                 }
01526                 
01527                 //printf("%s << Track (%d) : estimatedLocations.size() = %d\n", __FUNCTION__, indices.at(iii), estimatedLocations.size());
01528                 
01529                 if (estimatedLocations.size() >= minPairs) {
01530                                 
01531                         //printf("%s << Assigning (%d)\n", __FUNCTION__, indices.at(iii));
01532                         
01533                         //printf("%s << Calculating means..\n", __FUNCTION__);
01534                         
01535                         for (unsigned int qqq = 0; qqq < estimatedLocations.size(); qqq++) {
01536                                 
01537                                 mean3d.x += (estimatedLocations.at(qqq).x / ((double) estimatedLocations.size()));
01538                                 mean3d.y += (estimatedLocations.at(qqq).y / ((double) estimatedLocations.size()));
01539                                 mean3d.z += (estimatedLocations.at(qqq).z / ((double) estimatedLocations.size()));
01540                                 
01541                         }
01542                         
01543                         //printf("%s << Calculating deviations..\n", __FUNCTION__);
01544                         
01545                         for (unsigned int qqq = 0; qqq < estimatedLocations.size(); qqq++) {
01546                                 
01547                                 stddev3d.x += (pow((estimatedLocations.at(qqq).x - mean3d.x), 2.0) / ((double) estimatedLocations.size()));
01548                                 stddev3d.y += (pow((estimatedLocations.at(qqq).y - mean3d.y), 2.0) / ((double) estimatedLocations.size()));
01549                                 stddev3d.z += (pow((estimatedLocations.at(qqq).z - mean3d.z), 2.0) / ((double) estimatedLocations.size()));
01550                                 
01551                         }
01552                         
01553                         stddev3d.x = pow(stddev3d.x, 0.5);
01554                         stddev3d.y = pow(stddev3d.y, 0.5);
01555                         stddev3d.z = pow(stddev3d.z, 0.5);
01556                         
01557                         //printf("%s << Erasing outliers..\n", __FUNCTION__);
01558                         
01559                         for (int qqq = estimatedLocations.size()-1; qqq >= 0; qqq--) {
01560                                 
01561                                 //printf("%s << qqq = %d\n", __FUNCTION__, qqq);
01562                                 
01563                                 double abs_diff_x = abs(estimatedLocations.at(qqq).x - mean3d.x);
01564                                 double abs_diff_y = abs(estimatedLocations.at(qqq).y - mean3d.y); 
01565                                 double abs_diff_z = abs(estimatedLocations.at(qqq).z - mean3d.z); 
01566                                 
01567                                 if ((abs_diff_x > 2*stddev3d.x) || (abs_diff_y > 2*stddev3d.y) || (abs_diff_z > 2*stddev3d.z)) {
01568                                         estimatedLocations.erase(estimatedLocations.begin() + qqq);
01569                                 }
01570 
01571                         }
01572 
01573                                 
01574                         //printf("%s << Mean: (%f, %f, %f)\n", __FUNCTION__, mean3d.x, mean3d.y, mean3d.z);
01575                         //printf("%s << Std deviation: (%f, %f, %f)\n", __FUNCTION__, stddev3d.x, stddev3d.y, stddev3d.z);
01576                         
01577                         
01578                         if (estimatedLocations.size() >= minPairs) {
01579                                 //printf("%s << Re-calculating mean..\n", __FUNCTION__);
01580                         
01581                                 for (unsigned int qqq = 0; qqq < estimatedLocations.size(); qqq++) {
01582                                         
01583                                         //printf("%s << qqq = %d\n", __FUNCTION__, qqq);
01584                                         
01585                                         pt3d.x += (estimatedLocations.at(qqq).x / ((double) estimatedLocations.size()));
01586                                         pt3d.y += (estimatedLocations.at(qqq).y / ((double) estimatedLocations.size()));
01587                                         pt3d.z += (estimatedLocations.at(qqq).z / ((double) estimatedLocations.size()));
01588                                         
01589                                 }
01590 
01591                                 tracks.at(indices.at(iii)).set3dLoc(pt3d);
01592                                 
01593                                 //printf("%s << Adding contribution: (%f, %f, %f)\n", __FUNCTION__, pt3d.x, pt3d.y, pt3d.z);
01594                                 
01595                         }
01596                         
01597                         
01598                         
01599                         
01600                 }
01601                 
01602         //      printf("%s << Track (%d) : DONE!\n", __FUNCTION__, indices.at(iii));
01603         }
01604         
01605         //printf("%s << Exiting.\n", __FUNCTION__);
01606 }
01607 
01608 unsigned int addNewPoints(vector<featureTrack>& tracks, vector<unsigned int>& indices, cameraParameters& cameraData, cv::Mat *cameras, unsigned int earliest_index, unsigned int latest_index) {
01609 
01610         unsigned int totalTriangulatedPoints = 0;
01611         
01612         for (unsigned int iii = 0; iii < indices.size(); iii++) {
01613                 if (tracks.size() < indices.at(iii)) {
01614                         continue;
01615                 }
01616                 
01617                 if (tracks.at(indices.at(iii)).locations.size() < 2) {
01618                         continue;
01619                 }
01620                 
01621                 for (unsigned int jjj = 0; jjj < tracks.at(indices.at(iii)).locations.size()-1; jjj++) {
01622                         
01623                         //printf("%s << jjj = %d\n", __FUNCTION__, jjj);
01624                         
01625                         if (tracks.at(indices.at(iii)).isTriangulated) {
01626                                 continue;
01627                         }
01628                         
01629                         //printf("%s << jjj (continuing)\n", __FUNCTION__, jjj);
01630                         
01631                         unsigned int contribCount = 0;
01632                         cv::Point3d pt3d(0.0, 0.0, 0.0);
01633                         
01634                         unsigned int rrr = tracks.at(indices.at(iii)).locations.at(jjj).imageIndex;
01635                         
01636                         
01637                         
01638                         
01639                         if (rrr == earliest_index) {
01640                         
01641                                 if (cameras[rrr].rows != 4) {
01642                                         printf("%s << Breaking rrr (%d)...\n", __FUNCTION__, rrr);
01643                                         continue;
01644                                 }
01645                         
01646                                 //printf("%s << rrr = %d\n", __FUNCTION__, rrr);
01647                                 
01648                                 cv::Mat temp_C0;
01649                                 cameras[rrr].copyTo(temp_C0);
01650                                 
01651                                 for (unsigned int kkk = jjj+1; kkk < tracks.at(indices.at(iii)).locations.size(); kkk++) {
01652                                         
01653                                         unsigned int sss = tracks.at(indices.at(iii)).locations.at(kkk).imageIndex;
01654                                         
01655                                         
01656                                         
01657                                         //printf("%s << sss = %d\n", __FUNCTION__, sss);
01658                                         
01659                                         if (sss == latest_index) {
01660                                         
01661                                                 if (cameras[sss].rows != 4) {
01662                                                         printf("%s << Breaking sss (%d)...\n", __FUNCTION__, sss);
01663                                                         continue;
01664                                                 }
01665                                                 
01666                                                 //printf("%s << sss = %d\n", __FUNCTION__, sss);
01667                                                 
01668                                                 cv::Mat temp_C1;
01669                                                 cameras[sss].copyTo(temp_C1);
01670                                                 
01671                                                 // This should be a valid pair of projections to triangulate from for this point..
01672                                                 
01673                                                 cv::Point2f pt1_, pt2_;
01674                                                 cv::Point3d pt3d_;
01675                                                 
01676                                                 pt1_ = tracks.at(indices.at(iii)).getCoord(rrr);
01677                                                 pt2_ = tracks.at(indices.at(iii)).getCoord(sss);
01678                                                 
01679                                                 //printf("%s << Triangulating...\n", __FUNCTION__);
01680                                                 //printf("%s << pts = (%f, %f) & (%f, %f)\n", __FUNCTION__, pt1_.x, pt1_.y, pt2_.x, pt2_.y);
01681                                                 //cout << cameraData.K << endl;
01682                                                 //cout << cameraData.K_inv << endl;
01683                                                 //cout << temp_C1 << endl;
01684                                                 //cout << temp_C0 << endl;
01685                                                 
01686                                                 Triangulate(pt1_, pt2_, cameraData.K, cameraData.K_inv, temp_C0, temp_C1, pt3d_, false);
01687                                                 
01688                                                 //if ((pointIsInFront(temp_C0, pt3d_)) && (pointIsInFront(temp_C1, pt3d_))) {
01689                                                         pt3d.x += pt3d_.x;
01690                                                         pt3d.y += pt3d_.y;
01691                                                         pt3d.z += pt3d_.z;
01692                                                         contribCount++;
01693                                                 //}
01694                                         }
01695                                 }
01696                         }
01697                         
01698                         if (contribCount > 0) {
01699                                 
01700                                 //printf("%s << Assigning (%d)\n", __FUNCTION__, indices.at(iii));
01701                                 
01702                                 pt3d.x /= ((double) contribCount); 
01703                                 pt3d.y /= ((double) contribCount);
01704                                 pt3d.z /= ((double) contribCount);
01705                                 
01706                                 tracks.at(indices.at(iii)).set3dLoc(pt3d);
01707                         }
01708 
01709                         
01710                         
01711                 }
01712                 
01713         }
01714         
01715         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01716                 if (tracks.at(iii).isTriangulated) {
01717                         totalTriangulatedPoints++;
01718                 }
01719         }
01720         
01721         return totalTriangulatedPoints;
01722         
01723 }
01724 
01725 unsigned int putativelyTriangulateNewTracks(vector<featureTrack>& tracks, vector<unsigned int>& indices, cameraParameters& cameraData, cv::Mat *cameras, unsigned int earliest_index, unsigned int latest_index) {
01726         
01727         //printf("%s << Entered: (%d, %d, %d, %d)\n", __FUNCTION__, tracks.size(), indices.size(), earliest_index, latest_index);
01728         
01729         unsigned int totalTriangulatedPoints = 0;
01730         
01731         for (unsigned int iii = 0; iii < indices.size(); iii++) {
01732                 
01733                 //printf("%s << iii = %d\n", __FUNCTION__, iii);
01734                 
01735                 if (tracks.size() < indices.at(iii)) {
01736                         continue;
01737                 }
01738                 
01739                 if (tracks.at(indices.at(iii)).locations.size() < 2) {
01740                         continue;
01741                 }
01742                 
01743                 for (unsigned int jjj = 0; jjj < tracks.at(indices.at(iii)).locations.size()-1; jjj++) {
01744                         
01745                         //printf("%s << jjj = %d\n", __FUNCTION__, jjj);
01746                         
01747                         if (tracks.at(indices.at(iii)).isTriangulated) {
01748                                 continue;
01749                         }
01750                         
01751                         //printf("%s << jjj (continuing)\n", __FUNCTION__, jjj);
01752                         
01753                         unsigned int contribCount = 0;
01754                         cv::Point3d pt3d(0.0, 0.0, 0.0);
01755                         
01756                         unsigned int rrr = tracks.at(indices.at(iii)).locations.at(jjj).imageIndex;
01757                         
01758                         if (cameras[rrr].rows != 4) {
01759                                 continue;
01760                         }
01761                         
01762                         if ((rrr >= earliest_index) && (rrr <= latest_index)) {
01763                                 
01764                                 //printf("%s << rrr = %d\n", __FUNCTION__, rrr);
01765                                 
01766                                 cv::Mat temp_C0;
01767                                 cameras[rrr].copyTo(temp_C0);
01768                                 
01769                                 for (unsigned int kkk = jjj+1; kkk < tracks.at(indices.at(iii)).locations.size(); kkk++) {
01770                                         
01771                                         unsigned int sss = tracks.at(indices.at(iii)).locations.at(kkk).imageIndex;
01772                                         
01773                                         if (cameras[sss].rows != 4) {
01774                                                 continue;
01775                                         }
01776                                         
01777                                         //printf("%s << sss = %d\n", __FUNCTION__, sss);
01778                                         
01779                                         if ((sss >= earliest_index) && (sss <= latest_index)) {
01780                                                 
01781                                                 //printf("%s << sss = %d\n", __FUNCTION__, sss);
01782                                                 
01783                                                 cv::Mat temp_C1;
01784                                                 cameras[sss].copyTo(temp_C1);
01785                                                 
01786                                                 // This should be a valid pair of projections to triangulate from for this point..
01787                                                 
01788                                                 cv::Point2f pt1_, pt2_;
01789                                                 cv::Point3d pt3d_;
01790                                                 
01791                                                 pt1_ = tracks.at(indices.at(iii)).getCoord(rrr);
01792                                                 pt2_ = tracks.at(indices.at(iii)).getCoord(sss);
01793                                                 
01794                                                 //printf("%s << Triangulating...\n", __FUNCTION__);
01795                                                 //printf("%s << pts = (%f, %f) & (%f, %f)\n", __FUNCTION__, pt1_.x, pt1_.y, pt2_.x, pt2_.y);
01796                                                 //cout << cameraData.K << endl;
01797                                                 //cout << cameraData.K_inv << endl;
01798                                                 //cout << temp_C1 << endl;
01799                                                 //cout << temp_C0 << endl;
01800                                                 
01801                                                 Triangulate(pt1_, pt2_, cameraData.K, cameraData.K_inv, temp_C0, temp_C1, pt3d_, false);
01802                                                 
01803                                                 //if ((pointIsInFront(temp_C0, pt3d_)) && (pointIsInFront(temp_C1, pt3d_))) {
01804                                                         pt3d.x += pt3d_.x;
01805                                                         pt3d.y += pt3d_.y;
01806                                                         pt3d.z += pt3d_.z;
01807                                                         contribCount++;
01808                                                 //}
01809                                         }
01810                                 }
01811                         }
01812                         
01813                         if (contribCount > 0) {
01814                                 
01815                                 //printf("%s << Assigning (%d)\n", __FUNCTION__, indices.at(iii));
01816                                 
01817                                 pt3d.x /= ((double) contribCount); 
01818                                 pt3d.y /= ((double) contribCount);
01819                                 pt3d.z /= ((double) contribCount);
01820                                 
01821                                 tracks.at(indices.at(iii)).set3dLoc(pt3d);
01822                         }
01823 
01824                         
01825                         
01826                 }
01827                 
01828         }
01829         
01830         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01831                 if (tracks.at(iii).isTriangulated) {
01832                         totalTriangulatedPoints++;
01833                 }
01834         }
01835         
01836         return totalTriangulatedPoints;
01837         
01838 }
01839 
01840 void getPointsFromTracks(vector<featureTrack>& tracks, vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, int idx1, int idx2) {
01841         
01842         // Could make more efficient by only testing tracks that are long enough, but
01843         // If there are missing frames (acceptable?) then the simple way of achieving this won't work)
01844         
01845         //printf("%s << searching for indices (%d) & (%d) [tracks.size() = (%d)]\n", __FUNCTION__, idx1, idx2, tracks.size());
01846         
01847         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01848                 
01849                 //printf("%s << Searching track (%d)...\n", __FUNCTION__, iii);
01850                 
01851                 for (unsigned int kkk = 0; kkk < tracks.at(iii).locations.size(); kkk++) {
01852                         
01853                         //printf("%s << Searching element (%d) ; (%d)\n", __FUNCTION__, kkk, tracks.at(iii).locations.at(kkk).imageIndex);
01854                         
01855                         //if (tracks.at(iii).locations.at(kkk).imageIndex == 0) {
01856                                 //printf("%s << FOUND A ZERO TRACK!!!\n", __FUNCTION__);
01857                         //}
01858                         
01859                         // If the track extends between the two images of interest
01860                         if (((int)tracks.at(iii).locations.at(kkk).imageIndex) == idx1) {
01861                                 
01862                                 //printf("%s << Found index A (%d)...\n", __FUNCTION__, idx1);
01863                                 
01864                                 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
01865                                         
01866                                         //printf("%s << Searching element (%d)...\n", __FUNCTION__, jjj);
01867                                         
01868                                         if (((int)tracks.at(iii).locations.at(jjj).imageIndex) == idx2) {
01869                                                 
01870                                                 //printf("%s << Found match!\n", __FUNCTION__);
01871                                                 
01872                                                 pts1.push_back(tracks.at(iii).locations.at(kkk).featureCoord);
01873                                                 pts2.push_back(tracks.at(iii).locations.at(jjj).featureCoord);
01874                                                 break;
01875                                         }
01876                                 }
01877                                 
01878                         }
01879                 }
01880         }
01881 }
01882 
01883 void obtainAppropriateBaseTransformation(cv::Mat& C0, vector<featureTrack>& tracks) {
01884         
01885         cv::Point3d centroid, deviations;
01886         
01887         int numTriangulatedPts = 0;
01888         
01889         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01890                 if (tracks.at(iii).isTriangulated) {
01891                         
01892                         numTriangulatedPts += 1;
01893                         
01894                 }
01895         }
01896         
01897         if (numTriangulatedPts == 0) {
01898                 C0 = cv::Mat::eye(4, 4, CV_64FC1);
01899         } else {
01900                 // Find centroid and standard deviations of points
01901                 findCentroidAndSpread(tracks, centroid, deviations);
01902                 
01903                 // Create transformation matrix with a centroid that is distance
01904                 cv::Mat t(4, 1, CV_64FC1), R;
01905                 
01906                 R = cv::Mat::eye(3, 3, CV_64FC1);
01907                 
01908                 t.at<double>(0,0) = centroid.x + 3.0 * deviations.x;
01909                 t.at<double>(0,0) = centroid.y + 3.0 * deviations.y;
01910                 t.at<double>(0,0) = centroid.z + 3.0 * deviations.z;
01911                 t.at<double>(3,0) = 1.0;
01912 
01913                 composeTransform(R, t, C0);
01914         }
01915 }
01916 
01917 void findCentroidAndSpread(vector<featureTrack>& tracks, cv::Point3d& centroid, cv::Point3d& deviations) {
01918         
01919         centroid = cv::Point3d(0.0, 0.0, 0.0);
01920         deviations = cv::Point3d(0.0, 0.0, 0.0);
01921         
01922         double numPoints = 0.00;
01923         
01924         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01925                 if (tracks.at(iii).isTriangulated) {
01926                         
01927                         numPoints += 1.00;
01928                         
01929                 }
01930         }
01931         
01932         if (numPoints == 0.00) {
01933                 return;
01934         }
01935         
01936         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01937                 
01938                 if (tracks.at(iii).isTriangulated) {
01939                         
01940                         cv::Point3d tmpPt;
01941                         tmpPt = tracks.at(iii).get3dLoc();
01942                         centroid.x += (tmpPt.x / numPoints);
01943                         centroid.y += (tmpPt.y / numPoints);
01944                         centroid.z += (tmpPt.z / numPoints);
01945                         
01946                 }
01947                 
01948         }
01949         
01950         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01951                 
01952                 if (tracks.at(iii).isTriangulated) {
01953                         cv::Point3d tmpPt;
01954                         tmpPt = tracks.at(iii).get3dLoc();
01955                         deviations.x += (pow((tmpPt.x - centroid.x), 2.0) / numPoints);
01956                         deviations.y += (pow((tmpPt.y - centroid.y), 2.0) / numPoints);
01957                         deviations.z += (pow((tmpPt.z - centroid.z), 2.0) / numPoints);
01958                 }
01959                 
01960         }
01961         
01962         deviations.x = pow(deviations.x, 0.5);
01963         deviations.y = pow(deviations.y, 0.5);
01964         deviations.z = pow(deviations.z, 0.5);
01965 }
01966 
01967 void getPoints3dFromTracks(vector<featureTrack>& tracks, vector<cv::Point3d>& cloud, int idx1, int idx2) {
01968         
01969         cloud.clear();
01970         
01971         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01972                 
01973                 if (!tracks.at(iii).isTriangulated) {
01974                         continue;
01975                 }
01976                 
01977                 if (tracks.at(iii).locations.size() == 0) {
01978                         continue;
01979                 }
01980                 
01981                 for (unsigned int kkk = 0; kkk < tracks.at(iii).locations.size(); kkk++) {
01982                         
01983                         bool addedPoint = false;
01984                         // If the track extends between the two images of interest
01985                         if ((((int)tracks.at(iii).locations.at(kkk).imageIndex) == idx1) || (idx1 == -1)) {
01986                                 
01987                                 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
01988                                         
01989                                         if ((((int)tracks.at(iii).locations.at(jjj).imageIndex) == idx2) || (idx2 == -1)) {
01990                                                 cloud.push_back(tracks.at(iii).get3dLoc());
01991                                                 addedPoint = true;
01992                                                 break;
01993                                         }
01994                                 }
01995                                 
01996                         }
01997                         
01998                         if (addedPoint) {
01999                                 break;
02000                         }
02001                         
02002                 }
02003                 
02004                 
02005 
02006         }
02007         
02008 }
02009 
02010 
02011 void findFourTransformations(cv::Mat *C, const cv::Mat& E, const cv::Mat& K, const vector<cv::Point2f>& pts1, const vector<cv::Point2f>& pts2) {
02012         
02013         
02014         cv::Mat I, negI, t33, W, Winv, Z, Kinv, zeroTrans, R, t, Rvec;
02015         
02016         Kinv = K.inv();
02017         zeroTrans = cv::Mat::zeros(3, 1, CV_64FC1);
02018         I = cv::Mat::eye(3, 3, CV_64FC1);
02019         negI = -I;
02020         
02021         getWandZ(W, Winv, Z);
02022         
02023         //cout << __FUNCTION__ << " << W = " << W << endl;
02024         //cout << __FUNCTION__ << " << Winv = " << Winv << endl;
02025         
02026         //R = svd.u * W * svd.vt;
02027         //t = svd.u.col(2);
02028         
02029         //cout << __FUNCTION__ << " << R = " << R << endl;
02030         
02031         //Rodrigues(R, Rvec);
02032         
02033         //cout << __FUNCTION__ << " << Rvec = " << Rvec << endl;
02034         
02035         //cout << __FUNCTION__ << " << t = " << t << endl;
02036         
02037         cv::Mat c;
02038         //compileTransform(c, R, t);
02039         
02040         //cout << __FUNCTION__ << " << c = " << c << endl;
02041         
02042         cv::Mat u_transposePos, u_transposeNeg;
02043         cv::SVD svdPos, svdNeg;
02044         
02045         svdPos = cv::SVD(E);
02046         svdNeg = cv::SVD(-E);
02047                 
02048         transpose(svdPos.u, u_transposePos);
02049         transpose(svdNeg.u, u_transposeNeg);
02050         
02051         double detVal;
02052         
02053         for (unsigned int zzz = 0; zzz < 4; zzz++) {
02054                 
02055                 //printf("%s << Loop [%d]\n", __FUNCTION__, zzz);
02056                 
02057                 switch (zzz) {
02058                         case 0:
02059                                 //t33 = v * W * SIGMA * vt;
02060                                 t33 = svdPos.u * Z * u_transposePos;
02061                                 R = svdPos.u * Winv * svdPos.vt;
02062                                 detVal = determinant(R);
02063                                 if (detVal < 0) {
02064                                         t33 = svdNeg.u * Z * u_transposeNeg;
02065                                         R = svdNeg.u * Winv * svdNeg.vt;
02066                                 }
02067                                 break;
02068                         case 1:
02069                                 //t33 = v * W_inv * SIGMA * vt;
02070                                 t33 = negI * svdPos.u * Z * u_transposePos;
02071                                 R = svdPos.u * Winv * svdPos.vt;
02072                                 detVal = determinant(R);
02073                                 if (detVal < 0) {
02074                                         t33 = negI * svdNeg.u * Z * u_transposeNeg;
02075                                         R = svdNeg.u * Winv * svdNeg.vt;
02076                                 }
02077                                 break;
02078                         case 2:
02079                                 //t33 = v * W * SIGMA * vt;
02080                                 t33 = svdPos.u * Z * u_transposePos;
02081                                 R = svdPos.u * W * svdPos.vt;
02082                                 detVal = determinant(R);
02083                                 if (detVal < 0) {
02084                                         t33 = svdNeg.u * Z * u_transposeNeg;
02085                                         R = svdNeg.u * W * svdNeg.vt;
02086                                 }
02087                                 break;
02088                         case 3:
02089                                 //t33 = v * W_inv * SIGMA * vt;
02090                                 t33 = negI * svdPos.u * Z * u_transposePos;
02091                                 R = svdPos.u * W * svdPos.vt;
02092                                 detVal = determinant(R);
02093                                 if (detVal < 0) {
02094                                         t33 = negI * svdNeg.u * Z * u_transposeNeg;
02095                                         R = svdNeg.u * W * svdNeg.vt;
02096                                 }
02097                                 break;
02098                         default:
02099                                 break;
02100                 }
02101                 
02102                 // Converting 3x3 t mat to vector
02103                 t = cv::Mat::zeros(3, 1, CV_64F);
02104                 t.at<double>(0,0) = -t33.at<double>(1,2); // originally had -ve
02105                 t.at<double>(1,0) = t33.at<double>(0,2); // originall had a +ve
02106                 t.at<double>(2,0) = -t33.at<double>(0,1); // originally had -ve
02107                 
02108                 //cout << __FUNCTION__ << " << t[" << zzz << "] = " << t << endl;
02109                 
02110                 if (abs(1.0 - detVal) > 0.01) {
02111                         //printf("%s << Solution [%d] is invalid - det(R) = %f\n", __FUNCTION__, zzz, detVal);
02112                 } else {
02113                         //printf("%s << Solution [%d] det(R) = %f\n", __FUNCTION__, zzz, detVal);
02114                 }
02115                 
02116                 //compileTransform(c, R, -R*t);
02117                 //compileTransform(c, R, t);
02118                 composeTransform(R, t, c);
02119                 
02120                 //char printSummary[256];
02121                 //summarizeTransformation(c, printSummary);
02122                 //printf("%s << Original c[%d] = %s\n", __FUNCTION__, zzz, printSummary);
02123                 
02124                 //c = c.inv();
02125                 
02126                 c.copyTo(C[zzz]);
02127                 
02128                 //cout << __FUNCTION__ << " << Czzz = " << C[zzz] << endl;
02129                 
02130         }
02131 
02132 }
02133 
02134 
02135 
02136 bool pointIsInFront(const cv::Mat& C, const cv::Point3d& pt) {
02137         
02138         cv::Point3d p1;
02139         
02140         transfer3dPoint(pt, p1, C);
02141 
02142         if (p1.z > 0) {
02143                 return true;
02144         } else {
02145                 
02146                 return false;
02147                 
02148         }
02149         
02150         
02151 }
02152 
02153 // This function is when you have the 3D points and both transformation matrices
02154 int pointsInFront(const cv::Mat& C1, const cv::Mat& C2, const vector<cv::Point3d>& pts) {
02155         int retVal = 0;
02156         
02157         vector<cv::Point3d> pts1, pts2;
02158         
02159         cv::Mat R1, t1, R2, t2;
02160         decomposeTransform(C1, R1, t1);
02161         decomposeTransform(C2, R2, t2);
02162         
02163         double rot1, rot2;
02164         rot1 = getRotationInDegrees(R1);
02165         rot2 = getRotationInDegrees(R2);
02166         
02167         printf("%s << Two rotations = (%f, %f)\n", __FUNCTION__, rot1, rot2);
02168         
02169         // maybe something to do with intrinsics matrix....
02170         
02171         // want to transfer the 3D point locations into the co-ordinate system of each camera
02172         transfer3DPoints(pts, pts1, C1);
02173         transfer3DPoints(pts, pts2, C2);
02174         
02175         for (unsigned int iii = 0; iii < pts.size(); iii++) {
02176                 
02177                 //printf("%s << [%d](%f, %f, %f)-(%f, %f, %f)\n", __FUNCTION__, iii, pts1.at(iii).x, pts1.at(iii).y, pts1.at(iii).z, pts2.at(iii).x, pts2.at(iii).y, pts2.at(iii).z);
02178                 
02179                 if ((pts1.at(iii).z > 0) && (pts2.at(iii).z > 0)) {
02180                         
02181                         if (retVal < 5) {
02182                                 printf("%s << Point location is (%f, %f, %f)\n", __FUNCTION__, pts.at(iii).x, pts.at(iii).y, pts.at(iii).z);
02183                                 printf("%s << Rel #1 is (%f, %f, %f)\n", __FUNCTION__, pts1.at(iii).x, pts1.at(iii).y, pts1.at(iii).z);
02184                                 printf("%s << Rel #2 is (%f, %f, %f)\n", __FUNCTION__, pts2.at(iii).x, pts2.at(iii).y, pts2.at(iii).z);
02185                         }
02186                         
02187                         retVal++;
02188                 }
02189         }
02190         
02191         return retVal;
02192 }
02193 
02194 // This function is when you have the relative transformation matrix, cam matrix, and 2D locations of points..
02195 int pointsInFront(const cv::Mat& C1, const cv::Mat& K, const vector<cv::Point2f>& pts1, const vector<cv::Point2f>& pts2) {
02196         
02197         int retVal = 0;
02198         
02199         cv::Mat Kinv;
02200         Kinv = K.inv();
02201         
02202         // Representing initial camera relative to itself
02203         cv::Mat P0, C0;
02204         initializeP0(P0);
02205         projectionToTransformation(P0, C0);
02206         
02207         // Representing second camera relative to first camera
02208         cv::Mat P1;
02209         transformationToProjection(C1, P1);
02210         
02211 
02212         vector<cv::Point3d> pc1, pc2;
02213         vector<cv::Point2f> correspImg1Pt, correspImg2Pt;       
02214 
02215         // Get 3D locations of points relative to first camera
02216         TriangulatePoints(pts1, pts2, K, Kinv, P0, P1, pc1, correspImg1Pt);
02217         
02218         // Transfer 3D locations so that they are relative to second camera
02219         cv::Mat C1inv;
02220         C1inv = C1.inv();
02221         
02222         // src, dst, transform : if C1 represents transform from world to cam 1...
02223         transfer3DPoints(pc1, pc2, C1); // trying C1inv...
02224         
02225         //Mat R1, t1;
02226         //decomposeTransform(C, R1, t1);
02227         //double deg1 = getRotationInDegrees(R1);
02228         //printf("%s << Forwards rotation = %f\n", __FUNCTION__, deg1);
02229 
02230         
02231         //printf("%s << DEBUG %d\n", __FUNCTION__, 2);
02232         //Cinv = C.inv();
02233         //transformationToProjection(Cinv, P1b);
02234         
02235         //Mat R2, t2;
02236         //decomposeTransform(Cinv, R2, t2);
02237         //double deg2 = getRotationInDegrees(R2);
02238         //printf("%s << Backwards rotation = %f\n", __FUNCTION__, deg2);
02239         
02240         //printf("%s << DEBUG %d\n", __FUNCTION__, 3);
02241         //TriangulatePoints(pts2, pts1, K, Kinv, P0, P1b, pc2, correspImg2Pt);
02242 
02243         //printf("%s << DEBUG %d\n", __FUNCTION__, 4);
02244         
02245         int inFront1 = 0, inFront2 = 0;
02246         
02247         for (unsigned int iii = 0; iii < pc1.size(); iii++) {
02248                 
02249                 // Check z-coordinate in both clouds to make sure it's > 0
02250                 
02251                 //printf("%s << pc1 = (%f, %f, %f); pc2 = (%f, %f, %f)\n", __FUNCTION__, pc1.at(iii).x, pc1.at(iii).y, pc1.at(iii).z, pc2.at(iii).x, pc2.at(iii).y, pc2.at(iii).z);
02252                 
02253                 if (pc1.at(iii).z > 0) {
02254                         inFront1++;
02255                 }
02256                 
02257                 if (pc2.at(iii).z > 0) {
02258                         inFront2++;
02259                 }
02260                 
02261                 if ((pc1.at(iii).z > 0) && (pc2.at(iii).z > 0)) {
02262                         retVal++;
02263                 }
02264                 
02265         }
02266         
02267         //printf("%s << Pts in front of cams: %d, %d\n", __FUNCTION__, inFront1, inFront2);
02268         
02269         return retVal;
02270         
02271 }
02272 
02273 void convertPoint3dToMat(const cv::Point3d& src, cv::Mat& dst) {
02274         dst = cv::Mat::zeros(4, 1, CV_64FC1);
02275         
02276         dst.at<double>(3, 0) = 1.0;
02277 
02278         dst.at<double>(0,0) = src.x;
02279         dst.at<double>(1,0) = src.y;
02280         dst.at<double>(2,0) = src.z;
02281 }
02282 
02283 void transfer3dPoint(const cv::Point3d& src, cv::Point3d& dst, const cv::Mat& C) {
02284         
02285         cv::Mat pt1, pt2;
02286         
02287         pt1 = cv::Mat::zeros(4, 1, CV_64FC1);
02288         pt2 = cv::Mat::zeros(4, 1, CV_64FC1);
02289         
02290         pt1.at<double>(3, 0) = 1.0;
02291         pt2.at<double>(3, 0) = 1.0;
02292 
02293         
02294         pt1.at<double>(0,0) = src.x;
02295         pt1.at<double>(1,0) = src.y;
02296         pt1.at<double>(2,0) = src.z;
02297         
02298         pt2 = C * pt1;
02299         
02300         dst = cv::Point3d(pt2.at<double>(0,0), pt2.at<double>(1,0), pt2.at<double>(2,0));
02301         
02302 }
02303 
02304 void transfer3DPoints(const vector<cv::Point3d>& src, vector<cv::Point3d>& dst, const cv::Mat& C) {
02305         
02306         cv::Mat pt1, pt2;
02307         
02308         pt1 = cv::Mat::zeros(4, 1, CV_64FC1);
02309         pt2 = cv::Mat::zeros(4, 1, CV_64FC1);
02310         
02311         pt1.at<double>(3, 0) = 1.0;
02312         pt2.at<double>(3, 0) = 1.0;
02313         
02314         cv::Point3d shiftedPoint;
02315                 
02316         for (unsigned int iii = 0; iii < src.size(); iii++) {
02317                 pt1.at<double>(0,0) = src.at(iii).x;
02318                 pt1.at<double>(1,0) = src.at(iii).y;
02319                 pt1.at<double>(2,0) = src.at(iii).z;
02320                 
02321                 pt2 = C * pt1;          // pt2 = C.inv() * pt1;
02322                 
02323                 //printf("%s << pt2.at<double>(3,0) = %f\n", __FUNCTION__, pt2.at<double>(3,0));
02324                 
02325                 shiftedPoint.x = pt2.at<double>(0,0);
02326                 shiftedPoint.y = pt2.at<double>(1,0);
02327                 shiftedPoint.z = pt2.at<double>(2,0);
02328                 
02329                 dst.push_back(shiftedPoint);
02330         }
02331         
02332         
02333         
02334 }
02335 
02336 
02337 
02338 double calcInlierGeometryDistance(vector<cv::Point2f>& points1, vector<cv::Point2f>& points2, cv::Mat& mat, cv::Mat& mask, int distMethod) {
02339         
02340         double error = 0.0;
02341         
02342         int inlierCounter = 0;
02343 
02344         for (unsigned int iii = 0; iii < points1.size(); iii++) {
02345                 if (mask.at<char>(iii, 0) > 0) {
02346                         
02347                         error += calcGeometryDistance(points1.at(iii), points2.at(iii), mat, distMethod);
02348                         
02349                         inlierCounter++;
02350                 }
02351         }
02352         
02353         error /= (double) inlierCounter;
02354 
02355         return error;
02356 }
02357 
02358 double calcGeometryScore(vector<cv::Point2f>& points1, vector<cv::Point2f>& points2, cv::Mat& F, cv::Mat& Fmask, cv::Mat& H, cv::Mat& Hmask) {
02359         double gScore = 0.0;
02360         
02361         int inliers_H = 0, inliers_F = 0;
02362         
02363         /*
02364         for (int iii = 0; iii < points1.size(); iii++) {
02365                 if (Hmask.at<char>(iii, 0) > 0) {
02366                         inliers_H++;
02367                 }
02368                 
02369                 if (Fmask.at<char>(iii, 0) > 0) {
02370                         inliers_F++;
02371                 }               
02372         }
02373         * */
02374         
02375         inliers_H = countNonZero(Hmask);
02376         inliers_F = countNonZero(Fmask);
02377         
02378         printf("%s << Inliers: %d (H), %d (F)\n", __FUNCTION__, inliers_H, inliers_F);
02379         
02380         double sampson_H, sampson_F;
02381         
02382         sampson_H = calcSampsonError(points1, points2, H, Hmask);
02383         sampson_F = calcSampsonError(points1, points2, F, Fmask);
02384         
02385         double sampson_H2 = 0.0, sampson_F2 = 0.0;
02386         
02387         printf("%s << Sampson errors: %f (H), %f (F)\n", __FUNCTION__, sampson_H, sampson_F);
02388         
02389         for (unsigned int iii = 0; iii < points1.size(); iii++) {
02390                 sampson_H2 += calcSampsonDistance(points1.at(iii), points2.at(iii), H) / (double)points1.size();
02391                 sampson_F2 += calcSampsonDistance(points1.at(iii), points2.at(iii), F) / (double)points1.size();
02392         }
02393         
02394         printf("%s << Sampson errors2: %f (H), %f (F)\n", __FUNCTION__, sampson_H2, sampson_F2);
02395         
02396         
02397         gScore = (((double) inliers_F) / ((double) inliers_H)) * ( sampson_H / pow(sampson_F, 0.5));
02398         
02399         printf("%s << gScore = %f\n", __FUNCTION__, gScore);
02400         
02401         return gScore;
02402 }
02403 
02404 double calcFrameScore(double geomScore, int numFeatures, int numTracks) {
02405         
02406         double frameScore;
02407         
02408         frameScore = geomScore * ((double) numTracks) / ((double) numFeatures);
02409         
02410         return frameScore;
02411 }
02412  
02413 double calcSampsonError(vector<cv::Point2f>& points1, vector<cv::Point2f>& points2, cv::Mat& H, cv::Mat& Hmask) {
02414         double sampsonError = 0.0;
02415         
02416         int inlierCounter = 0;
02417 
02418         
02419         for (unsigned int iii = 0; iii < points1.size(); iii++) {
02420                 if (Hmask.at<char>(iii, 0) > 0) {
02421                         
02422                         sampsonError += lourakisSampsonError(points1.at(iii), points2.at(iii), H);
02423                         
02424                         inlierCounter++;
02425                 }
02426         }
02427         
02428         sampsonError /= (double) inlierCounter;
02429 
02430         return sampsonError;
02431 
02432 }
02433 
02434 // http://www.mathworks.com.au/help/toolbox/vision/ref/estimatefundamentalmatrix.html
02435 double calcSampsonDistance(cv::Point2f& pt1, cv::Point2f& pt2, cv::Mat& F) {
02436         
02437         double dist;
02438         
02439         cv::Mat point1(1, 3, CV_64FC1), point2(1, 3, CV_64FC1);
02440         
02441         point1.at<double>(0, 0) = (double) pt1.x;
02442         point1.at<double>(0, 1) = (double) pt1.y;
02443         point1.at<double>(0, 2) = 1.0;
02444         
02445         cv::Mat t1;
02446         transpose(point1, t1);
02447         
02448         point2.at<double>(0, 0) = (double) pt2.x;
02449         point2.at<double>(0, 1) = (double) pt2.y;
02450         point2.at<double>(0, 2) = 1.0;
02451         
02452         cv::Mat a, b, c;
02453         
02454         a = point2 * F * t1;
02455         b = F * t1;
02456         c = point2 * F;
02457         
02458         double val1 = pow(a.at<double>(0, 0), 2.0);
02459         double val2 = 1.0 / ((pow(b.at<double>(0, 0), 2.0)) + (pow(b.at<double>(1, 0), 2.0)));
02460         double val3 = 1.0 / ((pow(c.at<double>(0, 0), 2.0)) + (pow(c.at<double>(1, 0), 2.0)));
02461         
02462         dist = val1 * (val2 + val3);
02463         
02464         return dist;
02465         
02466 }
02467 
02468 double calcGeometryScore(int numInliers_H, int numInliers_F, double sampsonError_H, double sampsonError_F) {
02469         double geometryScore = 0.0;
02470         
02471         geometryScore = ((double) numInliers_F / (double) numInliers_H) * sampsonError_H / pow(sampsonError_F, 0.5);
02472         
02473         return geometryScore;
02474 }
02475 
02476 void assignIntrinsicsToP0(cv::Mat& P0, const cv::Mat& K) {
02477         P0 = cv::Mat::zeros(3, 4, CV_64FC1);
02478         
02479         for (int iii = 0; iii < 3; iii++) {
02480                 for (int jjj = 0; jjj < 3; jjj++) {
02481                         P0.at<double>(iii,jjj) = K.at<double>(iii,jjj);
02482                 }
02483         }
02484         
02485 }
02486 
02487 double getQuaternionAngle(const Quaterniond& q1, const Quaterniond& q2) {
02488         double angle, dot_prod;
02489         
02490         dot_prod = dotProduct(q1, q2);
02491         
02492         angle = 2.0 * acos(abs(dot_prod));
02493         
02494         return angle;
02495 }
02496 
02497 double dotProduct(const Quaterniond& q1, const Quaterniond& q2) {
02498         double prod;
02499         
02500         prod = q1.x()*q2.x() + q1.y()*q2.y() + q1.z()*q2.z() + q1.w()*q2.w();
02501         
02502         return prod;
02503 }
02504 
02505 void combineTransforms(cv::Mat& CN, const cv::Mat& C0, const cv::Mat& C1) {
02506         CN = cv::Mat::eye(4, 4, CV_64FC1);
02507         
02508         CN = C0 * C1;
02509 }
02510 
02511 double dotProduct(const cv::Mat& vec1, const cv::Mat& vec2) {
02512         double prod;
02513         
02514         prod = vec1.at<double>(0,0)*vec2.at<double>(0,0) + vec1.at<double>(0,0)*vec2.at<double>(0,0) + vec1.at<double>(0,0)*vec2.at<double>(0,0);
02515 
02516         return prod;
02517 
02518 }
02519 
02520 double getRotationInDegrees(const cv::Mat& R) {
02521         Quaterniond rotation;
02522         matrixToQuaternion(R, rotation);
02523         Quaterniond dq = defaultQuaternion();
02524         double qa = getQuaternionAngle(rotation, dq) * 180.0 / M_PI;
02525         
02526         return qa;
02527 
02528 }
02529 
02530 double getDistanceInUnits(const cv::Mat& t) {
02531         double retVal = 0.0;
02532         
02533         retVal += pow(t.at<double>(0,0), 2.0);
02534         retVal += pow(t.at<double>(1,0), 2.0);
02535         retVal += pow(t.at<double>(2,0), 2.0);
02536         retVal = pow(retVal, 0.5);
02537         
02538         return retVal;
02539 }
02540 
02541 
02542 
02543 void addFixedCamera(SysSBA& sys, cameraParameters& cameraData, const cv::Mat& C) {
02544         addBlankCamera(sys, cameraData, true);
02545         updateCameraNode_2(sys, C, sys.nodes.size()-1);
02546 }
02547 
02548 void addNewCamera(SysSBA& sys, cameraParameters& cameraData, const cv::Mat& C) {
02549         addBlankCamera(sys, cameraData, false);
02550         updateCameraNode_2(sys, C, sys.nodes.size()-1);
02551 }
02552 
02553 void convertVec4dToMat(const Vector4d& vec4, cv::Mat& mat) {
02554         mat = cv::Mat::zeros(3, 1, CV_64FC1);
02555         
02556         mat.at<double>(0,0) = vec4.x();
02557         mat.at<double>(1,0) = vec4.y();
02558         mat.at<double>(2,0) = vec4.z();
02559         
02560 }
02561 
02562 void updateTracks(vector<featureTrack>& trackVector, const SysSBA& sys) {
02563         cv::Point3d tmpPt;
02564         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
02565                 if (iii < trackVector.size()) {
02566                         tmpPt.x = sys.tracks[iii].point.x();
02567                         tmpPt.y = sys.tracks[iii].point.y();
02568                         tmpPt.z = sys.tracks[iii].point.z();
02569                         trackVector.at(iii).set3dLoc(tmpPt);
02570                 } // otherwise these points mightn't belong in the track vector..
02571                 
02572         }
02573 }
02574 
02575 void retrieveAllPoints(vector<cv::Point3d>& pts, const SysSBA& sys) {
02576         
02577         cv::Point3d point_3;
02578         
02579         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
02580                 point_3.x = sys.tracks[iii].point.x();
02581                 point_3.y = sys.tracks[iii].point.y();
02582                 point_3.z = sys.tracks[iii].point.z();
02583                         
02584                 pts.push_back(point_3);
02585         }
02586 }
02587 
02588 void retrieveCameraPose(const SysSBA& sys, unsigned int idx, cv::Mat& camera) {
02589         
02590         cv::Mat R, t;
02591         quaternionToMatrix(sys.nodes[idx].qrot, R);
02592         convertVec4dToMat(sys.nodes[idx].trans, t);
02593         composeTransform(R, t, camera);
02594         
02595 }
02596 
02597 double retrieveCameraPose(const SysSBA& sys, unsigned int idx, geometry_msgs::Pose& pose) {
02598         
02599         cv::Point3d sysPt(sys.nodes[idx].trans(0), sys.nodes[idx].trans(1), sys.nodes[idx].trans(2));
02600         cv::Point3d posePt(pose.position.x, pose.position.y, pose.position.z);
02601         
02602         double dist = distBetweenPts(sysPt, posePt);
02603         
02604         
02605         pose.orientation.w = sys.nodes[idx].qrot.w();
02606         pose.orientation.x = sys.nodes[idx].qrot.x();
02607         pose.orientation.y = sys.nodes[idx].qrot.y();
02608         pose.orientation.z = sys.nodes[idx].qrot.z();
02609         
02610         pose.position.x = sys.nodes[idx].trans(0);
02611         pose.position.y = sys.nodes[idx].trans(1);
02612         pose.position.z = sys.nodes[idx].trans(2);
02613         
02614         return dist;
02615         
02616 }
02617                 
02618 
02619 void retrieveAllCameras(cv::Mat *allCameraPoses, const SysSBA& sys) {
02620         
02621         for (unsigned int iii = 0; iii < sys.nodes.size(); iii++) {
02622                 //if (allCameraPoses[iii].rows < 4) {
02623                         
02624                 retrieveCameraPose(sys, iii, allCameraPoses[iii]);
02625                         
02626                 /*
02627                 Mat R, t, C;
02628                 quaternionToMatrix(sys.nodes[iii].qrot, R);
02629                 convertVec4dToMat(sys.nodes[iii].trans, t);
02630                 
02631                 compileTransform(C, R, t);
02632                 C.copyTo(allCameraPoses[iii]);
02633                 */
02634                 //} 
02635         }
02636 }
02637 
02638 void assignTracksToSBA(SysSBA& sys, vector<featureTrack>& trackVector, int maxIndex) {
02639         
02640         sys.tracks.clear();
02641         
02642         // ConnMat ??
02643         sys.connMat.clear();
02644         
02645         
02646         //printf("%s << Assigning (%d) tracks...\n", __FUNCTION__, trackVector.size());
02647         
02648         
02649         // For each track
02650         for (unsigned int iii = 0; iii < trackVector.size(); iii++) {
02651                 
02652                 // The first occurence of this feature has to be before the "maxIndex"
02653                 if (((int)trackVector.at(iii).locations.at(0).imageIndex) < maxIndex) {
02654                         cv::Point3d tmp3dPt = trackVector.at(iii).get3dLoc();
02655                         Vector4d temppoint(tmp3dPt.x, tmp3dPt.y, tmp3dPt.z, 1.0);
02656                         sys.addPoint(temppoint);
02657                 }
02658                 
02659         }
02660         
02661         // For each track
02662         for (unsigned int iii = 0; iii < trackVector.size(); iii++) {
02663                 Vector2d proj;
02664                 
02665                 // The first occurence of this feature has to be before the "maxIndex"
02666                 if (((int)trackVector.at(iii).locations.at(0).imageIndex) < maxIndex) {
02667                         
02668                         // For each projection
02669                         for (unsigned int jjj = 0; jjj < trackVector.at(iii).locations.size(); jjj++) {
02670 
02671                                 // Projection cannot be in an image beyond the currently "active" camera
02672                                 if (trackVector.at(iii).locations.at(jjj).imageIndex < (maxIndex+1)) {
02673                                         proj.x() = trackVector.at(iii).locations.at(jjj).featureCoord.x;
02674                                         proj.y() = trackVector.at(iii).locations.at(jjj).featureCoord.y;
02675                                         
02676                                         sys.addMonoProj(trackVector.at(iii).locations.at(jjj).imageIndex, iii, proj);
02677                                 }
02678 
02679                                 
02680                         }
02681                 }
02682                 
02683                                                         
02684         }
02685         
02686 }
02687 
02688 void estimateNewPose(vector<featureTrack>& tracks, cv::Mat& K, int idx, cv::Mat& pose) {
02689         // Find any tracks that have at least 2 "sightings" (so that 3d location is known)
02690         // Use 3D points and 2d locations to estimate R and t and then get pose
02691         
02692         vector<cv::Point3d> worldPoints;
02693         vector<cv::Point2f> imagePoints1, imagePoints2;
02694         
02695         cv::Mat blankCoeffs = cv::Mat::zeros(1, 8, CV_64FC1);
02696         
02697         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
02698                 if (tracks.at(iii).locations.size() >= 2) {
02699                         
02700                         int finalIndex = tracks.at(iii).locations.size()-1;
02701                         
02702                         if (((int)tracks.at(iii).locations.at(finalIndex).imageIndex) == idx) {
02703                                 //Point3d tmpPt(tracks.at(iii).xyzEstimate.x, tracks.at(iii).xyzEstimate.y, tracks.at(iii).xyzEstimate.z);
02704                                 worldPoints.push_back(tracks.at(iii).get3dLoc());
02705                                 cv::Point2f tmpPt2(tracks.at(iii).locations.at(finalIndex-1).featureCoord.x, tracks.at(iii).locations.at(finalIndex-1).featureCoord.y);
02706                                 imagePoints1.push_back(tmpPt2);
02707                                 tmpPt2 = cv::Point2f(tracks.at(iii).locations.at(finalIndex).featureCoord.x, tracks.at(iii).locations.at(finalIndex).featureCoord.y);
02708                                 imagePoints2.push_back(tmpPt2);
02709                         }
02710                         
02711                 }
02712         }
02713         
02714         
02715         cv::Mat Rvec, R, t;
02716 
02717         vector<cv::Point3f> objectPoints;
02718         cv::Point3f tmpPt;
02719         
02720         for (unsigned int jjj = 0; jjj < worldPoints.size(); jjj++) {
02721                 tmpPt = cv::Point3f((float) worldPoints.at(jjj).x, (float) worldPoints.at(jjj).y, (float) worldPoints.at(jjj).z);
02722                 objectPoints.push_back(tmpPt);
02723         }
02724         
02725         //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() );
02726         solvePnPRansac(objectPoints, imagePoints2, K, blankCoeffs, Rvec, t);
02727         Rodrigues(Rvec, R);
02728 
02729         //compileTransform(pose, R, t);
02730         composeTransform(R, t, pose);
02731 }
02732 
02733 void addNewPoints(SysSBA& sys, const vector<cv::Point3d>& pc) {
02734         
02735         Vector2d proj;
02736         
02737         proj.x() = 0.0;
02738         proj.y() = 0.0;
02739         
02740         for (unsigned int iii = 0; iii < pc.size(); iii++) {
02741                 Vector4d temppoint(pc.at(iii).x, pc.at(iii).y, pc.at(iii).z, 1.0);
02742                         
02743                 sys.addPoint(temppoint);
02744                 
02745                 sys.addMonoProj(0, iii, proj);
02746         }
02747 }
02748 
02749 int addToTracks(SysSBA& sys, int im1, vector<cv::Point2f>& pts1, int im2, vector<cv::Point2f>& pts2) {
02750         
02751         //printSystemSummary(sys);
02752         
02753         //printf("%s << Entered.\n", __FUNCTION__);
02754         
02755         Vector2d proj;
02756         
02757         //printf("%s << oldTrackCount = %d\n", __FUNCTION__, oldTrackCount);
02758         //printf("%s << nodes = %d\n", __FUNCTION__, sys.nodes.size());
02759         
02760         for (unsigned int iii = 0; iii < pts1.size(); iii++) {
02761                 
02762                 bool pointInTracks = false;
02763                 
02764                 //printf("%s << [%d][%d][%d] : tracks = %d\n", __FUNCTION__, im1, im2, iii, sys.tracks.size());
02765                 
02766                 for (unsigned int ttt = 0; ttt < sys.tracks.size(); ttt++) { // NOT oldTrackCount, in case of automatic re-ordering...
02767                         
02768                         //printf("%s << old_track(%d) size = %d\n", __FUNCTION__, ttt, sys.tracks.at(ttt).projections.size());
02769                         
02770                         int finalIndex = sys.tracks.at(ttt).projections.size() - 1;
02771                         
02772                         //printf("%s << [%d] finalIndex = %d\n", __FUNCTION__, ttt, finalIndex);
02773                         
02774                         if (finalIndex > -1) {
02775                                 
02776                                 //printf("%s << DEBUG[%d] (%d vs %d)\n", __FUNCTION__, 0, finalIndex, sys.tracks.at(ttt).projections.size());
02777                                 
02778                                 printf("%s << Attempting [%d][%d][%d][%d]\n", __FUNCTION__, im1, im2, iii, ttt);
02779                                 printf("%s << ndi(%d / %d) = \n", __FUNCTION__, finalIndex, ((int)sys.tracks.at(ttt).projections.size()));
02780                                 
02781                                 printf("%s << sizeof() %d\n", __FUNCTION__, int(sizeof(sys.tracks.at(ttt).projections)));
02782                                 
02783                                 if (finalIndex > 0) {
02784                                         printf("%s << (-1) %d\n", __FUNCTION__, sys.tracks.at(ttt).projections.at(finalIndex-1).ndi);
02785                                 }
02786                                 
02787                                 printf("%s << %d\n", __FUNCTION__, sys.tracks.at(ttt).projections.at(finalIndex).ndi);
02788                                 
02789                                 if ((im1 == 2) && (im2 == 3) && (iii == 16) && (ttt == 68)) {
02790                                         //cin.get();
02791                                 }
02792                                 // 3, 4, 0, #49/50 track
02793                                 
02794                                 // why would it say that projections is large enough, but then you can't read ndi...?
02795                                 // or is size returning the wrong info?
02796                                 
02797                                 if (sys.tracks.at(ttt).projections.at(finalIndex).ndi == im1) {
02798 
02799                                         //printf("%s << DEBUG[%d]\n", __FUNCTION__, 1);
02800                                         
02801                                         if ((sys.tracks.at(ttt).projections.at(finalIndex).kp.x() == pts1.at(iii).x) && (sys.tracks.at(ttt).projections.at(finalIndex).kp.y() == pts1.at(iii).y)) {
02802                                                 
02803                                                 //printf("%s << DEBUG[%d]\n", __FUNCTION__, 2);
02804                                                 
02805                                                 //printf("%s << Point exists in this track (%d)!\n", __FUNCTION__, ttt);
02806                                                 
02807                                                 pointInTracks = true;
02808                                                 
02809                                                 proj.x() = pts2.at(iii).x;
02810                                                 proj.y() = pts2.at(iii).y;
02811                                                 
02812                                                 if (!sys.addMonoProj(im2, ttt, proj)) {
02813                                                         printf("%s << Adding point failed!\n", __FUNCTION__);
02814                                                 }
02815                                                 
02816                                                 //printf("%s << Projection added.\n", __FUNCTION__);
02817                                                 
02818                                                 break;
02819                                                 
02820                                         }
02821                                         
02822                                         //printf("%s << DEBUG[%d]\n", __FUNCTION__, 3);
02823                                 }
02824                                 
02825                                 //printf("%s << DEBUG[%d]\n", __FUNCTION__, 4);
02826                         }
02827                         
02828                         
02829 
02830                 }
02831                 
02832                 if (!pointInTracks) {
02833                         
02834                         //printf("%s << Point not in any of the tracks...\n", __FUNCTION__);
02835                         
02836                         int newTrackNum = sys.tracks.size();
02837                         
02838                         Vector4d temppoint(0.0, 0.0, 0.0, 1.0);
02839                         
02840                         //temppoint.x() = 0.0;
02841                         //temppoint.y() = 0.0;
02842                         //temppoint.z() = 0.0;
02843                         sys.addPoint(temppoint);
02844                         
02845                         // Then add a track?
02846                         //sys.tracks.push_back(Track(temppoint));
02847                         
02848                         proj.x() = pts1.at(iii).x;
02849                         proj.y() = pts1.at(iii).y;
02850                         
02851                         if (!sys.addMonoProj(im1, newTrackNum, proj)) {
02852                                 printf("%s << Adding point failed!\n", __FUNCTION__);
02853                         }
02854                         
02855                         proj.x() = pts2.at(iii).x;
02856                         proj.y() = pts2.at(iii).y;
02857                         
02858                         if (!sys.addMonoProj(im2, newTrackNum, proj)) {
02859                                 printf("%s << Adding point failed!\n", __FUNCTION__);
02860                         }
02861                         
02862                         //printf("%s << Two projections added.\n", __FUNCTION__);
02863                 } else {
02864                         //printf("%s << Point already in tracks...\n", __FUNCTION__);
02865                 }
02866                 
02867                 
02868         }
02869         
02870         return sys.tracks.size();
02871 }
02872 
02873 void addBlankCamera(SysSBA& sys, cameraParameters& cameraData, bool isFixed) {
02874         
02875         frame_common::CamParams cam_params;
02876         
02877         
02878     cam_params.fx = cameraData.K.at<double>(0, 0);      // Focal length in x
02879     cam_params.fy = cameraData.K.at<double>(1, 1);      // Focal length in y
02880     
02881     cam_params.cx = cameraData.K.at<double>(0, 2);      // X position of principal point
02882     cam_params.cy = cameraData.K.at<double>(1, 2);      // Y position of principal point
02883     cam_params.tx = 0;                                                          // Baseline (no baseline since this is monocular)
02884     
02885     // printf("%s << Added camera: (%f, %f, %f, %f)\n", __FUNCTION__, cam_params.fx, cam_params.fy, cam_params.cx, cam_params.cy);
02886     
02887         Vector4d trans(0, 0, 0, 1);
02888             
02889         // Don't rotate.
02890         Quaterniond rot(1, 0, 0, 0);
02891         rot.normalize();
02892         
02893         //printf("%s << rot = (%f, %f, %f, %f)\n", __FUNCTION__, rot.x(), rot.y(), rot.z(), rot.w());
02894 
02895         // Add a new node to the system.
02896         sys.addNode(trans, rot, cam_params, isFixed);   // isFixed
02897         
02898         sys.nodes.at(sys.nodes.size()-1).setDr(true);
02899         
02900         if (isFixed) {
02901                 // sys.nFixed++;
02902         }
02903         
02904         /*
02905         sys.nodes[currIndex].normRot();
02906         sys.nodes[currIndex].setTransform();
02907         sys.nodes[currIndex].setProjection();
02908         sys.nodes[currIndex].setDr(true);
02909         */
02910 
02911 }
02912 
02913 void printSystemSummary(SysSBA& sys) {
02914         printf("%s << sys.nodes.size() = %d\n", __FUNCTION__, ((int)sys.nodes.size()));
02915         printf("%s << sys.tracks.size() = %d\n", __FUNCTION__, ((int)sys.tracks.size()));
02916 }
02917 
02918 Quaterniond defaultQuaternion() {
02919         Quaterniond defQuaternion(1, 0, 0, 0);
02920         
02921         return defQuaternion;
02922 }
02923 
02924 void updateCameraNode_2(SysSBA& sys, const cv::Mat& C, int image_index) {
02925         cv::Mat R, t;
02926         
02927         cv::Mat Cnew;
02928         
02929         if (C.rows == 4) {
02930                 C.copyTo(Cnew);
02931         } else {
02932                 Cnew = cv::Mat(4, 4, CV_64FC1);
02933                 for (unsigned int iii = 0; iii < 3; iii++) {
02934                         for (unsigned int jjj = 0; jjj < 4; jjj++) {
02935                                 Cnew.at<double>(iii,jjj) = C.at<double>(iii,jjj);
02936                                 
02937                         }
02938                 }
02939                 
02940                 Cnew.at<double>(3,0) = 0.0;
02941                 Cnew.at<double>(3,1) = 0.0;
02942                 Cnew.at<double>(3,2) = 0.0;
02943                 Cnew.at<double>(3,3) = 1.0;
02944         }
02945         
02946         cv::Mat C_inv = Cnew.inv();
02947         
02948         decomposeTransform(C, R, t);
02949         
02950         for (unsigned int iii = 0; iii < 3; iii++) {
02951                 for (unsigned int jjj = 0; jjj < 4; jjj++) {
02952                         sys.nodes.at(image_index).w2n(iii,jjj) = C.at<double>(iii,jjj);
02953                 }
02954         }
02955         
02956         updateCameraNode_2(sys, R, t, image_index);
02957 }
02958 
02959 void updateCameraNode_2(SysSBA& sys, const cv::Mat& R, const cv::Mat& t, int image_index) {
02960         Vector4d translation;
02961         Quaterniond rotation;
02962         
02963         // printf("%s << t = (%f, %f, %f, %f)\n", __FUNCTION__, t.at<double>(0,0), t.at<double>(1,0), t.at<double>(2,0), t.at<double>(3,0));
02964         
02965         translation.x() = t.at<double>(0,0);
02966         translation.y() = t.at<double>(1,0);
02967         translation.z() = t.at<double>(2,0);
02968         
02969         //printf("%s << Assigning (%d) translation: (%f, %f, %f)\n", __FUNCTION__, image_index, translation.x(), translation.y(), translation.z());
02970         
02971         matrixToQuaternion(R, rotation);
02972         
02973         //Quaterniond dq = defaultQuaternion();
02974         //double qa = getQuaternionAngle(rotation, dq);
02975         
02976         //printf("%s << Angle = %f / %f\n", __FUNCTION__, qa, qa * 180.0 / M_PI);
02977         
02978         //cout << __FUNCTION__ << " << R = " << R << endl;
02979         
02980         //printf("%s << rotation = (%f, %f, %f, %f)\n", __FUNCTION__, rotation.x(), rotation.y(), rotation.z(), rotation.w());
02981         
02982         //cv::Mat R2;
02983         //quaternionToMatrix(rotation, R2);
02984         
02985         //cout << __FUNCTION__ << " << R2 = " << R2 << endl;
02986         
02987         sys.nodes[image_index].trans = translation;
02988         sys.nodes[image_index].qrot = rotation;
02989         
02990 }
02991 
02992 void convertProjectionMatCVToEigen(const cv::Mat& mat, Eigen::Matrix< double, 3, 4 > m) {
02993         
02994         m(0,0) = mat.at<double>(0,0);
02995         m(0,1) = mat.at<double>(0,1);
02996         m(0,2) = mat.at<double>(0,2);
02997         m(0,3) = mat.at<double>(0,3);
02998         
02999         m(1,0) = mat.at<double>(1,0);
03000         m(1,1) = mat.at<double>(1,1);
03001         m(1,2) = mat.at<double>(1,2);
03002         m(1,3) = mat.at<double>(1,3);
03003         
03004         m(2,0) = mat.at<double>(2,0);
03005         m(2,1) = mat.at<double>(2,1);
03006         m(2,2) = mat.at<double>(2,2);
03007         m(2,3) = mat.at<double>(2,3);
03008         
03009 }
03010 
03011 void convertProjectionMatEigenToCV(const Eigen::Matrix< double, 3, 4 > m, cv::Mat& mat) {
03012         
03013         mat = cv::Mat::zeros(3, 4, CV_64FC1);
03014         
03015         mat.at<double>(0,0) = m(0,0);
03016         mat.at<double>(0,1) = m(0,1);
03017         mat.at<double>(0,2) = m(0,2);
03018         mat.at<double>(0,3) = m(0,3);
03019         
03020         mat.at<double>(1,0) = m(1,0);
03021         mat.at<double>(1,1) = m(1,1);
03022         mat.at<double>(1,2) = m(1,2);
03023         mat.at<double>(1,3) = m(1,3);
03024         
03025         mat.at<double>(2,0) = m(2,0);
03026         mat.at<double>(2,1) = m(2,1);
03027         mat.at<double>(2,2) = m(2,2);
03028         mat.at<double>(2,3) = m(2,3);
03029         
03030 }
03031 
03032 
03033 
03034 // J.M.P. van Waveren
03035 float ReciprocalSqrt( float x ) {
03036         long i;
03037         float y, r;
03038         
03039         y = x * 0.5f;
03040         i = *(long *)( &x );
03041         i = 0x5f3759df - ( i >> 1 );
03042         r = *(float *)( &i );
03043         r = r * ( 1.5f - r * r * y );
03044         return r;
03045 }
03046 
03047 
03048 void updateCameraNode(SysSBA& sys, cv::Mat R, cv::Mat t, int img1, int img2) {
03049         
03050         cv::Mat full_R;
03051         
03052         Rodrigues(R, full_R);
03053         
03054         printf("%s << Trying to determine position of camera node (%d, %d)...\n", __FUNCTION__, img1, img2);
03055         
03056         cout << "R = " << R << endl;
03057         cout << "t = " << t << endl;
03058         
03059         // First camera parameters
03060         Vector4d temptrans = sys.nodes[img1].trans;
03061         Quaterniond tempqrot = sys.nodes[img1].qrot;
03062         
03063         //printf("%s << Debug [%d]\n", __FUNCTION__, 0);
03064         
03065         // NEED TO COMBINE TRANSLATION AND QUATERNION FOR PREVIOUS CAMERA WITH THE ONE FOR THE PRESENT ONE...
03066         // NEED TO KNOW:        CONVERSION FROM R/t to quaternion
03067         //                                      mapping of one co-ordinate system onto another
03068         
03069         // Establish ORIGIN relative to NODE A
03070                         Vector4d temptrans_N;
03071                         Quaterniond tempqrot_N;
03072                         temptrans_N.x() = -temptrans.x();
03073                         temptrans_N.y() = -temptrans.y();
03074                         temptrans_N.z() = -temptrans.z();
03075                         tempqrot_N.x() = tempqrot.x();
03076                         tempqrot_N.y() = tempqrot.y();
03077                         tempqrot_N.z() = tempqrot.z();
03078                         tempqrot_N.w() = -tempqrot.w();
03079                         tempqrot_N.normalize();
03080                         
03081                         sba::Node negativeOrigin;
03082                         negativeOrigin.trans = temptrans_N;
03083                         negativeOrigin.qrot = tempqrot_N;
03084         
03085         //Mat testMat;
03086         //Quaterniond testQuaterniond;
03087         //printf("%s << q(1) = (%f, %f, %f, %f)\n", __FUNCTION__, tempqrot_N.x(), tempqrot_N.y(), tempqrot_N.z(), tempqrot_N.w());
03088         //convertFromQuaternionToMat(tempqrot_N, testMat);
03089         //cout << "testMat = " << testMat << endl;
03090         //convertFromMatToQuaternion(testMat, testQuaterniond);
03091         //printf("%s << q(2) = (%f, %f, %f, %f)\n", __FUNCTION__, testQuaterniond.x(), testQuaterniond.y(), testQuaterniond.z(), testQuaterniond.w());  
03092         //convertFromQuaternionToMat(testQuaterniond, testMat);
03093         //cout << "testMat2 = " << testMat << endl;
03094         
03095         //cout << "temptrans_N = " << temptrans_N << endl;
03096         //cout << "tempqrot_N = " << tempqrot_N << endl;
03097                         
03098         //printf("%s << Debug [%d]\n", __FUNCTION__, 1);
03099                         
03100         // Establish NODE B relative to NODE A
03101                                 
03102                         Vector4d temptrans_B;
03103                         Quaterniond tempqrot_B;
03104                         temptrans_B.x() = t.at<double>(0,0);
03105                         temptrans_B.y() = t.at<double>(1,0);
03106                         temptrans_B.z() = t.at<double>(2,0);
03107                         
03108                         matrixToQuaternion(full_R, tempqrot_B);
03109                         
03110                         //cout << "full_R = " << full_R << endl;
03111                         //printf("%s << tempqrot_B = (%f, %f, %f, %f)\n", __FUNCTION__, tempqrot_B.x(), tempqrot_B.y(), tempqrot_B.z(), tempqrot_B.w());
03112                         
03113                         //tempqrot_B.x() = R.at<double>(0,0);           // not correct conversion to quaternion
03114                         //tempqrot_B.y() = R.at<double>(1,0);
03115                         //tempqrot_B.z() = R.at<double>(2,0);
03116                         tempqrot_B.normalize();
03117                         
03118                         sba::Node secondNode;
03119                         secondNode.trans = temptrans_B;
03120                         secondNode.qrot = tempqrot_B;
03121                         
03122         //printf("%s << Debug [%d]\n", __FUNCTION__, 2);
03123         
03124         // Find transform from Origin to camera B
03125 
03126                         Eigen::Matrix< double, 4, 1 > transformationMat;
03127                         Eigen::Quaternion< double > quaternionVec;
03128 
03129                         sba::transformN2N(transformationMat, quaternionVec, negativeOrigin, secondNode);
03130                         
03131         //printf("%s << Debug [%d]\n", __FUNCTION__, 3);
03132                         
03133         // Assign this transformation to the new camera mode
03134         
03135                         temptrans.x() = transformationMat(0,0);
03136                         temptrans.y() = transformationMat(1,0);
03137                         temptrans.z() = transformationMat(2,0);
03138                 
03139                         tempqrot.x() = quaternionVec.x();
03140                         tempqrot.y() = quaternionVec.y();
03141                         tempqrot.z() = quaternionVec.z();
03142                         tempqrot.normalize();
03143 
03144                         sys.nodes[img2].trans = temptrans;
03145                         sys.nodes[img2].qrot = tempqrot;
03146 
03147                         sys.nodes[img2].normRot();
03148                         sys.nodes[img2].setTransform();
03149                         sys.nodes[img2].setProjection();
03150                         sys.nodes[img2].setDr(true);
03151                         
03152         //printf("%s << Debug [%d]\n", __FUNCTION__, 4);
03153         
03154         return;
03155         
03156         // OLD
03157 
03158 
03159         // Add the new translations
03160         temptrans.x() += t.at<double>(0,0);
03161         temptrans.y() += t.at<double>(1,0);
03162         temptrans.z() += t.at<double>(2,0);
03163         
03164         // This is probably not a valid conversion 
03165         
03166         tempqrot.x() += R.at<double>(0,0);
03167         tempqrot.y() += R.at<double>(1,0);
03168         tempqrot.z() += R.at<double>(2,0);
03169         tempqrot.normalize();
03170 
03171         sys.nodes[img2].trans = temptrans;
03172         sys.nodes[img2].qrot = tempqrot;
03173 
03174         // These methods should be called to update the node.
03175         
03176         sys.nodes[img2].normRot();
03177         sys.nodes[img2].setTransform();
03178         sys.nodes[img2].setProjection();
03179         sys.nodes[img2].setDr(true);
03180         
03181 }
03182 
03183 void constrainDodgyPoints(SysSBA& sys) {
03184         
03185         for (unsigned int iii = 0; iii < sys.nodes.size(); iii++) {
03186                 if ((abs(sys.nodes[iii].trans.x()) > POSITION_LIMIT) || (abs(sys.nodes[iii].trans.y()) > POSITION_LIMIT) || (abs(sys.nodes[iii].trans.z()) > POSITION_LIMIT)) {
03187                         sys.nodes[iii].trans.x() = 0.0;
03188                         sys.nodes[iii].trans.y() = 0.0;
03189                         sys.nodes[iii].trans.z() = 0.0;
03190                 }
03191         }
03192         
03193         for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
03194                 if ((abs(sys.tracks[iii].point.x()) > POSITION_LIMIT) || (abs(sys.tracks[iii].point.y()) > POSITION_LIMIT) || (abs(sys.tracks[iii].point.z()) > POSITION_LIMIT)) {
03195                         sys.tracks[iii].point.x() = 0.0;
03196                         sys.tracks[iii].point.y() = 0.0;
03197                         sys.tracks[iii].point.z() = 0.0;
03198                 }
03199         }
03200 }
03201 
03202 int TriangulateNewTracks(vector<featureTrack>& trackVector, const int index1, const int index2, const cv::Mat& K, const cv::Mat& K_inv, const cv::Mat& P0, const cv::Mat& P1, bool initializeOnFocalPlane) {
03203         
03204         cv::Mat coordinateTransform;
03205         
03206         int tracksTriangulated = 0;
03207 
03208         
03209         for (unsigned int iii = 0; iii < trackVector.size(); iii++) {
03210                 
03211                 for (unsigned int jjj = 0; jjj < trackVector.at(iii).locations.size()-1; jjj++) {
03212                                         
03213                         int trInd1 = trackVector.at(iii).locations.at(jjj).imageIndex;
03214                                 
03215                         if (trInd1 == index1) {
03216                                 
03217                                 for (unsigned int kkk = jjj+1; kkk < trackVector.at(iii).locations.size(); kkk++) {
03218                                         
03219                                         int trInd2 = trackVector.at(iii).locations.at(kkk).imageIndex;
03220                                         
03221                                         if (trInd2 == index2) {
03222                                                 
03223                                                 cv::Point2f loc1 = trackVector.at(iii).locations.at(jjj).featureCoord;
03224                                                 cv::Point2f loc2 = trackVector.at(iii).locations.at(kkk).featureCoord;
03225                                                 
03226                                                 cv::Point3d xyzPoint;
03227                         
03228                                                 // This puts the 3D point out but in camera A's co-ordinates
03229                                                 if (initializeOnFocalPlane) {
03230                                                         xyzPoint.x = loc1.x;
03231                                                         xyzPoint.y = loc1.y;
03232                                                         xyzPoint.z = 1.0;
03233                                                 } else {
03234                                                         Triangulate(loc1, loc2, K, K_inv, P0, P1, xyzPoint);
03235                                                 }
03236                                                 
03237                                                 //printf("%s << PT relative to cam A: (%f, %f, %f)\n", __FUNCTION__, xyzPoint.x, xyzPoint.y, xyzPoint.z);
03238                                                 
03239                                                 // Convert XYZ co-ordinate to WORLD co-ordinates
03240                                                 
03241                                                 trackVector.at(iii).set3dLoc(xyzPoint);
03242                                                 //trackVector.at(iii).xyzEstimate.x = xyzPoint.x;
03243                                                 //trackVector.at(iii).xyzEstimate.y = xyzPoint.y;
03244                                                 //trackVector.at(iii).xyzEstimate.z = xyzPoint.z;
03245                                                 
03246                                                 //printf("%s << PT relative to WORLD: (%f, %f, %f)\n", __FUNCTION__, trackVector.at(iii).xyzEstimate.x, trackVector.at(iii).xyzEstimate.y, trackVector.at(iii).xyzEstimate.z);
03247                                                 
03248                                                 tracksTriangulated++;
03249                                                 
03250                                         }
03251                                         
03252                                 }
03253                                 
03254                         }
03255                                 
03256                                 
03257                 }
03258                 
03259                 
03260                 
03261         
03262         }
03263         
03264         return tracksTriangulated;
03265 
03266 }
03267 
03268 void ExtractPointCloud(vector<cv::Point3d>& cloud, vector<featureTrack>& trackVector) {
03269         
03270         
03271         for (unsigned int iii = 0; iii < trackVector.size(); iii++) {
03272                 // Copy the track vector co-ordinate
03273                 cloud.push_back(trackVector.at(iii).get3dLoc());
03274         }
03275         
03276         
03277 }
03278 
03279 
03280 
03281 void reduceVectorsToTrackedPoints(const vector<cv::Point2f>& points1, vector<cv::Point2f>& trackedPoints1, const vector<cv::Point2f>& points2, vector<cv::Point2f>& trackedPoints2, vector<uchar>& statusVec) {
03282         
03283         trackedPoints1.clear();
03284         trackedPoints2.clear();
03285         
03286         for (unsigned int iii = 0; iii < statusVec.size(); iii++) {
03287                 
03288                 if (statusVec.at(iii) > 0) {
03289                         //printf("%s << 1: statusVec.at(%d) = %c\n", __FUNCTION__, iii, statusVec.at(iii));
03290                         trackedPoints1.push_back(points1.at(iii));
03291                         trackedPoints2.push_back(points2.at(iii));
03292                 } else {
03293                         //printf("%s << 0: statusVec.at(%d) = %c\n", __FUNCTION__, iii, statusVec.at(iii));
03294                 }
03295         }
03296         
03297 }
03298 
03299 bool findBestReconstruction(const cv::Mat& P0, cv::Mat& P1, cv::Mat& R, cv::Mat& t, const cv::SVD& svd, const cv::Mat& K, const vector<cv::Point2f>& pts1, const vector<cv::Point2f>& pts2, bool useDefault) {
03300         
03301         bool validity = false;
03302         
03303         //printf("%s << Entered.\n", __FUNCTION__);
03304         
03305         if (pts1.size() != pts2.size()) {
03306                 printf("%s << ERROR! Point vector size mismatch.\n", __FUNCTION__);
03307         }
03308         
03309         int bestIndex = 0, bestScore = -1;
03310         cv::Mat t33, t_tmp[4], R_tmp[4], W, Z, Winv, I, negI, P1_tmp[4];
03311         cv::Mat Kinv;
03312         //printf("%s << DEBUG [%d].\n", __FUNCTION__, -2);
03313         //printf("%s << DEBUG [%d].\n", __FUNCTION__, -1);
03314         Kinv = K.inv();
03315         
03316         //printf("%s << DEBUG [%d].\n", __FUNCTION__, 0);
03317         
03318         cv::Mat zeroTrans;
03319         zeroTrans = cv::Mat::zeros(3, 1, CV_64F);       // correct dimension?
03320         
03321         I = cv::Mat::eye(3, 3, CV_64FC1);
03322         negI = -I;
03323         getWandZ(W, Winv, Z);
03324         
03325         //printf("%s << DEBUG [%d].\n", __FUNCTION__, 1);
03326         
03327         cv::Mat u_transpose;
03328         transpose(svd.u, u_transpose);
03329         
03330         cv::Mat rotation1;
03331         Rodrigues(I, rotation1);
03332         
03333         //printf("%s << DEBUG [%d].\n", __FUNCTION__, 2);
03334 
03335         //cout << "rotation1 = " << rotation1 << endl;
03336         
03337         float sig = rotation1.at<double>(0,1);
03338         float phi = rotation1.at<double>(0,2);
03339 
03340         //printf("%s << sig = %f; phi = %f\n", __FUNCTION__, sig, phi);
03341 
03342         cv::Point3d unitVec1(1.0*sin(sig)*cos(phi), 1.0*sin(sig)*cos(phi), 1.0*cos(sig));
03343         
03344         //printf("%s << DEBUG [%d].\n", __FUNCTION__, 3);
03345 
03346         cv::Mat uv1(unitVec1);
03347         
03348         //printf("%s << DEBUG [%d].\n", __FUNCTION__, 4);
03349         
03350         // Go through all four cases...
03351         for (int zzz = 0; zzz < 4; zzz++) {
03352                 
03353                 //printf("%s << Loop [%d]\n", __FUNCTION__, zzz);
03354                 
03355                 switch (zzz) {
03356                         case 0:
03357                                 //t33 = v * W * SIGMA * vt;
03358                                 t33 = svd.u * Z * u_transpose;
03359                                 R_tmp[zzz] = svd.u * Winv * svd.vt;
03360                                 break;
03361                         case 1:
03362                                 //t33 = v * W_inv * SIGMA * vt;
03363                                 t33 = negI * svd.u * Z * u_transpose;
03364                                 R_tmp[zzz] = svd.u * Winv * svd.vt;
03365                                 break;
03366                         case 2:
03367                                 //t33 = v * W * SIGMA * vt;
03368                                 t33 = svd.u * Z * u_transpose;
03369                                 R_tmp[zzz] = svd.u * W * svd.vt;
03370                                 break;
03371                         case 3:
03372                                 //t33 = v * W_inv * SIGMA * vt;
03373                                 t33 = negI * svd.u * Z * u_transpose;
03374                                 R_tmp[zzz] = svd.u * W * svd.vt;
03375                                 break;
03376                         default:
03377                                 break;
03378                 }
03379                 
03380                 // Converting 3x3 t mat to vector
03381                 t_tmp[zzz] = cv::Mat::zeros(3, 1, CV_64F);
03382                 t_tmp[zzz].at<double>(0,0) = -t33.at<double>(1,2);
03383                 t_tmp[zzz].at<double>(1,0) = t33.at<double>(0,2);
03384                 t_tmp[zzz].at<double>(2,0) = -t33.at<double>(0,1);
03385                 
03386                 // Get new P1 matrix
03387                 findP1Matrix(P1_tmp[zzz], R_tmp[zzz], t_tmp[zzz]);
03388                 
03389                 // Find camera vectors
03390                 cv::Mat rotation2;
03391                 Rodrigues(R_tmp[zzz], rotation2);
03392 
03393                 //cout << "rotation2 = " << rotation2 << endl;
03394 
03395                 sig = rotation2.at<double>(0,1);
03396                 phi = rotation2.at<double>(0,2);
03397 
03398                 //printf("%s << sig = %f; phi = %f\n", __FUNCTION__, sig, phi);
03399 
03400                 cv::Point3d unitVec2(1.0*sin(sig)*cos(phi), 1.0*sin(sig)*cos(phi), 1.0*cos(sig));
03401 
03402                 cv::Mat uv2(unitVec2);
03403 
03404                 //printf("%s << unitVec2 = (%f, %f, %f)\n", __FUNCTION__, unitVec2.x, unitVec2.y, unitVec2.z);
03405                 
03406                 int badCount = 0;
03407                 
03408                 vector<cv::Point3d> pointcloud;
03409                 vector<cv::Point2f> correspImg1Pt;
03410                 
03411                 //printf("%s << DEBUG [%d].\n", __FUNCTION__, 7);
03412                 
03413                 TriangulatePoints(pts1, pts2, K, Kinv, P0, P1_tmp[zzz], pointcloud, correspImg1Pt);
03414                 
03415                 //printf("%s << DEBUG [%d]. (pointcloud.size() = %d)\n", __FUNCTION__, 8, pointcloud.size());
03416                 
03417                 cv::Mat Rs_k[2], ts_k[2];
03418 
03419                 // Then check how many points are NOT in front of BOTH of the cameras
03420                 for (unsigned int kkk = 0; kkk < pointcloud.size(); kkk++) {
03421                         
03422                         
03423                         
03424                         //printf("%s << DEBUG [%d][%d].\n", __FUNCTION__, kkk, 0);
03425 
03426                         cv::Point3d rayVec1, rayVec2;
03427 
03428                         Rs_k[0] = I;
03429                         Rs_k[1] = R_tmp[zzz];
03430 
03431                         ts_k[0] = zeroTrans;
03432                         ts_k[1] = t_tmp[zzz];
03433                         
03434                         //printf("%s << DEBUG [%d][%d].\n", __FUNCTION__, kkk, 1);
03435                         
03436                         //cout << endl << "t_tmp[zzz] = " << t_tmp[zzz] << endl;
03437 
03438                         //printf("%s << objpt = (%f, %f, %f)\n", __FUNCTION__, objpt.x, objpt.y, objpt.z);
03439 
03440                         // so this is getting the displacements between the points and both cameras...
03441                         rayVec1.x = pointcloud.at(kkk).x - ts_k[0].at<double>(0,0);
03442                         rayVec1.y = pointcloud.at(kkk).y - ts_k[0].at<double>(1,0);
03443                         rayVec1.z = pointcloud.at(kkk).z - ts_k[0].at<double>(2,0);
03444 
03445                         rayVec2.x = pointcloud.at(kkk).x - ts_k[1].at<double>(0,0);
03446                         rayVec2.y = pointcloud.at(kkk).y - ts_k[1].at<double>(1,0);
03447                         rayVec2.z = pointcloud.at(kkk).z - ts_k[1].at<double>(2,0);
03448                         
03449                         /*
03450                         if (kkk < 0) {
03451                                 printf("%s << pt(%d) = (%f, %f, %f)\n", __FUNCTION__, kkk, pointcloud.at(kkk).x, pointcloud.at(kkk).y, pointcloud.at(kkk).z);
03452                                 printf("%s << rayVec1(%d) = (%f, %f, %f)\n", __FUNCTION__, kkk, rayVec1.x, rayVec1.y, rayVec1.z);
03453                                 printf("%s << rayVec2(%d) = (%f, %f, %f)\n", __FUNCTION__, kkk, rayVec2.x, rayVec2.y, rayVec2.z);
03454                         }
03455                         * */
03456                         
03457                         //printf("%s << DEBUG [%d][%d].\n", __FUNCTION__, kkk, 2);
03458 
03459                         //printf("%s << rayVec1 = (%f, %f, %f)\n", __FUNCTION__, rayVec1.x, rayVec1.y, rayVec1.z);
03460                         //printf("%s << rayVec2 = (%f, %f, %f)\n", __FUNCTION__, rayVec2.x, rayVec2.y, rayVec2.z);
03461 
03462                         //cin.get();
03463 
03464                         double dot1, dot2;
03465                         
03466                         cv::Mat rv1(rayVec1), rv2(rayVec2);
03467                         
03468                         /*
03469                         cout << endl << "uv1 = " << uv1 << endl;
03470                         cout << endl << "rv1 = " << rv1 << endl;
03471                         
03472                         cout << endl << "uv2 = " << uv2 << endl;
03473                         cout << endl << "rv2 = " << rv2 << endl;
03474                         */
03475 
03476                         dot1 = uv1.dot(rv1);
03477                         dot2 = uv2.dot(rv2);
03478 
03479                         //printf("%s << DEBUG [%d][%d].\n", __FUNCTION__, kkk, 3);
03480 
03481                         //printf("%s << dot1 = %f; dot2 = %f\n", __FUNCTION__, dot1, dot2);
03482 
03483                         double mag1 = pow(pow(rayVec1.x, 2) + pow(rayVec1.y, 2) + pow(rayVec1.z, 2), 0.5);
03484                         double mag2 = pow(pow(rayVec2.x, 2) + pow(rayVec2.y, 2) + pow(rayVec2.z, 2), 0.5);
03485 
03486                         //printf("%s << mag1 = %f; mag2 = %f\n", __FUNCTION__, mag1, mag2);
03487 
03488                         double ang1 = fmod(acos(dot1 / mag1), 2*M_PI);
03489                         double ang2 = fmod(acos(dot2 / mag2), 2*M_PI);
03490 
03491                         //printf("%s << ang1 = %f; ang2 = %f\n", __FUNCTION__, ang1, ang2);
03492                         // just try to check if angle is greater than 90deg from where each camera is facing to the pt
03493 
03494                         // get vector from each camera to the point
03495 
03496                         // use dot product to determine angle
03497                         if ((abs(ang1) < M_PI/2 ) || (abs(ang2) < M_PI/2)) {
03498                                 //printf("%s << ang1 = %f; ang2 = %f\n", __FUNCTION__, ang1, ang2);
03499                         //if ((dot1 < 0.0) || (dot2 < 0.0)) {
03500                                 validity = false;
03501                                 badCount++;
03502                         }
03503 
03504                         if (rayVec1.z < 0) {
03505                                 //printf("%s << rayVec1.z < 0; abs(ang1) = %f\n", __FUNCTION__, abs(ang1));
03506 
03507                         } else {
03508                                 //printf("%s << rayVec1.z >= 0; abs(ang1) = %f\n", __FUNCTION__, abs(ang1));
03509 
03510                         }
03511 
03512                         //cin.get();
03513 
03514                 }
03515 
03516                 printf("%s << badCount[%d] = %d\n", __FUNCTION__, zzz, badCount);
03517                 
03518                 if (zzz == 0) {
03519                         bestScore = badCount;
03520                 } else {
03521                         if (badCount < bestScore) {
03522                                 bestScore = badCount;
03523                                 bestIndex = zzz;
03524                         }
03525                 }
03526 
03527                 
03528         }
03529         
03530         if (bestScore == 0) {
03531                 validity = true;
03532         }
03533         
03534         // Should be 2 - but try different ones...
03535         if (useDefault) {
03536                 bestIndex = 2;
03537                 printf("%s << Defaulting to model #%d\n", __FUNCTION__, bestIndex);
03538         }
03539         
03540         findP1Matrix(P1, R_tmp[bestIndex], t_tmp[bestIndex]);
03541 
03542         R_tmp[bestIndex].copyTo(R);
03543         t_tmp[bestIndex].copyTo(t);
03544         
03545         return validity;
03546 }
03547 
03548 void initializeP0(cv::Mat& P) {
03549         P = cv::Mat::zeros(3, 4, CV_64FC1);
03550         P.at<double>(0,0) = 1.0;
03551         P.at<double>(0,1) = 0.0;
03552         P.at<double>(0,2) = 0.0;
03553         P.at<double>(0,3) = 0.0;
03554         P.at<double>(1,0) = 0.0;
03555         P.at<double>(1,1) = 1.0;
03556         P.at<double>(1,2) = 0.0;
03557         P.at<double>(1,3) = 0.0;
03558         P.at<double>(2,0) = 0.0;
03559         P.at<double>(2,1) = 0.0;
03560         P.at<double>(2,2) = 1.0;
03561         P.at<double>(2,3) = 0.0;
03562 }
03563 
03564 void LinearLSTriangulation(cv::Mat& dst, const cv::Point3d& u1, const cv::Mat& P1, const cv::Point3d& u2, const cv::Mat& P2) {
03565 
03566         // https://github.com/MasteringOpenCV/code/blob/master/Chapter4_StructureFromMotion/Triangulation.cpp
03567         // http://www.morethantechnical.com/2012/01/04/simple-triangulation-with-opencv-from-harley-zisserman-w-code/
03568         
03569         // dst  : 3D point (homogeneous?)
03570         // u1   : image 1 homogenous 2D point
03571         // P1   : image 1 camera projection (3,4)
03572         // u2   : image 2 homogenous 2D point
03573         // P2   : image 2 camera projection     
03574         
03575     // First, build matrix A for homogenous equation system Ax = 0
03576     
03577     cv::Mat A(4, 3, CV_64FC1);
03578     
03579     A.at<double>(0,0) = u1.x * P1.at<double>(2,0) - P1.at<double>(0,0);
03580     A.at<double>(0,1) = u1.x * P1.at<double>(2,1) - P1.at<double>(0,1);
03581     A.at<double>(0,2) = u1.x * P1.at<double>(2,2) - P1.at<double>(0,2);
03582     
03583     A.at<double>(1,0) = u1.y * P1.at<double>(2,0) - P1.at<double>(1,0);
03584     A.at<double>(1,1) = u1.y * P1.at<double>(2,1) - P1.at<double>(1,1);
03585     A.at<double>(1,2) = u1.y * P1.at<double>(2,2) - P1.at<double>(1,2);
03586     
03587     A.at<double>(2,0) = u2.x * P2.at<double>(2,0) - P2.at<double>(0,0);
03588     A.at<double>(2,1) = u2.x * P2.at<double>(2,1) - P2.at<double>(0,1);
03589     A.at<double>(2,2) = u2.x * P2.at<double>(2,2) - P2.at<double>(0,2);
03590     
03591     A.at<double>(3,0) = u2.y * P2.at<double>(2,0) - P2.at<double>(1,0);
03592     A.at<double>(3,1) = u2.y * P2.at<double>(2,1) - P2.at<double>(1,1);
03593     A.at<double>(3,2) = u2.y * P2.at<double>(2,2) - P2.at<double>(1,2);
03594 
03595         // Assume X = (x,y,z,1), for Linear-LS method
03596     
03597     // Which turns it into a AX = B system, where A is 4x3, X is 3x1 and B is 4x1
03598 
03599         cv::Mat B(4, 1, CV_64FC1);
03600         
03601         B.at<double>(0,0) = -((double) u1.x * P1.at<double>(2,3) - P1.at<double>(0,3));
03602         B.at<double>(0,1) = -((double) u1.y * P1.at<double>(2,3) - P1.at<double>(1,3));
03603         B.at<double>(0,2) = -((double) u2.x * P2.at<double>(2,3) - P2.at<double>(0,3));
03604         B.at<double>(0,3) = -((double) u2.y * P2.at<double>(2,3) - P2.at<double>(1,3));
03605  
03606     cv::solve(A, B, dst, cv::DECOMP_SVD);
03607 
03608 }
03609 
03610 void Triangulate_1(const cv::Point2d& pt1, const cv::Point2d& pt2, const cv::Mat& K, const cv::Mat& Kinv, const cv::Mat& P1, const cv::Mat& P2, cv::Point3d& xyzPoint, bool iterate) {
03611 
03612         cv::Mat C1, C2;
03613         projectionToTransformation(P1, C1);
03614         projectionToTransformation(P2, C2);
03615 
03616         cv::Mat U1(3, 1, CV_64FC1);
03617         U1.at<double>(0,0) = pt1.x;
03618         U1.at<double>(1,0) = pt1.y;
03619         U1.at<double>(2,0) = 1.0;
03620         cv::Mat UM1 = Kinv * U1;
03621         // Get the image point into normalized camera co-ordinates..
03622         cv::Point3d u1(UM1.at<double>(0,0), UM1.at<double>(1,0), UM1.at<double>(2,0));
03623         
03624         cv::Mat U2(3, 1, CV_64FC1);
03625         U2.at<double>(0,0) = pt2.x;
03626         U2.at<double>(1,0) = pt2.y;
03627         U2.at<double>(2,0) = 1.0;
03628         cv::Mat UM2 = Kinv * U2;
03629         // Get the image point into normalized camera co-ordinates..
03630         cv::Point3d u2(UM2.at<double>(0,0), UM2.at<double>(1,0), UM2.at<double>(2,0));
03631         
03632         // printf("%s << normalized co-ordinates = (%f, %f) & (%f, %f)\n", __FUNCTION__, u1.x, u1.y, u2.x, u2.y);
03633         
03634         cv::Mat X;
03635         
03636         if (iterate) {
03637                 IterativeLinearLSTriangulation(X, u1, C1, u2, C2);
03638                 
03639                 /*
03640                 cv::Mat C1X, C2X;
03641                 transformationToProjection(C1, C1X);
03642                 transformationToProjection(C2, C2X);
03643                 
03644                 cv::Mat U1X(2, 1, CV_64FC1);
03645                 U1X.at<double>(0,0) = UM1.at<double>(0,0);
03646                 U1X.at<double>(1,0) = UM1.at<double>(1,0);
03647                 cv::Mat U2X(2, 1, CV_64FC1);
03648                 U2X.at<double>(0,0) = UM2.at<double>(0,0);
03649                 U2X.at<double>(1,0) = UM2.at<double>(1,0);
03650                 
03651                 triangulatePoints(C1X, C2X, U1X, U2X, X);
03652                 */
03653                 
03654         } else {
03655                 LinearLSTriangulation(X, u1, C1, u2, C2);
03656         }
03657 
03658 
03659         xyzPoint = cv::Point3d(X.at<double>(0,0), X.at<double>(1,0), X.at<double>(2,0));
03660         
03661         //printf("%s << Points triangulated to (%f, %f, %f)\n", __FUNCTION__, xyzPoint.x, xyzPoint.y, xyzPoint.z);
03662 
03663 }
03664 
03665 void IterativeLinearLSTriangulation(cv::Mat& dst, const cv::Point3d& u1, const cv::Mat& P1, const cv::Point3d& u2, const cv::Mat& P2) {
03666         
03667     int maxIterations = 10; //Hartley suggests 10 iterations at most
03668     
03669     cv::Mat X(4, 1, CV_64FC1), XA;
03670     
03671     
03672     
03673     LinearLSTriangulation(XA, u1, P1, u2, P2);
03674 
03675     
03676     X.at<double>(0,0) = XA.at<double>(0,0);
03677         X.at<double>(1,0) = XA.at<double>(1,0); 
03678         X.at<double>(2,0) = XA.at<double>(2,0); 
03679         X.at<double>(3,0) = 1.0;
03680     
03681     double wi1 = 1.0, wi2 = 1.0;
03682     
03683     for (int i = 0; i < maxIterations; i++) {
03684  
03685         // recalculate weights
03686         cv::Mat P1X = P1.row(2) * X;
03687         double p1a = P1X.at<double>(0, 0);
03688         
03689         cv::Mat P2X = P2.row(2) * X;
03690         double p2a = P2X.at<double>(0, 0);
03691         
03692         // breaking point
03693         if ((fabsf(wi1 - p1a) <= EPSILON) && (fabsf(wi2 - p2a) <= EPSILON)) {
03694                         break;
03695                 } 
03696  
03697         wi1 = p1a;
03698         wi2 = p2a;
03699  
03700         // reweight equations and solve
03701         cv::Mat A(4, 3, CV_64FC1);
03702         
03703         A.at<double>(0,0) = (u1.x * P1.at<double>(2,0) - P1.at<double>(0,0)) / wi1;
03704         A.at<double>(0,1) = (u1.x * P1.at<double>(2,1) - P1.at<double>(0,1)) / wi1;
03705         A.at<double>(0,2) = (u1.x * P1.at<double>(2,2) - P1.at<double>(0,2)) / wi1;
03706         
03707         A.at<double>(1,0) = (u1.y * P1.at<double>(2,0) - P1.at<double>(1,0)) / wi1;
03708         A.at<double>(1,1) = (u1.y * P1.at<double>(2,1) - P1.at<double>(1,1)) / wi1;
03709         A.at<double>(1,2) = (u1.y * P1.at<double>(2,2) - P1.at<double>(1,2)) / wi1;
03710         
03711         A.at<double>(2,0) = (u2.x * P2.at<double>(2,0) - P2.at<double>(0,0)) / wi2;
03712         A.at<double>(2,1) = (u2.x * P2.at<double>(2,1) - P2.at<double>(0,1)) / wi2;
03713         A.at<double>(2,2) = (u2.x * P2.at<double>(2,2) - P2.at<double>(0,2)) / wi2;
03714         
03715         A.at<double>(3,0) = (u2.y * P2.at<double>(2,0) - P2.at<double>(1,0)) / wi2;
03716         A.at<double>(3,1) = (u2.y * P2.at<double>(2,1) - P2.at<double>(1,1)) / wi2;
03717         A.at<double>(3,2) = (u2.y * P2.at<double>(2,2) - P2.at<double>(1,2)) / wi2;
03718         
03719         cv::Mat B(4, 1, CV_64FC1);
03720         
03721         B.at<double>(0,0) = -(u1.x * P1.at<double>(2,3) - P1.at<double>(0,3)) / wi1;
03722         B.at<double>(1,0) = -(u1.y * P1.at<double>(2,3) - P1.at<double>(1,3)) / wi1;
03723         B.at<double>(2,0) = -(u2.x * P2.at<double>(2,3) - P2.at<double>(0,3)) / wi2;
03724         B.at<double>(3,0) = -(u2.y * P2.at<double>(2,3) - P2.at<double>(1,3)) / wi2;
03725 
03726         cv::solve(A, B, XA, cv::DECOMP_SVD);
03727 
03728         X.at<double>(0,0) = XA.at<double>(0,0);
03729         X.at<double>(1,0) = XA.at<double>(1,0); 
03730         X.at<double>(2,0) = XA.at<double>(2,0); 
03731         X.at<double>(3,0) = 1.0; 
03732         
03733     }
03734     
03735     X.copyTo(dst);
03736 
03737 }
03738 
03739 void getWandZ(cv::Mat& W, cv::Mat& Winv, cv::Mat& Z) {
03740         W = cv::Mat::zeros(3, 3, CV_64FC1);
03741         
03742         W.at<double>(0,0) = 0.0;
03743         W.at<double>(0,1) = -1.0;
03744         W.at<double>(0,2) = 0.0;
03745         
03746         W.at<double>(1,0) = 1.0;
03747         W.at<double>(1,1) = 0.0;
03748         W.at<double>(1,2) = 0.0;
03749         
03750         W.at<double>(2,0) = 0.0;
03751         W.at<double>(2,1) = 0.0;
03752         W.at<double>(2,2) = 1.0;
03753         
03754         Winv = cv::Mat::zeros(3, 3, CV_64FC1);
03755         
03756         Winv.at<double>(0,0) = 0.0;
03757         Winv.at<double>(0,1) = 1.0;
03758         Winv.at<double>(0,2) = 0.0;
03759         
03760         Winv.at<double>(1,0) = -1.0;
03761         Winv.at<double>(1,1) = 0.0;
03762         Winv.at<double>(1,2) = 0.0;
03763         
03764         Winv.at<double>(2,0) = 0.0;
03765         Winv.at<double>(2,1) = 0.0;
03766         Winv.at<double>(2,2) = 1.0;     
03767         
03768         Z = cv::Mat::zeros(3, 3, CV_64FC1);
03769         
03770         Z.at<double>(0,1) = 1.0;
03771         Z.at<double>(1,0) = -1.0;
03772 }
03773 
03774 void findP1Matrix(cv::Mat& P1, const cv::Mat& R, const cv::Mat& t) {
03775         //cv::Mat W, Winv, Z;
03776         
03777         //getWandZ(W, Z);
03778         //Winv = W.inv();
03779 
03780         //R = svd.u * W * svd.vt; //HZ 9.19
03781         //t = svd.u.col(2); //u3
03782         
03783         P1 = cv::Mat(3, 4, CV_64FC1);
03784                         
03785         P1.at<double>(0,0) = R.at<double>(0,0);
03786         P1.at<double>(0,1) = R.at<double>(0,1);
03787         P1.at<double>(0,2) = R.at<double>(0,2);
03788         P1.at<double>(0,3) = t.at<double>(0,0);
03789         
03790         P1.at<double>(1,0) = R.at<double>(1,0);
03791         P1.at<double>(1,1) = R.at<double>(1,1);
03792         P1.at<double>(1,2) = R.at<double>(1,2);
03793         P1.at<double>(1,3) = t.at<double>(1,0);
03794         
03795         P1.at<double>(2,0) = R.at<double>(2,0);
03796         P1.at<double>(2,1) = R.at<double>(2,1);
03797         P1.at<double>(2,2) = R.at<double>(2,2);
03798         P1.at<double>(2,3) = t.at<double>(2,0);
03799 }
03800 
03801 void Triangulate(const cv::Point2f& pt1, const cv::Point2f& pt2, const cv::Mat& K, const cv::Mat& Kinv, const cv::Mat& P1, const cv::Mat& P2, cv::Point3d& xyzPoint, bool debug) {
03802 
03803         cv::Mat C1, C2;
03804         projectionToTransformation(P1, C1);
03805         projectionToTransformation(P2, C2);
03806         
03807         // Relative
03808         cv::Mat P0, PR, C0, CR;
03809         initializeP0(P0);
03810         projectionToTransformation(P0, C0);
03811         CR = C2 * C1.inv();
03812         transformationToProjection(CR, PR);
03813 
03814         cv::Point3d xyzPoint_R;
03815 
03816         
03817         
03818         //cv::Point2f kp = pt1;
03819         cv::Point3d u_1(pt1.x, pt1.y, 1.0);
03820         cv::Mat umx1 = Kinv * cv::Mat(u_1);
03821         
03822         u_1.x = umx1.at<double>(0, 0);
03823         u_1.y = umx1.at<double>(1, 0);
03824         u_1.z = umx1.at<double>(2, 0);
03825         
03826         //cv::Point2f kp1 = pt2;
03827         cv::Point3d u_2(pt2.x, pt2.y,1.0);
03828         cv::Mat umx2 = Kinv * cv::Mat(u_2);
03829         
03830         u_2.x = umx2.at<double>(0, 0);
03831         u_2.y = umx2.at<double>(1, 0);
03832         u_2.z = umx2.at<double>(2, 0);
03833         
03834 
03835         
03836         cv::Mat X;
03837         //LinearLSTriangulation(X, u_1, P0, u_2, PR);
03838         IterativeLinearLSTriangulation(X, u_1, P0, u_2, PR);    // switched from u then u1
03839         
03840         xyzPoint_R = cv::Point3d( X.at<double>(0, 0), X.at<double>(1, 0), X.at<double>(2, 0) );
03841         
03842         cv::Mat A(4, 1, CV_64FC1), B(4, 1, CV_64FC1);
03843         
03844         A.at<double>(0,0) = xyzPoint_R.x;
03845         A.at<double>(1,0) = xyzPoint_R.y;
03846         A.at<double>(2,0) = xyzPoint_R.z;
03847         A.at<double>(3,0) = 1.0;
03848 
03849         
03850         B = C1 * A;
03851         
03852         xyzPoint.x = B.at<double>(0,0) / B.at<double>(3,0);
03853         xyzPoint.y = B.at<double>(1,0) / B.at<double>(3,0);
03854         xyzPoint.z = B.at<double>(2,0) / B.at<double>(3,0);
03855         
03856         if (debug) {
03857                 
03858                 printf("%s << DEBUG SUMMARY:\n", __FUNCTION__);
03859                 
03860                 
03861                 cout << endl << "P1 = " << P1 << endl;
03862                 cout << "P2 = " << P2 << endl;
03863                 cout << "P0 = " << P0 << endl;
03864                 cout << "PR = " << PR << endl;
03865                 cout << "C1 = " << C1 << endl << endl;
03866                 
03867                 printf("pt1 -> u_1 = (%f, %f), (%f, %f, %f)\n", pt1.x, pt1.y, u_1.x, u_1.y, u_1.z);
03868                 printf("pt2 -> u_2 = (%f, %f), (%f, %f, %f)\n\n", pt2.x, pt2.y, u_2.x, u_2.y, u_2.z);
03869 
03870                 printf("xyzPoint_R = (%f, %f, %f)\n", xyzPoint_R.x, xyzPoint_R.y, xyzPoint_R.z);
03871                 printf("xyzPoint = (%f, %f, %f)\n\n", xyzPoint.x, xyzPoint.y, xyzPoint.z);
03872                 
03873                 cin.get();
03874         }
03875         
03876 
03877 }
03878 
03879 void TriangulatePoints(const vector<cv::Point2f>& pt_set1,
03880                        const vector<cv::Point2f>& pt_set2,
03881                        const cv::Mat& K,
03882                        const cv::Mat& Kinv,
03883                        const cv::Mat& P,
03884                        const cv::Mat& P1,
03885                        vector<cv::Point3d>& pointcloud,
03886                        vector<cv::Point2f>& correspImg1Pt)
03887 {
03888  
03889     pointcloud.clear();
03890     correspImg1Pt.clear();
03891     
03892     cv::Point3d point_3;
03893 
03894     for (unsigned int iii = 0; iii < pt_set1.size(); iii++) {    
03895                 
03896                 Triangulate(pt_set1.at(iii), pt_set2.at(iii), K, Kinv,  P, P1, point_3, false);
03897                  
03898                 pointcloud.push_back(point_3);
03899                 correspImg1Pt.push_back(pt_set1[iii]);
03900         }
03901 }
03902 
03903 void findCentroid(vector<featureTrack>& tracks, cv::Point3d& centroid, cv::Point3d& stdDeviation) {
03904         
03905         unsigned int triangulatedPoints = 0;
03906         
03907         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
03908                 if (tracks.at(iii).isTriangulated) {
03909                         triangulatedPoints++;
03910                 }
03911         }
03912         
03913         printf("%s << triangulatedPoints = %d\n", __FUNCTION__, triangulatedPoints);
03914         
03915         centroid = cv::Point3d(0.0, 0.0, 0.0);
03916         stdDeviation = cv::Point3d(0.0, 0.0, 0.0);
03917         
03918         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
03919                 if (tracks.at(iii).isTriangulated) {
03920                         centroid.x += (tracks.at(iii).get3dLoc().x / ((double) triangulatedPoints));
03921                         centroid.y += (tracks.at(iii).get3dLoc().y / ((double) triangulatedPoints));
03922                         centroid.z += (tracks.at(iii).get3dLoc().z / ((double) triangulatedPoints));
03923                 }
03924         }
03925         
03926         for (unsigned int iii = 0; iii < tracks.size(); iii++) {
03927                 if (tracks.at(iii).isTriangulated) {
03928                         stdDeviation.x += (pow((tracks.at(iii).get3dLoc().x - centroid.x), 2.0) / ((double) triangulatedPoints));
03929                         stdDeviation.y += (pow((tracks.at(iii).get3dLoc().y - centroid.y), 2.0) / ((double) triangulatedPoints));
03930                         stdDeviation.z += (pow((tracks.at(iii).get3dLoc().z - centroid.z), 2.0) / ((double) triangulatedPoints));
03931                 }
03932                 
03933         }
03934         
03935         stdDeviation.x = pow(stdDeviation.x, 0.5);
03936         stdDeviation.y = pow(stdDeviation.y, 0.5);
03937         stdDeviation.z = pow(stdDeviation.z, 0.5);
03938         
03939 }
03940 


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