kopia lustrzana https://github.com/OpenDroneMap/ODM
Merge remote-tracking branch 'OpenDroneMap/gh-pages' into gh-pages
commit
c6932c459d
|
@ -8,4 +8,4 @@ odm_texturing-build/
|
||||||
*.user
|
*.user
|
||||||
cmvs.tar.gz
|
cmvs.tar.gz
|
||||||
parallel.tar.bz2
|
parallel.tar.bz2
|
||||||
pcl.tar.gz
|
pcl.tar.gz
|
||||||
|
|
|
@ -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
|
|
Plik binarny nie jest wyświetlany.
47
install.sh
47
install.sh
|
@ -31,15 +31,14 @@ echo " - script started - `date`"
|
||||||
INC_PATH="/usr/local/include"
|
INC_PATH="/usr/local/include"
|
||||||
|
|
||||||
## source paths
|
## source paths
|
||||||
BUNDLER_PATH="$TOOLS_SRC_PATH/bundler"
|
BUNDLER_PATH="$TOOLS_SRC_PATH/bundler"
|
||||||
CMVS_PATH="$TOOLS_SRC_PATH/cmvs"
|
CMVS_PATH="$TOOLS_SRC_PATH/cmvs"
|
||||||
PMVS_PATH="$TOOLS_SRC_PATH/pmvs"
|
PMVS_PATH="$TOOLS_SRC_PATH/pmvs"
|
||||||
CLAPACK_PATH="$TOOLS_SRC_PATH/clapack"
|
CLAPACK_PATH="$TOOLS_SRC_PATH/clapack"
|
||||||
VLFEAT_PATH="$TOOLS_SRC_PATH/vlfeat"
|
VLFEAT_PATH="$TOOLS_SRC_PATH/vlfeat"
|
||||||
PARALLEL_PATH="$TOOLS_SRC_PATH/parallel"
|
PARALLEL_PATH="$TOOLS_SRC_PATH/parallel"
|
||||||
PSR_PATH="$TOOLS_SRC_PATH/PoissonRecon"
|
PSR_PATH="$TOOLS_SRC_PATH/PoissonRecon"
|
||||||
GRACLUS_PATH="$TOOLS_SRC_PATH/graclus"
|
GRACLUS_PATH="$TOOLS_SRC_PATH/graclus"
|
||||||
CERES_PATH="$TOOLS_SRC_PATH/ceres-solver"
|
|
||||||
|
|
||||||
PCL_PATH="$TOOLS_SRC_PATH/pcl"
|
PCL_PATH="$TOOLS_SRC_PATH/pcl"
|
||||||
ODM_MESHING_PATH="$TOOLS_SRC_PATH/odm_meshing"
|
ODM_MESHING_PATH="$TOOLS_SRC_PATH/odm_meshing"
|
||||||
|
@ -104,10 +103,6 @@ uname -a > "$TOOLS_LOG_PATH/sysinfo.txt"
|
||||||
echo
|
echo
|
||||||
echo " > installing required packages"
|
echo " > installing required packages"
|
||||||
|
|
||||||
echo " - installing git submodules"
|
|
||||||
git submodule init
|
|
||||||
git submodule update
|
|
||||||
|
|
||||||
echo " - updating"
|
echo " - updating"
|
||||||
sudo apt-get update --assume-yes > "$TOOLS_LOG_PATH/apt-get_get.log" 2>&1
|
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 \
|
libzip-dev \
|
||||||
libswitch-perl libjson-perl \
|
libswitch-perl libjson-perl \
|
||||||
libcv-dev libcvaux-dev libopencv-dev \
|
libcv-dev libcvaux-dev libopencv-dev \
|
||||||
libgoogle-glog-dev libatlas-base-dev libsuitesparse-dev \
|
|
||||||
> "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1
|
> "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1
|
||||||
else
|
else
|
||||||
sudo apt-get install --assume-yes --install-recommends \
|
sudo apt-get install --assume-yes --install-recommends \
|
||||||
|
@ -139,7 +133,6 @@ sudo apt-get install --assume-yes --install-recommends \
|
||||||
libzip-dev \
|
libzip-dev \
|
||||||
libswitch-perl \
|
libswitch-perl \
|
||||||
libcv-dev libcvaux-dev libopencv-dev \
|
libcv-dev libcvaux-dev libopencv-dev \
|
||||||
libgoogle-glog-dev libatlas-base-dev libsuitesparse-dev \
|
|
||||||
> "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1
|
> "$TOOLS_LOG_PATH/apt-get_install.log" 2>&1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -168,6 +161,7 @@ do
|
||||||
done <<EOF
|
done <<EOF
|
||||||
parallel.tar.bz2 http://ftp.gnu.org/gnu/parallel/parallel-20141022.tar.bz2
|
parallel.tar.bz2 http://ftp.gnu.org/gnu/parallel/parallel-20141022.tar.bz2
|
||||||
clapack.tgz http://www.netlib.org/clapack/clapack-3.2.1-CMAKE.tgz
|
clapack.tgz http://www.netlib.org/clapack/clapack-3.2.1-CMAKE.tgz
|
||||||
|
bundler.zip http://phototour.cs.washington.edu/bundler/distr/bundler-v0.4-source.zip
|
||||||
PoissonRecon.zip http://www.cs.jhu.edu/~misha/Code/PoissonRecon/Version2/PoissonRecon.zip
|
PoissonRecon.zip http://www.cs.jhu.edu/~misha/Code/PoissonRecon/Version2/PoissonRecon.zip
|
||||||
vlfeat.tar.gz http://www.vlfeat.org/download/vlfeat-0.9.13-bin.tar.gz
|
vlfeat.tar.gz http://www.vlfeat.org/download/vlfeat-0.9.13-bin.tar.gz
|
||||||
cmvs.tar.gz http://www.di.ens.fr/cmvs/cmvs-fix2.tar.gz
|
cmvs.tar.gz http://www.di.ens.fr/cmvs/cmvs-fix2.tar.gz
|
||||||
|
@ -196,11 +190,13 @@ wait
|
||||||
mv -f graclus1.2 "$GRACLUS_PATH"
|
mv -f graclus1.2 "$GRACLUS_PATH"
|
||||||
mv -f clapack-3.2.1-CMAKE "$CLAPACK_PATH"
|
mv -f clapack-3.2.1-CMAKE "$CLAPACK_PATH"
|
||||||
mv -f vlfeat-0.9.13 "$VLFEAT_PATH"
|
mv -f vlfeat-0.9.13 "$VLFEAT_PATH"
|
||||||
|
mv -f bundler-v0.4-source "$BUNDLER_PATH"
|
||||||
mv -f parallel-20141022 "$PARALLEL_PATH"
|
mv -f parallel-20141022 "$PARALLEL_PATH"
|
||||||
mv -f PoissonRecon "$PSR_PATH"
|
mv -f PoissonRecon "$PSR_PATH"
|
||||||
mv -f cmvs "$CMVS_PATH"
|
mv -f cmvs "$CMVS_PATH"
|
||||||
mv -f pcl-pcl-1.7.2 "$PCL_PATH"
|
mv -f pcl-pcl-1.7.2 "$PCL_PATH"
|
||||||
|
|
||||||
|
|
||||||
echo " < done - `date`"
|
echo " < done - `date`"
|
||||||
|
|
||||||
|
|
||||||
|
@ -350,34 +346,21 @@ echo " > cmvs/pmvs"
|
||||||
echo " < done - `date`"
|
echo " < done - `date`"
|
||||||
echo
|
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"
|
echo " > bundler"
|
||||||
cd "$BUNDLER_PATH"
|
cd "$BUNDLER_PATH"
|
||||||
|
|
||||||
|
sed -i "$BUNDLER_PATH/src/BundlerApp.h" -e "620c\ BundlerApp();"
|
||||||
|
|
||||||
echo " - cleaning bundler"
|
echo " - cleaning bundler"
|
||||||
make clean > "$TOOLS_LOG_PATH/bundler_1_clean.log" 2>&1
|
make clean > "$TOOLS_LOG_PATH/bundler_1_clean.log" 2>&1
|
||||||
|
|
||||||
echo " - building bundler"
|
echo " - building bundler"
|
||||||
make -j > "$TOOLS_LOG_PATH/bundler_2_build.log" 2>&1
|
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 " < done - `date`"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|
|
@ -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 <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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 <keys1.in> <keys2.in> <out.txt> <ratio> <threshold>\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<KeypointMatch> matches =
|
||||||
|
MatchKeys(num1, keys1, num2, keys2, ratio);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
std::vector<KeypointMatch> 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);
|
||||||
|
*/
|
||||||
|
}
|
|
@ -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)
|
|
@ -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 <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#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<Keypoint *> ReadKeysMMAP(FILE *fp)
|
||||||
|
{
|
||||||
|
int i, j, num, len, val, n;
|
||||||
|
|
||||||
|
std::vector<Keypoint *> 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<Keypoint *> 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<Keypoint *> 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<KeypointMatch> MatchKeys(int num_keys1, unsigned char *k1,
|
||||||
|
ANNkd_tree *tree2,
|
||||||
|
double ratio, int max_pts_visit)
|
||||||
|
{
|
||||||
|
annMaxPtsVisit(max_pts_visit);
|
||||||
|
std::vector<KeypointMatch> 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<KeypointMatch> 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<KeypointMatch> 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;
|
||||||
|
}
|
|
@ -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 <vector>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#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<Keypoint *> 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<KeypointMatch> MatchKeys(int num_keys1, unsigned char *k1,
|
||||||
|
int num_keys2, unsigned char *k2,
|
||||||
|
double ratio = 0.6,
|
||||||
|
int max_pts_visit = 200);
|
||||||
|
|
||||||
|
std::vector<KeypointMatch> MatchKeys(int num_keys1, unsigned char *k1,
|
||||||
|
ANNkd_tree *tree2,
|
||||||
|
double ratio = 0.6,
|
||||||
|
int max_pts_visit = 200);
|
||||||
|
|
||||||
|
#endif /* __keys2_h__ */
|
1
run.pl
1
run.pl
|
@ -684,7 +684,6 @@ sub bundler {
|
||||||
$bundlerOptions .= "--constrain_focal\n";
|
$bundlerOptions .= "--constrain_focal\n";
|
||||||
$bundlerOptions .= "--constrain_focal_weight 0.0\n";
|
$bundlerOptions .= "--constrain_focal_weight 0.0\n";
|
||||||
$bundlerOptions .= "--estimate_distortion\n";
|
$bundlerOptions .= "--estimate_distortion\n";
|
||||||
$bundlerOptions .= "--use_ceres\n";
|
|
||||||
$bundlerOptions .= "--run_bundle";
|
$bundlerOptions .= "--run_bundle";
|
||||||
|
|
||||||
system("echo \"$bundlerOptions\" > \"$jobOptions{step_3_bundlerOptions}\"");
|
system("echo \"$bundlerOptions\" > \"$jobOptions{step_3_bundlerOptions}\"");
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit b34cc5dcd54345272028b68f82fa4d0ae8a103c9
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit b0696f6269d12abc6ea63083d565fe2ec8172da9
|
|
Ładowanie…
Reference in New Issue