From b64592a921be9b21abd1890424c46cd1784cd9f0 Mon Sep 17 00:00:00 2001 From: Stephen Mather Date: Sun, 16 Aug 2015 08:49:41 -0400 Subject: [PATCH] Revert "Upgrade Bundler + add support for Ceres solver" Former-commit-id: 667ea4e8ffc90e51ce2db2882ad763742a3f51ec --- .gitignore | 2 +- .gitmodules | 6 - bundler.zip.REMOVED.git-id | 1 + install.sh | 47 +-- patched_files/src/bundler/src/KeyMatch.cpp | 124 ++++++ patched_files/src/bundler/src/Makefile | 82 ++++ patched_files/src/bundler/src/keys2a.cpp | 465 +++++++++++++++++++++ patched_files/src/bundler/src/keys2a.h | 110 +++++ run.pl | 1 - src/bundler | 1 - src/ceres-solver | 1 - 11 files changed, 798 insertions(+), 42 deletions(-) delete mode 100644 .gitmodules create mode 100644 bundler.zip.REMOVED.git-id create mode 100644 patched_files/src/bundler/src/KeyMatch.cpp create mode 100644 patched_files/src/bundler/src/Makefile create mode 100644 patched_files/src/bundler/src/keys2a.cpp create mode 100644 patched_files/src/bundler/src/keys2a.h delete mode 160000 src/bundler delete mode 160000 src/ceres-solver diff --git a/.gitignore b/.gitignore index 4a5be868..40869556 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ odm_texturing-build/ *.user cmvs.tar.gz parallel.tar.bz2 -pcl.tar.gz \ No newline at end of file +pcl.tar.gz diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index ca2530c3..00000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "src/bundler"] - path = src/bundler - url = https://github.com/chris-cooper/bundler_sfm -[submodule "src/ceres-solver"] - path = src/ceres-solver - url = https://ceres-solver.googlesource.com/ceres-solver diff --git a/bundler.zip.REMOVED.git-id b/bundler.zip.REMOVED.git-id new file mode 100644 index 00000000..0709de58 --- /dev/null +++ b/bundler.zip.REMOVED.git-id @@ -0,0 +1 @@ +adcbb33f758d9d13c5bf07348d048620b70dc392 \ No newline at end of file diff --git a/install.sh b/install.sh index 18d1f3c8..09d45459 100755 --- a/install.sh +++ b/install.sh @@ -31,15 +31,14 @@ echo " - script started - `date`" INC_PATH="/usr/local/include" ## source paths - BUNDLER_PATH="$TOOLS_SRC_PATH/bundler" - CMVS_PATH="$TOOLS_SRC_PATH/cmvs" - PMVS_PATH="$TOOLS_SRC_PATH/pmvs" - CLAPACK_PATH="$TOOLS_SRC_PATH/clapack" - VLFEAT_PATH="$TOOLS_SRC_PATH/vlfeat" - PARALLEL_PATH="$TOOLS_SRC_PATH/parallel" - PSR_PATH="$TOOLS_SRC_PATH/PoissonRecon" - GRACLUS_PATH="$TOOLS_SRC_PATH/graclus" - CERES_PATH="$TOOLS_SRC_PATH/ceres-solver" + BUNDLER_PATH="$TOOLS_SRC_PATH/bundler" + CMVS_PATH="$TOOLS_SRC_PATH/cmvs" + PMVS_PATH="$TOOLS_SRC_PATH/pmvs" + CLAPACK_PATH="$TOOLS_SRC_PATH/clapack" + VLFEAT_PATH="$TOOLS_SRC_PATH/vlfeat" + PARALLEL_PATH="$TOOLS_SRC_PATH/parallel" + PSR_PATH="$TOOLS_SRC_PATH/PoissonRecon" + GRACLUS_PATH="$TOOLS_SRC_PATH/graclus" PCL_PATH="$TOOLS_SRC_PATH/pcl" ODM_MESHING_PATH="$TOOLS_SRC_PATH/odm_meshing" @@ -104,10 +103,6 @@ uname -a > "$TOOLS_LOG_PATH/sysinfo.txt" echo echo " > installing required packages" -echo " - installing git submodules" -git submodule init -git submodule update - echo " - updating" sudo apt-get update --assume-yes > "$TOOLS_LOG_PATH/apt-get_get.log" 2>&1 @@ -125,7 +120,6 @@ sudo apt-get install --assume-yes --install-recommends \ libzip-dev \ libswitch-perl libjson-perl \ libcv-dev libcvaux-dev libopencv-dev \ - libgoogle-glog-dev libatlas-base-dev libsuitesparse-dev \ > "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1 else sudo apt-get install --assume-yes --install-recommends \ @@ -139,7 +133,6 @@ sudo apt-get install --assume-yes --install-recommends \ libzip-dev \ libswitch-perl \ libcv-dev libcvaux-dev libopencv-dev \ - libgoogle-glog-dev libatlas-base-dev libsuitesparse-dev \ > "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1 fi @@ -168,6 +161,7 @@ do done < cmvs/pmvs" echo " < done - `date`" echo -echo " > ceres" - cd "$CERES_PATH" - - echo " - configuring ceres" - mkdir -p build - cd build - cmake .. -DCMAKE_INSTALL_PREFIX=$TOOLS_PATH \ - -DCMAKE_C_FLAGS=-fPIC -DCMAKE_CXX_FLAGS=-fPIC \ - -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF > "$TOOLS_LOG_PATH/ceres_1_config.log" 2>&1 - - echo " - building ceres" - make install > "$TOOLS_LOG_PATH/ceres_1_build.log" 2>&1 - -echo " < done - `date`" -echo echo " > bundler" cd "$BUNDLER_PATH" + sed -i "$BUNDLER_PATH/src/BundlerApp.h" -e "620c\ BundlerApp();" + echo " - cleaning bundler" make clean > "$TOOLS_LOG_PATH/bundler_1_clean.log" 2>&1 echo " - building bundler" make -j > "$TOOLS_LOG_PATH/bundler_2_build.log" 2>&1 - ln -s "$BUNDLER_PATH/bin/Bundle2PMVS" "$BUNDLER_PATH/bin/Bundle2Vis" "$BUNDLER_PATH/bin/KeyMatchFull" "$BUNDLER_PATH/bin/KeyMatch" "$BUNDLER_PATH/bin/bundler" "$BUNDLER_PATH/bin/RadialUndistort" "$TOOLS_BIN_PATH/" + cp -f "$BUNDLER_PATH/bin/Bundle2PMVS" "$BUNDLER_PATH/bin/Bundle2Vis" "$BUNDLER_PATH/bin/KeyMatchFull" "$BUNDLER_PATH/bin/KeyMatch" "$BUNDLER_PATH/bin/bundler" "$BUNDLER_PATH/bin/RadialUndistort" "$TOOLS_BIN_PATH/" - ln -s "$BUNDLER_PATH/lib/libANN_char.so" "$TOOLS_LIB_PATH/" + cp -f "$BUNDLER_PATH/lib/libANN_char.so" "$TOOLS_LIB_PATH/" echo " < done - `date`" echo diff --git a/patched_files/src/bundler/src/KeyMatch.cpp b/patched_files/src/bundler/src/KeyMatch.cpp new file mode 100644 index 00000000..87017b94 --- /dev/null +++ b/patched_files/src/bundler/src/KeyMatch.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2008-2010 Noah Snavely (snavely (at) cs.cornell.edu) + * and the University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* KeyMatch.cpp */ +/* Read in keys, match, write results to a file */ + +#include +#include +#include + +#include "keys2a.h" + +int main(int argc, char **argv) { + char *keys1_in; + char *keys2_in; + char *file_out; + double ratio, threshold; + + if (argc != 6) { + printf("Usage: %s \n", argv[0]); + return -1; + } + + keys1_in = argv[1]; + keys2_in = argv[2]; + file_out = argv[3]; + + ratio = atof(argv[4]); + threshold = atof(argv[5]); + + clock_t start = clock(); + + unsigned char *keys1, *keys2; + + int num1 = ReadKeyFile(keys1_in, &keys1); + int num2 = ReadKeyFile(keys2_in, &keys2); + + + /* Compute likely matches between two sets of keypoints */ + std::vector matches = + MatchKeys(num1, keys1, num2, keys2, ratio); + +#if 0 + std::vector matches_sym = + MatchKeys(num2, keys2, num1, keys1); +#endif + + int num_matches = (int) matches.size(); + // int num_matches_sym = (int) matches_sym.size(); + + // printf("num_matches = %d\n", num_matches); + // printf("num_matches_sym = %d\n", num_matches_sym); + +#if 0 + /* Prune asymmetric matches */ + for (int i = 0; i < num_matches; i++) { + int idx1 = matches[i].m_idx1; + int idx2 = matches[i].m_idx2; + + for (int j = 0; j < num_matches_sym; j++) { + if (matches_sym[j].m_idx1 == idx2) { + if (matches_sym[j].m_idx2 != idx1) { + matches.erase(matches.begin() + i); + i--; + num_matches--; + } + + break; + } + } + } +#endif + + clock_t end = clock(); + + int m = (num1 < num2 ? num1 : num2); + float r = ((float)num_matches * 100 / m); + + bool used = false; + + if (num_matches >= 16 && r > threshold) { + used = true; + + FILE *f = fopen(file_out, "w"); + + /* Write the number of matches */ + fprintf(f, "%d\n", (int) matches.size()); + + for (int i = 0; i < num_matches; i++) { + fprintf(f, "%d %d\n", matches[i].m_idx1, matches[i].m_idx2); + } + + fclose(f); + } + + + if(used) printf("\n%8d matches (%4.1f%%) took %5.2fs for %s\t", + num_matches, + r, + (end - start) / ((double) CLOCKS_PER_SEC), + file_out); + + +/* printf("%8d matches = %5.2f%% %d in %6.3fs in %s\n", + num_matches, + r, + m, + (end - start) / ((double) CLOCKS_PER_SEC), + file_out); + */ +} diff --git a/patched_files/src/bundler/src/Makefile b/patched_files/src/bundler/src/Makefile new file mode 100644 index 00000000..f7aaf13a --- /dev/null +++ b/patched_files/src/bundler/src/Makefile @@ -0,0 +1,82 @@ +# Makefile for bundler + +CC=gcc +OPTFLAGS=-O3 -Wall + +OS=$(shell uname -o) + +ifeq ($(OS), Cygwin) +BUNDLER=bundler.exe +KEYMATCHFULL=KeyMatchFull.exe +KEYMATCH=KeyMatch.exe +BUNDLE2PMVS=Bundle2PMVS.exe +BUNDLE2VIS=Bundle2Vis.exe +RADIALUNDISTORT=RadialUndistort.exe +else +BUNDLER=bundler +KEYMATCHFULL=KeyMatchFull +KEYMATCH=KeyMatch +BUNDLE2PMVS=Bundle2PMVS +BUNDLE2VIS=Bundle2Vis +RADIALUNDISTORT=RadialUndistort +endif + +INCLUDE_PATH=-I../lib/imagelib -I../lib/sfm-driver -I../lib/matrix \ + -I../lib/5point -I../lib/sba-1.5 -I../lib/ann_1.1_char/include + +LIB_PATH=-L../lib -L../lib/ann_1.1_char/lib + +CPPFLAGS=$(OPTFLAGS) $(OTHERFLAGS) $(INCLUDE_PATH) $(DEFINES) + +BUNDLER_DEFINES=-D__NO_UI__ -D__BUNDLER__ -D__BUNDLER_DISTR__ + +BUNDLER_OBJS=BaseApp.o BundlerApp.o keys.o Register.o Epipolar.o \ + Bundle.o BundleFast.o MatchTracks.o Camera.o Geometry.o \ + ImageData.o SifterUtil.o BaseGeometry.o BundlerGeometry.o \ + BoundingBox.o BundleAdd.o ComputeTracks.o BruteForceSearch.o \ + BundleIO.o ProcessBundle.o BundleTwo.o Decompose.o \ + RelativePose.o Distortion.o TwoFrameModel.o LoadJPEG.o + +BUNDLER_LIBS=-limage -lsfmdrv -lsba.v1.5 -lmatrix -lz -llapack -lblas \ + -lcblas -lminpack -lm -l5point -ljpeg -lANN_char -lgfortran + + +all: $(BUNDLER) $(KEYMATCHFULL) $(KEYMATCH) $(BUNDLE2PMVS) $(BUNDLE2VIS) $(RADIALUNDISTORT) + +%.o : %.cpp + $(CXX) -c -o $@ $(CPPFLAGS) $(WXFLAGS) $(BUNDLER_DEFINES) $< + +$(BUNDLER): $(BUNDLER_OBJS) + $(CXX) -o $@ $(CPPFLAGS) $(LIB_PATH) \ + $(BUNDLER_DEFINES) $(BUNDLER_OBJS) $(BUNDLER_LIBS) + cp $@ ../bin + +$(KEYMATCHFULL): KeyMatchFull.o keys2a.o + $(CXX) -o $@ $(CPPFLAGS) $(LIB_PATH) KeyMatchFull.o keys2a.o \ + -lANN_char -lz + cp $@ ../bin + +$(KEYMATCH): KeyMatch.o keys2a.o + $(CXX) -o $@ $(CPPFLAGS) $(LIB_PATH) KeyMatch.o keys2a.o \ + -lANN_char -lz + cp $@ ../bin + +$(BUNDLE2PMVS): Bundle2PMVS.o LoadJPEG.o + $(CXX) -o $@ $(CPPFLAGS) $(LIB_PATH) Bundle2PMVS.o LoadJPEG.o \ + -limage -lmatrix -llapack -lblas -lcblas -lgfortran \ + -lminpack -ljpeg + cp $@ ../bin + +$(BUNDLE2VIS): Bundle2Vis.o + $(CXX) -o $@ $(CPPFLAGS) $(LIB_PATH) Bundle2Vis.o + cp $@ ../bin + +$(RADIALUNDISTORT): RadialUndistort.o LoadJPEG.o + $(CXX) -o $@ $(CPPFLAGS) $(LIB_PATH) $^ \ + -limage -lmatrix -llapack -lblas -lcblas -lgfortran \ + -lminpack -ljpeg + cp $@ ../bin + +clean: + rm -f *.o *~ $(BUNDLER) $(KEYMATCHFULL) $(KEYMATCH) $(BUNDLE2PMVS) \ + $(BUNDLE2VIS) $(RADIALUNDISTORT) diff --git a/patched_files/src/bundler/src/keys2a.cpp b/patched_files/src/bundler/src/keys2a.cpp new file mode 100644 index 00000000..ff75700d --- /dev/null +++ b/patched_files/src/bundler/src/keys2a.cpp @@ -0,0 +1,465 @@ +/* +* Copyright (c) 2008-2010 Noah Snavely (snavely (at) cs.cornell.edu) +* and the University of Washington +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ + +/* keys2.cpp */ +/* Class for SIFT keypoints */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "keys2a.h" + +int GetNumberOfKeysNormal(FILE *fp) +{ + int num, len; + + if (fscanf(fp, "%d %d", &num, &len) != 2) { + printf("Invalid keypoint file.\n"); + return 0; + } + + return num; +} + +int GetNumberOfKeysGzip(gzFile fp) +{ + int num, len; + + char header[256]; + gzgets(fp, header, 256); + + if (sscanf(header, "%d %d", &num, &len) != 2) { + printf("Invalid keypoint file.\n"); + return 0; + } + + return num; +} + +/* Returns the number of keys in a file */ +int GetNumberOfKeys(const char *filename) +{ + FILE *file; + + file = fopen (filename, "r"); + if (! file) { + /* Try to file a gzipped keyfile */ + char buf[1024]; + sprintf(buf, "%s.gz", filename); + gzFile gzf = gzopen(buf, "rb"); + + if (gzf == NULL) { + printf("Could not open file: %s\n", filename); + return 0; + } else { + int n = GetNumberOfKeysGzip(gzf); + gzclose(gzf); + return n; + } + } + + int n = GetNumberOfKeysNormal(file); + fclose(file); + return n; +} + +/* This reads a keypoint file from a given filename and returns the list +* of keypoints. */ +int ReadKeyFile(const char *filename, unsigned char **keys, keypt_t **info) +{ + FILE *file; + + file = fopen (filename, "r"); + if (! file) { + /* Try to file a gzipped keyfile */ + char buf[1024]; + sprintf(buf, "%s.bin", filename); + FILE *binfile = fopen(buf, "rb"); + + if (binfile == NULL) { + printf("Could not open file: %s\n", filename); + return 0; + } else { + int n = ReadKeysBin(binfile, keys, info); + fclose(binfile); + return n; + } + } + + int n = ReadKeys(file, keys, info); + fclose(file); + return n; + + // return ReadKeysMMAP(file); +} + +#if 0 +/* Read keys using MMAP to speed things up */ +std::vector ReadKeysMMAP(FILE *fp) +{ + int i, j, num, len, val, n; + + std::vector kps; + + struct stat sb; + + /* Stat the file */ + if (fstat(fileno(fp), &sb) < 0) { + printf("[ReadKeysMMAP] Error: could not stat file\n"); + return kps; + } + + char *file = (char *)mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, + fileno(fp), 0); + + char *file_start = file; + + if (sscanf(file, "%d %d%n", &num, &len, &n) != 2) { + printf("[ReadKeysMMAP] Invalid keypoint file beginning."); + return kps; + } + + file += n; + + if (len != 128) { + printf("[ReadKeysMMAP] Keypoint descriptor length invalid " + "(should be 128)."); + return kps; + } + + for (i = 0; i < num; i++) { + /* Allocate memory for the keypoint. */ + unsigned char *d = new unsigned char[len]; + float x, y, scale, ori; + + if (sscanf(file, "%f %f %f %f%n", &y, &x, &scale, &ori, &n) != 4) { + printf("[ReadKeysMMAP] Invalid keypoint file format."); + return kps; + } + + file += n; + + for (j = 0; j < len; j++) { + if (sscanf(file, "%d%n", &val, &n) != 1 || val < 0 || val > 255) { + printf("[ReadKeysMMAP] Invalid keypoint file value."); + return kps; + } + d[j] = (unsigned char) val; + file += n; + } + + kps.push_back(new Keypoint(x, y, scale, ori, d)); + } + + /* Unmap */ + if (munmap(file_start, sb.st_size) < 0) { + printf("[ReadKeysMMAP] Error: could not unmap memory\n"); + return kps; + } + + return kps; +} +#endif + +/* Read keypoints from the given file pointer and return the list of +* keypoints. The file format starts with 2 integers giving the total +* number of keypoints and the size of descriptor vector for each +* keypoint (currently assumed to be 128). Then each keypoint is +* specified by 4 floating point numbers giving subpixel row and +* column location, scale, and orientation (in radians from -PI to +* PI). Then the descriptor vector for each keypoint is given as a +* list of integers in range [0,255]. */ +int ReadKeys(FILE *fp, unsigned char **keys, keypt_t **info) +{ + int i, num, len; + + std::vector kps; + + if (fscanf(fp, "%d %d", &num, &len) != 2) { + printf("Invalid keypoint file\n"); + return 0; + } + + if (len != 128) { + printf("Keypoint descriptor length invalid (should be 128)."); + return 0; + } + + *keys = new unsigned char[128 * num + 8]; + + if (info != NULL) + *info = new keypt_t[num]; + + unsigned char *p = *keys; + for (i = 0; i < num; i++) { + /* Allocate memory for the keypoint. */ + // short int *d = new short int[128]; + float x, y, scale, ori; + + if (fscanf(fp, "%f %f %f %f\n", &y, &x, &scale, &ori) != 4) { + printf("Invalid keypoint file format."); + return 0; + } + + if (info != NULL) { + (*info)[i].x = x; + (*info)[i].y = y; + (*info)[i].scale = scale; + (*info)[i].orient = ori; + } + + char buf[1024]; + for (int line = 0; line < 7; line++) { + fgets(buf, 1024, fp); + + if (line < 6) { + sscanf(buf, + "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu " + "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu", + p+0, p+1, p+2, p+3, p+4, p+5, p+6, p+7, p+8, p+9, + p+10, p+11, p+12, p+13, p+14, + p+15, p+16, p+17, p+18, p+19); + + p += 20; + } else { + sscanf(buf, + "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu", + p+0, p+1, p+2, p+3, p+4, p+5, p+6, p+7); + p += 8; + } + } + } + + return num; // kps; +} + +int ReadKeysBin(FILE* fp, unsigned char **keys, keypt_t **info) +{ + + int32_t num_keys; + fread(&num_keys, sizeof(int), 1, fp); +// printf("num_keys: %d\n", num_keys); + + + *keys = new unsigned char[128 * num_keys + 8]; + + if (info != NULL) + *info = new keypt_t[num_keys]; + + unsigned char *p = *keys; + for (int i = 0; i < num_keys; i++) { + /* Allocate memory for the keypoint. */ + // short int *d = new short int[128]; + float x, y, scale, ori; + + fread(&x, sizeof(float), 1, fp); + fread(&y, sizeof(float), 1, fp); + fread(&scale, sizeof(float), 1, fp); + fread(&ori, sizeof(float), 1, fp); + + if (info != NULL) { + (*info)[i].x = x; + (*info)[i].y = y; + (*info)[i].scale = scale; + (*info)[i].orient = ori; + } + + fread(p, sizeof(unsigned char), 128, fp); + +// printf("key %d: %f, %f, %f, %f - %d\n", i, x, y, scale, ori, *p); + + p += 128; + } + + + return num_keys; +} +int ReadKeysGzip(gzFile fp, unsigned char **keys, keypt_t **info) +{ + int i, num, len; + + std::vector kps; + char header[256]; + gzgets(fp, header, 256); + + if (sscanf(header, "%d %d", &num, &len) != 2) { + printf("Invalid keypoint file.\n"); + return 0; + } + + if (len != 128) { + printf("Keypoint descriptor length invalid (should be 128)."); + return 0; + } + + *keys = new unsigned char[128 * num + 8]; + + if (info != NULL) + *info = new keypt_t[num]; + + unsigned char *p = *keys; + for (i = 0; i < num; i++) { + /* Allocate memory for the keypoint. */ + // short int *d = new short int[128]; + float x, y, scale, ori; + char buf[1024]; + gzgets(fp, buf, 1024); + + if (sscanf(buf, "%f %f %f %f\n", &y, &x, &scale, &ori) != 4) { + printf("Invalid keypoint file format."); + return 0; + } + + if (info != NULL) { + (*info)[i].x = x; + (*info)[i].y = y; + (*info)[i].scale = scale; + (*info)[i].orient = ori; + } + + for (int line = 0; line < 7; line++) { + char *str = gzgets(fp, buf, 1024); + assert(str != Z_NULL); + + if (line < 6) { + sscanf(buf, + "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu " + "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu", + p+0, p+1, p+2, p+3, p+4, p+5, p+6, p+7, p+8, p+9, + p+10, p+11, p+12, p+13, p+14, + p+15, p+16, p+17, p+18, p+19); + + p += 20; + } else { + sscanf(buf, + "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu", + p+0, p+1, p+2, p+3, p+4, p+5, p+6, p+7); + p += 8; + } + } + } + + assert(p == *keys + 128 * num); + + return num; // kps; +} + +/* Create a search tree for the given set of keypoints */ +ANNkd_tree *CreateSearchTree(int num_keys, unsigned char *keys) +{ + // clock_t start = clock(); + + /* Create a new array of points */ + ANNpointArray pts = annAllocPts(num_keys, 128); + + for (int i = 0; i < num_keys; i++) { + memcpy(pts[i], keys + 128 * i, sizeof(unsigned char) * 128); + } + + /* Create a search tree for k2 */ + ANNkd_tree *tree = new ANNkd_tree(pts, num_keys, 128, 16); + // clock_t end = clock(); + + // printf("Building tree took %0.3fs\n", + // (end - start) / ((double) CLOCKS_PER_SEC)); + + return tree; +} + +std::vector MatchKeys(int num_keys1, unsigned char *k1, + ANNkd_tree *tree2, + double ratio, int max_pts_visit) +{ + annMaxPtsVisit(max_pts_visit); + std::vector matches; + + /* Now do the search */ + // clock_t start = clock(); + for (int i = 0; i < num_keys1; i++) { + ANNidx nn_idx[2]; + ANNdist dist[2]; + + tree2->annkPriSearch(k1 + 128 * i, 2, nn_idx, dist, 0.0); + + if (((double) dist[0]) < ratio * ratio * ((double) dist[1])) { + matches.push_back(KeypointMatch(i, nn_idx[0])); + } + } + // clock_t end = clock(); + + // printf("Searching tree took %0.3fs\n", + // (end - start) / ((double) CLOCKS_PER_SEC)); + + return matches; +} + +/* Compute likely matches between two sets of keypoints */ +std::vector MatchKeys(int num_keys1, unsigned char *k1, + int num_keys2, unsigned char *k2, + double ratio, int max_pts_visit) +{ + annMaxPtsVisit(max_pts_visit); + + int num_pts = 0; + std::vector matches; + + num_pts = num_keys2; + clock_t start = clock(); + + /* Create a new array of points */ + ANNpointArray pts = annAllocPts(num_pts, 128); + + for (int i = 0; i < num_pts; i++) { + memcpy(pts[i], k2 + 128 * i, sizeof(unsigned char) * 128); + } + + /* Create a search tree for k2 */ + ANNkd_tree *tree = new ANNkd_tree(pts, num_pts, 128, 16); + clock_t end = clock(); + + // printf("Building tree took %0.3fs\n", + // (end - start) / ((double) CLOCKS_PER_SEC)); + + /* Now do the search */ + start = clock(); + for (int i = 0; i < num_keys1; i++) { + ANNidx nn_idx[2]; + ANNdist dist[2]; + + tree->annkPriSearch(k1 + 128 * i, 2, nn_idx, dist, 0.0); + + if (((double) dist[0]) < ratio * ratio * ((double) dist[1])) { + matches.push_back(KeypointMatch(i, nn_idx[0])); + } + } + end = clock(); + // printf("Searching tree took %0.3fs\n", + // (end - start) / ((double) CLOCKS_PER_SEC)); + + /* Cleanup */ + annDeallocPts(pts); + // annDeallocPt(axis_weights); + + delete tree; + + return matches; +} diff --git a/patched_files/src/bundler/src/keys2a.h b/patched_files/src/bundler/src/keys2a.h new file mode 100644 index 00000000..805eeff8 --- /dev/null +++ b/patched_files/src/bundler/src/keys2a.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2008-2010 Noah Snavely (snavely (at) cs.cornell.edu) + * and the University of Washington + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* keys2a.h */ +/* Class for SIFT keypoints */ + +#ifndef __keys2a_h__ +#define __keys2a_h__ + +#include +#include + +#include + +#include "ANN/ANN.h" + +using namespace ann_1_1_char; + +class Keypoint { +public: + Keypoint(float x, float y, float scale, float ori, short int *d) : + m_x(x), m_y(y), m_scale(scale), m_ori(ori), m_d(d) + { } + + float m_x, m_y; /* Subpixel location of keypoint. */ + float m_scale, m_ori; /* Scale and orientation (range [-PI,PI]) */ + short int *m_d; /* Vector of descriptor values */ +}; + + +/* Data struct for matches */ +class KeypointMatch { +public: + KeypointMatch() + { } + +#if 0 + KeypointMatch(int idx1, int idx2, float x1, float y1, float x2, float y2) : + m_idx1(idx1), m_idx2(idx2), m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) + { } +#endif + + KeypointMatch(int idx1, int idx2) : + m_idx1(idx1), m_idx2(idx2) + { } + + int m_idx1, m_idx2; + // float m_x1, m_y1; + // float m_x2, m_y2; +}; + +typedef struct { + float x, y; + float scale; + float orient; +} keypt_t; + +/* Returns the number of keys in a file */ +int GetNumberOfKeys(const char *filename); + +/* This reads a keypoint file from a given filename and returns the list + * of keypoints. */ +int ReadKeyFile(const char *filename, unsigned char **keys, + keypt_t **info = NULL); + +int ReadKeyPositions(const char *filename, keypt_t **info); + +/* Read keypoints from the given file pointer and return the list of + * keypoints. The file format starts with 2 integers giving the total + * number of keypoints and the size of descriptor vector for each + * keypoint (currently assumed to be 128). Then each keypoint is + * specified by 4 floating point numbers giving subpixel row and + * column location, scale, and orientation (in radians from -PI to + * PI). Then the descriptor vector for each keypoint is given as a + * list of integers in range [0,255]. */ +int ReadKeys(FILE *fp, unsigned char **keys, keypt_t **info = NULL); +int ReadKeysBin(FILE *fp, unsigned char **keys, keypt_t **info = NULL); +int ReadKeysGzip(gzFile fp, unsigned char **keys, keypt_t **info = NULL); + +/* Read keys using MMAP to speed things up */ +std::vector ReadKeysMMAP(FILE *fp); + +/* Create a search tree for the given set of keypoints */ +ANNkd_tree *CreateSearchTree(int num_keys, unsigned char *keys); + +/* Compute likely matches between two sets of keypoints */ +std::vector MatchKeys(int num_keys1, unsigned char *k1, + int num_keys2, unsigned char *k2, + double ratio = 0.6, + int max_pts_visit = 200); + +std::vector MatchKeys(int num_keys1, unsigned char *k1, + ANNkd_tree *tree2, + double ratio = 0.6, + int max_pts_visit = 200); + +#endif /* __keys2_h__ */ diff --git a/run.pl b/run.pl index 7e56b349..df708f7f 100755 --- a/run.pl +++ b/run.pl @@ -684,7 +684,6 @@ sub bundler { $bundlerOptions .= "--constrain_focal\n"; $bundlerOptions .= "--constrain_focal_weight 0.0\n"; $bundlerOptions .= "--estimate_distortion\n"; - $bundlerOptions .= "--use_ceres\n"; $bundlerOptions .= "--run_bundle"; system("echo \"$bundlerOptions\" > \"$jobOptions{step_3_bundlerOptions}\""); diff --git a/src/bundler b/src/bundler deleted file mode 160000 index b34cc5dc..00000000 --- a/src/bundler +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b34cc5dcd54345272028b68f82fa4d0ae8a103c9 diff --git a/src/ceres-solver b/src/ceres-solver deleted file mode 160000 index b0696f62..00000000 --- a/src/ceres-solver +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b0696f6269d12abc6ea63083d565fe2ec8172da9