Ajout prototype Wrapper ROS matcher
This commit is contained in:
parent
f17bbbcc51
commit
373a75ae87
409 changed files with 133617 additions and 507 deletions
|
@ -1,3 +1,6 @@
|
|||
#ifndef ASIFTMATCHER_HPP
|
||||
#define ASIFTMATCHER_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -94,3 +97,5 @@ protected:
|
|||
bool _resize_imgs;// = false; //Resize images to IM_X/IM_Y ?
|
||||
bool _showDebug;// = 0; //Show debugging messages ?
|
||||
};
|
||||
|
||||
#endif
|
|
@ -17,10 +17,6 @@ SET(CMAKE_MAKEFILE_DEPENDS
|
|||
"io_png/libs/zlib/CMakeLists.txt"
|
||||
"libMatch/CMakeLists.txt"
|
||||
"libNumerics/CMakeLists.txt"
|
||||
"/usr/share/OpenCV/OpenCVConfig-version.cmake"
|
||||
"/usr/share/OpenCV/OpenCVConfig.cmake"
|
||||
"/usr/share/OpenCV/OpenCVModules-release.cmake"
|
||||
"/usr/share/OpenCV/OpenCVModules.cmake"
|
||||
"/usr/share/cmake-2.8/Modules/CMakeCInformation.cmake"
|
||||
"/usr/share/cmake-2.8/Modules/CMakeCXXInformation.cmake"
|
||||
"/usr/share/cmake-2.8/Modules/CMakeCommonLanguageInclude.cmake"
|
||||
|
|
|
@ -6,3 +6,81 @@
|
|||
|
||||
#IncludeRegexTransform:
|
||||
|
||||
./io_png/libs/png/png.h
|
||||
../zlib/zlib.h
|
||||
./io_png/libs/zlib/zlib.h
|
||||
pngconf.h
|
||||
./io_png/libs/png/pngconf.h
|
||||
crtdbg.h
|
||||
-
|
||||
|
||||
./io_png/libs/png/pngconf.h
|
||||
pngusr.h
|
||||
./io_png/libs/png/pngusr.h
|
||||
config.h
|
||||
./io_png/libs/png/config.h
|
||||
windows.h
|
||||
-
|
||||
stdio.h
|
||||
-
|
||||
stdio.h
|
||||
-
|
||||
sys/types.h
|
||||
-
|
||||
setjmp.h
|
||||
-
|
||||
strings.h
|
||||
-
|
||||
string.h
|
||||
-
|
||||
stdlib.h
|
||||
-
|
||||
fp.h
|
||||
-
|
||||
math.h
|
||||
-
|
||||
m68881.h
|
||||
-
|
||||
mem.h
|
||||
-
|
||||
alloc.h
|
||||
-
|
||||
malloc.h
|
||||
-
|
||||
time.h
|
||||
-
|
||||
dos.h
|
||||
-
|
||||
|
||||
./io_png/libs/zlib/zconf.h
|
||||
windows.h
|
||||
-
|
||||
sys/types.h
|
||||
-
|
||||
unistd.h
|
||||
-
|
||||
unixio.h
|
||||
-
|
||||
|
||||
./io_png/libs/zlib/zlib.h
|
||||
zconf.h
|
||||
./io_png/libs/zlib/zconf.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/io_png/io_png.c
|
||||
stdlib.h
|
||||
-
|
||||
stdio.h
|
||||
-
|
||||
math.h
|
||||
-
|
||||
assert.h
|
||||
-
|
||||
png.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/io_png/png.h
|
||||
png.h
|
||||
-
|
||||
io_png.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/io_png/io_png.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/io_png/io_png.h
|
||||
|
||||
|
|
|
@ -6,143 +6,3 @@
|
|||
|
||||
#IncludeRegexTransform:
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/compute_asift_keypoints.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
demo_lib_sift.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_lib_sift.h
|
||||
frot.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/frot.h
|
||||
fproj.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fproj.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/compute_asift_matches.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
demo_lib_sift.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_lib_sift.h
|
||||
frot.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/frot.h
|
||||
fproj.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fproj.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_ASIFT.cpp
|
||||
stdio.h
|
||||
-
|
||||
stdlib.h
|
||||
-
|
||||
string.h
|
||||
-
|
||||
time.h
|
||||
-
|
||||
vector
|
||||
-
|
||||
omp.h
|
||||
-
|
||||
demo_lib_sift.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_lib_sift.h
|
||||
io_png/io_png.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/io_png/io_png.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
frot.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/frot.h
|
||||
fproj.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fproj.h
|
||||
compute_asift_keypoints.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/compute_asift_keypoints.h
|
||||
compute_asift_matches.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/compute_asift_matches.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_lib_sift.h
|
||||
stdlib.h
|
||||
-
|
||||
assert.h
|
||||
-
|
||||
numerics1.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/numerics1.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
filter.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/filter.h
|
||||
domain.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/domain.h
|
||||
splines.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/splines.h
|
||||
flimage.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/flimage.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/domain.h
|
||||
numerics1.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/numerics1.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
splines.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/splines.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/filter.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/flimage.h
|
||||
iostream
|
||||
-
|
||||
string
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fproj.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/frot.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/io_png/io_png.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
stdio.h
|
||||
-
|
||||
stdlib.h
|
||||
-
|
||||
math.h
|
||||
-
|
||||
time.h
|
||||
-
|
||||
float.h
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/numerics1.h
|
||||
stdio.h
|
||||
-
|
||||
stdlib.h
|
||||
-
|
||||
math.h
|
||||
-
|
||||
fstream
|
||||
-
|
||||
iostream
|
||||
-
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/splines.h
|
||||
numerics1.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/numerics1.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
string.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/string.h
|
||||
vector
|
||||
-
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ SET(CMAKE_C_TARGET_INCLUDE_PATH
|
|||
"."
|
||||
"./io_png"
|
||||
"./io_png/libs/png"
|
||||
"/usr/include/opencv"
|
||||
)
|
||||
SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH})
|
||||
SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH})
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3,11 +3,11 @@
|
|||
|
||||
# compile C with /usr/bin/cc
|
||||
# compile CXX with /usr/bin/c++
|
||||
C_FLAGS = -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/. -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png/libs/png -I/usr/include/opencv
|
||||
C_FLAGS = -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/. -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png/libs/png
|
||||
|
||||
C_DEFINES =
|
||||
|
||||
CXX_FLAGS = -fopenmp -Wall -Wno-strict-aliasing -Wextra -Wno-write-strings -Wno-deprecated -ansi -O2 -ftree-vectorize -funroll-loops -L/usr/X11R6/lib -lm -lpthread -lX11 -std=c++11 -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/. -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png/libs/png -I/usr/include/opencv
|
||||
CXX_FLAGS = -fopenmp -Wall -Wno-strict-aliasing -Wextra -Wno-write-strings -Wno-deprecated -ansi -O2 -ftree-vectorize -funroll-loops -L/usr/X11R6/lib -lm -lpthread -lX11 -std=c++11 -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/. -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png/libs/png
|
||||
|
||||
CXX_DEFINES =
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -6,353 +6,3 @@
|
|||
|
||||
#IncludeRegexTransform:
|
||||
|
||||
./io_png/libs/png/png.h
|
||||
../zlib/zlib.h
|
||||
./io_png/libs/zlib/zlib.h
|
||||
pngconf.h
|
||||
./io_png/libs/png/pngconf.h
|
||||
crtdbg.h
|
||||
-
|
||||
|
||||
./io_png/libs/png/pngconf.h
|
||||
pngusr.h
|
||||
./io_png/libs/png/pngusr.h
|
||||
config.h
|
||||
./io_png/libs/png/config.h
|
||||
windows.h
|
||||
-
|
||||
stdio.h
|
||||
-
|
||||
stdio.h
|
||||
-
|
||||
sys/types.h
|
||||
-
|
||||
setjmp.h
|
||||
-
|
||||
strings.h
|
||||
-
|
||||
string.h
|
||||
-
|
||||
stdlib.h
|
||||
-
|
||||
fp.h
|
||||
-
|
||||
math.h
|
||||
-
|
||||
m68881.h
|
||||
-
|
||||
mem.h
|
||||
-
|
||||
alloc.h
|
||||
-
|
||||
malloc.h
|
||||
-
|
||||
time.h
|
||||
-
|
||||
dos.h
|
||||
-
|
||||
|
||||
./io_png/libs/zlib/zconf.h
|
||||
windows.h
|
||||
-
|
||||
sys/types.h
|
||||
-
|
||||
unistd.h
|
||||
-
|
||||
unixio.h
|
||||
-
|
||||
|
||||
./io_png/libs/zlib/zlib.h
|
||||
zconf.h
|
||||
./io_png/libs/zlib/zconf.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/ASIFT_matcher.hpp
|
||||
stdio.h
|
||||
-
|
||||
stdlib.h
|
||||
-
|
||||
string.h
|
||||
-
|
||||
time.h
|
||||
-
|
||||
vector
|
||||
-
|
||||
sstream
|
||||
-
|
||||
omp.h
|
||||
-
|
||||
demo_lib_sift.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_lib_sift.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
frot.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/frot.h
|
||||
fproj.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fproj.h
|
||||
compute_asift_keypoints.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/compute_asift_keypoints.h
|
||||
compute_asift_matches.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/compute_asift_matches.h
|
||||
CImg.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/CImg.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/CImg.h
|
||||
cstdio
|
||||
-
|
||||
cstdlib
|
||||
-
|
||||
cstdarg
|
||||
-
|
||||
cstring
|
||||
-
|
||||
cmath
|
||||
-
|
||||
cfloat
|
||||
-
|
||||
climits
|
||||
-
|
||||
ctime
|
||||
-
|
||||
exception
|
||||
-
|
||||
algorithm
|
||||
-
|
||||
stdio.h
|
||||
-
|
||||
sys/types.h
|
||||
-
|
||||
sys/time.h
|
||||
-
|
||||
sys/stat.h
|
||||
-
|
||||
unistd.h
|
||||
-
|
||||
dirent.h
|
||||
-
|
||||
fnmatch.h
|
||||
-
|
||||
windows.h
|
||||
-
|
||||
shlobj.h
|
||||
-
|
||||
process.h
|
||||
-
|
||||
io.h
|
||||
-
|
||||
initializer_list
|
||||
-
|
||||
utility
|
||||
-
|
||||
X11/Xlib.h
|
||||
-
|
||||
X11/Xutil.h
|
||||
-
|
||||
X11/keysym.h
|
||||
-
|
||||
pthread.h
|
||||
-
|
||||
sys/ipc.h
|
||||
-
|
||||
sys/shm.h
|
||||
-
|
||||
X11/extensions/XShm.h
|
||||
-
|
||||
X11/extensions/Xrandr.h
|
||||
-
|
||||
omp.h
|
||||
-
|
||||
cstddef
|
||||
-
|
||||
cv.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/cv.h
|
||||
highgui.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/highgui.h
|
||||
png.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/png.h
|
||||
jpeglib.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/jpeglib.h
|
||||
setjmp.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/setjmp.h
|
||||
tiffio.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/tiffio.h
|
||||
minc_io_simple_volume.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/minc_io_simple_volume.h
|
||||
minc_1_simple.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/minc_1_simple.h
|
||||
minc_1_simple_rw.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/minc_1_simple_rw.h
|
||||
zlib.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/zlib.h
|
||||
curl/curl.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/curl/curl.h
|
||||
Magick++.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/Magick++.h
|
||||
fftw3.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fftw3.h
|
||||
Board.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/Board.h
|
||||
ImfRgbaFile.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/ImfRgbaFile.h
|
||||
ImfInputFile.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/ImfInputFile.h
|
||||
ImfChannelList.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/ImfChannelList.h
|
||||
ImfMatrixAttribute.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/ImfMatrixAttribute.h
|
||||
ImfArray.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/ImfArray.h
|
||||
tinyexr.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/tinyexr.h
|
||||
CImg.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/CImg.h
|
||||
stdint.h
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/compute_asift_keypoints.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
demo_lib_sift.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_lib_sift.h
|
||||
frot.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/frot.h
|
||||
fproj.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fproj.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/compute_asift_matches.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
demo_lib_sift.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_lib_sift.h
|
||||
frot.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/frot.h
|
||||
fproj.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fproj.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/demo_lib_sift.h
|
||||
stdlib.h
|
||||
-
|
||||
assert.h
|
||||
-
|
||||
numerics1.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/numerics1.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
filter.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/filter.h
|
||||
domain.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/domain.h
|
||||
splines.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/splines.h
|
||||
flimage.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/flimage.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/domain.h
|
||||
numerics1.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/numerics1.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
splines.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/splines.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/filter.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/flimage.h
|
||||
iostream
|
||||
-
|
||||
string
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/fproj.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/frot.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
stdio.h
|
||||
-
|
||||
stdlib.h
|
||||
-
|
||||
math.h
|
||||
-
|
||||
time.h
|
||||
-
|
||||
float.h
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/numerics1.h
|
||||
stdio.h
|
||||
-
|
||||
stdlib.h
|
||||
-
|
||||
math.h
|
||||
-
|
||||
fstream
|
||||
-
|
||||
iostream
|
||||
-
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/splines.h
|
||||
numerics1.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/numerics1.h
|
||||
library.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/library.h
|
||||
string.h
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/string.h
|
||||
vector
|
||||
-
|
||||
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/test_ASIFT.cpp
|
||||
ASIFT_matcher.hpp
|
||||
/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/ASIFT_matcher.hpp
|
||||
|
||||
/usr/include/opencv/cv.h
|
||||
opencv2/core/core_c.h
|
||||
/usr/include/opencv/opencv2/core/core_c.h
|
||||
opencv2/core/core.hpp
|
||||
/usr/include/opencv/opencv2/core/core.hpp
|
||||
opencv2/imgproc/imgproc_c.h
|
||||
/usr/include/opencv/opencv2/imgproc/imgproc_c.h
|
||||
opencv2/imgproc/imgproc.hpp
|
||||
/usr/include/opencv/opencv2/imgproc/imgproc.hpp
|
||||
opencv2/video/tracking.hpp
|
||||
/usr/include/opencv/opencv2/video/tracking.hpp
|
||||
opencv2/features2d/features2d.hpp
|
||||
/usr/include/opencv/opencv2/features2d/features2d.hpp
|
||||
opencv2/flann/flann.hpp
|
||||
/usr/include/opencv/opencv2/flann/flann.hpp
|
||||
opencv2/calib3d/calib3d.hpp
|
||||
/usr/include/opencv/opencv2/calib3d/calib3d.hpp
|
||||
opencv2/objdetect/objdetect.hpp
|
||||
/usr/include/opencv/opencv2/objdetect/objdetect.hpp
|
||||
opencv2/legacy/compat.hpp
|
||||
/usr/include/opencv/opencv2/legacy/compat.hpp
|
||||
opencv2/core/internal.hpp
|
||||
/usr/include/opencv/opencv2/core/internal.hpp
|
||||
|
||||
/usr/include/opencv/highgui.h
|
||||
opencv2/core/core_c.h
|
||||
/usr/include/opencv/opencv2/core/core_c.h
|
||||
opencv2/core/core.hpp
|
||||
/usr/include/opencv/opencv2/core/core.hpp
|
||||
opencv2/highgui/highgui_c.h
|
||||
/usr/include/opencv/opencv2/highgui/highgui_c.h
|
||||
opencv2/highgui/highgui.hpp
|
||||
/usr/include/opencv/opencv2/highgui/highgui.hpp
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ SET(CMAKE_C_TARGET_INCLUDE_PATH
|
|||
"."
|
||||
"./io_png"
|
||||
"./io_png/libs/png"
|
||||
"/usr/include/opencv"
|
||||
)
|
||||
SET(CMAKE_CXX_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH})
|
||||
SET(CMAKE_Fortran_TARGET_INCLUDE_PATH ${CMAKE_C_TARGET_INCLUDE_PATH})
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3,11 +3,11 @@
|
|||
|
||||
# compile C with /usr/bin/cc
|
||||
# compile CXX with /usr/bin/c++
|
||||
C_FLAGS = -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/. -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png/libs/png -I/usr/include/opencv
|
||||
C_FLAGS = -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/. -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png/libs/png
|
||||
|
||||
C_DEFINES =
|
||||
|
||||
CXX_FLAGS = -fopenmp -Wall -Wno-strict-aliasing -Wextra -Wno-write-strings -Wno-deprecated -ansi -O2 -ftree-vectorize -funroll-loops -L/usr/X11R6/lib -lm -lpthread -lX11 -std=c++11 -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/. -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png/libs/png -I/usr/include/opencv
|
||||
CXX_FLAGS = -fopenmp -Wall -Wno-strict-aliasing -Wextra -Wno-write-strings -Wno-deprecated -ansi -O2 -ftree-vectorize -funroll-loops -L/usr/X11R6/lib -lm -lpthread -lX11 -std=c++11 -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/. -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png -I/home/harle/catkin_ws/src/BaxterInterface/ASIFT_tests/demo_ASIFT_src/./io_png/libs/png
|
||||
|
||||
CXX_DEFINES =
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -45,13 +45,14 @@ set(ASIFT_srcs
|
|||
|
||||
include_directories(.
|
||||
./io_png
|
||||
./io_png/libs/png)
|
||||
./io_png/libs/png
|
||||
)
|
||||
|
||||
|
||||
add_executable(demo_ASIFT demo_ASIFT.cpp ${ASIFT_srcs})
|
||||
TARGET_LINK_LIBRARIES(demo_ASIFT png zlib Match Numerics)
|
||||
|
||||
find_package( OpenCV REQUIRED )
|
||||
#find_package( OpenCV REQUIRED )
|
||||
add_executable(test_ASIFT test_ASIFT.cpp ASIFT_matcher.cpp ${ASIFT_srcs})
|
||||
TARGET_LINK_LIBRARIES(test_ASIFT png zlib Match Numerics X11) #${OpenCV_LIBS})
|
||||
TARGET_LINK_LIBRARIES(test_ASIFT png zlib Match Numerics X11)
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
|
|||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wno-write-strings")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -ansi")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -ftree-vectorize -funroll-loops")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L/usr/X11R6/lib -lm -lpthread -lX11")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
|
||||
|
@ -45,13 +45,14 @@ set(ASIFT_srcs
|
|||
|
||||
include_directories(.
|
||||
./io_png
|
||||
./io_png/libs/png)
|
||||
./io_png/libs/png
|
||||
)
|
||||
|
||||
|
||||
add_executable(demo_ASIFT demo_ASIFT.cpp ${ASIFT_srcs})
|
||||
TARGET_LINK_LIBRARIES(demo_ASIFT png zlib Match Numerics)
|
||||
|
||||
find_package( OpenCV REQUIRED )
|
||||
#find_package( OpenCV REQUIRED )
|
||||
add_executable(test_ASIFT test_ASIFT.cpp ASIFT_matcher.cpp ${ASIFT_srcs})
|
||||
TARGET_LINK_LIBRARIES(test_ASIFT png zlib Match Numerics X11 ${OpenCV_LIBS})
|
||||
TARGET_LINK_LIBRARIES(test_ASIFT zlib Match Numerics X11)
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
195
asift_match/CMakeLists.txt
Normal file
195
asift_match/CMakeLists.txt
Normal file
|
@ -0,0 +1,195 @@
|
|||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(asift_matching)
|
||||
|
||||
## Find catkin macros and libraries
|
||||
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
|
||||
## is used, also find other catkin packages
|
||||
find_package(cmake_modules)
|
||||
IF(cmake_modules_FOUND)
|
||||
find_package(Eigen REQUIRED)
|
||||
ELSE()
|
||||
find_package(Eigen3 REQUIRED)
|
||||
set(Eigen_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(OpenMP)
|
||||
if (OPENMP_FOUND)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
endif (OPENMP_FOUND)
|
||||
|
||||
IF(MSVC)
|
||||
ADD_DEFINITIONS(/arch:SSE2)
|
||||
ENDIF(MSVC)
|
||||
|
||||
find_package(catkin REQUIRED COMPONENTS
|
||||
roscpp
|
||||
tf
|
||||
rospy
|
||||
pcl_conversions
|
||||
pcl_ros
|
||||
sensor_msgs
|
||||
)
|
||||
#find_package(Eigen3 REQUIRED)
|
||||
#find_package(cmake_modules REQUIRED)
|
||||
|
||||
## Compile as C++11, supported in ROS Kinetic and newer
|
||||
#add_compile_options(-std=c++11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -ftree-vectorize -funroll-loops -L/usr/X11R6/lib -lm -lpthread -lX11 -std=c++11")
|
||||
|
||||
################################################
|
||||
## Declare ROS messages, services and actions ##
|
||||
################################################
|
||||
|
||||
## To declare and build messages, services or actions from within this
|
||||
## package, follow these steps:
|
||||
## * Let MSG_DEP_SET be the set of packages whose message types you use in
|
||||
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
|
||||
## * In the file package.xml:
|
||||
## * add a build_depend tag for "message_generation"
|
||||
## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
|
||||
## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
|
||||
## but can be declared for certainty nonetheless:
|
||||
## * add a exec_depend tag for "message_runtime"
|
||||
## * In this file (CMakeLists.txt):
|
||||
## * add "message_generation" and every package in MSG_DEP_SET to
|
||||
## find_package(catkin REQUIRED COMPONENTS ...)
|
||||
## * add "message_runtime" and every package in MSG_DEP_SET to
|
||||
## catkin_package(CATKIN_DEPENDS ...)
|
||||
## * uncomment the add_*_files sections below as needed
|
||||
## and list every .msg/.srv/.action file to be processed
|
||||
## * uncomment the generate_messages entry below
|
||||
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
|
||||
|
||||
## Generate messages in the 'msg' folder
|
||||
#add_message_files(
|
||||
# FILES
|
||||
#)
|
||||
|
||||
## Generate services in the 'srv' folder
|
||||
# add_service_files(
|
||||
# FILES
|
||||
# Service1.srv
|
||||
# Service2.srv
|
||||
# )
|
||||
|
||||
## Generate actions in the 'action' folder
|
||||
# add_action_files(
|
||||
# FILES
|
||||
# Action1.action
|
||||
# Action2.action
|
||||
# )
|
||||
|
||||
## Generate added messages and services with any dependencies listed here
|
||||
#generate_messages(
|
||||
# DEPENDENCIES
|
||||
# std_msgs
|
||||
# geometry_msgs
|
||||
#)
|
||||
|
||||
###################################
|
||||
## catkin specific configuration ##
|
||||
###################################
|
||||
## The catkin_package macro generates cmake config files for your package
|
||||
## Declare things to be passed to dependent projects
|
||||
## LIBRARIES: libraries you create in this project that dependent projects also need
|
||||
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
#CATKIN_DEPENDS roscpp tf message_runtime
|
||||
#INCLUDE_DIRS include
|
||||
)
|
||||
|
||||
###########
|
||||
## Build ##
|
||||
###########
|
||||
set(ASIFT_srcs
|
||||
src/numerics1.cpp src/frot.cpp src/splines.cpp src/fproj.cpp
|
||||
src/library.cpp src/flimage.cpp src/filter.cpp
|
||||
src/demo_lib_sift.cpp src/compute_asift_keypoints.cpp
|
||||
src/compute_asift_matches.cpp
|
||||
src/orsa.cpp
|
||||
src/ASIFT_matcher.cpp
|
||||
src/ROS_matcher.cpp
|
||||
src/ROS_matcher_node.cpp
|
||||
)
|
||||
|
||||
## Specify additional locations of header files
|
||||
## Your package locations should be listed before other locations
|
||||
include_directories(
|
||||
.
|
||||
#include
|
||||
${catkin_INCLUDE_DIRS}
|
||||
${Eigen_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
## Declare a C++ executable
|
||||
## With catkin_make all packages are built within a single CMake context
|
||||
## The recommended prefix ensures that target names across packages don't collide
|
||||
add_executable(ASIFT_matcher ${ASIFT_srcs})
|
||||
target_link_libraries(ASIFT_matcher
|
||||
${catkin_LIBRARIES}
|
||||
${Eigen_LIBRARIES}
|
||||
X11
|
||||
)
|
||||
|
||||
|
||||
## Add cmake target dependencies of the executable
|
||||
## same as for the library above
|
||||
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||
#add_dependencies(ASIFT_matcher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||
|
||||
## Specify libraries to link a library or executable target against
|
||||
# target_link_libraries(${PROJECT_NAME}_node
|
||||
# ${catkin_LIBRARIES}
|
||||
# )
|
||||
|
||||
#############
|
||||
## Install ##
|
||||
#############
|
||||
|
||||
## Mark executable scripts (Python etc.) for installation
|
||||
## in contrast to setup.py, you can choose the destination
|
||||
|
||||
#install(PROGRAMS
|
||||
#scripts/basic_controls.py
|
||||
#scripts/cube.py
|
||||
#scripts/menu.py
|
||||
#scripts/simple_marker.py
|
||||
#DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
#)
|
||||
|
||||
## Mark executables and/or libraries for installation
|
||||
#install(TARGETS
|
||||
# ASIFT_matcher
|
||||
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
#)
|
||||
|
||||
|
||||
## Mark cpp header files for installation
|
||||
# install(DIRECTORY include/${PROJECT_NAME}/
|
||||
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
|
||||
# FILES_MATCHING PATTERN "*.h"
|
||||
# PATTERN ".svn" EXCLUDE
|
||||
# )
|
||||
|
||||
## Mark other files for installation (e.g. launch and bag files, etc.)
|
||||
# install(FILES
|
||||
# # myfile1
|
||||
# # myfile2
|
||||
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||
# )
|
||||
|
||||
#############
|
||||
## Testing ##
|
||||
#############
|
||||
|
||||
## Add gtest based cpp test target and link libraries
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_beginner_tutorials.cpp)
|
||||
# if(TARGET ${PROJECT_NAME}-test)
|
||||
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
|
||||
# endif()
|
||||
|
||||
## Add folders to be run by python nosetests
|
||||
# catkin_add_nosetests(test)
|
192
asift_match/CMakeLists.txt~
Normal file
192
asift_match/CMakeLists.txt~
Normal file
|
@ -0,0 +1,192 @@
|
|||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(asift_matching)
|
||||
|
||||
## Find catkin macros and libraries
|
||||
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
|
||||
## is used, also find other catkin packages
|
||||
find_package(cmake_modules)
|
||||
IF(cmake_modules_FOUND)
|
||||
find_package(Eigen REQUIRED)
|
||||
ELSE()
|
||||
find_package(Eigen3 REQUIRED)
|
||||
set(Eigen_INCLUDE_DIRS ${EIGEN3_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(OpenMP)
|
||||
if (OPENMP_FOUND)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
endif (OPENMP_FOUND)
|
||||
|
||||
IF(MSVC)
|
||||
ADD_DEFINITIONS(/arch:SSE2)
|
||||
ENDIF(MSVC)
|
||||
|
||||
find_package(catkin REQUIRED COMPONENTS
|
||||
roscpp
|
||||
tf
|
||||
rospy
|
||||
)
|
||||
#find_package(Eigen3 REQUIRED)
|
||||
#find_package(cmake_modules REQUIRED)
|
||||
|
||||
## Compile as C++11, supported in ROS Kinetic and newer
|
||||
#add_compile_options(-std=c++11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -ftree-vectorize -funroll-loops -L/usr/X11R6/lib -lm -lpthread -lX11 -std=c++11")
|
||||
|
||||
################################################
|
||||
## Declare ROS messages, services and actions ##
|
||||
################################################
|
||||
|
||||
## To declare and build messages, services or actions from within this
|
||||
## package, follow these steps:
|
||||
## * Let MSG_DEP_SET be the set of packages whose message types you use in
|
||||
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
|
||||
## * In the file package.xml:
|
||||
## * add a build_depend tag for "message_generation"
|
||||
## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
|
||||
## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
|
||||
## but can be declared for certainty nonetheless:
|
||||
## * add a exec_depend tag for "message_runtime"
|
||||
## * In this file (CMakeLists.txt):
|
||||
## * add "message_generation" and every package in MSG_DEP_SET to
|
||||
## find_package(catkin REQUIRED COMPONENTS ...)
|
||||
## * add "message_runtime" and every package in MSG_DEP_SET to
|
||||
## catkin_package(CATKIN_DEPENDS ...)
|
||||
## * uncomment the add_*_files sections below as needed
|
||||
## and list every .msg/.srv/.action file to be processed
|
||||
## * uncomment the generate_messages entry below
|
||||
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
|
||||
|
||||
## Generate messages in the 'msg' folder
|
||||
#add_message_files(
|
||||
# FILES
|
||||
#)
|
||||
|
||||
## Generate services in the 'srv' folder
|
||||
# add_service_files(
|
||||
# FILES
|
||||
# Service1.srv
|
||||
# Service2.srv
|
||||
# )
|
||||
|
||||
## Generate actions in the 'action' folder
|
||||
# add_action_files(
|
||||
# FILES
|
||||
# Action1.action
|
||||
# Action2.action
|
||||
# )
|
||||
|
||||
## Generate added messages and services with any dependencies listed here
|
||||
#generate_messages(
|
||||
# DEPENDENCIES
|
||||
# std_msgs
|
||||
# geometry_msgs
|
||||
#)
|
||||
|
||||
###################################
|
||||
## catkin specific configuration ##
|
||||
###################################
|
||||
## The catkin_package macro generates cmake config files for your package
|
||||
## Declare things to be passed to dependent projects
|
||||
## LIBRARIES: libraries you create in this project that dependent projects also need
|
||||
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
#CATKIN_DEPENDS roscpp tf message_runtime
|
||||
#INCLUDE_DIRS include
|
||||
)
|
||||
|
||||
###########
|
||||
## Build ##
|
||||
###########
|
||||
set(ASIFT_srcs
|
||||
src/numerics1.cpp src/frot.cpp src/splines.cpp src/fproj.cpp
|
||||
src/library.cpp src/flimage.cpp src/filter.cpp
|
||||
src/demo_lib_sift.cpp src/compute_asift_keypoints.cpp
|
||||
src/compute_asift_matches.cpp
|
||||
src/orsa.cpp
|
||||
src/ASIFT_matcher.cpp
|
||||
src/ROS_matcher.cpp
|
||||
src/ROS_matcher_node.cpp
|
||||
)
|
||||
|
||||
## Specify additional locations of header files
|
||||
## Your package locations should be listed before other locations
|
||||
include_directories(
|
||||
.
|
||||
#include
|
||||
${catkin_INCLUDE_DIRS}
|
||||
${Eigen_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
## Declare a C++ executable
|
||||
## With catkin_make all packages are built within a single CMake context
|
||||
## The recommended prefix ensures that target names across packages don't collide
|
||||
add_executable(ASIFT_matcher ${ASIFT_srcs})
|
||||
target_link_libraries(ASIFT_matcher
|
||||
${catkin_LIBRARIES}
|
||||
${Eigen_LIBRARIES}
|
||||
X11
|
||||
)
|
||||
|
||||
|
||||
## Add cmake target dependencies of the executable
|
||||
## same as for the library above
|
||||
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||
#add_dependencies(ASIFT_matcher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
|
||||
|
||||
## Specify libraries to link a library or executable target against
|
||||
# target_link_libraries(${PROJECT_NAME}_node
|
||||
# ${catkin_LIBRARIES}
|
||||
# )
|
||||
|
||||
#############
|
||||
## Install ##
|
||||
#############
|
||||
|
||||
## Mark executable scripts (Python etc.) for installation
|
||||
## in contrast to setup.py, you can choose the destination
|
||||
|
||||
#install(PROGRAMS
|
||||
#scripts/basic_controls.py
|
||||
#scripts/cube.py
|
||||
#scripts/menu.py
|
||||
#scripts/simple_marker.py
|
||||
#DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
#)
|
||||
|
||||
## Mark executables and/or libraries for installation
|
||||
#install(TARGETS
|
||||
# ASIFT_matcher
|
||||
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
#)
|
||||
|
||||
|
||||
## Mark cpp header files for installation
|
||||
# install(DIRECTORY include/${PROJECT_NAME}/
|
||||
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
|
||||
# FILES_MATCHING PATTERN "*.h"
|
||||
# PATTERN ".svn" EXCLUDE
|
||||
# )
|
||||
|
||||
## Mark other files for installation (e.g. launch and bag files, etc.)
|
||||
# install(FILES
|
||||
# # myfile1
|
||||
# # myfile2
|
||||
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||
# )
|
||||
|
||||
#############
|
||||
## Testing ##
|
||||
#############
|
||||
|
||||
## Add gtest based cpp test target and link libraries
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_beginner_tutorials.cpp)
|
||||
# if(TARGET ${PROJECT_NAME}-test)
|
||||
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
|
||||
# endif()
|
||||
|
||||
## Add folders to be run by python nosetests
|
||||
# catkin_add_nosetests(test)
|
73
asift_match/package.xml
Normal file
73
asift_match/package.xml
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0"?>
|
||||
<package>
|
||||
<name>asift_matching</name>
|
||||
<version>0.0.0</version>
|
||||
<description>ASIFT based matching package</description>
|
||||
|
||||
<!-- One maintainer tag required, multiple allowed, one person per tag -->
|
||||
<!-- Example: -->
|
||||
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
|
||||
<maintainer email="blue@todo.todo">blue</maintainer>
|
||||
|
||||
|
||||
<!-- One license tag required, multiple allowed, one license per tag -->
|
||||
<!-- Commonly used license strings: -->
|
||||
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
|
||||
<license>DREAM</license>
|
||||
|
||||
|
||||
<!-- Url tags are optional, but multiple are allowed, one per tag -->
|
||||
<!-- Optional attribute type can be: website, bugtracker, or repository -->
|
||||
<!-- Example: -->
|
||||
<!-- <url type="website">http://wiki.ros.org/rviz_interface</url> -->
|
||||
|
||||
|
||||
<!-- Author tags are optional, multiple are allowed, one per tag -->
|
||||
<!-- Authors do not have to be maintainers, but could be -->
|
||||
<!-- Example: -->
|
||||
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
|
||||
|
||||
|
||||
<!-- The *depend tags are used to specify dependencies -->
|
||||
<!-- Dependencies can be catkin packages or system dependencies -->
|
||||
<!-- Examples: -->
|
||||
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
|
||||
<!-- <depend>roscpp</depend> -->
|
||||
<!-- Note that this is equivalent to the following: -->
|
||||
<!-- <build_depend>roscpp</build_depend> -->
|
||||
<!-- <exec_depend>roscpp</exec_depend> -->
|
||||
<!-- Use build_depend for packages you need at compile time: -->
|
||||
<!-- <build_depend>message_generation</build_depend> -->
|
||||
<!-- Use build_export_depend for packages you need in order to build against this package: -->
|
||||
<!-- <build_export_depend>message_generation</build_export_depend> -->
|
||||
<!-- Use buildtool_depend for build tool packages: -->
|
||||
<!-- <buildtool_depend>catkin</buildtool_depend> -->
|
||||
<!-- Use exec_depend for packages you need at runtime: -->
|
||||
<!-- <exec_depend>message_runtime</exec_depend> -->
|
||||
<!-- Use test_depend for packages you need only for testing: -->
|
||||
<!-- <test_depend>gtest</test_depend> -->
|
||||
<!-- Use doc_depend for packages you need only for building documentation: -->
|
||||
<!-- <doc_depend>doxygen</doc_depend> -->
|
||||
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
|
||||
<build_depend>roscpp</build_depend>
|
||||
<build_depend>tf</build_depend>
|
||||
<build_depend>pcl_conversions</build_depend>
|
||||
<build_depend>pcl_ros</build_depend>
|
||||
<build_depend>sensor_msgs</build_depend>
|
||||
<build_depend>libpcl-all-dev</build_depend>
|
||||
|
||||
<run_depend>libpcl-all</run_depend>
|
||||
<run_depend>pcl_conversions</run_depend>
|
||||
<run_depend>pcl_ros</run_depend>
|
||||
<run_depend>roscpp</run_depend>
|
||||
<run_depend>sensor_msgs</run_depend>
|
||||
<run_depend>roscpp</run_depend>
|
||||
<run_depend>tf</run_depend>
|
||||
<!--run_depend>message_runtime</run_depend-->
|
||||
|
||||
<export>
|
||||
|
||||
</export>
|
||||
</package>
|
79
asift_match/package.xml~
Normal file
79
asift_match/package.xml~
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0"?>
|
||||
<package>
|
||||
<name>asift_matching</name>
|
||||
<version>0.0.0</version>
|
||||
<description>ASIFT based matching package</description>
|
||||
|
||||
<!-- One maintainer tag required, multiple allowed, one person per tag -->
|
||||
<!-- Example: -->
|
||||
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
|
||||
<maintainer email="blue@todo.todo">blue</maintainer>
|
||||
|
||||
|
||||
<!-- One license tag required, multiple allowed, one license per tag -->
|
||||
<!-- Commonly used license strings: -->
|
||||
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
|
||||
<license>DREAM</license>
|
||||
|
||||
|
||||
<!-- Url tags are optional, but multiple are allowed, one per tag -->
|
||||
<!-- Optional attribute type can be: website, bugtracker, or repository -->
|
||||
<!-- Example: -->
|
||||
<!-- <url type="website">http://wiki.ros.org/rviz_interface</url> -->
|
||||
|
||||
|
||||
<!-- Author tags are optional, multiple are allowed, one per tag -->
|
||||
<!-- Authors do not have to be maintainers, but could be -->
|
||||
<!-- Example: -->
|
||||
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
|
||||
|
||||
|
||||
<!-- The *depend tags are used to specify dependencies -->
|
||||
<!-- Dependencies can be catkin packages or system dependencies -->
|
||||
<!-- Examples: -->
|
||||
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
|
||||
<!-- <depend>roscpp</depend> -->
|
||||
<!-- Note that this is equivalent to the following: -->
|
||||
<!-- <build_depend>roscpp</build_depend> -->
|
||||
<!-- <exec_depend>roscpp</exec_depend> -->
|
||||
<!-- Use build_depend for packages you need at compile time: -->
|
||||
<!-- <build_depend>message_generation</build_depend> -->
|
||||
<!-- Use build_export_depend for packages you need in order to build against this package: -->
|
||||
<!-- <build_export_depend>message_generation</build_export_depend> -->
|
||||
<!-- Use buildtool_depend for build tool packages: -->
|
||||
<!-- <buildtool_depend>catkin</buildtool_depend> -->
|
||||
<!-- Use exec_depend for packages you need at runtime: -->
|
||||
<!-- <exec_depend>message_runtime</exec_depend> -->
|
||||
<!-- Use test_depend for packages you need only for testing: -->
|
||||
<!-- <test_depend>gtest</test_depend> -->
|
||||
<!-- Use doc_depend for packages you need only for building documentation: -->
|
||||
<!-- <doc_depend>doxygen</doc_depend> -->
|
||||
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
|
||||
<build_depend>roscpp</build_depend>
|
||||
<build_depend>tf</build_depend>
|
||||
<build_depend>pcl_conversions</build_depend>
|
||||
<build_depend>pcl_ros</build_depend>
|
||||
<build_depend>sensor_msgs</build_depend>
|
||||
|
||||
<build_export_depend>pcl_conversions</build_export_depend>
|
||||
<build_export_depend>pcl_ros</build_export_depend>
|
||||
<build_export_depend>roscpp</build_export_depend>
|
||||
<build_export_depend>sensor_msgs</build_export_depend>
|
||||
|
||||
<exec_depend>pcl_conversions</exec_depend>
|
||||
<exec_depend>pcl_ros</exec_depend>
|
||||
<exec_depend>roscpp</exec_depend>
|
||||
<exec_depend>sensor_msgs</exec_depend>
|
||||
|
||||
<build_depend>libpcl-all-dev</build_depend>
|
||||
<exec_depend>libpcl-all</exec_depend>
|
||||
<run_depend>roscpp</run_depend>
|
||||
<run_depend>tf</run_depend>
|
||||
<!--run_depend>message_runtime</run_depend-->
|
||||
|
||||
<export>
|
||||
|
||||
</export>
|
||||
</package>
|
717
asift_match/src/ASIFT_matcher.cpp
Normal file
717
asift_match/src/ASIFT_matcher.cpp
Normal file
|
@ -0,0 +1,717 @@
|
|||
#include "ASIFT_matcher.hpp"
|
||||
|
||||
ASIFT_matcher::ASIFT_matcher(): _nb_refs(0), _total_num_matchings(0), _resize_imgs(false), _showDebug(false)
|
||||
{
|
||||
default_sift_parameters(_siftParam);
|
||||
}
|
||||
|
||||
ASIFT_matcher::ASIFT_matcher(const char* ref_path): ASIFT_matcher()
|
||||
{
|
||||
if(!loadReferences(ref_path))
|
||||
{
|
||||
std::cerr<<"Error : Failed to load references"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ASIFT_matcher::~ASIFT_matcher()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
//Return true if successfull
|
||||
bool ASIFT_matcher::addReference(const char* image_path, unsigned int num_tilts)
|
||||
{
|
||||
///// Read input
|
||||
// float * iarr1;
|
||||
// size_t w1, h1;
|
||||
// if (NULL == (iarr1 = read_png_f32_gray(image_path, &w1, &h1))) {
|
||||
// std::cerr << "Unable to load image file " << image_path << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
// std::vector<float> ipixels1(iarr1, iarr1 + w1 * h1);
|
||||
// free(iarr1); /*memcheck*/
|
||||
|
||||
// cout<<"Size : "<<w1<<"/"<<h1<<" - "<<ipixels1.size()<<endl;
|
||||
|
||||
cimg_library::CImg<float> image;
|
||||
try
|
||||
{
|
||||
image.assign(image_path);
|
||||
}
|
||||
catch(cimg_library::CImgIOException)
|
||||
{
|
||||
std::cerr << "Unable to load image file " << image_path << std::endl;
|
||||
return false;
|
||||
}
|
||||
//Convert to grayscale
|
||||
cimg_library::CImg<float> gray(image.width(), image.height(), 1, 1, 0);
|
||||
cimg_forXY(image,x,y) {
|
||||
// Separation of channels
|
||||
int R = (int)image(x,y,0,0);
|
||||
int G = (int)image(x,y,0,1);
|
||||
int B = (int)image(x,y,0,2);
|
||||
// Arithmetic addition of channels for gray
|
||||
// int grayValue = (int)(0.33*R + 0.33*G + 0.33*B);
|
||||
// Real weighted addition of channels for gray
|
||||
int grayValueWeight = (int)(0.299*R + 0.587*G + 0.114*B);
|
||||
// saving píxel values into image information
|
||||
// gray(x,y,0,0) = grayValue;
|
||||
gray(x,y,0,0) = grayValueWeight;
|
||||
}
|
||||
|
||||
std::vector<float> ipixels1;
|
||||
size_t w1=gray.width(), h1=gray.height();
|
||||
ipixels1.assign(gray.begin(), gray.end());
|
||||
|
||||
std::cout<<"Building reference from "<< image_path << std::endl;
|
||||
|
||||
return addReference(ipixels1, w1, h1, num_tilts);
|
||||
}
|
||||
|
||||
//Image : Gray scale image (image size = w*h)
|
||||
bool ASIFT_matcher::addReference(const vector<float>& image, unsigned int w, unsigned int h, unsigned int num_tilts)
|
||||
{
|
||||
if(image.size()!=w*h)
|
||||
{
|
||||
cerr<<"Error : Input image size doesn't correspond with parameters"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
int w1=w, h1=h;
|
||||
vector<float> ipixels1 = image;
|
||||
|
||||
///// Resize the images to area wS*hW in remaining the apsect-ratio
|
||||
///// Resize if the resize flag is not set or if the flag is set unequal to 0
|
||||
float wS = IM_X;
|
||||
float hS = IM_Y;
|
||||
|
||||
float zoom1=0;
|
||||
int wS1=0, hS1=0;
|
||||
vector<float> ipixels1_zoom;
|
||||
|
||||
if(_resize_imgs)
|
||||
{
|
||||
cout << "WARNING: The input image is resized to " << wS << "x" << hS << " for ASIFT. " << endl
|
||||
<< " But the results will be normalized to the original image size." << endl << endl;
|
||||
|
||||
float InitSigma_aa = 1.6;
|
||||
|
||||
float fproj_p, fproj_bg;
|
||||
char fproj_i;
|
||||
float *fproj_x4, *fproj_y4;
|
||||
int fproj_o;
|
||||
|
||||
fproj_o = 3;
|
||||
fproj_p = 0;
|
||||
fproj_i = 0;
|
||||
fproj_bg = 0;
|
||||
fproj_x4 = 0;
|
||||
fproj_y4 = 0;
|
||||
|
||||
float areaS = wS * hS;
|
||||
|
||||
// Resize image 1
|
||||
float area1 = w1 * h1;
|
||||
zoom1 = sqrt(area1/areaS);
|
||||
|
||||
wS1 = (int) (w1 / zoom1);
|
||||
hS1 = (int) (h1 / zoom1);
|
||||
|
||||
int fproj_sx = wS1;
|
||||
int fproj_sy = hS1;
|
||||
|
||||
float fproj_x1 = 0;
|
||||
float fproj_y1 = 0;
|
||||
float fproj_x2 = wS1;
|
||||
float fproj_y2 = 0;
|
||||
float fproj_x3 = 0;
|
||||
float fproj_y3 = hS1;
|
||||
|
||||
/* Anti-aliasing filtering along vertical direction */
|
||||
if ( zoom1 > 1 )
|
||||
{
|
||||
float sigma_aa = InitSigma_aa * zoom1 / 2;
|
||||
GaussianBlur1D(ipixels1,w1,h1,sigma_aa,1);
|
||||
GaussianBlur1D(ipixels1,w1,h1,sigma_aa,0);
|
||||
}
|
||||
|
||||
// simulate a tilt: subsample the image along the vertical axis by a factor of t.
|
||||
ipixels1_zoom.resize(wS1*hS1);
|
||||
fproj (ipixels1, ipixels1_zoom, w1, h1, &fproj_sx, &fproj_sy, &fproj_bg, &fproj_o, &fproj_p,
|
||||
&fproj_i , fproj_x1 , fproj_y1 , fproj_x2 , fproj_y2 , fproj_x3 , fproj_y3, fproj_x4, fproj_y4);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipixels1_zoom.resize(w1*h1);
|
||||
ipixels1_zoom = ipixels1;
|
||||
wS1 = w1;
|
||||
hS1 = h1;
|
||||
zoom1 = 1;
|
||||
}
|
||||
|
||||
///// Compute ASIFT keypoints
|
||||
asift_keypoints keys;
|
||||
int num_keys = 0;
|
||||
|
||||
time_t tstart, tend;
|
||||
tstart = time(0);
|
||||
|
||||
num_keys = compute_asift_keypoints(ipixels1_zoom, wS1, hS1, num_tilts, _showDebug, keys, _siftParam);
|
||||
|
||||
tend = time(0);
|
||||
|
||||
//Save data
|
||||
_im_refs.push_back(ipixels1_zoom);
|
||||
_size_refs.push_back(make_pair(wS1,hS1));
|
||||
_zoom_refs.push_back(zoom1);
|
||||
|
||||
_num_keys.push_back(num_keys);
|
||||
_num_tilts.push_back(num_tilts);
|
||||
_keys.push_back(keys);
|
||||
|
||||
_nb_refs++;
|
||||
|
||||
cout<<"Reference built in "<< difftime(tend, tstart) << " seconds." << endl;
|
||||
cout<<" "<< num_keys <<" ASIFT keypoints found."<< endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Return number of match
|
||||
unsigned int ASIFT_matcher::match(const char* image_path, unsigned int num_tilts)
|
||||
{
|
||||
if(_nb_refs<=0)
|
||||
{
|
||||
cout<<"ASIFT_matcher Error : Trying to match without reference"<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
///// Read input
|
||||
// float * iarr1;
|
||||
// size_t w1, h1;
|
||||
// if (NULL == (iarr1 = read_png_f32_gray(image_path, &w1, &h1))) {
|
||||
// std::cerr << "Unable to load image file " << image_path << std::endl;
|
||||
// return 1;
|
||||
// }
|
||||
// std::vector<float> ipixels1(iarr1, iarr1 + w1 * h1);
|
||||
// free(iarr1); /*memcheck*/
|
||||
|
||||
cimg_library::CImg<float> image;
|
||||
try
|
||||
{
|
||||
image.assign(image_path);
|
||||
}
|
||||
catch(cimg_library::CImgIOException)
|
||||
{
|
||||
std::cerr << "Unable to load image file " << image_path << std::endl;
|
||||
return 0;
|
||||
}
|
||||
//Convert to grayscale
|
||||
cimg_library::CImg<float> gray(image.width(), image.height(), 1, 1, 0);
|
||||
cimg_forXY(image,x,y) {
|
||||
// Separation of channels
|
||||
int R = (int)image(x,y,0,0);
|
||||
int G = (int)image(x,y,0,1);
|
||||
int B = (int)image(x,y,0,2);
|
||||
// Arithmetic addition of channels for gray
|
||||
// int grayValue = (int)(0.33*R + 0.33*G + 0.33*B);
|
||||
// Real weighted addition of channels for gray
|
||||
int grayValueWeight = (int)(0.299*R + 0.587*G + 0.114*B);
|
||||
// saving píxel values into image information
|
||||
// gray(x,y,0,0) = grayValue;
|
||||
gray(x,y,0,0) = grayValueWeight;
|
||||
}
|
||||
vector<float> ipixels1;
|
||||
size_t w1=gray.width(), h1=gray.height();
|
||||
ipixels1.assign(gray.begin(), gray.end());
|
||||
|
||||
std::cout<<"Matching from "<<image_path<<std::endl;
|
||||
|
||||
return match(ipixels1, w1, h1, num_tilts);
|
||||
}
|
||||
|
||||
//Image : Gray scale image (image size = w*h)
|
||||
//Return number of match
|
||||
unsigned int ASIFT_matcher::match(const vector<float>& image, unsigned int w, unsigned int h, unsigned int num_tilts)
|
||||
{
|
||||
if(image.size()!=w*h)
|
||||
{
|
||||
cerr<<"Error : Input image size doesn't correspond with parameters"<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int w1=w, h1=h;
|
||||
vector<float> ipixels1 = image;
|
||||
|
||||
///// Resize the images to area wS*hW in remaining the apsect-ratio
|
||||
///// Resize if the resize flag is not set or if the flag is set unequal to 0
|
||||
float wS = IM_X;
|
||||
float hS = IM_Y;
|
||||
|
||||
float zoom1=0;
|
||||
int wS1=0, hS1=0;
|
||||
vector<float> ipixels1_zoom;
|
||||
|
||||
if(_resize_imgs)
|
||||
{
|
||||
cout << "WARNING: The input image is resized to " << wS << "x" << hS << " for ASIFT. " << endl
|
||||
<< " But the results will be normalized to the original image size." << endl << endl;
|
||||
|
||||
float InitSigma_aa = 1.6;
|
||||
|
||||
float fproj_p, fproj_bg;
|
||||
char fproj_i;
|
||||
float *fproj_x4, *fproj_y4;
|
||||
int fproj_o;
|
||||
|
||||
fproj_o = 3;
|
||||
fproj_p = 0;
|
||||
fproj_i = 0;
|
||||
fproj_bg = 0;
|
||||
fproj_x4 = 0;
|
||||
fproj_y4 = 0;
|
||||
|
||||
float areaS = wS * hS;
|
||||
|
||||
// Resize image 1
|
||||
float area1 = w1 * h1;
|
||||
zoom1 = sqrt(area1/areaS);
|
||||
|
||||
wS1 = (int) (w1 / zoom1);
|
||||
hS1 = (int) (h1 / zoom1);
|
||||
|
||||
int fproj_sx = wS1;
|
||||
int fproj_sy = hS1;
|
||||
|
||||
float fproj_x1 = 0;
|
||||
float fproj_y1 = 0;
|
||||
float fproj_x2 = wS1;
|
||||
float fproj_y2 = 0;
|
||||
float fproj_x3 = 0;
|
||||
float fproj_y3 = hS1;
|
||||
|
||||
/* Anti-aliasing filtering along vertical direction */
|
||||
if ( zoom1 > 1 )
|
||||
{
|
||||
float sigma_aa = InitSigma_aa * zoom1 / 2;
|
||||
GaussianBlur1D(ipixels1,w1,h1,sigma_aa,1);
|
||||
GaussianBlur1D(ipixels1,w1,h1,sigma_aa,0);
|
||||
}
|
||||
|
||||
// simulate a tilt: subsample the image along the vertical axis by a factor of t.
|
||||
ipixels1_zoom.resize(wS1*hS1);
|
||||
fproj (ipixels1, ipixels1_zoom, w1, h1, &fproj_sx, &fproj_sy, &fproj_bg, &fproj_o, &fproj_p,
|
||||
&fproj_i , fproj_x1 , fproj_y1 , fproj_x2 , fproj_y2 , fproj_x3 , fproj_y3, fproj_x4, fproj_y4);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipixels1_zoom.resize(w1*h1);
|
||||
ipixels1_zoom = ipixels1;
|
||||
wS1 = w1;
|
||||
hS1 = h1;
|
||||
zoom1 = 1;
|
||||
}
|
||||
|
||||
///// Compute ASIFT keypoints
|
||||
asift_keypoints keys;
|
||||
int num_keys = 0;
|
||||
|
||||
time_t tstart, tend;
|
||||
tstart = time(0);
|
||||
|
||||
num_keys = compute_asift_keypoints(ipixels1_zoom, wS1, hS1, num_tilts, _showDebug, keys, _siftParam);
|
||||
|
||||
tend = time(0);
|
||||
cout<< "Keypoints computation accomplished in " << difftime(tend, tstart) << " seconds." << endl;
|
||||
cout<<" "<< num_keys <<" ASIFT keypoints found."<< endl;
|
||||
|
||||
//// Match ASIFT keypoints
|
||||
_total_num_matchings=0;
|
||||
|
||||
for(unsigned int i = 0; i<_nb_refs;i++)
|
||||
{
|
||||
int num_matchings = 0;
|
||||
matchingslist matchings;
|
||||
|
||||
cout << "Matching the keypoints..." << endl;
|
||||
tstart = time(0);
|
||||
try
|
||||
{
|
||||
num_matchings = compute_asift_matches(num_tilts, _num_tilts[i], w, h, _size_refs[i].first, _size_refs[i].second, _showDebug, keys, _keys[i], matchings, _siftParam);
|
||||
}
|
||||
catch(const bad_alloc& ba)
|
||||
{
|
||||
cerr<<"ERROR: ASIFT_matcher::match - ";
|
||||
cerr << ba.what() << endl;
|
||||
}
|
||||
// cout<< _keys[i].size()<< " " << _keys[i][0].size() <<" "<< _keys[i][0][0].size()<<endl;
|
||||
|
||||
tend = time(0);
|
||||
cout << "Keypoints matching accomplished in " << difftime(tend, tstart) << " seconds." << endl;
|
||||
|
||||
_num_matchings.push_back(num_matchings);
|
||||
_total_num_matchings += num_matchings;
|
||||
_matchings.push_back(matchings);
|
||||
}
|
||||
|
||||
return _total_num_matchings;
|
||||
}
|
||||
|
||||
//Return true if successfull
|
||||
bool ASIFT_matcher::computeROI(int& x, int& y, unsigned int& h, unsigned int& w) const
|
||||
{
|
||||
if(getNbMatch()==0)
|
||||
{
|
||||
cerr<<"Error : cannot compute ROI without matchs"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
pair<int,int> upLe, doRi; //UpLeft / DownRight
|
||||
//Initialisation
|
||||
for(unsigned int i=0;i<_matchings.size();i++)
|
||||
{
|
||||
if(getNbMatchs()[i]!=0)
|
||||
{
|
||||
upLe = make_pair(_matchings[i][0].first.x,_matchings[i][0].first.y);
|
||||
doRi = make_pair(_matchings[i][0].first.x,_matchings[i][0].first.y);
|
||||
}
|
||||
}
|
||||
|
||||
//Compute ROI
|
||||
for(unsigned int i=0;i<_matchings.size();i++)
|
||||
{
|
||||
for(unsigned int j=0;j<_matchings[i].size();j++)
|
||||
{
|
||||
keypoint kp = _matchings[i][j].first;
|
||||
if(kp.x<upLe.first)
|
||||
upLe.first = kp.x;
|
||||
if(kp.y<upLe.second)
|
||||
upLe.second=kp.y;
|
||||
if(kp.x>doRi.first)
|
||||
doRi.first=kp.x;
|
||||
if(kp.y>doRi.second)
|
||||
doRi.second=kp.y;
|
||||
}
|
||||
}
|
||||
x=upLe.first; //Système de coordonée ? (devrait etre bon)
|
||||
y=upLe.second;
|
||||
h=doRi.second-y;
|
||||
w=doRi.first-x;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Return true if successfull
|
||||
bool ASIFT_matcher::computeCenter(int& cx, int& cy) const
|
||||
{
|
||||
if(getNbMatch()==0)
|
||||
{
|
||||
cerr<<"Error : cannot compute Center without matchs"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int total_kp =0;
|
||||
cx=0;cy=0;
|
||||
for(unsigned int i=0;i<_matchings.size();i++)
|
||||
{
|
||||
for(unsigned int j=0;j<_matchings[i].size();j++)
|
||||
{
|
||||
keypoint kp = _matchings[i][j].first;
|
||||
cx+=kp.x;
|
||||
cy+=kp.y;
|
||||
}
|
||||
total_kp += _matchings[i].size();
|
||||
}
|
||||
cx/=total_kp;
|
||||
cy/=total_kp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Filter keypoint which are far (Euclidian distance) from the center.
|
||||
//Not optimized
|
||||
//threshold : 1-68%/2-95%/3-99%
|
||||
//Return true if successfull
|
||||
bool ASIFT_matcher::distFilter(int threshold=2)
|
||||
{
|
||||
cout<<"filtering keypoint..."<<endl;
|
||||
if(getNbMatch()==0)
|
||||
{
|
||||
cerr<<"Error : cannot filter points without matchs"<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Compute standard deviation
|
||||
int cx, cy;
|
||||
unsigned int total_kp =0;
|
||||
unsigned int euc_dist, dist_avg =0, dist_var=0, std_dev;
|
||||
vector< vector< int > > kp_euc_dist;
|
||||
|
||||
if(computeCenter(cx,cy))
|
||||
{
|
||||
// cout<<"Center : "<<cx<<" / "<<cy<<endl;
|
||||
|
||||
//Compute means/average distance to center + euclidian distances to center for each keypoint
|
||||
for(unsigned int i=0;i<_matchings.size();i++)
|
||||
{
|
||||
vector<int> temp_euc_dist;
|
||||
for(unsigned int j=0;j<_matchings[i].size();j++)
|
||||
{
|
||||
keypoint kp = _matchings[i][j].first;
|
||||
euc_dist =sqrt((kp.x-cx)*(kp.x-cx)+(kp.y-cy)+(kp.y-cy));
|
||||
dist_avg+=euc_dist;
|
||||
temp_euc_dist.push_back(euc_dist);
|
||||
}
|
||||
total_kp += _matchings[i].size();
|
||||
kp_euc_dist.push_back(temp_euc_dist);
|
||||
}
|
||||
dist_avg/=total_kp;
|
||||
// cout<<"Dist avg: "<<dist_avg<<endl;
|
||||
|
||||
//Compute variance
|
||||
for(unsigned int i=0;i<_matchings.size();i++)
|
||||
{
|
||||
for(unsigned int j=0;j<_matchings[i].size();j++)
|
||||
{
|
||||
euc_dist =kp_euc_dist[i][j];
|
||||
dist_var+=(euc_dist-dist_avg)*(euc_dist-dist_avg);
|
||||
}
|
||||
}
|
||||
dist_var/=total_kp;
|
||||
|
||||
//Compute standard deviation
|
||||
std_dev=sqrt(dist_var);
|
||||
// cout<<"Standard Deviation : "<<std_dev<<endl;
|
||||
|
||||
//Filter
|
||||
vector< matchingslist > filtered_match;
|
||||
|
||||
for(unsigned int i=0;i<_matchings.size();i++)
|
||||
{
|
||||
matchingslist new_match;
|
||||
for(unsigned int j=0;j<_matchings[i].size();j++)
|
||||
{
|
||||
euc_dist =kp_euc_dist[i][j];
|
||||
|
||||
if(euc_dist<dist_avg+threshold*std_dev) //Filtering Condition
|
||||
{
|
||||
new_match.push_back(_matchings[i][j]);
|
||||
}
|
||||
}
|
||||
filtered_match.push_back(new_match);
|
||||
_num_matchings[i]=new_match.size();
|
||||
}
|
||||
|
||||
//Save filtered matchs
|
||||
_matchings = filtered_match;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Save reference data necessary for the matching
|
||||
//Doesn't save references images or Sift parameters
|
||||
bool ASIFT_matcher::saveReferences(const char* ref_path) const
|
||||
{
|
||||
// Write all the keypoints (row, col, scale, orientation, desciptor (128 integers))
|
||||
std::ofstream file_key1(ref_path);
|
||||
if (file_key1.is_open())
|
||||
{
|
||||
file_key1<<_nb_refs<<" "<<std::endl;
|
||||
for(unsigned int j=0; j<_keys.size();j++)
|
||||
{
|
||||
asift_keypoints kps =_keys[j];
|
||||
// Follow the same convention of David Lowe:
|
||||
// the first line contains the number of keypoints and the length of the desciptors (128)
|
||||
// Added number of tilts
|
||||
// Added sizes
|
||||
file_key1 << _num_keys[j] << " " << VecLength << " " <<_size_refs[j].first<<" "<<_size_refs[j].second<<" "<<std::endl; //<<_num_tilts[j] << " "
|
||||
for (int tt = 0; tt < (int) kps.size(); tt++)
|
||||
{
|
||||
for (int rr = 0; rr < (int) kps[tt].size(); rr++)
|
||||
{
|
||||
keypointslist::iterator ptr = kps[tt][rr].begin();
|
||||
for(int i=0; i < (int) kps[tt][rr].size(); i++, ptr++)
|
||||
{
|
||||
file_key1 << _zoom_refs[j]*ptr->x << " " << _zoom_refs[j]*ptr->y << " " << _zoom_refs[j]*ptr->scale << " " << ptr->angle;
|
||||
|
||||
for (int ii = 0; ii < (int) VecLength; ii++)
|
||||
{
|
||||
file_key1 << " " << ptr->vec[ii];
|
||||
}
|
||||
|
||||
file_key1 << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
// file_key1<<std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unable to open the file :"<<ref_path;
|
||||
return false;
|
||||
}
|
||||
|
||||
file_key1.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
//Load reference data necessary for the matching
|
||||
//Doesn't load references images or Sift parameters
|
||||
//TODO : split data between different tilts
|
||||
bool ASIFT_matcher::loadReferences(const char* ref_path)
|
||||
{
|
||||
std::ifstream ref_file(ref_path);
|
||||
std::string line, tmp;
|
||||
std::stringstream iss;
|
||||
pair<int,int> size_tmp;
|
||||
if (ref_file.is_open())
|
||||
{
|
||||
std::getline(ref_file, line);
|
||||
std::string::size_type sz;
|
||||
// _nb_refs = std::stoi(line, &sz); //C++11
|
||||
_nb_refs = atoi(line.c_str());
|
||||
_keys = std::vector<asift_keypoints>(_nb_refs);
|
||||
_num_keys = std::vector< int >(_nb_refs);
|
||||
_size_refs= std::vector< pair<int,int> >(_nb_refs);
|
||||
_num_tilts = std::vector< int >(_nb_refs,1);
|
||||
_zoom_refs = std::vector<float>(_nb_refs,1);
|
||||
for(unsigned int i = 0; i<_nb_refs;i++)
|
||||
{
|
||||
std::getline(ref_file, line);
|
||||
std::stringstream iss(line);
|
||||
|
||||
std::getline(iss,tmp,' ');
|
||||
_num_keys[i]=atoi(tmp.c_str());
|
||||
|
||||
std::getline(iss,tmp,' ');
|
||||
if(VecLength!=atoi(tmp.c_str()))
|
||||
{
|
||||
std::cerr<<"Error VecLength doesn't correspond..."<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// std::getline(iss,tmp,' ');
|
||||
// _num_tilts[i]=atoi(tmp.c_str());
|
||||
|
||||
std::getline(iss,tmp,' ');
|
||||
size_tmp.first=atoi(tmp.c_str());
|
||||
|
||||
std::getline(iss,tmp,' ');
|
||||
size_tmp.second=atoi(tmp.c_str());
|
||||
|
||||
_size_refs[i]=size_tmp;
|
||||
|
||||
keypointslist list;
|
||||
for(unsigned int j =0; j<(unsigned int)_num_keys[i];j++)
|
||||
{
|
||||
keypoint nkp;
|
||||
|
||||
std::getline(ref_file, line);
|
||||
std::stringstream iss(line);
|
||||
// if(j==0)
|
||||
// cout<<line<<endl;
|
||||
|
||||
std::getline(iss,tmp,' ');
|
||||
// std::stof(nb_ref, nkp.x); //C++11
|
||||
nkp.x=atof(tmp.c_str());
|
||||
// if(j<5)
|
||||
// cout<<"x : "<<nkp.x<<endl;
|
||||
std::getline(iss,tmp,' ');
|
||||
nkp.y=atof(tmp.c_str());
|
||||
// if(j<5)
|
||||
// cout<<"y : "<<nkp.y<<endl;
|
||||
std::getline(iss,tmp,' ');
|
||||
nkp.scale=atof(tmp.c_str());
|
||||
// if(j<5)
|
||||
// cout<<"Scale : "<<nkp.scale<<endl;
|
||||
std::getline(iss,tmp,' ');
|
||||
nkp.angle=atof(tmp.c_str());
|
||||
|
||||
for(unsigned int k=0; k<(int) VecLength; k++)
|
||||
{
|
||||
std::getline(iss,tmp,' ');
|
||||
nkp.vec[k]=atof(tmp.c_str());
|
||||
}
|
||||
|
||||
list.push_back(nkp);
|
||||
// if(j<5)
|
||||
// {
|
||||
// cout<<"x : "<<list[j].x<<endl;
|
||||
// cout<<"y : "<<list[j].y<<endl;
|
||||
// cout<<"Scale : "<<list[j].scale<<endl;
|
||||
// }
|
||||
|
||||
}
|
||||
std::vector< keypointslist > vkps(1,list);
|
||||
asift_keypoints akps(1,vkps);
|
||||
_keys[i]=akps;
|
||||
// std::getline(ref_file, line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unable to open the file :"<<ref_path;
|
||||
return false;
|
||||
}
|
||||
|
||||
ref_file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
ASIFT_matcher& ASIFT_matcher::operator=(const ASIFT_matcher& m)
|
||||
{
|
||||
|
||||
_nb_refs=m.getNbRef();
|
||||
_im_refs=m.getRefImgs();
|
||||
_size_refs=m.getSizeRef();
|
||||
_zoom_refs=m.getZoomRef();
|
||||
|
||||
_num_keys=m.getNumKeys();
|
||||
_num_tilts=m.getNumTilts();
|
||||
_keys=m.getKeys();
|
||||
|
||||
_total_num_matchings=m.getNbMatch();
|
||||
_num_matchings=getNbMatchs();
|
||||
_matchings=m.getMatch();
|
||||
|
||||
_siftParam=m.getSiftPar();
|
||||
|
||||
_resize_imgs=m.isResizingImg();
|
||||
_showDebug=m.isShowingDebug();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//Debugging function
|
||||
void ASIFT_matcher::print() const
|
||||
{
|
||||
for(unsigned int i=0; i< _keys.size();i++)
|
||||
{
|
||||
cout<<"Ref size:"<<i<<" - size :"<<_keys[i].size()<<endl;
|
||||
for(unsigned int j=0; j<_keys[i].size();j++)
|
||||
{
|
||||
cout<<" "<<j<<" - size :"<<_keys[i][j].size()<<endl;
|
||||
for(unsigned int k=0; k<_keys[i][j].size();k++)
|
||||
{
|
||||
cout<<" "<<k<<" - size :"<<_keys[i][j][k].size()<<endl;
|
||||
double sx=0,sy=0,ss=0,sa=0, sv=0;
|
||||
for(unsigned int l=0; l<_keys[i][j][k].size();l++)
|
||||
{
|
||||
sx+=_keys[i][j][k][l].x;
|
||||
sy+=_keys[i][j][k][l].y;
|
||||
ss+=_keys[i][j][k][l].scale;
|
||||
sa+=_keys[i][j][k][l].angle;
|
||||
for(unsigned int v=0;v<VecLength;v++)
|
||||
{
|
||||
sv+=_keys[i][j][k][l].vec[v];
|
||||
}
|
||||
// cout<<" "<<sx<<"-"<<sy<<"-"<<ss<<"-"<<sa<<"-"<<sv<<endl;
|
||||
}
|
||||
cout<<" "<<sx<<"-"<<sy<<"-"<<ss<<"-"<<sa<<"-"<<sv<<endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
101
asift_match/src/ASIFT_matcher.hpp
Normal file
101
asift_match/src/ASIFT_matcher.hpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
#ifndef ASIFTMATCHER_HPP
|
||||
#define ASIFTMATCHER_HPP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "demo_lib_sift.h"
|
||||
// #include "io_png/io_png.h"
|
||||
|
||||
#include "library.h"
|
||||
#include "frot.h"
|
||||
#include "fproj.h"
|
||||
#include "compute_asift_keypoints.h"
|
||||
#include "compute_asift_matches.h"
|
||||
|
||||
#include "CImg.h" //Need ImageMagick package
|
||||
|
||||
# define IM_X 800
|
||||
# define IM_Y 600
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef vector< vector< keypointslist > > asift_keypoints;
|
||||
|
||||
//ASIFT wrapper
|
||||
class ASIFT_matcher
|
||||
{
|
||||
public:
|
||||
ASIFT_matcher();
|
||||
ASIFT_matcher(const char* ref_path);
|
||||
ASIFT_matcher(const ASIFT_matcher& matcher) { *this = matcher;}
|
||||
// virtual ~ASIFT_matcher();
|
||||
|
||||
bool addReference(const char* image_path, unsigned int num_tilts=1);
|
||||
bool addReference(const vector<float>& image, unsigned int w, unsigned int h, unsigned int num_tilts =1);
|
||||
unsigned int match(const char* image_path, unsigned int num_tilts =1);
|
||||
unsigned int match(const vector<float>& image, unsigned int w, unsigned int h, unsigned int num_tilts =1);
|
||||
bool computeROI(int& x, int& y, unsigned int& h, unsigned int& w) const; //Compute the bounding rectangle of the keypoints
|
||||
bool computeCenter(int& cx, int& cy) const;
|
||||
bool distFilter(int threshold); //Filter keypoint which are far (Euclidian distance) from the center.
|
||||
|
||||
bool saveReferences(const char* ref_path) const;
|
||||
bool loadReferences(const char* ref_path);
|
||||
|
||||
ASIFT_matcher& operator=(const ASIFT_matcher& m);
|
||||
|
||||
unsigned int getNbRef() const{ return _nb_refs;}
|
||||
const vector< vector< float > >& getRefImgs() const{ return _im_refs;}
|
||||
const vector< pair<int,int> >& getSizeRef() const{ return _size_refs;}
|
||||
const vector<float>& getZoomRef() const{ return _zoom_refs;}
|
||||
const std::vector<int>& getNumKeys() const{ return _num_keys;}
|
||||
const std::vector<int>& getNumTilts() const{ return _num_tilts;}
|
||||
const std::vector< asift_keypoints >& getKeys() const{ return _keys;}
|
||||
const vector < unsigned int >& getNbMatchs() const{ return _num_matchings;}
|
||||
unsigned int getNbMatch() const{ return _total_num_matchings;}
|
||||
const vector< matchingslist >& getMatch() const{ return _matchings;}
|
||||
vector< matchingslist >& getMatch(){ return _matchings;}
|
||||
const siftPar& getSiftPar() const{ return _siftParam;}
|
||||
void setSiftPar(const siftPar &newSiftPar){ _siftParam = newSiftPar;}
|
||||
bool isResizingImg() const{ return _resize_imgs;}
|
||||
void setResizeImg(bool resize_imgs){ _resize_imgs=resize_imgs;}
|
||||
bool isShowingDebug() const{ return _showDebug;}
|
||||
void showDebug(bool showDebug){ _showDebug=showDebug;}
|
||||
|
||||
void print() const; //Debugging function
|
||||
|
||||
protected:
|
||||
|
||||
//Reference Images
|
||||
// vector< image > _im_refs;
|
||||
unsigned int _nb_refs;// = 0; //Number of reference images
|
||||
vector< vector< float > > _im_refs; //Reference images used for matching
|
||||
vector< pair<int,int> > _size_refs; //Width/Height
|
||||
vector<float> _zoom_refs; //Zoom coeffs
|
||||
|
||||
//ASIFT Keypoints
|
||||
vector< int > _num_keys; //Number of keypoint/reference
|
||||
vector< int > _num_tilts; //Number of tilts/reference (Speed VS Precision)
|
||||
vector< asift_keypoints > _keys; //Keypoints
|
||||
|
||||
//Matchs
|
||||
unsigned int _total_num_matchings;
|
||||
vector < unsigned int > _num_matchings; //Number of match/reference
|
||||
vector< matchingslist > _matchings; //Matchs
|
||||
|
||||
siftPar _siftParam; //SIFT parameters
|
||||
|
||||
//Flags
|
||||
bool _resize_imgs;// = false; //Resize images to IM_X/IM_Y ?
|
||||
bool _showDebug;// = 0; //Show debugging messages ?
|
||||
};
|
||||
|
||||
#endif
|
60936
asift_match/src/CImg.h
Normal file
60936
asift_match/src/CImg.h
Normal file
File diff suppressed because it is too large
Load diff
57
asift_match/src/ROS_matcher.cpp
Normal file
57
asift_match/src/ROS_matcher.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "ROS_matcher.hpp"
|
||||
|
||||
ROS_matcher::ROS_matcher(): _num_tilt(1), _status(MATCHER_STATUS_WAITING_INIT)
|
||||
{
|
||||
_center_pub = _nh.advertise<geometry_msgs::PointStamped>("/ROS_matcher/center", 10);
|
||||
|
||||
message_filters::Subscriber<sensor_msgs::CameraInfo> info_sub(_nh, "/camera/rgb/camera_info", 1);
|
||||
message_filters::Subscriber<sensor_msgs::Image> image_sub(_nh, "/camera/rgb/image_raw", 1);
|
||||
message_filters::Subscriber<sensor_msgs::PointCloud2> pointcloud_sub(_nh, "/camera/depth_registered/points", 1);
|
||||
message_filters::TimeSynchronizer<sensor_msgs::CameraInfo, sensor_msgs::Image, sensor_msgs::PointCloud2> sync(info_sub, image_sub, pointcloud_sub, 10);
|
||||
sync.registerCallback(boost::bind(&ROS_matcher::cameraCallback, this, _1, _2, _3));
|
||||
|
||||
|
||||
unsigned int nb_ref =2;
|
||||
std::string refData[] = {
|
||||
"book_training/train_image_000.png",
|
||||
"book_training/train_image_001.png",
|
||||
"book_training/train_image_002.png",
|
||||
"book_training/train_image_003.png"};
|
||||
|
||||
for(unsigned int i=0; i<nb_ref;i++)
|
||||
{
|
||||
matcher.addReference(refData[i].c_str(), _num_tilt);
|
||||
}
|
||||
}
|
||||
|
||||
void ROS_matcher::cameraCallback(const sensor_msgs::CameraInfo::ConstPtr& info_msg, const sensor_msgs::Image::ConstPtr& image_msg, const sensor_msgs::PointCloud2::ConstPtr& pointcloud_msg)
|
||||
{
|
||||
if(_status == MATCHER_STATUS_IDLE)
|
||||
{
|
||||
unsigned int width = image_msg->width, height = image_msg->height;
|
||||
std::vector<float> image(height*width);
|
||||
|
||||
//Conversion en niveau de gris
|
||||
if(image_msg->encoding == "yuv422")
|
||||
{
|
||||
for(unsigned int i=0; i<height*width; i++)
|
||||
{
|
||||
image[i]=image_msg->data[3*i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ROS_WARN("Encoding doesn't correspond to yuv422");
|
||||
return;
|
||||
}
|
||||
|
||||
int nb_match=0;
|
||||
nb_match = matcher.match(image, width, height, _num_tilt);
|
||||
|
||||
ROS_INFO("Match : %d", nb_match);
|
||||
}
|
||||
else
|
||||
{
|
||||
ROS_INFO("Matcher not ready to process");
|
||||
}
|
||||
}
|
45
asift_match/src/ROS_matcher.hpp
Normal file
45
asift_match/src/ROS_matcher.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef ROSMATCHER_HPP
|
||||
#define ROSMATCHER_HPP
|
||||
|
||||
#include <ros/ros.h>
|
||||
#include <tf/tf.h>
|
||||
|
||||
#include <message_filters/subscriber.h>
|
||||
#include <message_filters/time_synchronizer.h>
|
||||
|
||||
#include <sensor_msgs/CameraInfo.h>
|
||||
#include <sensor_msgs/PointCloud2.h>
|
||||
#include <sensor_msgs/Image.h>
|
||||
#include <geometry_msgs/PointStamped.h>
|
||||
|
||||
#include "ASIFT_matcher.hpp"
|
||||
|
||||
enum MATCHER_STATUS{
|
||||
MATCHER_STATUS_IDLE=0,
|
||||
MATCHER_STATUS_PROCESSING,
|
||||
MATCHER_STATUS_WAITING_INIT};
|
||||
|
||||
class ROS_matcher
|
||||
{
|
||||
protected:
|
||||
ros::NodeHandle _nh;
|
||||
|
||||
//Publisher ROS
|
||||
ros::Publisher _center_pub;
|
||||
|
||||
//Subscriber ROS
|
||||
// ros::Subscriber _image_sub;
|
||||
|
||||
//Matcher
|
||||
int _num_tilt;
|
||||
ASIFT_matcher matcher;
|
||||
|
||||
MATCHER_STATUS _status;
|
||||
|
||||
public:
|
||||
ROS_matcher();
|
||||
// ~ROS_matcher();
|
||||
void cameraCallback(const sensor_msgs::CameraInfo::ConstPtr& info_msg, const sensor_msgs::Image::ConstPtr& image_msg, const sensor_msgs::PointCloud2::ConstPtr& pointcloud_msg);
|
||||
|
||||
};
|
||||
#endif
|
12
asift_match/src/ROS_matcher_node.cpp
Normal file
12
asift_match/src/ROS_matcher_node.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "ROS_matcher.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ros::init(argc, argv, "ROS_matcher");
|
||||
|
||||
ROS_matcher ros_matcher;
|
||||
|
||||
ros::spin();
|
||||
|
||||
return 0;
|
||||
}
|
BIN
asift_match/src/book_training/train_image_000.png
Normal file
BIN
asift_match/src/book_training/train_image_000.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 522 KiB |
BIN
asift_match/src/book_training/train_image_001.png
Normal file
BIN
asift_match/src/book_training/train_image_001.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 552 KiB |
BIN
asift_match/src/book_training/train_image_002.png
Normal file
BIN
asift_match/src/book_training/train_image_002.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 484 KiB |
BIN
asift_match/src/book_training/train_image_003.png
Normal file
BIN
asift_match/src/book_training/train_image_003.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 458 KiB |
8
asift_match/src/book_training/train_image_005.yml~
Normal file
8
asift_match/src/book_training/train_image_005.yml~
Normal file
|
@ -0,0 +1,8 @@
|
|||
Book cMo for training image 005
|
||||
rows: 4
|
||||
cols: 4
|
||||
data:
|
||||
- [-0.2314201876, -0.9583649151, 0.1672763771, 0.09835545579]
|
||||
- [0.7484075924, -0.06552319445, 0.6599945353, -0.0974700766]
|
||||
- [-0.6215551242, 0.2779269699, 0.7324109687, 0.5499983612]
|
||||
- [0; 0; 0; 1]
|
8
asift_match/src/book_training/train_image_006.yml~
Normal file
8
asift_match/src/book_training/train_image_006.yml~
Normal file
|
@ -0,0 +1,8 @@
|
|||
Book cMo for training image 008
|
||||
rows: 4
|
||||
cols: 4
|
||||
data:
|
||||
- [0.02063568325, -0.5653102458, -0.8246202123, 0.0403687505]
|
||||
- [0.8210674394, 0.4801939642, -0.3086454546, -0.1745029756]
|
||||
- [0.5704580865, -0.6706996964, 0.4740669666, 0.4630312508]
|
||||
- [0, 0, 0, 1]
|
9
asift_match/src/book_training/train_image_007.yml~
Normal file
9
asift_match/src/book_training/train_image_007.yml~
Normal file
|
@ -0,0 +1,9 @@
|
|||
Book cMo for training image 007
|
||||
rows: 4
|
||||
cols: 4
|
||||
data:
|
||||
- [-0.03609085509, -0.3148440768, 0.9484569877, 0.04713881051]
|
||||
- [-0.8006242946, 0.5771011583, 0.1611055304, 0.02971868344]
|
||||
- [-0.5980787482, -0.7535432704, -0.2728998912, 0.6240615433]
|
||||
- [0, 0, 0, 1]
|
||||
|
569
asift_match/src/compute_asift_keypoints.cpp
Executable file
569
asift_match/src/compute_asift_keypoints.cpp
Executable file
|
@ -0,0 +1,569 @@
|
|||
// Copyright (c) 2008-2011, Guoshen Yu <yu@cmap.polytechnique.fr>
|
||||
// Copyright (c) 2008-2011, Jean-Michel Morel <morel@cmla.ens-cachan.fr>
|
||||
//
|
||||
// WARNING:
|
||||
// This file implements an algorithm possibly linked to the patent
|
||||
//
|
||||
// Jean-Michel Morel and Guoshen Yu, Method and device for the invariant
|
||||
// affine recognition recognition of shapes (WO/2009/150361), patent pending.
|
||||
//
|
||||
// This file is made available for the exclusive aim of serving as
|
||||
// scientific tool to verify of the soundness and
|
||||
// completeness of the algorithm description. Compilation,
|
||||
// execution and redistribution of this file may violate exclusive
|
||||
// patents rights in certain countries.
|
||||
// The situation being different for every country and changing
|
||||
// over time, it is your responsibility to determine which patent
|
||||
// rights restrictions apply to you before you compile, use,
|
||||
// modify, or redistribute this file. A patent lawyer is qualified
|
||||
// to make this determination.
|
||||
// If and only if they don't conflict with any patent terms, you
|
||||
// can benefit from the following license terms attached to this
|
||||
// file.
|
||||
//
|
||||
// This program is provided for scientific and educational only:
|
||||
// you can use and/or modify it for these purposes, but you are
|
||||
// not allowed to redistribute this work or derivative works in
|
||||
// source or executable form. A license must be obtained from the
|
||||
// patent right holders for any other use.
|
||||
//
|
||||
//
|
||||
//*------------------------ compute_asift_keypoints -------------------------*/
|
||||
// Compute the ASIFT keypoints on the input image.
|
||||
//
|
||||
// Please report bugs and/or send comments to Guoshen Yu yu@cmap.polytechnique.fr
|
||||
//
|
||||
// Reference: J.M. Morel and G.Yu, ASIFT: A New Framework for Fully Affine Invariant Image
|
||||
// Comparison, SIAM Journal on Imaging Sciences, vol. 2, issue 2, pp. 438-469, 2009.
|
||||
// Reference: ASIFT online demo (You can try ASIFT with your own images online.)
|
||||
// http://www.ipol.im/pub/algo/my_affine_sift/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include "compute_asift_keypoints.h"
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define ABS(x) (((x) > 0) ? (x) : (-(x)))
|
||||
|
||||
|
||||
/* InitSigma gives the amount of smoothing applied to the image at the
|
||||
first level of each octave. In effect, this determines the sampling
|
||||
needed in the image domain relative to amount of smoothing. Good
|
||||
values determined experimentally are in the range 1.2 to 1.8.
|
||||
*/
|
||||
/* float InitSigma_aa = 1.0;*/
|
||||
static float InitSigma_aa = 1.6;
|
||||
|
||||
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||
|
||||
/* Gaussian convolution kernels are truncated at this many sigmas from
|
||||
the center. While it is more efficient to keep this value small,
|
||||
experiments show that for consistent scale-space analysis it needs
|
||||
a value of about 3.0, at which point the Gaussian has fallen to
|
||||
only 1% of its central value. A value of 2.0 greatly reduces
|
||||
keypoint consistency, and a value of 4.0 is better than 3.0.
|
||||
*/
|
||||
const float GaussTruncate1 = 4.0;
|
||||
|
||||
|
||||
/* --------------------------- Blur image --------------------------- */
|
||||
|
||||
|
||||
/* Same as ConvBuffer, but implemented with loop unrolling for increased
|
||||
speed. This is the most time intensive routine in keypoint detection,
|
||||
so deserves careful attention to efficiency. Loop unrolling simply
|
||||
sums 5 multiplications at a time to allow the compiler to schedule
|
||||
operations better and avoid loop overhead. This almost triples
|
||||
speed of previous version on a Pentium with gcc.
|
||||
*/
|
||||
void ConvBufferFast(float *buffer, float *kernel, int rsize, int ksize)
|
||||
{
|
||||
int i;
|
||||
float *bp, *kp, *endkp;
|
||||
float sum;
|
||||
|
||||
for (i = 0; i < rsize; i++) {
|
||||
sum = 0.0;
|
||||
bp = &buffer[i];
|
||||
kp = &kernel[0];
|
||||
endkp = &kernel[ksize];
|
||||
|
||||
/* Loop unrolling: do 5 multiplications at a time. */
|
||||
// while (kp + 4 < endkp) {
|
||||
// sum += (double) bp[0] * (double) kp[0] + (double) bp[1] * (double) kp[1] + (double) bp[2] * (double) kp[2] +
|
||||
// (double) bp[3] * (double) kp[3] + (double) bp[4] * (double) kp[4];
|
||||
// bp += 5;
|
||||
// kp += 5;
|
||||
// }
|
||||
// /* Do 2 multiplications at a time on remaining items. */
|
||||
// while (kp + 1 < endkp) {
|
||||
// sum += (double) bp[0] * (double) kp[0] + (double) bp[1] * (double) kp[1];
|
||||
// bp += 2;
|
||||
// kp += 2;
|
||||
// }
|
||||
// /* Finish last one if needed. */
|
||||
// if (kp < endkp) {
|
||||
// sum += (double) *bp * (double) *kp;
|
||||
// }
|
||||
|
||||
while (kp < endkp) {
|
||||
sum += *bp++ * *kp++;
|
||||
}
|
||||
|
||||
buffer[i] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convolve image with the 1-D kernel vector along image rows. This
|
||||
is designed to be as efficient as possible. Pixels outside the
|
||||
image are set to the value of the closest image pixel.
|
||||
*/
|
||||
void ConvHorizontal(vector<float>& image, int width, int height, float *kernel, int ksize)
|
||||
{
|
||||
int rows, cols, r, c, i, halfsize;
|
||||
float buffer[4000];
|
||||
vector<float> pixels(width*height);
|
||||
|
||||
|
||||
rows = height;
|
||||
cols = width;
|
||||
|
||||
halfsize = ksize / 2;
|
||||
pixels = image;
|
||||
assert(cols + ksize < 4000);
|
||||
|
||||
for (r = 0; r < rows; r++) {
|
||||
/* Copy the row into buffer with pixels at ends replicated for
|
||||
half the mask size. This avoids need to check for ends
|
||||
within inner loop. */
|
||||
for (i = 0; i < halfsize; i++)
|
||||
buffer[i] = pixels[r*cols];
|
||||
for (i = 0; i < cols; i++)
|
||||
buffer[halfsize + i] = pixels[r*cols+i];
|
||||
for (i = 0; i < halfsize; i++)
|
||||
buffer[halfsize + cols + i] = pixels[r*cols+cols-1];
|
||||
|
||||
ConvBufferFast(buffer, kernel, cols, ksize);
|
||||
for (c = 0; c < cols; c++)
|
||||
pixels[r*cols+c] = buffer[c];
|
||||
}
|
||||
image = pixels;
|
||||
}
|
||||
|
||||
|
||||
/* Same as ConvHorizontal, but apply to vertical columns of image.
|
||||
*/
|
||||
void ConvVertical(vector<float>& image, int width, int height, float *kernel, int ksize)
|
||||
{
|
||||
int rows, cols, r, c, i, halfsize;
|
||||
float buffer[4000];
|
||||
vector<float> pixels(width*height);
|
||||
|
||||
rows = height;
|
||||
cols = width;
|
||||
|
||||
halfsize = ksize / 2;
|
||||
pixels = image;
|
||||
assert(rows + ksize < 4000);
|
||||
|
||||
for (c = 0; c < cols; c++) {
|
||||
for (i = 0; i < halfsize; i++)
|
||||
buffer[i] = pixels[c];
|
||||
for (i = 0; i < rows; i++)
|
||||
buffer[halfsize + i] = pixels[i*cols+c];
|
||||
for (i = 0; i < halfsize; i++)
|
||||
buffer[halfsize + rows + i] = pixels[(rows - 1)*cols+c];
|
||||
|
||||
ConvBufferFast(buffer, kernel, rows, ksize);
|
||||
for (r = 0; r < rows; r++)
|
||||
pixels[r*cols+c] = buffer[r];
|
||||
}
|
||||
|
||||
image = pixels;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 1D Convolve image with a Gaussian of width sigma and store result back
|
||||
in image. This routine creates the Gaussian kernel, and then applies
|
||||
it in horizontal (flag_dir=0) OR vertical directions (flag_dir!=0).
|
||||
*/
|
||||
void GaussianBlur1D(vector<float>& image, int width, int height, float sigma, int flag_dir)
|
||||
{
|
||||
float x, kernel[100], sum = 0.0;
|
||||
int ksize, i;
|
||||
|
||||
/* The Gaussian kernel is truncated at GaussTruncate sigmas from
|
||||
center. The kernel size should be odd.
|
||||
*/
|
||||
ksize = (int)(2.0 * GaussTruncate1 * sigma + 1.0);
|
||||
ksize = MAX(3, ksize); /* Kernel must be at least 3. */
|
||||
if (ksize % 2 == 0) /* Make kernel size odd. */
|
||||
ksize++;
|
||||
assert(ksize < 100);
|
||||
|
||||
/* Fill in kernel values. */
|
||||
for (i = 0; i <= ksize; i++) {
|
||||
x = i - ksize / 2;
|
||||
kernel[i] = exp(- x * x / (2.0 * sigma * sigma));
|
||||
sum += kernel[i];
|
||||
}
|
||||
/* Normalize kernel values to sum to 1.0. */
|
||||
for (i = 0; i < ksize; i++)
|
||||
kernel[i] /= sum;
|
||||
|
||||
if (flag_dir == 0)
|
||||
{
|
||||
ConvHorizontal(image, width, height, kernel, ksize);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConvVertical(image, width, height, kernel, ksize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void compensate_affine_coor1(float *x0, float *y0, int w1, int h1, float t1, float t2, float Rtheta)
|
||||
{
|
||||
float x_ori, y_ori;
|
||||
float x_tmp, y_tmp;
|
||||
|
||||
float x1 = *x0;
|
||||
float y1 = *y0;
|
||||
|
||||
|
||||
Rtheta = Rtheta*PI/180;
|
||||
|
||||
if ( Rtheta <= PI/2 )
|
||||
{
|
||||
x_ori = 0;
|
||||
y_ori = w1 * sin(Rtheta) / t1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x_ori = -w1 * cos(Rtheta) / t2;
|
||||
y_ori = ( w1 * sin(Rtheta) + h1 * sin(Rtheta-PI/2) ) / t1;
|
||||
}
|
||||
|
||||
float sin_Rtheta = sin(Rtheta);
|
||||
float cos_Rtheta = cos(Rtheta);
|
||||
|
||||
|
||||
/* project the coordinates of im1 to original image before tilt-rotation transform */
|
||||
/* Get the coordinates with respect to the 'origin' of the original image before transform */
|
||||
x1 = x1 - x_ori;
|
||||
y1 = y1 - y_ori;
|
||||
/* Invert tilt */
|
||||
x1 = x1 * t2;
|
||||
y1 = y1 * t1;
|
||||
/* Invert rotation (Note that the y direction (vertical) is inverse to the usual concention. Hence Rtheta instead of -Rtheta to inverse the rotation.) */
|
||||
x_tmp = cos_Rtheta*x1 - sin_Rtheta*y1;
|
||||
y_tmp = sin_Rtheta*x1 + cos_Rtheta*y1;
|
||||
x1 = x_tmp;
|
||||
y1 = y_tmp;
|
||||
|
||||
*x0 = x1;
|
||||
*y0 = y1;
|
||||
}
|
||||
|
||||
|
||||
/* -------------- MAIN FUNCTION ---------------------- */
|
||||
|
||||
int compute_asift_keypoints(vector<float>& image, int width, int height, int num_of_tilts, int verb, vector< vector< keypointslist > >& keys_all, siftPar &siftparameters)
|
||||
// Compute ASIFT keypoints in the input image.
|
||||
// Input:
|
||||
// image: input image
|
||||
// width, height: width and height of the input image.
|
||||
// num_of_tilts: number of tilts to simulate.
|
||||
// verb: 1/0 --> show/don not show verbose messages. (1 for debugging)
|
||||
// keys_all (output): ASIFT keypoints. It is a 2D matrix with varying rows and columns. Each entry keys_all[tt][rr]
|
||||
// stores the SIFT keypoints calculated on the image with the simulated tilt index tt and simulated rotation index rr (see the code below). In the coordinates of the keypoints,
|
||||
// the affine distortions have been compensated.
|
||||
// siftparameters: SIFT parameters.
|
||||
//
|
||||
// Output: the number of keypoints
|
||||
{
|
||||
vector<float> image_t, image_tmp1, image_tmp;
|
||||
|
||||
float t_min, t_k;
|
||||
int num_tilt, tt, num_rot_t2, rr;
|
||||
int fproj_o;
|
||||
float fproj_p, fproj_bg;
|
||||
char fproj_i;
|
||||
float *fproj_x4, *fproj_y4;
|
||||
// float frot_b=0;
|
||||
float frot_b=128;
|
||||
char *frot_k;
|
||||
int counter_sim=0, num_sim;
|
||||
int flag_dir = 1;
|
||||
float BorderFact=6*sqrt(2.);
|
||||
|
||||
int num_keys_total=0;
|
||||
|
||||
|
||||
fproj_o = 3;
|
||||
fproj_p = 0;
|
||||
fproj_i = 0;
|
||||
fproj_bg = 0;
|
||||
fproj_x4 = 0;
|
||||
fproj_y4 = 0;
|
||||
|
||||
frot_k = 0;
|
||||
|
||||
num_rot_t2 = 10;
|
||||
|
||||
t_min = 1;
|
||||
t_k = sqrt(2.);
|
||||
|
||||
|
||||
num_tilt = num_of_tilts;
|
||||
|
||||
|
||||
if ( num_tilt < 1)
|
||||
{
|
||||
printf("Number of tilts num_tilt should be equal or larger than 1. \n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
image_tmp1 = image;
|
||||
|
||||
|
||||
/* Calculate the number of simulations, and initialize keys_all */
|
||||
keys_all = std::vector< vector< keypointslist > >(num_tilt);
|
||||
for (tt = 1; tt <= num_tilt; tt++)
|
||||
{
|
||||
float t = t_min * pow(t_k, tt-1);
|
||||
|
||||
if ( t == 1 )
|
||||
{
|
||||
counter_sim ++;
|
||||
|
||||
keys_all[tt-1] = std::vector< keypointslist >(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int num_rot1 = round(num_rot_t2*t/2);
|
||||
if ( num_rot1%2 == 1 )
|
||||
{
|
||||
num_rot1 = num_rot1 + 1;
|
||||
}
|
||||
num_rot1 = num_rot1 / 2;
|
||||
counter_sim += num_rot1;
|
||||
|
||||
keys_all[tt-1] = std::vector< keypointslist >(num_rot1);
|
||||
}
|
||||
}
|
||||
|
||||
num_sim = counter_sim;
|
||||
|
||||
if ( verb )
|
||||
{
|
||||
printf("%d affine simulations will be performed. \n", num_sim);
|
||||
}
|
||||
|
||||
counter_sim = 0;
|
||||
|
||||
|
||||
|
||||
/* Affine simulation (rotation+tilt simulation) */
|
||||
// Loop on tilts.
|
||||
#ifdef _OPENMP
|
||||
omp_set_nested(1);
|
||||
#endif
|
||||
#pragma omp parallel for private(tt)
|
||||
for (tt = 1; tt <= num_tilt; tt++)
|
||||
{
|
||||
float t = t_min * pow(t_k, tt-1);
|
||||
|
||||
float t1 = 1;
|
||||
float t2 = 1/t;
|
||||
|
||||
// If tilt t = 1, do not simulate rotation.
|
||||
if ( t == 1 )
|
||||
{
|
||||
// copy the image from vector to array as compute_sift_keypoints uses only array.
|
||||
float *image_tmp1_float = new float[width*height];
|
||||
for (int cc = 0; cc < width*height; cc++)
|
||||
image_tmp1_float[cc] = image_tmp1[cc];
|
||||
|
||||
compute_sift_keypoints(image_tmp1_float,keys_all[tt-1][0],width,height,siftparameters);
|
||||
|
||||
delete[] image_tmp1_float;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// The number of rotations to simulate under the current tilt.
|
||||
int num_rot1 = round(num_rot_t2*t/2);
|
||||
|
||||
if ( num_rot1%2 == 1 )
|
||||
{
|
||||
num_rot1 = num_rot1 + 1;
|
||||
}
|
||||
num_rot1 = num_rot1 / 2;
|
||||
float delta_theta = PI/num_rot1;
|
||||
|
||||
// Loop on rotations.
|
||||
#pragma omp parallel for private(rr)
|
||||
for ( int rr = 1; rr <= num_rot1; rr++ )
|
||||
{
|
||||
float theta = delta_theta * (rr-1);
|
||||
theta = theta * 180 / PI;
|
||||
|
||||
vector<float> image_t;
|
||||
int width_r, height_r;
|
||||
|
||||
// simulate a rotation: rotate the image with an angle theta. (the outside of the rotated image are padded with the value frot_b)
|
||||
frot(image, image_t, width, height, &width_r, &height_r, &theta, &frot_b , frot_k);
|
||||
|
||||
/* Tilt */
|
||||
int width_t = (int) (width_r * t1);
|
||||
int height_t = (int) (height_r * t2);
|
||||
|
||||
int fproj_sx = width_t;
|
||||
int fproj_sy = height_t;
|
||||
|
||||
float fproj_x1 = 0;
|
||||
float fproj_y1 = 0;
|
||||
float fproj_x2 = width_t;
|
||||
float fproj_y2 = 0;
|
||||
float fproj_x3 = 0;
|
||||
float fproj_y3 = height_t;
|
||||
|
||||
/* Anti-aliasing filtering along vertical direction */
|
||||
/* sigma_aa = InitSigma_aa * log2(t);*/
|
||||
float sigma_aa = InitSigma_aa * t / 2;
|
||||
GaussianBlur1D(image_t,width_r,height_r,sigma_aa,flag_dir);
|
||||
|
||||
|
||||
// simulate a tilt: subsample the image along the vertical axis by a factor of t.
|
||||
vector<float> image_tmp(width_t*height_t);
|
||||
fproj (image_t, image_tmp, width_r, height_r, &fproj_sx, &fproj_sy, &fproj_bg, &fproj_o, &fproj_p, &fproj_i , fproj_x1 , fproj_y1 , fproj_x2 , fproj_y2 , fproj_x3 , fproj_y3, fproj_x4, fproj_y4);
|
||||
|
||||
vector<float> image_tmp1 = image_tmp;
|
||||
|
||||
if ( verb )
|
||||
{
|
||||
printf("Rotation theta = %.2f, Tilt t = %.2f. w=%d, h=%d, sigma_aa=%.2f, \n", theta, t, width_t, height_t, sigma_aa);
|
||||
}
|
||||
|
||||
|
||||
float *image_tmp1_float = new float[width_t*height_t];
|
||||
for (int cc = 0; cc < width_t*height_t; cc++)
|
||||
image_tmp1_float[cc] = image_tmp1[cc];
|
||||
|
||||
// compute SIFT keypoints on simulated image.
|
||||
keypointslist keypoints;
|
||||
keypointslist keypoints_filtered;
|
||||
compute_sift_keypoints(image_tmp1_float,keypoints,width_t,height_t,siftparameters);
|
||||
|
||||
delete[] image_tmp1_float;
|
||||
|
||||
/* check if the keypoint is located on the boundary of the parallelogram (i.e., the boundary of the distorted input image). If so, remove it to avoid boundary artifacts. */
|
||||
if ( keypoints.size() != 0 )
|
||||
{
|
||||
for ( int cc = 0; cc < (int) keypoints.size(); cc++ )
|
||||
{
|
||||
|
||||
float x0, y0, x1, y1, x2, y2, x3, y3 ,x4, y4, d1, d2, d3, d4, scale1, theta1, sin_theta1, cos_theta1, BorderTh;
|
||||
|
||||
x0 = keypoints[cc].x;
|
||||
y0 = keypoints[cc].y;
|
||||
scale1= keypoints[cc].scale;
|
||||
|
||||
theta1 = theta * PI / 180;
|
||||
sin_theta1 = sin(theta1);
|
||||
cos_theta1 = cos(theta1);
|
||||
|
||||
/* the coordinates of the 4 submits of the parallelogram */
|
||||
if ( theta <= 90 )
|
||||
{
|
||||
x1 = height * sin_theta1;
|
||||
y1 = 0;
|
||||
y2 = width * sin_theta1;
|
||||
x3 = width * cos_theta1;
|
||||
x4 = 0;
|
||||
y4 = height * cos_theta1;
|
||||
x2 = x1 + x3;
|
||||
y3 = y2 + y4;
|
||||
|
||||
/* note that the vertical direction goes from top to bottom!!!
|
||||
The calculation above assumes that the vertical direction goes from the bottom to top. Thus the vertical coordinates need to be reversed!!! */
|
||||
y1 = y3 - y1;
|
||||
y2 = y3 - y2;
|
||||
y4 = y3 - y4;
|
||||
y3 = 0;
|
||||
|
||||
y1 = y1 * t2;
|
||||
y2 = y2 * t2;
|
||||
y3 = y3 * t2;
|
||||
y4 = y4 * t2;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1 = -height * cos_theta1;
|
||||
x2 = height * sin_theta1;
|
||||
x3 = 0;
|
||||
y3 = width * sin_theta1;
|
||||
x4 = -width * cos_theta1;
|
||||
y4 = 0;
|
||||
x1 = x2 + x4;
|
||||
y2 = y1 + y3;
|
||||
|
||||
/* note that the vertical direction goes from top to bottom!!!
|
||||
The calculation above assumes that the vertical direction goes from the bottom to top. Thus the vertical coordinates need to be reversed!!! */
|
||||
y1 = y2 - y1;
|
||||
y3 = y2 - y3;
|
||||
y4 = y2 - y4;
|
||||
y2 = 0;
|
||||
|
||||
y1 = y1 * t2;
|
||||
y2 = y2 * t2;
|
||||
y3 = y3 * t2;
|
||||
y4 = y4 * t2;
|
||||
}
|
||||
|
||||
/* the distances from the keypoint to the 4 sides of the parallelogram */
|
||||
d1 = ABS((x2-x1)*(y1-y0)-(x1-x0)*(y2-y1)) / sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
|
||||
d2 = ABS((x3-x2)*(y2-y0)-(x2-x0)*(y3-y2)) / sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
|
||||
d3 = ABS((x4-x3)*(y3-y0)-(x3-x0)*(y4-y3)) / sqrt((x4-x3)*(x4-x3)+(y4-y3)*(y4-y3));
|
||||
d4 = ABS((x1-x4)*(y4-y0)-(x4-x0)*(y1-y4)) / sqrt((x1-x4)*(x1-x4)+(y1-y4)*(y1-y4));
|
||||
|
||||
BorderTh = BorderFact*scale1;
|
||||
|
||||
if (!((d1<BorderTh) || (d2<BorderTh) || (d3<BorderTh) || (d4<BorderTh) ))
|
||||
{
|
||||
// Normalize the coordinates of the matched points by compensate the simulate affine transformations
|
||||
compensate_affine_coor1(&x0, &y0, width, height, 1/t2, t1, theta);
|
||||
keypoints[cc].x = x0;
|
||||
keypoints[cc].y = y0;
|
||||
|
||||
keypoints_filtered.push_back(keypoints[cc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
keys_all[tt-1][rr-1] = keypoints_filtered;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (tt = 0; tt < (int) keys_all.size(); tt++)
|
||||
for (rr = 0; rr < (int) keys_all[tt].size(); rr++)
|
||||
{
|
||||
num_keys_total += (int) keys_all[tt][rr].size();
|
||||
}
|
||||
printf("%d ASIFT keypoints are detected. \n", num_keys_total);
|
||||
}
|
||||
|
||||
return num_keys_total;
|
||||
}
|
53
asift_match/src/compute_asift_keypoints.h
Executable file
53
asift_match/src/compute_asift_keypoints.h
Executable file
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2008-2011, Guoshen Yu <yu@cmap.polytechnique.fr>
|
||||
// Copyright (c) 2008-2011, Jean-Michel Morel <morel@cmla.ens-cachan.fr>
|
||||
//
|
||||
// WARNING:
|
||||
// This file implements an algorithm possibly linked to the patent
|
||||
//
|
||||
// Jean-Michel Morel and Guoshen Yu, Method and device for the invariant
|
||||
// affine recognition recognition of shapes (WO/2009/150361), patent pending.
|
||||
//
|
||||
// This file is made available for the exclusive aim of serving as
|
||||
// scientific tool to verify of the soundness and
|
||||
// completeness of the algorithm description. Compilation,
|
||||
// execution and redistribution of this file may violate exclusive
|
||||
// patents rights in certain countries.
|
||||
// The situation being different for every country and changing
|
||||
// over time, it is your responsibility to determine which patent
|
||||
// rights restrictions apply to you before you compile, use,
|
||||
// modify, or redistribute this file. A patent lawyer is qualified
|
||||
// to make this determination.
|
||||
// If and only if they don't conflict with any patent terms, you
|
||||
// can benefit from the following license terms attached to this
|
||||
// file.
|
||||
//
|
||||
// This program is provided for scientific and educational only:
|
||||
// you can use and/or modify it for these purposes, but you are
|
||||
// not allowed to redistribute this work or derivative works in
|
||||
// source or executable form. A license must be obtained from the
|
||||
// patent right holders for any other use.
|
||||
//
|
||||
//
|
||||
//*------------------------ compute_asift_keypoints -------------------------*/
|
||||
// Compute the ASIFT keypoints on the input image.
|
||||
//
|
||||
// Please report bugs and/or send comments to Guoshen Yu yu@cmap.polytechnique.fr
|
||||
//
|
||||
// Reference: J.M. Morel and G.Yu, ASIFT: A New Framework for Fully Affine Invariant Image
|
||||
// Comparison, SIAM Journal on Imaging Sciences, vol. 2, issue 2, pp. 438-469, 2009.
|
||||
// Reference: ASIFT online demo (You can try ASIFT with your own images online.)
|
||||
// http://www.ipol.im/pub/algo/my_affine_sift/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "library.h"
|
||||
#include "demo_lib_sift.h"
|
||||
#include "frot.h"
|
||||
#include "fproj.h"
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
|
||||
int compute_asift_keypoints(vector<float>& image, int width, int height, int num_of_tilts, int verb, vector< vector< keypointslist > >& keys_all, siftPar &siftparameters);
|
||||
|
||||
void GaussianBlur1D(vector<float>& image, int width, int height, float sigma, int flag_dir);
|
791
asift_match/src/compute_asift_matches.cpp
Executable file
791
asift_match/src/compute_asift_matches.cpp
Executable file
|
@ -0,0 +1,791 @@
|
|||
// Copyright (c) 2008-2011, Guoshen Yu <yu@cmap.polytechnique.fr>
|
||||
// Copyright (c) 2008-2011, Jean-Michel Morel <morel@cmla.ens-cachan.fr>
|
||||
//
|
||||
// WARNING:
|
||||
// This file implements an algorithm possibly linked to the patent
|
||||
//
|
||||
// Jean-Michel Morel and Guoshen Yu, Method and device for the invariant
|
||||
// affine recognition recognition of shapes (WO/2009/150361), patent pending.
|
||||
//
|
||||
// This file is made available for the exclusive aim of serving as
|
||||
// scientific tool to verify of the soundness and
|
||||
// completeness of the algorithm description. Compilation,
|
||||
// execution and redistribution of this file may violate exclusive
|
||||
// patents rights in certain countries.
|
||||
// The situation being different for every country and changing
|
||||
// over time, it is your responsibility to determine which patent
|
||||
// rights restrictions apply to you before you compile, use,
|
||||
// modify, or redistribute this file. A patent lawyer is qualified
|
||||
// to make this determination.
|
||||
// If and only if they don't conflict with any patent terms, you
|
||||
// can benefit from the following license terms attached to this
|
||||
// file.
|
||||
//
|
||||
// This program is provided for scientific and educational only:
|
||||
// you can use and/or modify it for these purposes, but you are
|
||||
// not allowed to redistribute this work or derivative works in
|
||||
// source or executable form. A license must be obtained from the
|
||||
// patent right holders for any other use.
|
||||
//
|
||||
//
|
||||
//*------------------------ compute_asift_matches-- -------------------------*/
|
||||
// Match the ASIFT keypoints.
|
||||
//
|
||||
// Please report bugs and/or send comments to Guoshen Yu yu@cmap.polytechnique.fr
|
||||
//
|
||||
// Reference: J.M. Morel and G.Yu, ASIFT: A New Framework for Fully Affine Invariant Image
|
||||
// Comparison, SIAM Journal on Imaging Sciences, vol. 2, issue 2, pp. 438-469, 2009.
|
||||
// Reference: ASIFT online demo (You can try ASIFT with your own images online.)
|
||||
// http://www.ipol.im/pub/algo/my_affine_sift/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "compute_asift_matches.h"
|
||||
#include "libMatch/match.h"
|
||||
#include "orsa.h"
|
||||
|
||||
|
||||
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||
|
||||
/* Remove the repetitive matches that appear in different simulations and retain only one */
|
||||
void unique_match1(matchingslist &seg_in, matchingslist &seg_out, vector< vector <float> > &Minfoall_in, vector< vector <float> > &Minfoall_out)
|
||||
{
|
||||
int i_in, i_out;
|
||||
float x1_in, x2_in, y1_in, y2_in, x1_out, x2_out, y1_out, y2_out;
|
||||
int flag_unique;
|
||||
float d1, d2;
|
||||
int Th2 = 2;
|
||||
|
||||
seg_out.push_back(seg_in[0]);
|
||||
Minfoall_out.push_back(Minfoall_in[0]);
|
||||
|
||||
/* For other matches */
|
||||
if ( seg_in.size() > 1 )
|
||||
{
|
||||
/* check if a match is unique. if yes, copy */
|
||||
/* Bug fix by Xiaoyu Sun (Sichuan university) (Dec 13, 2015) */
|
||||
/* Original version
|
||||
matchingslist::iterator ptr_in = seg_in.begin();
|
||||
for ( i_in = 1; i_in < (int) seg_in.size(); i_in++, ptr_in++ )
|
||||
*/
|
||||
/* Bug fixed */
|
||||
matchingslist::iterator ptr_in = seg_in.begin();
|
||||
ptr_in++;
|
||||
for ( i_in = 1; i_in < (int) seg_in.size(); i_in++, ptr_in++ )
|
||||
{
|
||||
x1_in = ptr_in->first.x;
|
||||
y1_in = ptr_in->first.y;
|
||||
x2_in = ptr_in->second.x;
|
||||
y2_in = ptr_in->second.y;
|
||||
|
||||
flag_unique = 1;
|
||||
|
||||
matchingslist::iterator ptr_out = seg_out.begin();
|
||||
for ( i_out = 0; i_out < (int) seg_out.size(); i_out++, ptr_out++ )
|
||||
{
|
||||
x1_out = ptr_out->first.x;
|
||||
y1_out = ptr_out->first.y;
|
||||
x2_out = ptr_out->second.x;
|
||||
y2_out = ptr_out->second.y;
|
||||
|
||||
d1 = (x1_in - x1_out)*(x1_in - x1_out) + (y1_in - y1_out)*(y1_in - y1_out);
|
||||
d2 = (x2_in - x2_out)*(x2_in - x2_out) + (y2_in - y2_out)*(y2_in - y2_out);
|
||||
|
||||
|
||||
if ( ( d1 <= Th2) && ( d2 <= Th2) )
|
||||
{
|
||||
flag_unique = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( flag_unique == 1 )
|
||||
{
|
||||
seg_out.push_back(seg_in[i_in]);
|
||||
Minfoall_out.push_back(Minfoall_in[i_in]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the ALL one-to-multiple matches. */
|
||||
void clean_match1(matchingslist &seg_in, matchingslist &seg_out, vector< vector <float> > &Minfoall_in, vector< vector <float> > &Minfoall_out)
|
||||
{
|
||||
int i1, i2;
|
||||
float x1_in, x2_in, y1_in, y2_in, x1_out, x2_out, y1_out, y2_out;
|
||||
|
||||
// Guoshen Yu, 2010.09.22, Windows version
|
||||
// int flag_unique[seg_in.size()];
|
||||
int tmp_size = seg_in.size();
|
||||
int *flag_unique = new int[tmp_size];
|
||||
|
||||
int sum_flag=0;
|
||||
float d1, d2;
|
||||
int Th1 = 1;
|
||||
int Th2 = 4;
|
||||
|
||||
for ( i1 = 0; i1 < (int) seg_in.size(); i1++ )
|
||||
{
|
||||
flag_unique[i1] = 1;
|
||||
}
|
||||
|
||||
/* Set the flag of redundant matches to 0. */
|
||||
matchingslist::iterator ptr_in = seg_in.begin();
|
||||
for ( i1 = 0; i1 < (int) seg_in.size() - 1; i1++, ptr_in++ )
|
||||
{
|
||||
x1_in = ptr_in->first.x;
|
||||
y1_in = ptr_in->first.y;
|
||||
x2_in = ptr_in->second.x;
|
||||
y2_in = ptr_in->second.y;
|
||||
|
||||
matchingslist::iterator ptr_out = ptr_in+1;
|
||||
for ( i2 = i1 + 1; i2 < (int) seg_in.size(); i2++, ptr_out++ )
|
||||
{
|
||||
x1_out = ptr_out->first.x;
|
||||
y1_out = ptr_out->first.y;
|
||||
x2_out = ptr_out->second.x;
|
||||
y2_out = ptr_out->second.y;
|
||||
|
||||
d1 = (x1_in - x1_out)*(x1_in - x1_out) + (y1_in - y1_out)*(y1_in - y1_out);
|
||||
d2 = (x2_in - x2_out)*(x2_in - x2_out) + (y2_in - y2_out)*(y2_in - y2_out);
|
||||
|
||||
/* If redundant, set flags of both elements to 0.*/
|
||||
if ( ( ( d1 <= Th1) && ( d2 > Th2) ) || ( ( d1 > Th2) && ( d2 <= Th1) ) )
|
||||
{
|
||||
flag_unique[i1] = 0;
|
||||
flag_unique[i2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( i1 = 0; i1 < (int) seg_in.size(); i1++ )
|
||||
{
|
||||
sum_flag += flag_unique[i1];
|
||||
}
|
||||
|
||||
/* Copy the matches that are not redundant */
|
||||
if ( sum_flag > 0 )
|
||||
{
|
||||
for ( i1 = 0; i1 < (int) seg_in.size(); i1++ )
|
||||
{
|
||||
if ( flag_unique[i1] == 1 )
|
||||
{
|
||||
seg_out.push_back(seg_in[i1]);
|
||||
Minfoall_out.push_back(Minfoall_in[i1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Warning: all matches are redundant and are thus removed! This step of match cleaning is short circuited. (Normally this should not happen...)\n");
|
||||
}
|
||||
|
||||
// Guoshen Yu, 2010.09.22, Windows version
|
||||
delete [] flag_unique;
|
||||
}
|
||||
|
||||
|
||||
/* Remove the ALL multiple-to-one matches */
|
||||
void clean_match2(matchingslist &seg_in, matchingslist &seg_out, vector< vector <float> > &Minfoall_in, vector< vector <float> > &Minfoall_out)
|
||||
{
|
||||
int i1, i2;
|
||||
float x1_in, x2_in, y1_in, y2_in, x1_out, x2_out, y1_out, y2_out;
|
||||
|
||||
// Guoshen Yu, 2010.09.22, Windows version
|
||||
// int flag_unique[seg_in.size()];
|
||||
int tmp_size = seg_in.size();
|
||||
int *flag_unique = new int[tmp_size];
|
||||
|
||||
int sum_flag=0;
|
||||
float d1, d2;
|
||||
int Th1 = 1;
|
||||
int Th2 = 4;
|
||||
|
||||
for ( i1 = 0; i1 < (int) seg_in.size(); i1++ )
|
||||
{
|
||||
flag_unique[i1] = 1;
|
||||
}
|
||||
|
||||
/* Set the flag of redundant matches to 0. */
|
||||
matchingslist::iterator ptr_in = seg_in.begin();
|
||||
for ( i1 = 0; i1 < (int) seg_in.size() - 1; i1++, ptr_in++ )
|
||||
{
|
||||
x1_in = ptr_in->first.x;
|
||||
y1_in = ptr_in->first.y;
|
||||
x2_in = ptr_in->second.x;
|
||||
y2_in = ptr_in->second.y;
|
||||
|
||||
matchingslist::iterator ptr_out = ptr_in+1;
|
||||
for ( i2 = i1 + 1; i2 < (int) seg_in.size(); i2++, ptr_out++ )
|
||||
{
|
||||
|
||||
x1_out = ptr_out->first.x;
|
||||
y1_out = ptr_out->first.y;
|
||||
x2_out = ptr_out->second.x;
|
||||
y2_out = ptr_out->second.y;
|
||||
|
||||
d1 = (x1_in - x1_out)*(x1_in - x1_out) + (y1_in - y1_out)*(y1_in - y1_out);
|
||||
d2 = (x2_in - x2_out)*(x2_in - x2_out) + (y2_in - y2_out)*(y2_in - y2_out);
|
||||
|
||||
|
||||
/* If redundant, set flags of both elements to 0.*/
|
||||
if ( ( d1 > Th2) && ( d2 <= Th1) )
|
||||
{
|
||||
flag_unique[i1] = 0;
|
||||
flag_unique[i2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( i1 = 0; i1 < (int) seg_in.size(); i1++ )
|
||||
{
|
||||
sum_flag += flag_unique[i1];
|
||||
}
|
||||
|
||||
/* Copy the matches that are not redundant */
|
||||
if ( sum_flag > 0 )
|
||||
{
|
||||
for ( i1 = 0; i1 < (int) seg_in.size(); i1++ )
|
||||
{
|
||||
if ( flag_unique[i1] == 1 )
|
||||
{
|
||||
seg_out.push_back(seg_in[i1]);
|
||||
Minfoall_out.push_back(Minfoall_in[i1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Warning: all matches are redundant and are thus removed! This step of match cleaning is short circuited. (Normally this should not happen...)\n");
|
||||
}
|
||||
|
||||
// Guoshen Yu, 2010.09.22, Windows version
|
||||
delete [] flag_unique;
|
||||
}
|
||||
|
||||
|
||||
// Normalize the coordinates of the matched points by compensating the simulate affine transformations
|
||||
void compensate_affine_coor(matching &matching1, int w1, int h1, int w2, int h2, float t1, float t2, float Rtheta, float t_im2_1, float t_im2_2, float Rtheta2)
|
||||
{
|
||||
float x_ori, y_ori;
|
||||
float x_ori2, y_ori2, x_tmp, y_tmp;
|
||||
float x1, y1, x2, y2;
|
||||
|
||||
Rtheta = Rtheta*PI/180;
|
||||
|
||||
if ( Rtheta <= PI/2 )
|
||||
{
|
||||
x_ori = 0;
|
||||
y_ori = w1 * sin(Rtheta) / t1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x_ori = -w1 * cos(Rtheta) / t2;
|
||||
y_ori = ( w1 * sin(Rtheta) + h1 * sin(Rtheta-PI/2) ) / t1;
|
||||
}
|
||||
|
||||
Rtheta2 = Rtheta2*PI/180;
|
||||
|
||||
if ( Rtheta2 <= PI/2 )
|
||||
{
|
||||
x_ori2 = 0;
|
||||
y_ori2 = w2 * sin(Rtheta2) / t_im2_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x_ori2 = -w2 * cos(Rtheta2) / t_im2_2;
|
||||
y_ori2 = ( w2 * sin(Rtheta2) + h2 * sin(Rtheta2-PI/2) ) / t_im2_1;
|
||||
}
|
||||
|
||||
float sin_Rtheta = sin(Rtheta);
|
||||
float cos_Rtheta = cos(Rtheta);
|
||||
float sin_Rtheta2 = sin(Rtheta2);
|
||||
float cos_Rtheta2 = cos(Rtheta2);
|
||||
|
||||
x1 = matching1.first.x;
|
||||
y1 = matching1.first.y;
|
||||
x2 = matching1.second.x;
|
||||
y2 = matching1.second.y;
|
||||
|
||||
/* project the coordinates of im1 to original image before tilt-rotation transform */
|
||||
/* Get the coordinates with respect to the 'origin' of the original image before transform */
|
||||
x1 = x1 - x_ori;
|
||||
y1 = y1 - y_ori;
|
||||
/* Invert tilt */
|
||||
x1 = x1 * t2;
|
||||
y1 = y1 * t1;
|
||||
/* Invert rotation (Note that the y direction (vertical) is inverse to the usual concention. Hence Rtheta instead of -Rtheta to inverse the rotation.) */
|
||||
x_tmp = cos_Rtheta*x1 - sin_Rtheta*y1;
|
||||
y_tmp = sin_Rtheta*x1 + cos_Rtheta*y1;
|
||||
x1 = x_tmp;
|
||||
y1 = y_tmp;
|
||||
|
||||
/* Coordinate projection on image2 */
|
||||
|
||||
/* Get the coordinates with respect to the 'origin' of the original image before transform */
|
||||
x2 = x2 - x_ori2;
|
||||
y2 = y2 - y_ori2;
|
||||
/* Invert tilt */
|
||||
x2 = x2 * t_im2_2;
|
||||
y2 = y2 * t_im2_1;
|
||||
/* Invert rotation (Note that the y direction (vertical) is inverse to the usual concention. Hence Rtheta instead of -Rtheta to inverse the rotation.) */
|
||||
x_tmp = cos_Rtheta2*x2 - sin_Rtheta2*y2;
|
||||
y_tmp = sin_Rtheta2*x2 + cos_Rtheta2*y2;
|
||||
x2 = x_tmp;
|
||||
y2 = y_tmp;
|
||||
|
||||
matching1.first.x = x1;
|
||||
matching1.first.y = y1;
|
||||
matching1.second.x = x2;
|
||||
matching1.second.y = y2;
|
||||
}
|
||||
|
||||
int compute_asift_matches(int num_of_tilts1, int num_of_tilts2, int w1, int h1, int w2, int h2, int verb, vector< vector< keypointslist > >& keys1, vector< vector< keypointslist > >& keys2, matchingslist &matchings, siftPar &siftparameters)
|
||||
// Match the ASIFT keypoints.
|
||||
// Input:
|
||||
// num_of_tilts1, num_of_tilts2: number of tilts that have been simulated on the two images. (They can be different.)
|
||||
// w1, h1, w2, h2: widht/height of image1/image2.
|
||||
// verb: 1/0 --> show/don not show verbose messages. (1 for debugging)
|
||||
// keys1, keys2: ASIFT keypoints of image1/image2. (They should be calculated with compute_asift_keypoints.)
|
||||
// matchings (output): the coordinates (col1, row1, col2, row2) of all the matching points.
|
||||
//
|
||||
// Output: the number of matching points.
|
||||
{
|
||||
float t_min, t_k, t;
|
||||
int num_tilt1, num_tilt2, tt, num_rot_t2, num_rot1, rr;
|
||||
int cc;
|
||||
|
||||
int tt2, rr2, num_rot1_2;
|
||||
float t_im2;
|
||||
|
||||
/* It stores the coordinates of ALL matches points of ALL affine simulations */
|
||||
vector< vector <float> > Minfoall;
|
||||
|
||||
int Tmin = 8;
|
||||
float nfa_max = -2;
|
||||
|
||||
num_rot_t2 = 10;
|
||||
|
||||
t_min = 1;
|
||||
t_k = sqrt(2.);
|
||||
|
||||
num_tilt1 = num_of_tilts1;
|
||||
num_tilt2 = num_of_tilts2;
|
||||
|
||||
if ( ( num_tilt1 < 1 ) || ( num_tilt2 < 1 ) )
|
||||
{
|
||||
printf("Number of tilts num_tilt should be equal or larger than 1. \n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the vector structure for the matching points */
|
||||
std::vector< vector< vector < vector < matchingslist > > > > matchings_vec(num_tilt1);
|
||||
std::vector< vector< vector< vector< vector< vector <float> > > > > > Minfoall_vec(num_tilt1);
|
||||
for (tt = 1; tt <= num_tilt1; tt++)
|
||||
{
|
||||
t = t_min * pow(t_k, tt-1);
|
||||
if ( t == 1 )
|
||||
{
|
||||
num_rot1 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_rot1 = round(num_rot_t2*t/2);
|
||||
if ( num_rot1%2 == 1 )
|
||||
{
|
||||
num_rot1 = num_rot1 + 1;
|
||||
}
|
||||
num_rot1 = num_rot1 / 2;
|
||||
}
|
||||
|
||||
matchings_vec[tt-1].resize(num_rot1);
|
||||
Minfoall_vec[tt-1].resize(num_rot1);
|
||||
|
||||
for ( rr = 1; rr <= num_rot1; rr++ )
|
||||
{
|
||||
|
||||
matchings_vec[tt-1][rr-1].resize(num_tilt2);
|
||||
Minfoall_vec[tt-1][rr-1].resize(num_tilt2);
|
||||
|
||||
for (tt2 = 1; tt2 <= num_tilt2; tt2++)
|
||||
{
|
||||
t_im2 = t_min * pow(t_k, tt2-1);
|
||||
if ( t_im2 == 1 )
|
||||
{
|
||||
num_rot1_2 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_rot1_2 = round(num_rot_t2*t_im2/2);
|
||||
if ( num_rot1_2%2 == 1 )
|
||||
{
|
||||
num_rot1_2 = num_rot1_2 + 1;
|
||||
}
|
||||
num_rot1_2 = num_rot1_2 / 2;
|
||||
}
|
||||
|
||||
matchings_vec[tt-1][rr-1][tt2-1].resize(num_rot1_2);
|
||||
Minfoall_vec[tt-1][rr-1][tt2-1].resize(num_rot1_2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///*
|
||||
// * setup the tilt and rotation parameters
|
||||
// * for all the loops, this vector will hold
|
||||
// * the following parameters:
|
||||
// * tt, num_rot1, rr, tt2, num_rot1_2, rr2
|
||||
// */
|
||||
//vector<int> tilt_rot;
|
||||
///* loop on tilts for image 1 */
|
||||
//for (int tt = 1; tt <= num_tilt1; tt++)
|
||||
//{
|
||||
// float t = t_min * pow(t_k, tt-1);
|
||||
// int num_rot1;
|
||||
// /* if tilt t = 1, do not simulate rotation. */
|
||||
// if ( 1 == tt )
|
||||
// num_rot1 = 1;
|
||||
// else
|
||||
// {
|
||||
// /* number of rotations to simulate */
|
||||
// num_rot1 = round(num_rot_t2 * t / 2);
|
||||
// if ( num_rot1%2 == 1 )
|
||||
// num_rot1 = num_rot1 + 1;
|
||||
// num_rot1 = num_rot1 / 2;
|
||||
// }
|
||||
// /* loop on rotations for image 1 */
|
||||
// for (int rr = 1; rr <= num_rot1; rr++ )
|
||||
// {
|
||||
// /* loop on tilts for image 2 */
|
||||
// for (int tt2 = 1; tt2 <= num_tilt2; tt2++)
|
||||
// {
|
||||
// float t_im2 = t_min * pow(t_k, tt2-1);
|
||||
// int num_rot1_2;
|
||||
// if ( tt2 == 1 )
|
||||
// num_rot1_2 = 1;
|
||||
// else
|
||||
// {
|
||||
// num_rot1_2 = round(num_rot_t2 * t_im2 / 2);
|
||||
// if ( num_rot1_2%2 == 1 )
|
||||
// num_rot1_2 = num_rot1_2 + 1;
|
||||
// num_rot1_2 = num_rot1_2 / 2;
|
||||
// }
|
||||
// /* loop on rotations for image 2 */
|
||||
// for (int rr2 = 1; rr2 <= num_rot1_2; rr2++ )
|
||||
// {
|
||||
// tilt_rot.push_back(tt);
|
||||
// tilt_rot.push_back(num_rot1);
|
||||
// tilt_rot.push_back(rr);
|
||||
// tilt_rot.push_back(tt2);
|
||||
// tilt_rot.push_back(num_rot1_2);
|
||||
// tilt_rot.push_back(rr2);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
/* Calculate the number of simulations */
|
||||
#ifdef _OPENMP
|
||||
omp_set_nested(1);
|
||||
#endif
|
||||
// loop on tilts for image 1.
|
||||
#pragma omp parallel for private(tt)
|
||||
for (int tt = 1; tt <= num_tilt1; tt++)
|
||||
{
|
||||
|
||||
float t = t_min * pow(t_k, tt-1);
|
||||
|
||||
/* Attention: the t1, t2 do not follow the same convention as in compute_asift_keypoints */
|
||||
float t1 = t;
|
||||
float t2 = 1;
|
||||
|
||||
int num_rot1;
|
||||
|
||||
// If tilt t = 1, do not simulate rotation.
|
||||
if ( tt == 1 )
|
||||
{
|
||||
num_rot1 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The number of rotations to simulate under the current tilt.
|
||||
num_rot1 = round(num_rot_t2*t/2);
|
||||
if ( num_rot1%2 == 1 )
|
||||
{
|
||||
num_rot1 = num_rot1 + 1;
|
||||
}
|
||||
num_rot1 = num_rot1 / 2;
|
||||
}
|
||||
|
||||
|
||||
float delta_theta = PI/num_rot1;
|
||||
|
||||
// Loop on rotations for image 1.
|
||||
#pragma omp parallel for private(rr)
|
||||
for ( int rr = 1; rr <= num_rot1; rr++ )
|
||||
{
|
||||
float theta = delta_theta * (rr-1);
|
||||
theta = theta * 180 / PI;
|
||||
|
||||
/* Read the keypoints of image 1 */
|
||||
keypointslist keypoints1 = keys1[tt-1][rr-1];
|
||||
|
||||
// loop on tilts for image 2.
|
||||
#pragma omp parallel for private(tt2)
|
||||
for (int tt2 = 1; tt2 <= num_tilt2; tt2++)
|
||||
{
|
||||
float t_im2 = t_min * pow(t_k, tt2-1);
|
||||
|
||||
/* Attention: the t1, t2 do not follow the same convention as in asift_v1.c */
|
||||
float t_im2_1 = t_im2;
|
||||
float t_im2_2 = 1;
|
||||
|
||||
int num_rot1_2;
|
||||
|
||||
if ( tt2 == 1 )
|
||||
{
|
||||
num_rot1_2 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_rot1_2 = round(num_rot_t2*t_im2/2);
|
||||
if ( num_rot1_2%2 == 1 )
|
||||
{
|
||||
num_rot1_2 = num_rot1_2 + 1;
|
||||
}
|
||||
num_rot1_2 = num_rot1_2 / 2;
|
||||
}
|
||||
|
||||
float delta_theta2 = PI/num_rot1_2;
|
||||
|
||||
#pragma omp parallel for private(rr2)
|
||||
// Loop on rotations for image 2.
|
||||
for ( int rr2 = 1; rr2 <= num_rot1_2; rr2++ )
|
||||
{
|
||||
float theta2 = delta_theta2 * (rr2-1);
|
||||
theta2 = theta2 * 180 / PI;
|
||||
|
||||
/* Read the keypoints of image2. */
|
||||
keypointslist keypoints2 = keys2[tt2-1][rr2-1];
|
||||
|
||||
|
||||
// Match the keypoints of image1 and image2.
|
||||
matchingslist matchings1;
|
||||
compute_sift_matches(keypoints1,keypoints2,matchings1,siftparameters);
|
||||
|
||||
if ( verb )
|
||||
{
|
||||
printf("t1=%.2f, theta1=%.2f, num keys1 = %d, t2=%.2f, theta2=%.2f, num keys2 = %d, num matches=%d\n", t, theta, (int) keypoints1.size(), t_im2, theta2, (int) keypoints2.size(), (int) matchings1.size());
|
||||
}
|
||||
|
||||
/* Store the matches */
|
||||
if ( matchings1.size() > 0 )
|
||||
{
|
||||
matchings_vec[tt-1][rr-1][tt2-1][rr2-1] = matchingslist(matchings1.size());
|
||||
Minfoall_vec[tt-1][rr-1][tt2-1][rr2-1].resize(matchings1.size());
|
||||
|
||||
for ( int cc = 0; cc < (int) matchings1.size(); cc++ )
|
||||
{
|
||||
///// In the coordinates the affine transformations have been normalized already in compute_asift_keypoints. So no need to normalize here.
|
||||
// Normalize the coordinates of the matched points by compensating the simulate affine transformations
|
||||
// compensate_affine_coor(matchings1[cc], w1, h1, w2, h2, t1, t2, theta, t_im2_1, t_im2_2, theta2);
|
||||
|
||||
matchings_vec[tt-1][rr-1][tt2-1][rr2-1][cc] = matchings1[cc];
|
||||
|
||||
vector<float> Minfo_1match(6);
|
||||
Minfo_1match[0] = t1;
|
||||
Minfo_1match[1] = t2;
|
||||
Minfo_1match[2] = theta;
|
||||
Minfo_1match[3] = t_im2_1;
|
||||
Minfo_1match[4] = t_im2_2;
|
||||
Minfo_1match[5] = theta2;
|
||||
Minfoall_vec[tt-1][rr-1][tt2-1][rr2-1][cc] = Minfo_1match;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move the matches to a 1D vector
|
||||
for (tt = 1; tt <= num_tilt1; tt++)
|
||||
{
|
||||
t = t_min * pow(t_k, tt-1);
|
||||
|
||||
if ( t == 1 )
|
||||
{
|
||||
num_rot1 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_rot1 = round(num_rot_t2*t/2);
|
||||
if ( num_rot1%2 == 1 )
|
||||
{
|
||||
num_rot1 = num_rot1 + 1;
|
||||
}
|
||||
num_rot1 = num_rot1 / 2;
|
||||
}
|
||||
|
||||
for ( rr = 1; rr <= num_rot1; rr++ )
|
||||
{
|
||||
for (tt2 = 1; tt2 <= num_tilt2; tt2++)
|
||||
{
|
||||
t_im2 = t_min * pow(t_k, tt2-1);
|
||||
if ( t_im2 == 1 )
|
||||
{
|
||||
num_rot1_2 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_rot1_2 = round(num_rot_t2*t_im2/2);
|
||||
if ( num_rot1_2%2 == 1 )
|
||||
{
|
||||
num_rot1_2 = num_rot1_2 + 1;
|
||||
}
|
||||
num_rot1_2 = num_rot1_2 / 2;
|
||||
}
|
||||
|
||||
for ( rr2 = 1; rr2 <= num_rot1_2; rr2++ )
|
||||
{
|
||||
for ( cc=0; cc < (int) matchings_vec[tt-1][rr-1][tt2-1][rr2-1].size(); cc++ )
|
||||
{
|
||||
matchings.push_back(matchings_vec[tt-1][rr-1][tt2-1][rr2-1][cc]);
|
||||
Minfoall.push_back(Minfoall_vec[tt-1][rr-1][tt2-1][rr2-1][cc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( verb )
|
||||
{
|
||||
printf("The number of matches is %d \n", (int) matchings.size());
|
||||
}
|
||||
|
||||
|
||||
if ( matchings.size() > 0 )
|
||||
{
|
||||
/* Remove the repetitive matches that appear in different simulations and retain only one. */
|
||||
// Since tilts are simuated on both image 1 and image 2, it is normal to have repetitive matches.
|
||||
matchingslist matchings_unique;
|
||||
vector< vector<float> > Minfoall_unique;
|
||||
unique_match1(matchings, matchings_unique, Minfoall, Minfoall_unique);
|
||||
matchings = matchings_unique;
|
||||
Minfoall = Minfoall_unique;
|
||||
|
||||
if ( verb )
|
||||
{
|
||||
printf("The number of unique matches is %d \n", (int) matchings.size());
|
||||
}
|
||||
|
||||
// There often appear to be some one-to-multiple/multiple-to-one matches (one point in image 1 matches with many points in image 2/vice versa).
|
||||
// This is an artifact of SIFT on interpolated images, as the interpolation tends to create some auto-similar structures (steps for example).
|
||||
// These matches need to be removed.
|
||||
/* Separating the removal of multiple-to-one and one-to-multiple in two steps:
|
||||
- first remove multiple-to-one
|
||||
- then remove one-to-multiple
|
||||
This allows to avoid removing some good matches: multiple-to-one matches is much more frequent than one-to-multiple. Sometimes some of the feature points in image 1 that take part in "multiple-to-one" bad matches have also correct matches in image 2. The modified scheme avoid removing these good matches. */
|
||||
|
||||
// Remove to multiple-to-one matches
|
||||
matchings_unique.clear();
|
||||
Minfoall_unique.clear();
|
||||
clean_match2(matchings, matchings_unique, Minfoall, Minfoall_unique);
|
||||
matchings = matchings_unique;
|
||||
Minfoall = Minfoall_unique;
|
||||
|
||||
// Remove to one-to-multiple matches
|
||||
matchings_unique.clear();
|
||||
Minfoall_unique.clear();
|
||||
clean_match1(matchings, matchings_unique, Minfoall, Minfoall_unique);
|
||||
matchings = matchings_unique;
|
||||
Minfoall = Minfoall_unique;
|
||||
|
||||
|
||||
if ( verb )
|
||||
{
|
||||
printf("The number of final matches is %d \n", (int) matchings.size());
|
||||
}
|
||||
|
||||
// If enough matches to do epipolar filtering
|
||||
if ( (int) matchings.size() >= Tmin )
|
||||
{
|
||||
//////// Use ORSA to filter out the incorrect matches.
|
||||
// store the coordinates of the matching points
|
||||
vector<Match> match_coor;
|
||||
for ( cc = 0; cc < (int) matchings.size(); cc++ )
|
||||
{
|
||||
Match match1_coor;
|
||||
match1_coor.x1 = matchings[cc].first.x;
|
||||
match1_coor.y1 = matchings[cc].first.y;
|
||||
match1_coor.x2 = matchings[cc].second.x;
|
||||
match1_coor.y2 = matchings[cc].second.y;
|
||||
|
||||
match_coor.push_back(match1_coor);
|
||||
}
|
||||
|
||||
std::vector<float> index;
|
||||
// Guoshen Yu, 2010.09.23
|
||||
// index.clear();
|
||||
|
||||
int t_value_orsa=10000;
|
||||
int verb_value_orsa=0;
|
||||
int n_flag_value_orsa=0;
|
||||
int mode_value_orsa=2;
|
||||
int stop_value_orsa=0;
|
||||
|
||||
// epipolar filtering with the Moisan-Stival ORSA algorithm.
|
||||
// float nfa = orsa(w1, h1, match_coor, index, t_value_orsa, verb_value_orsa, n_flag_value_orsa, mode_value_orsa, stop_value_orsa);
|
||||
float nfa = orsa((w1+w2)/2, (h1+h2)/2, match_coor, index, t_value_orsa, verb_value_orsa, n_flag_value_orsa, mode_value_orsa, stop_value_orsa);
|
||||
|
||||
|
||||
// if the matching is significant, register the good matches
|
||||
if ( nfa < nfa_max )
|
||||
{
|
||||
// extract meaningful matches
|
||||
matchings_unique.clear();
|
||||
Minfoall_unique.clear();
|
||||
for ( cc = 0; cc < (int) index.size(); cc++ )
|
||||
{
|
||||
matchings_unique.push_back(matchings[(int)index[cc]]);
|
||||
Minfoall_unique.push_back(Minfoall[(int)index[cc]]);
|
||||
}
|
||||
matchings = matchings_unique;
|
||||
Minfoall = Minfoall_unique;
|
||||
|
||||
cout << "The two images match! " << matchings.size() << " matchings are identified. log(nfa)=" << nfa << "." << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
matchings.clear();
|
||||
Minfoall.clear();
|
||||
cout << "The two images do not match. The matching is not significant: log(nfa)=" << nfa << "." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
matchings.clear();
|
||||
Minfoall.clear();
|
||||
cout << "The two images do not match. Not enough matches to do epipolar filtering." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "The two images do not match.\n" << endl;
|
||||
}
|
||||
|
||||
return matchings.size();
|
||||
|
||||
}
|
||||
|
51
asift_match/src/compute_asift_matches.h
Executable file
51
asift_match/src/compute_asift_matches.h
Executable file
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) 2008-2011, Guoshen Yu <yu@cmap.polytechnique.fr>
|
||||
// Copyright (c) 2008-2011, Jean-Michel Morel <morel@cmla.ens-cachan.fr>
|
||||
//
|
||||
// WARNING:
|
||||
// This file implements an algorithm possibly linked to the patent
|
||||
//
|
||||
// Jean-Michel Morel and Guoshen Yu, Method and device for the invariant
|
||||
// affine recognition recognition of shapes (WO/2009/150361), patent pending.
|
||||
//
|
||||
// This file is made available for the exclusive aim of serving as
|
||||
// scientific tool to verify of the soundness and
|
||||
// completeness of the algorithm description. Compilation,
|
||||
// execution and redistribution of this file may violate exclusive
|
||||
// patents rights in certain countries.
|
||||
// The situation being different for every country and changing
|
||||
// over time, it is your responsibility to determine which patent
|
||||
// rights restrictions apply to you before you compile, use,
|
||||
// modify, or redistribute this file. A patent lawyer is qualified
|
||||
// to make this determination.
|
||||
// If and only if they don't conflict with any patent terms, you
|
||||
// can benefit from the following license terms attached to this
|
||||
// file.
|
||||
//
|
||||
// This program is provided for scientific and educational only:
|
||||
// you can use and/or modify it for these purposes, but you are
|
||||
// not allowed to redistribute this work or derivative works in
|
||||
// source or executable form. A license must be obtained from the
|
||||
// patent right holders for any other use.
|
||||
//
|
||||
//
|
||||
//*------------------------ compute_asift_matches-- -------------------------*/
|
||||
// Match the ASIFT keypoints.
|
||||
//
|
||||
// Please report bugs and/or send comments to Guoshen Yu yu@cmap.polytechnique.fr
|
||||
//
|
||||
// Reference: J.M. Morel and G.Yu, ASIFT: A New Framework for Fully Affine Invariant Image
|
||||
// Comparison, SIAM Journal on Imaging Sciences, vol. 2, issue 2, pp. 438-469, 2009.
|
||||
// Reference: ASIFT online demo (You can try ASIFT with your own images online.)
|
||||
// http://www.ipol.im/pub/algo/my_affine_sift/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "library.h"
|
||||
#include "demo_lib_sift.h"
|
||||
#include "frot.h"
|
||||
#include "fproj.h"
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
|
||||
int compute_asift_matches(int num_of_tilts1, int num_of_tilts2, int w1, int h1, int w2, int h2, int verb, vector< vector< keypointslist > >& keys1, vector< vector< keypointslist > >& keys2, matchingslist &matchings, siftPar &siftparameters);
|
||||
|
1222
asift_match/src/demo_lib_sift.cpp
Executable file
1222
asift_match/src/demo_lib_sift.cpp
Executable file
File diff suppressed because it is too large
Load diff
298
asift_match/src/demo_lib_sift.h
Executable file
298
asift_match/src/demo_lib_sift.h
Executable file
|
@ -0,0 +1,298 @@
|
|||
// Authors: Unknown. Please, if you are the author of this file, or if you
|
||||
// know who are the authors of this file, let us know, so we can give the
|
||||
// adequate credits and/or get the adequate authorizations.
|
||||
|
||||
// WARNING:
|
||||
// This file implements an algorithm possibly linked to the patent
|
||||
//
|
||||
// David Lowe "Method and apparatus for identifying scale invariant
|
||||
// features in an image and use of same for locating an object in an
|
||||
// image", U.S. Patent 6,711,293.
|
||||
//
|
||||
// This file is made available for the exclusive aim of serving as
|
||||
// scientific tool to verify of the soundness and
|
||||
// completeness of the algorithm description. Compilation,
|
||||
// execution and redistribution of this file may violate exclusive
|
||||
// patents rights in certain countries.
|
||||
// The situation being different for every country and changing
|
||||
// over time, it is your responsibility to determine which patent
|
||||
// rights restrictions apply to you before you compile, use,
|
||||
// modify, or redistribute this file. A patent lawyer is qualified
|
||||
// to make this determination.
|
||||
// If and only if they don't conflict with any patent terms, you
|
||||
// can benefit from the following license terms attached to this
|
||||
// file.
|
||||
//
|
||||
// This program is provided for scientific and educational only:
|
||||
// you can use and/or modify it for these purposes, but you are
|
||||
// not allowed to redistribute this work or derivative works in
|
||||
// source or executable form. A license must be obtained from the
|
||||
// patent right holders for any other use.
|
||||
|
||||
|
||||
#ifndef _CLIBSIFT_H_
|
||||
#define _CLIBSIFT_H_
|
||||
|
||||
|
||||
|
||||
///////////// Description
|
||||
/// For each octave:
|
||||
/// - Divide in par.Scales scales
|
||||
/// - Convolve and compute differences of convolved scales
|
||||
/// - Look for a 3x3 multiscale extrema and contraste enough and with no predominant direction (no 1d edge)
|
||||
|
||||
/// For each extrema
|
||||
/// - Compute orientation histogram in neighborhood.
|
||||
/// - Generate a keypoint for each mode with this orientation
|
||||
|
||||
|
||||
/// For each keypoint
|
||||
/// - Create vector
|
||||
|
||||
|
||||
|
||||
///////////// Possible differences with MW
|
||||
/// Gaussian convolution
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "numerics1.h"
|
||||
#include "library.h"
|
||||
#include "filter.h"
|
||||
#include "domain.h"
|
||||
#include "splines.h"
|
||||
#include "flimage.h"
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
// BASIC STRUCTURES:
|
||||
|
||||
// Keypoints:
|
||||
#define OriSize 8
|
||||
#define IndexSize 4
|
||||
#define VecLength IndexSize * IndexSize * OriSize
|
||||
|
||||
|
||||
/* Keypoint structure:
|
||||
position: x,y
|
||||
scale: s
|
||||
orientation: angle
|
||||
descriptor: array of gradient orientation histograms in a neighbors */
|
||||
struct keypoint {
|
||||
float x,y,
|
||||
scale,
|
||||
angle;
|
||||
float vec[VecLength];
|
||||
};
|
||||
|
||||
|
||||
/* Keypoint structure:
|
||||
position: x,y
|
||||
scale: s
|
||||
orientation: angle
|
||||
descriptor: array of gradient orientation histograms in a neighbors */
|
||||
struct keypoint_char {
|
||||
float x,y,
|
||||
scale,
|
||||
angle;
|
||||
unsigned char vec[VecLength];
|
||||
};
|
||||
|
||||
/* Keypoint structure:
|
||||
position: x,y
|
||||
scale: s
|
||||
orientation: angle
|
||||
descriptor: array of gradient orientation histograms in a neighbors */
|
||||
struct keypoint_short {
|
||||
float x,y,
|
||||
scale,
|
||||
angle;
|
||||
unsigned short vec[VecLength];
|
||||
};
|
||||
|
||||
/* Keypoint structure:
|
||||
position: x,y
|
||||
scale: s
|
||||
orientation: angle
|
||||
descriptor: array of gradient orientation histograms in a neighbors */
|
||||
struct keypoint_int {
|
||||
float x,y,
|
||||
scale,
|
||||
angle;
|
||||
unsigned int vec[VecLength];
|
||||
};
|
||||
|
||||
/* List of keypoints: just use the standard class vector: */
|
||||
typedef std::vector<keypoint> keypointslist;
|
||||
|
||||
/* List of keypoints: just use the standard class vector: */
|
||||
typedef std::vector<keypoint_char> keypointslist_char;
|
||||
typedef std::vector<keypoint_short> keypointslist_short;
|
||||
typedef std::vector<keypoint_int> keypointslist_int;
|
||||
|
||||
|
||||
|
||||
/* Matching: just use the standard class pair: */
|
||||
typedef std::pair<keypoint,keypoint> matching;
|
||||
|
||||
|
||||
/* List of matchings: just use the standard class vector: */
|
||||
typedef std::vector<matching> matchingslist;
|
||||
|
||||
|
||||
struct siftPar
|
||||
{
|
||||
|
||||
int OctaveMax;
|
||||
|
||||
int DoubleImSize;
|
||||
|
||||
int order;
|
||||
|
||||
|
||||
/* InitSigma gives the amount of smoothing applied to the image at the
|
||||
first level of each octave. In effect, this determines the sampling
|
||||
needed in the image domain relative to amount of smoothing. Good
|
||||
values determined experimentally are in the range 1.2 to 1.8.
|
||||
*/
|
||||
float InitSigma /*= 1.6*/;
|
||||
|
||||
|
||||
/* Peaks in the DOG function must be at least BorderDist samples away
|
||||
from the image border, at whatever sampling is used for that scale.
|
||||
Keypoints close to the border (BorderDist < about 15) will have part
|
||||
of the descriptor landing outside the image, which is approximated by
|
||||
having the closest image pixel replicated. However, to perform as much
|
||||
matching as possible close to the edge, use BorderDist of 4.
|
||||
*/
|
||||
int BorderDist /*= 5*/;
|
||||
|
||||
|
||||
/* Scales gives the number of discrete smoothing levels within each octave.
|
||||
For example, Scales = 2 implies dividing octave into 2 intervals, so
|
||||
smoothing for each scale sample is sqrt(2) more than previous level.
|
||||
Value of 2 works well, but higher values find somewhat more keypoints.
|
||||
*/
|
||||
|
||||
int Scales /*= 3*/;
|
||||
|
||||
|
||||
/// Decreasing PeakThresh allows more non contrasted keypoints
|
||||
/* Magnitude of difference-of-Gaussian value at a keypoint must be above
|
||||
this threshold. This avoids considering points with very low contrast
|
||||
that are dominated by noise. It is divided by Scales because more
|
||||
closely spaced scale samples produce smaller DOG values. A value of
|
||||
0.08 considers only the most stable keypoints, but applications may
|
||||
wish to use lower values such as 0.02 to find keypoints from low-contast
|
||||
regions.
|
||||
*/
|
||||
|
||||
//#define PeakThreshInit 255*0.04
|
||||
//#define PeakThresh PeakThreshInit / Scales
|
||||
float PeakThresh /*255.0 * 0.04 / 3.0*/;
|
||||
|
||||
/// Decreasing EdgeThresh allows more edge points
|
||||
/* This threshold eliminates responses at edges. A value of 0.08 means
|
||||
that the ratio of the largest to smallest eigenvalues (principle
|
||||
curvatures) is below 10. A value of 0.14 means ratio is less than 5.
|
||||
A value of 0.0 does not eliminate any responses.
|
||||
Threshold at first octave is different.
|
||||
*/
|
||||
float EdgeThresh /*0.06*/;
|
||||
float EdgeThresh1 /*0.08*/;
|
||||
|
||||
|
||||
/* OriBins gives the number of bins in the histogram (36 gives 10
|
||||
degree spacing of bins).
|
||||
*/
|
||||
int OriBins /*36*/;
|
||||
|
||||
|
||||
/* Size of Gaussian used to select orientations as multiple of scale
|
||||
of smaller Gaussian in DOG function used to find keypoint.
|
||||
Best values: 1.0 for UseHistogramOri = FALSE; 1.5 for TRUE.
|
||||
*/
|
||||
float OriSigma /*1.5*/;
|
||||
|
||||
|
||||
/// Look for local (3-neighborhood) maximum with valuer larger or equal than OriHistThresh * maxval
|
||||
/// Setting one returns a single peak
|
||||
/* All local peaks in the orientation histogram are used to generate
|
||||
keypoints, as long as the local peak is within OriHistThresh of
|
||||
the maximum peak. A value of 1.0 only selects a single orientation
|
||||
at each location.
|
||||
*/
|
||||
float OriHistThresh /*0.8*/;
|
||||
|
||||
|
||||
/// Feature vector is normalized to has euclidean norm 1.
|
||||
/// This threshold avoid the excessive concentration of information on single peaks
|
||||
/* Index values are thresholded at this value so that regions with
|
||||
high gradients do not need to match precisely in magnitude.
|
||||
Best value should be determined experimentally. Value of 1.0
|
||||
has no effect. Value of 0.2 is significantly better.
|
||||
*/
|
||||
float MaxIndexVal /*0.2*/;
|
||||
|
||||
|
||||
/* This constant specifies how large a region is covered by each index
|
||||
vector bin. It gives the spacing of index samples in terms of
|
||||
pixels at this scale (which is then multiplied by the scale of a
|
||||
keypoint). It should be set experimentally to as small a value as
|
||||
possible to keep features local (good values are in range 3 to 5).
|
||||
*/
|
||||
int MagFactor /*3*/;
|
||||
|
||||
|
||||
/* Width of Gaussian weighting window for index vector values. It is
|
||||
given relative to half-width of index, so value of 1.0 means that
|
||||
weight has fallen to about half near corners of index patch. A
|
||||
value of 1.0 works slightly better than large values (which are
|
||||
equivalent to not using weighting). Value of 0.5 is considerably
|
||||
worse.
|
||||
*/
|
||||
float IndexSigma /*1.0*/;
|
||||
|
||||
/* If this is TRUE, then treat gradients with opposite signs as being
|
||||
the same. In theory, this could create more illumination invariance,
|
||||
but generally harms performance in practice.
|
||||
*/
|
||||
int IgnoreGradSign /*0*/;
|
||||
|
||||
|
||||
|
||||
float MatchRatio /*0.6*/;
|
||||
|
||||
/*
|
||||
In order to constrain the research zone for matches.
|
||||
Useful for example when looking only at epipolar lines
|
||||
*/
|
||||
|
||||
float MatchXradius /*= 1000000.0f*/;
|
||||
float MatchYradius /*= 1000000.0f*/;
|
||||
|
||||
int noncorrectlylocalized;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
/// SIFT
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
void default_sift_parameters(siftPar &par);
|
||||
|
||||
void compute_sift_keypoints(float *input, keypointslist& keypoints,int width, int height, siftPar &par);
|
||||
|
||||
|
||||
|
||||
|
||||
// MATCHING DETECTION FUNCTION:
|
||||
void compute_sift_matches( keypointslist& keys1, keypointslist& keys2, matchingslist& matchings, siftPar &par);
|
||||
|
||||
#endif // _LIBSIFT_H_
|
||||
|
||||
|
||||
|
145
asift_match/src/domain.cpp
Executable file
145
asift_match/src/domain.cpp
Executable file
|
@ -0,0 +1,145 @@
|
|||
// Authors: Unknown. Please, if you are the author of this file, or if you
|
||||
// know who are the authors of this file, let us know, so we can give the
|
||||
// adequate credits and/or get the adequate authorizations.
|
||||
|
||||
#include "domain.h"
|
||||
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
|
||||
|
||||
|
||||
void apply_zoom(float *input, float *out, float zoom, int order, int width, int height)
|
||||
{
|
||||
|
||||
int nwidth = (int)( zoom * (float) width);
|
||||
int nheight = (int)( zoom * (float) height);
|
||||
|
||||
float *coeffs;
|
||||
float *ref;
|
||||
|
||||
float cx[12],cy[12],ak[13];
|
||||
|
||||
// Guoshen Yu, 2010.09.22, Windows versions
|
||||
vector<float> input_vec, coeffs_vec, ref_vec;
|
||||
input_vec = vector<float>(width*height);
|
||||
coeffs_vec = vector<float>(width*height);
|
||||
ref_vec = vector<float>(width*height);
|
||||
for (int i = 0; i < width*height; i++)
|
||||
input_vec[i] = input[i];
|
||||
|
||||
if (order!=0 && order!=1 && order!=-3 &&
|
||||
order!=3 && order!=5 && order!=7 && order!=9 && order!=11)
|
||||
{
|
||||
printf("unrecognized interpolation order.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (order>=3) {
|
||||
|
||||
coeffs = new float[width*height];
|
||||
|
||||
// Guoshen Yu, 2010.09.21, Windows version
|
||||
//finvspline(input,order,coeffs,width,height);
|
||||
finvspline(input_vec,order,coeffs_vec,width,height);
|
||||
for (int i = 0; i < width*height; i++)
|
||||
coeffs[i] = coeffs_vec[i];
|
||||
|
||||
ref = coeffs;
|
||||
if (order>3) init_splinen(ak,order);
|
||||
|
||||
} else
|
||||
{
|
||||
coeffs = NULL;
|
||||
ref = input;
|
||||
}
|
||||
|
||||
int xi,yi;
|
||||
float xp,yp;
|
||||
float res;
|
||||
int n1,n2;
|
||||
float bg = 0.0f;
|
||||
float p=-0.5;
|
||||
for(int i=0; i < nwidth; i++)
|
||||
for(int j=0; j < nheight; j++)
|
||||
{
|
||||
|
||||
xp = (float) i / zoom;
|
||||
yp = (float) j / zoom;
|
||||
|
||||
if (order == 0) {
|
||||
|
||||
xi = (int)floor((double)xp);
|
||||
yi = (int)floor((double)yp);
|
||||
|
||||
if (xi<0 || xi>=width || yi<0 || yi>=height)
|
||||
res = bg;
|
||||
else res = input[yi*width+xi];
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
if (xp<0. || xp>=(float)width || yp<0. || yp>=(float)height) res=bg;
|
||||
else {
|
||||
xp -= 0.5; yp -= 0.5;
|
||||
int xi = (int)floor((double)xp);
|
||||
int yi = (int)floor((double)yp);
|
||||
float ux = xp-(float)xi;
|
||||
float uy = yp-(float)yi;
|
||||
|
||||
switch (order)
|
||||
{
|
||||
case 1: /* first order interpolation (bilinear) */
|
||||
n2 = 1;
|
||||
cx[0]=ux; cx[1]=1.-ux;
|
||||
cy[0]=uy; cy[1]=1.-uy;
|
||||
break;
|
||||
|
||||
case -3: /* third order interpolation (bicubic Keys' function) */
|
||||
n2 = 2;
|
||||
keys(cx,ux,p);
|
||||
keys(cy,uy,p);
|
||||
break;
|
||||
|
||||
case 3: /* spline of order 3 */
|
||||
n2 = 2;
|
||||
spline3(cx,ux);
|
||||
spline3(cy,uy);
|
||||
break;
|
||||
|
||||
default: /* spline of order >3 */
|
||||
n2 = (1+order)/2;
|
||||
splinen(cx,ux,ak,order);
|
||||
splinen(cy,uy,ak,order);
|
||||
break;
|
||||
}
|
||||
|
||||
res = 0.; n1 = 1-n2;
|
||||
if (xi+n1>=0 && xi+n2<width && yi+n1>=0 && yi+n2<height) {
|
||||
|
||||
int adr = yi*width+xi;
|
||||
for (int dy=n1;dy<=n2;dy++)
|
||||
for (int dx=n1;dx<=n2;dx++)
|
||||
res += cy[n2-dy]*cx[n2-dx]*ref[adr+width*dy+dx];
|
||||
} else
|
||||
|
||||
// Guoshen Yu, 2010.09.21, Windows
|
||||
for (int i = 0; i < width*height; i++)
|
||||
ref_vec[i] = ref[i];
|
||||
|
||||
for (int dy=n1;dy<=n2;dy++)
|
||||
for (int dx=n1;dx<=n2;dx++)
|
||||
// Guoshen Yu, 2010.09.21, Windows
|
||||
// res += cy[n2-dy]*cx[n2-dx]*v(ref,xi+dx,yi+dy,bg,width,height);
|
||||
res += cy[n2-dy]*cx[n2-dx]*v(ref_vec,xi+dx,yi+dy,bg,width,height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
out[j*nwidth+i] = res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
40
asift_match/src/domain.h
Executable file
40
asift_match/src/domain.h
Executable file
|
@ -0,0 +1,40 @@
|
|||
// Authors: Unknown. Please, if you are the author of this file, or if you
|
||||
// know who are the authors of this file, let us know, so we can give the
|
||||
// adequate credits and/or get the adequate authorizations.
|
||||
|
||||
|
||||
#ifndef _DOMAIN_H_
|
||||
#define _DOMAIN_H_
|
||||
|
||||
|
||||
#include "numerics1.h"
|
||||
#include "library.h"
|
||||
#include "splines.h"
|
||||
|
||||
|
||||
/// Compute homography from n points using svd
|
||||
void compute_planar_homography_n_points(float *x0, float *y0, float *x1, float *y1, int n, float **H);
|
||||
|
||||
|
||||
/// Compute homography using svd + Ransac
|
||||
void compute_ransac_planar_homography_n_points(float *x0, float *y0, float *x1, float *y1, int n, int niter, float tolerance, float **H);
|
||||
|
||||
/// Compute homography by using Lionel Code
|
||||
void compute_moisan_planar_homography_n_points(float *x0, float *y0, float *x1, float *y1, int n, int niter, float &epsilon, float **H, int &counter, int recursivity);
|
||||
|
||||
|
||||
/// Apply planar homography to image
|
||||
void compute_planar_homography_bounding_box(int width, int height, float **H, float *x0, float *y0, int *nwidth, int *nheight);
|
||||
|
||||
|
||||
void apply_planar_homography(float *input, int width, int height, float **H, float bg, int order, float *out, float x0, float y0, int nwidth, int nheight);
|
||||
|
||||
|
||||
/// Apply zoom of factor z
|
||||
void apply_zoom(float *input, float *out, float zoom, int order, int width, int height);
|
||||
|
||||
/// Apply general transformation
|
||||
void apply_general_transformation(float *input, float *transformx, float* transformy, float *out, float bg, int order, int width, int height, int nwidth,int nheight);
|
||||
|
||||
#endif
|
||||
|
460
asift_match/src/filter.cpp
Executable file
460
asift_match/src/filter.cpp
Executable file
|
@ -0,0 +1,460 @@
|
|||
// Authors: Unknown. Please, if you are the author of this file, or if you
|
||||
// know who are the authors of this file, let us know, so we can give the
|
||||
// adequate credits and/or get the adequate authorizations.
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////// Build Gaussian filters
|
||||
float * directional_gauss_filter(float xsigma, float ysigma, float angle, int *kwidth, int *kheight)
|
||||
{
|
||||
|
||||
|
||||
int ksize = (int)(2.0 * 2.0 * MAX(xsigma, ysigma) + 1.0);
|
||||
float *kernel = new float[ksize*ksize];
|
||||
|
||||
float xsigma2 = xsigma*xsigma;
|
||||
float ysigma2 = ysigma*ysigma;
|
||||
|
||||
int l2 = ksize/2;
|
||||
for(int y = -l2; y <= l2; y++)
|
||||
for(int x = -l2; x <= l2; x++)
|
||||
{
|
||||
|
||||
float a = (float) angle * PI / 180.0f;
|
||||
float sina = sin(a);
|
||||
float cosa = cos(a);
|
||||
|
||||
float ax = (float) x * cosa + (float) y * sina;
|
||||
float ay = -(float) x * sina + (float) y * cosa;
|
||||
kernel[(y+l2) * ksize + x + l2] = exp(-(ax*ax)/(2.0f*xsigma2) - (ay*ay)/(2.0f*ysigma2) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
float sum=0.0;
|
||||
for(int i=0; i < ksize*ksize; i++) sum += kernel[i];
|
||||
for(int i=0; i < ksize*ksize; i++) kernel[i] /= sum;
|
||||
|
||||
*kwidth = ksize;
|
||||
*kheight = ksize;
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Convolution with a kernel */
|
||||
/* No padding applied to the image */
|
||||
void convol(float *u,float *v,int width,int height,float *kernel,int kwidth,int kheight)
|
||||
{
|
||||
|
||||
// float S;
|
||||
// int K2,L2,m,n,kmin,kmax,lmin,lmax,l,k;
|
||||
|
||||
int K2 = kwidth / 2;
|
||||
int L2 = kheight / 2;
|
||||
|
||||
for(int y=0 ; y < height; y++)
|
||||
for (int x=0 ; x < width; x++) {
|
||||
|
||||
float S = 0.0;
|
||||
// kmax = MIN(kwidth-1,n+K2);
|
||||
// kmin = MAX(0,1+n+K2-width);
|
||||
// lmax = MIN(kheight-1,m+L2);
|
||||
// lmin = MAX(0,1+m+L2-height);
|
||||
|
||||
for (int l = -L2; l <= L2; l++)
|
||||
for (int k = -K2 ; k<= K2; k++)
|
||||
{
|
||||
int px=x+k;
|
||||
int py=y+l;
|
||||
|
||||
if (px>=0 && px < width && py>=0 && py<height)
|
||||
S += u[width*py + px] * kernel[kwidth*(l+L2) + k+K2];
|
||||
}
|
||||
|
||||
v[y*width+x] = (float) S;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void median(float *u,float *v, float radius, int niter, int width,int height)
|
||||
{
|
||||
|
||||
|
||||
int iradius = (int)(radius+1.0);
|
||||
int rsize=(2*iradius+1)*(2*iradius+1);
|
||||
|
||||
float * vector = new float[rsize];
|
||||
float * index = new float[rsize];
|
||||
|
||||
for(int n=0; n< niter;n++){
|
||||
|
||||
for(int x=0;x<width;x++)
|
||||
for(int y=0;y<height;y++){
|
||||
|
||||
int count=0;
|
||||
for(int i=-iradius;i<=iradius;i++)
|
||||
for(int j=-iradius;j<=iradius;j++)
|
||||
if ((float) (i*i + j*j) <= iradius*iradius){
|
||||
|
||||
int x0=x+i;
|
||||
int y0=y+j;
|
||||
|
||||
if (x0>=0 && y0>=0 && x0 < width && y0 < height) {
|
||||
vector[count] = u[y0*width+x0];
|
||||
index[count] = count;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
quick_sort(vector,index,count);
|
||||
v[y*width+x] = vector[count/2];
|
||||
|
||||
}
|
||||
|
||||
copy(v,u,width*height);
|
||||
}
|
||||
|
||||
delete[] vector;
|
||||
delete[] index;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void remove_outliers(float *igray,float *ogray,int width, int height)
|
||||
{
|
||||
|
||||
|
||||
int bloc=1;
|
||||
int bsize = (2*bloc+1)*(2*bloc+1)-1;
|
||||
for(int x=bloc;x<width-bloc;x++)
|
||||
for(int y=bloc;y<height-bloc;y++) {
|
||||
|
||||
int l = y*width+x;
|
||||
|
||||
int countmax=0;
|
||||
int countmin=0;
|
||||
float valueg0 = igray[l];
|
||||
|
||||
// float distmin = MAXFLOAT;
|
||||
float distmin = FLT_MAX; // Guoshen Yu
|
||||
float green = igray[l];
|
||||
|
||||
for(int i=-bloc;i<=bloc;i++)
|
||||
for(int j=-bloc;j<=bloc;j++)
|
||||
if ((i!=0 || j!=0)){
|
||||
|
||||
int l0 = (y+j)*width+x+i;
|
||||
|
||||
int valueg = (int) igray[l0];
|
||||
|
||||
if (valueg0>valueg) countmax++;
|
||||
if (valueg0<valueg) countmin++;
|
||||
|
||||
|
||||
float dist = fabsf(valueg - valueg0);
|
||||
|
||||
if (dist < distmin) {distmin=dist;green=valueg;}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (countmin == bsize || countmax == bsize ) ogray[l]=green;
|
||||
else ogray[l] = igray[l];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Convolution with a separable kernel */
|
||||
/* boundary condition: 0=zero, 1=symmetry */
|
||||
void separable_convolution(float *u, float *v, int width, int height,float * xkernel, int xsize,float *ykernel,int ysize,int boundary)
|
||||
{
|
||||
|
||||
int width2 = 2*width;
|
||||
int height2 = 2*height;
|
||||
|
||||
float *tmp = (float *) malloc(width*height*sizeof(float));
|
||||
|
||||
|
||||
/* convolution along x axis */
|
||||
float sum = 0.0;
|
||||
int org = xsize / 2;
|
||||
for (int y=height;y--;)
|
||||
for (int x=width;x--;) {
|
||||
|
||||
sum = 0.0;
|
||||
for (int i=xsize;i--;) {
|
||||
int s = x-i+org;
|
||||
switch(boundary) {
|
||||
|
||||
case 0:
|
||||
if (s>=0 && s<width) sum += xkernel[i]*u[y*width+s];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
while (s<0) s+=width2;
|
||||
while (s>=width2) s-=width2;
|
||||
if (s>=width) s = width2-1-s;
|
||||
sum += xkernel[i]*u[y*width+s];
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
tmp[y*width+x] = sum;
|
||||
}
|
||||
|
||||
/* convolution along y axis */
|
||||
org = ysize / 2;
|
||||
for (int y=height;y--;)
|
||||
for (int x=width;x--;) {
|
||||
|
||||
sum=0.0;
|
||||
for (int i=ysize;i--;) {
|
||||
int s = y-i+org;
|
||||
switch(boundary) {
|
||||
case 0:
|
||||
if (s>=0 && s<height) sum += ykernel[i]*tmp[s*width+x];
|
||||
break;
|
||||
case 1:
|
||||
while (s<0) s+=height2;
|
||||
while (s>=height2) s-=height2;
|
||||
if (s>=height) s = height2-1-s;
|
||||
sum += ykernel[i]*tmp[s*width+x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
v[y*width+x] = sum;
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
|
||||
void gaussian_convolution(float *u, float *v, int width, int height, float sigma)
|
||||
{
|
||||
|
||||
int ksize;
|
||||
float * kernel;
|
||||
|
||||
ksize = (int)(2.0 * 4.0 * sigma + 1.0);
|
||||
kernel = gauss(1,sigma,&ksize);
|
||||
|
||||
int boundary = 1;
|
||||
|
||||
copy(u,v,width*height);
|
||||
horizontal_convolution(v, v, width, height, kernel, ksize, boundary);
|
||||
vertical_convolution(v, v, width, height, kernel, ksize, boundary);
|
||||
delete[] kernel; /*memcheck*/
|
||||
}
|
||||
|
||||
|
||||
void gaussian_convolution(float *u, float *v, int width, int height, float sigma, int ksize)
|
||||
{
|
||||
float * kernel;
|
||||
kernel = gauss(1,sigma,&ksize);
|
||||
|
||||
int boundary = 1;
|
||||
|
||||
copy(u,v,width*height);
|
||||
horizontal_convolution(v, v, width, height, kernel, ksize, boundary);
|
||||
vertical_convolution(v, v, width, height, kernel, ksize, boundary);
|
||||
}
|
||||
|
||||
|
||||
void fast_separable_convolution(float *u, float *v, int width, int height,float * xkernel, int xsize,float *ykernel,int ysize,int boundary)
|
||||
{
|
||||
copy(u,v,width*height);
|
||||
|
||||
horizontal_convolution(v, v, width, height, xkernel, xsize, boundary);
|
||||
vertical_convolution(v, v, width, height, ykernel, ysize, boundary);
|
||||
|
||||
}
|
||||
|
||||
/* Loop unrolling simply sums 5 multiplications
|
||||
at a time to allow the compiler to schedule
|
||||
operations better and avoid loop overhead.
|
||||
*/
|
||||
void buffer_convolution(float *buffer,float *kernel,int size,int ksize)
|
||||
{
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
float sum = 0.0;
|
||||
float *bp = &buffer[i];
|
||||
float *kp = &kernel[0];
|
||||
|
||||
|
||||
/* Loop unrolling: do 5 multiplications at a time. */
|
||||
// int k=0;
|
||||
|
||||
for(int k = 0; k < ksize; k++)
|
||||
sum += *bp++ * *kp++;
|
||||
|
||||
// for(;k + 4 < ksize; bp += 5, kp += 5, k += 5)
|
||||
// sum += bp[0] * kp[0] + bp[1] * kp[1] + bp[2] * kp[2] +
|
||||
// bp[3] * kp[3] + bp[4] * kp[4];
|
||||
|
||||
/* Do multiplications at a time on remaining items. */
|
||||
// for(; k < ksize; bp++ , kp++, k++) sum += *bp * (*kp);
|
||||
|
||||
buffer[i] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Convolve image with the 1-D kernel vector along image rows. This
|
||||
is designed to be as efficient as possible.
|
||||
*/
|
||||
void horizontal_convolution(float *u, float *v, int width, int height, float *kernel, int ksize, int boundary)
|
||||
{
|
||||
|
||||
int halfsize = ksize / 2;
|
||||
int buffersize = width + ksize;
|
||||
float *buffer = new float[buffersize];
|
||||
|
||||
for (int r = 0; r < height; r++) {
|
||||
|
||||
/// symmetry
|
||||
int l = r*width;
|
||||
if (boundary == 1)
|
||||
for (int i = 0; i < halfsize; i++)
|
||||
buffer[i] = u[l + halfsize - 1 - i ];
|
||||
else
|
||||
for (int i = 0; i < halfsize; i++)
|
||||
buffer[i] = 0.0;
|
||||
|
||||
|
||||
for (int i = 0; i < width; i++)
|
||||
buffer[halfsize + i] = u[l + i];
|
||||
|
||||
|
||||
if (boundary == 1)
|
||||
for (int i = 0; i < halfsize; i++)
|
||||
buffer[i + width + halfsize] = u[l + width - 1 - i];
|
||||
else
|
||||
for (int i = 0; i < halfsize; i++)
|
||||
buffer[i + width + halfsize] = 0.0;
|
||||
|
||||
buffer_convolution(buffer, kernel, width, ksize);
|
||||
for (int c = 0; c < width; c++)
|
||||
v[r*width+c] = buffer[c];
|
||||
}
|
||||
delete[] buffer; /*memcheck*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
void vertical_convolution(float *u, float *v, int width, int height, float *kernel,int ksize, int boundary)
|
||||
{
|
||||
int halfsize = ksize / 2;
|
||||
int buffersize = height + ksize;
|
||||
float *buffer = new float[buffersize];
|
||||
|
||||
for (int c = 0; c < width; c++) {
|
||||
|
||||
if (boundary == 1)
|
||||
for (int i = 0; i < halfsize; i++)
|
||||
buffer[i] = u[(halfsize-i-1)*width + c];
|
||||
else
|
||||
for (int i = 0; i < halfsize; i++)
|
||||
buffer[i] = 0.0f;
|
||||
|
||||
for (int i = 0; i < height; i++)
|
||||
buffer[halfsize + i] = u[i*width + c];
|
||||
|
||||
if (boundary == 1)
|
||||
for (int i = 0; i < halfsize; i++)
|
||||
buffer[halfsize + height + i] = u[(height - i - 1)*width+c];
|
||||
else
|
||||
for (int i = 0; i < halfsize; i++)
|
||||
buffer[halfsize + height + i] = 0.0f;
|
||||
|
||||
buffer_convolution(buffer, kernel, height, ksize);
|
||||
|
||||
for (int r = 0; r < height; r++)
|
||||
v[r*width+c] = buffer[r];
|
||||
|
||||
}
|
||||
delete[] buffer; /*memcheck*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
void heat(float *input, float *out, float step, int niter, float sigma, int width, int height)
|
||||
{
|
||||
|
||||
int i,j,n,ksize,size,im,i1,j1,jm;
|
||||
float *kernel = NULL, *laplacian = NULL, *convolved = NULL;
|
||||
|
||||
|
||||
size = width*height;
|
||||
|
||||
if (sigma > 0.0) kernel = gauss(0,sigma,&ksize);
|
||||
|
||||
laplacian = (float *) malloc(size*sizeof(float));
|
||||
convolved = (float *) malloc(size*sizeof(float));
|
||||
|
||||
|
||||
|
||||
for(n=0; n < niter; n++)
|
||||
{
|
||||
|
||||
|
||||
if (sigma > 0.0)
|
||||
{
|
||||
|
||||
separable_convolution(input,convolved,width,height, kernel, ksize,kernel,ksize,1);
|
||||
|
||||
for(i=0; i< size; i++) laplacian[i] = convolved[i] - input[i];
|
||||
|
||||
} else
|
||||
{
|
||||
|
||||
|
||||
for (i=0; i < width;i++)
|
||||
for (j=0; j< height ;j++)
|
||||
{
|
||||
|
||||
if (j==0) jm=1; else jm=j-1;
|
||||
if (j==height-1) j1=height-2; else j1=j+1;
|
||||
|
||||
if (i==0) im=1; else im=i-1;
|
||||
if (i==width-1) i1=width-2; else i1=i+1;
|
||||
|
||||
laplacian[j*width + i] = - 4.0 * input[width*j+i] + input[width*j+im]+ input[width*j+i1]+input[width*jm + i] + input[width*j1 + i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for(i=0; i < size; i++) out[i] = input[i] + step * laplacian[i];
|
||||
|
||||
copy(out,input,size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
free(laplacian);
|
||||
free(convolved);
|
||||
if (kernel) free(kernel);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
38
asift_match/src/filter.h
Executable file
38
asift_match/src/filter.h
Executable file
|
@ -0,0 +1,38 @@
|
|||
// Authors: Unknown. Please, if you are the author of this file, or if you
|
||||
// know who are the authors of this file, let us know, so we can give the
|
||||
// adequate credits and/or get the adequate authorizations.
|
||||
|
||||
|
||||
#ifndef _FILTER_H_
|
||||
#define _FILTER_H_
|
||||
|
||||
|
||||
#include "library.h"
|
||||
|
||||
|
||||
float * directional_gauss_filter(float xsigma, float ysigma, float angle, int *kwidth, int *kheight);
|
||||
|
||||
|
||||
void median(float *u,float *v, float radius, int niter, int width,int height);
|
||||
void remove_outliers(float *igray,float *ogray,int width, int height);
|
||||
|
||||
/// Convolution with a separable kernel, boundary condition: 0=zero, 1=symmetry
|
||||
void separable_convolution(float *u, float *v, int width, int height, float *xkernel, int xsize, float *ykernel, int ysize,int boundary);
|
||||
|
||||
void buffer_convolution(float *buffer,float *kernel,int size,int ksize);
|
||||
void horizontal_convolution(float *u, float *v, int width, int height, float *kernel, int ksize, int boundary);
|
||||
void vertical_convolution(float *u, float *v, int width, int height, float *kernel,int ksize, int boundary);
|
||||
|
||||
void fast_separable_convolution(float *u, float *v, int width, int height,float * xkernel, int xsize,float *ykernel,int ysize,int boundary);
|
||||
|
||||
/// Can be called with u=v
|
||||
void gaussian_convolution(float *u, float *v, int width, int height, float sigma);
|
||||
void gaussian_convolution(float *u, float *v, int width, int height, float sigma, int ksize);
|
||||
|
||||
void convol(float *u, float *v, int width, int height, float *kernel, int kwidth, int kheight); /// Convolution with a kernel, No padding applied to the image
|
||||
|
||||
void heat(float *u, float *v, float step, int niter, float sigma, int width, int height);
|
||||
|
||||
|
||||
#endif // _FILTER_H_
|
||||
|
86
asift_match/src/flimage.cpp
Executable file
86
asift_match/src/flimage.cpp
Executable file
|
@ -0,0 +1,86 @@
|
|||
// Authors: Unknown. Please, if you are the author of this file, or if you
|
||||
// know who are the authors of this file, let us know, so we can give the
|
||||
// adequate credits and/or get the adequate authorizations.
|
||||
|
||||
#include "flimage.h"
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////// Class flimage
|
||||
//// Construction
|
||||
flimage::flimage() : width(0), height(0), p(0)
|
||||
{
|
||||
}
|
||||
|
||||
flimage::flimage(int w, int h) : width(w), height(h), p(new float[w*h])
|
||||
{
|
||||
for (int j=width*height-1; j>=0 ; j--) p[j] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
flimage::flimage(int w, int h, float v) : width(w), height(h), p(new float[w*h])
|
||||
{
|
||||
for (int j=width*height-1; j>=0 ; j--) p[j] = v;
|
||||
}
|
||||
|
||||
|
||||
flimage::flimage(int w, int h, float* v) : width(w), height(h), p(new float[w*h])
|
||||
{
|
||||
for (int j=width*height-1; j>=0 ; j--) p[j] = v[j];
|
||||
}
|
||||
|
||||
|
||||
void flimage::create(int w, int h)
|
||||
{
|
||||
erase();
|
||||
width = w; height = h;
|
||||
p = new float[w*h];
|
||||
for (int j=width*height-1; j>=0 ; j--) p[j] = 0.0;
|
||||
}
|
||||
|
||||
void flimage::create(int w, int h, float* v)
|
||||
{
|
||||
erase();
|
||||
width = w; height = h; p = new float[w*h];
|
||||
for (int j=width*height-1; j>=0 ; j--) p[j] = v[j];
|
||||
}
|
||||
|
||||
|
||||
flimage::flimage(const flimage& im) : width(im.width), height(im.height), p(new float[im.width*im.height])
|
||||
{
|
||||
for (int j=width*height-1; j>=0 ; j--) p[j] = im.p[j];
|
||||
}
|
||||
|
||||
flimage& flimage::operator= (const flimage& im)
|
||||
{
|
||||
if (&im == this) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (width != im.width || height != im.height)
|
||||
{
|
||||
erase();
|
||||
width = im.width; height=im.height; p = new float[width*height];
|
||||
}
|
||||
|
||||
for (int j=width*height-1; j>=0 ; j--) p[j] = im.p[j];
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//// Destruction
|
||||
void flimage::erase()
|
||||
{
|
||||
width = height = 0;
|
||||
if (p) delete[] p;
|
||||
p=0;
|
||||
}
|
||||
|
||||
flimage::~flimage()
|
||||
{
|
||||
erase();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue