From 2a14d220c70ad8c0d33c16766a810a890d91c4ef Mon Sep 17 00:00:00 2001 From: edgarriba Date: Mon, 5 Oct 2015 16:19:50 +0200 Subject: [PATCH 1/4] gsoc_2015: sfm module integration --- modules/sfm/CMakeLists.txt | 122 +++ modules/sfm/README.md | 118 +++ modules/sfm/doc/pics/desktop_trajectory.png | Bin 0 -> 11840 bytes .../sfm/doc/pics/sagrada_familia_input.jpg | Bin 0 -> 29564 bytes .../pics/sagrada_familia_reconstruction.jpg | Bin 0 -> 29050 bytes modules/sfm/doc/pics/temple_input.jpg | Bin 0 -> 20107 bytes .../sfm/doc/pics/temple_reconstruction.jpg | Bin 0 -> 16998 bytes modules/sfm/include/opencv2/sfm.hpp | 102 +++ .../sfm/include/opencv2/sfm/conditioning.hpp | 123 +++ .../sfm/include/opencv2/sfm/fundamental.hpp | 225 +++++ modules/sfm/include/opencv2/sfm/numeric.hpp | 94 +++ .../sfm/include/opencv2/sfm/projection.hpp | 106 +++ .../sfm/include/opencv2/sfm/reconstruct.hpp | 143 ++++ modules/sfm/include/opencv2/sfm/robust.hpp | 106 +++ .../include/opencv2/sfm/simple_pipeline.hpp | 270 ++++++ .../sfm/include/opencv2/sfm/triangulation.hpp | 69 ++ modules/sfm/samples/data/backyard.blend | Bin 0 -> 755164 bytes modules/sfm/samples/data/backyard_tracks.txt | 63 ++ modules/sfm/samples/data/desktop.blend | Bin 0 -> 956320 bytes modules/sfm/samples/data/desktop_tracks.txt | 26 + .../sfm/samples/data/images/dataset_files.txt | 4 + .../samples/data/images/resized_IMG_2889.jpg | Bin 0 -> 160295 bytes .../samples/data/images/resized_IMG_2890.jpg | Bin 0 -> 162891 bytes .../samples/data/images/resized_IMG_2891.jpg | Bin 0 -> 170198 bytes .../samples/data/images/resized_IMG_2892.jpg | Bin 0 -> 210762 bytes .../samples/data/recon2v_checkerboards.txt | 309 +++++++ modules/sfm/samples/recon2v.cpp | 126 +++ modules/sfm/samples/scene_reconstruction.cpp | 160 ++++ .../sfm/samples/trajectory_reconstruccion.cpp | 246 ++++++ modules/sfm/src/conditioning.cpp | 187 +++++ modules/sfm/src/fundamental.cpp | 595 ++++++++++++++ modules/sfm/src/libmv_capi.h | 435 ++++++++++ .../src/libmv_light/CMake/Installation.cmake | 9 + modules/sfm/src/libmv_light/CMakeLists.txt | 5 + .../sfm/src/libmv_light/libmv/CMakeLists.txt | 7 + .../src/libmv_light/libmv/base/CMakeLists.txt | 9 + .../sfm/src/libmv_light/libmv/base/vector.h | 176 ++++ .../src/libmv_light/libmv/base/vector_utils.h | 34 + .../libmv/correspondence/CMakeLists.txt | 13 + .../libmv/correspondence/bipartite_graph.h | 139 ++++ .../libmv/correspondence/feature.h | 72 ++ .../libmv/correspondence/feature_matching.cc | 143 ++++ .../libmv/correspondence/feature_matching.h | 96 +++ .../libmv/correspondence/matches.cc | 99 +++ .../libmv/correspondence/matches.h | 319 ++++++++ .../correspondence/nRobustViewMatching.cc | 303 +++++++ .../correspondence/nRobustViewMatching.h | 138 ++++ .../correspondence/nViewMatchingInterface.h | 70 ++ .../src/libmv_light/libmv/logging/logging.h | 31 + .../libmv/multiview/CMakeLists.txt | 22 + .../libmv/multiview/conditioning.cc | 99 +++ .../libmv/multiview/conditioning.h | 59 ++ .../libmv/multiview/euclidean_resection.cc | 774 ++++++++++++++++++ .../libmv/multiview/euclidean_resection.h | 148 ++++ .../libmv/multiview/fundamental.cc | 551 +++++++++++++ .../libmv_light/libmv/multiview/fundamental.h | 187 +++++ .../libmv/multiview/fundamental_kernel.cc | 110 +++ .../libmv/multiview/fundamental_kernel.h | 148 ++++ .../libmv_light/libmv/multiview/homography.cc | 477 +++++++++++ .../libmv_light/libmv/multiview/homography.h | 145 ++++ .../libmv/multiview/homography_error.h | 248 ++++++ .../multiview/homography_parameterization.h | 91 ++ .../libmv/multiview/nviewtriangulation.h | 80 ++ .../libmv_light/libmv/multiview/panography.cc | 125 +++ .../libmv_light/libmv/multiview/panography.h | 99 +++ .../libmv/multiview/panography_kernel.cc | 51 ++ .../libmv/multiview/panography_kernel.h | 54 ++ .../libmv_light/libmv/multiview/projection.cc | 224 +++++ .../libmv_light/libmv/multiview/projection.h | 231 ++++++ .../libmv/multiview/random_sample.h | 63 ++ .../libmv_light/libmv/multiview/resection.h | 62 ++ .../libmv/multiview/resection_kernel.h | 66 ++ .../libmv/multiview/robust_estimation.cc | 31 + .../libmv/multiview/robust_estimation.h | 154 ++++ .../libmv/multiview/robust_fundamental.cc | 69 ++ .../libmv/multiview/robust_fundamental.h | 53 ++ .../libmv/multiview/robust_resection.cc | 48 ++ .../libmv/multiview/robust_resection.h | 41 + .../libmv/multiview/triangulation.cc | 50 ++ .../libmv/multiview/triangulation.h | 38 + .../libmv/multiview/two_view_kernel.h | 137 ++++ .../libmv/multiview/twoviewtriangulation.cc | 90 ++ .../libmv/multiview/twoviewtriangulation.h | 82 ++ .../libmv_light/libmv/numeric/CMakeLists.txt | 12 + .../libmv/numeric/function_derivative.h | 107 +++ .../libmv/numeric/levenberg_marquardt.h | 183 +++++ .../src/libmv_light/libmv/numeric/numeric.cc | 136 +++ .../src/libmv_light/libmv/numeric/numeric.h | 502 ++++++++++++ .../sfm/src/libmv_light/libmv/numeric/poly.cc | 23 + .../sfm/src/libmv_light/libmv/numeric/poly.h | 123 +++ .../libmv/simple_pipeline/CMakeLists.txt | 22 + .../libmv/simple_pipeline/bundle.cc | 658 +++++++++++++++ .../libmv/simple_pipeline/bundle.h | 147 ++++ .../libmv/simple_pipeline/callbacks.h | 34 + .../simple_pipeline/camera_intrinsics.cc | 293 +++++++ .../libmv/simple_pipeline/camera_intrinsics.h | 406 +++++++++ .../simple_pipeline/camera_intrinsics_impl.h | 192 +++++ .../simple_pipeline/distortion_models.cc | 197 +++++ .../libmv/simple_pipeline/distortion_models.h | 131 +++ .../initialize_reconstruction.cc | 195 +++++ .../initialize_reconstruction.h | 74 ++ .../libmv/simple_pipeline/intersect.cc | 254 ++++++ .../libmv/simple_pipeline/intersect.h | 77 ++ .../simple_pipeline/keyframe_selection.cc | 450 ++++++++++ .../simple_pipeline/keyframe_selection.h | 53 ++ .../libmv/simple_pipeline/pipeline.cc | 368 +++++++++ .../libmv/simple_pipeline/pipeline.h | 98 +++ .../libmv/simple_pipeline/reconstruction.cc | 191 +++++ .../libmv/simple_pipeline/reconstruction.h | 217 +++++ .../simple_pipeline/reconstruction_scale.cc | 68 ++ .../simple_pipeline/reconstruction_scale.h | 36 + .../libmv/simple_pipeline/resect.cc | 270 ++++++ .../libmv/simple_pipeline/resect.h | 86 ++ .../libmv/simple_pipeline/tracks.cc | 187 +++++ .../libmv/simple_pipeline/tracks.h | 138 ++++ modules/sfm/src/numeric.cpp | 173 ++++ modules/sfm/src/precomp.hpp | 47 ++ modules/sfm/src/projection.cpp | 223 +++++ modules/sfm/src/reconstruct.cpp | 258 ++++++ modules/sfm/src/robust.cpp | 195 +++++ modules/sfm/src/simple_pipeline.cpp | 319 ++++++++ modules/sfm/src/triangulation.cpp | 196 +++++ modules/sfm/test/scene.cpp | 122 +++ modules/sfm/test/scene.h | 41 + modules/sfm/test/test_common.cpp | 132 +++ modules/sfm/test/test_conditioning.cpp | 64 ++ modules/sfm/test/test_fundamental.cpp | 176 ++++ modules/sfm/test/test_main.cpp | 3 + modules/sfm/test/test_numeric.cpp | 91 ++ modules/sfm/test/test_precomp.hpp | 140 ++++ modules/sfm/test/test_projection.cpp | 113 +++ modules/sfm/test/test_reconstruct.cpp | 96 +++ modules/sfm/test/test_robust.cpp | 160 ++++ modules/sfm/test/test_simple_pipeline.cpp | 89 ++ modules/sfm/test/test_triangulation.cpp | 96 +++ .../sfm_installation.markdown | 63 ++ .../sfm_scene_reconstruction.markdown | 104 +++ .../sfm_trajectory_estimation.markdown | 82 ++ .../tutorials/table_of_content_sfm.markdown | 26 + 139 files changed, 19136 insertions(+) create mode 100644 modules/sfm/CMakeLists.txt create mode 100644 modules/sfm/README.md create mode 100644 modules/sfm/doc/pics/desktop_trajectory.png create mode 100644 modules/sfm/doc/pics/sagrada_familia_input.jpg create mode 100644 modules/sfm/doc/pics/sagrada_familia_reconstruction.jpg create mode 100644 modules/sfm/doc/pics/temple_input.jpg create mode 100644 modules/sfm/doc/pics/temple_reconstruction.jpg create mode 100644 modules/sfm/include/opencv2/sfm.hpp create mode 100644 modules/sfm/include/opencv2/sfm/conditioning.hpp create mode 100644 modules/sfm/include/opencv2/sfm/fundamental.hpp create mode 100644 modules/sfm/include/opencv2/sfm/numeric.hpp create mode 100644 modules/sfm/include/opencv2/sfm/projection.hpp create mode 100644 modules/sfm/include/opencv2/sfm/reconstruct.hpp create mode 100644 modules/sfm/include/opencv2/sfm/robust.hpp create mode 100644 modules/sfm/include/opencv2/sfm/simple_pipeline.hpp create mode 100644 modules/sfm/include/opencv2/sfm/triangulation.hpp create mode 100644 modules/sfm/samples/data/backyard.blend create mode 100644 modules/sfm/samples/data/backyard_tracks.txt create mode 100644 modules/sfm/samples/data/desktop.blend create mode 100644 modules/sfm/samples/data/desktop_tracks.txt create mode 100644 modules/sfm/samples/data/images/dataset_files.txt create mode 100644 modules/sfm/samples/data/images/resized_IMG_2889.jpg create mode 100644 modules/sfm/samples/data/images/resized_IMG_2890.jpg create mode 100644 modules/sfm/samples/data/images/resized_IMG_2891.jpg create mode 100644 modules/sfm/samples/data/images/resized_IMG_2892.jpg create mode 100644 modules/sfm/samples/data/recon2v_checkerboards.txt create mode 100644 modules/sfm/samples/recon2v.cpp create mode 100644 modules/sfm/samples/scene_reconstruction.cpp create mode 100644 modules/sfm/samples/trajectory_reconstruccion.cpp create mode 100644 modules/sfm/src/conditioning.cpp create mode 100644 modules/sfm/src/fundamental.cpp create mode 100644 modules/sfm/src/libmv_capi.h create mode 100644 modules/sfm/src/libmv_light/CMake/Installation.cmake create mode 100644 modules/sfm/src/libmv_light/CMakeLists.txt create mode 100644 modules/sfm/src/libmv_light/libmv/CMakeLists.txt create mode 100644 modules/sfm/src/libmv_light/libmv/base/CMakeLists.txt create mode 100644 modules/sfm/src/libmv_light/libmv/base/vector.h create mode 100644 modules/sfm/src/libmv_light/libmv/base/vector_utils.h create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/CMakeLists.txt create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/bipartite_graph.h create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/feature.h create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/feature_matching.cc create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/feature_matching.h create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/matches.cc create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/matches.h create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/nRobustViewMatching.cc create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/nRobustViewMatching.h create mode 100644 modules/sfm/src/libmv_light/libmv/correspondence/nViewMatchingInterface.h create mode 100644 modules/sfm/src/libmv_light/libmv/logging/logging.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/CMakeLists.txt create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/conditioning.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/conditioning.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/euclidean_resection.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/euclidean_resection.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/fundamental.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/fundamental.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/fundamental_kernel.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/fundamental_kernel.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/homography.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/homography.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/homography_error.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/homography_parameterization.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/nviewtriangulation.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/panography.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/panography.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/panography_kernel.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/panography_kernel.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/projection.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/projection.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/random_sample.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/resection.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/resection_kernel.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/robust_estimation.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/robust_estimation.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/robust_fundamental.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/robust_fundamental.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/robust_resection.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/robust_resection.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/triangulation.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/triangulation.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/two_view_kernel.h create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/twoviewtriangulation.cc create mode 100644 modules/sfm/src/libmv_light/libmv/multiview/twoviewtriangulation.h create mode 100644 modules/sfm/src/libmv_light/libmv/numeric/CMakeLists.txt create mode 100644 modules/sfm/src/libmv_light/libmv/numeric/function_derivative.h create mode 100644 modules/sfm/src/libmv_light/libmv/numeric/levenberg_marquardt.h create mode 100644 modules/sfm/src/libmv_light/libmv/numeric/numeric.cc create mode 100644 modules/sfm/src/libmv_light/libmv/numeric/numeric.h create mode 100644 modules/sfm/src/libmv_light/libmv/numeric/poly.cc create mode 100644 modules/sfm/src/libmv_light/libmv/numeric/poly.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/CMakeLists.txt create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/bundle.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/bundle.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/callbacks.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics_impl.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/distortion_models.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/distortion_models.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/initialize_reconstruction.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/initialize_reconstruction.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/intersect.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/intersect.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/keyframe_selection.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/keyframe_selection.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/pipeline.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/pipeline.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction_scale.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction_scale.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/resect.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/resect.h create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/tracks.cc create mode 100644 modules/sfm/src/libmv_light/libmv/simple_pipeline/tracks.h create mode 100644 modules/sfm/src/numeric.cpp create mode 100644 modules/sfm/src/precomp.hpp create mode 100644 modules/sfm/src/projection.cpp create mode 100644 modules/sfm/src/reconstruct.cpp create mode 100644 modules/sfm/src/robust.cpp create mode 100644 modules/sfm/src/simple_pipeline.cpp create mode 100644 modules/sfm/src/triangulation.cpp create mode 100644 modules/sfm/test/scene.cpp create mode 100644 modules/sfm/test/scene.h create mode 100644 modules/sfm/test/test_common.cpp create mode 100644 modules/sfm/test/test_conditioning.cpp create mode 100644 modules/sfm/test/test_fundamental.cpp create mode 100644 modules/sfm/test/test_main.cpp create mode 100644 modules/sfm/test/test_numeric.cpp create mode 100644 modules/sfm/test/test_precomp.hpp create mode 100644 modules/sfm/test/test_projection.cpp create mode 100644 modules/sfm/test/test_reconstruct.cpp create mode 100644 modules/sfm/test/test_robust.cpp create mode 100644 modules/sfm/test/test_simple_pipeline.cpp create mode 100644 modules/sfm/test/test_triangulation.cpp create mode 100644 modules/sfm/tutorials/sfm_installation/sfm_installation.markdown create mode 100644 modules/sfm/tutorials/sfm_scene reconstruction/sfm_scene_reconstruction.markdown create mode 100644 modules/sfm/tutorials/sfm_trajectory_estimation/sfm_trajectory_estimation.markdown create mode 100644 modules/sfm/tutorials/table_of_content_sfm.markdown diff --git a/modules/sfm/CMakeLists.txt b/modules/sfm/CMakeLists.txt new file mode 100644 index 0000000000..2e74a432b4 --- /dev/null +++ b/modules/sfm/CMakeLists.txt @@ -0,0 +1,122 @@ +set(the_description "SFM algorithms") + + +### LIBMV LIGHT EXTERNAL DEPENDENCIES ### + +find_package(Ceres QUIET) + +if(NOT DEFINED SFM_DEPS_OK) + set(_fname "${CMAKE_CURRENT_BINARY_DIR}/test_sfm_deps.cpp") + file(WRITE "${_fname}" "#include \n#include \nint main() { (void)(0); return 0; }\n") + try_compile(SFM_DEPS_OK "${CMAKE_CURRENT_BINARY_DIR}" "${_fname}" + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${GLOG_INCLUDE_DIRS};${GFLAGS_INCLUDE_DIRS}" + LINK_LIBRARIES ${GLOG_LIBRARIES} ${GFLAGS_LIBRARIES} + OUTPUT_VARIABLE OUTPUT + ) + file(REMOVE "${_fname}") + message(STATUS "Checking SFM deps... ${SFM_DEPS_OK}") +endif() + +if(NOT HAVE_EIGEN OR NOT SFM_DEPS_OK) + set(DISABLE_MSG "Module opencv_sfm disabled because the following dependencies are not found:") + if(NOT HAVE_EIGEN) + set(DISABLE_MSG "${DISABLE_MSG} Eigen") + endif() + if(NOT SFM_DEPS_OK) + set(DISABLE_MSG "${DISABLE_MSG} Glog/Gflags") + endif() + message(STATUS ${DISABLE_MSG}) + ocv_module_disable(sfm) +endif() + + +### LIBMV LIGHT DEFINITIONS ### + +set(LIBMV_LIGHT_INCLUDES + src/libmv_light + "${OpenCV_SOURCE_DIR}/include/opencv" + "${GLOG_INCLUDE_DIRS}" + "${GFLAGS_INCLUDE_DIRS}" +) + +set(LIBMV_LIGHT_LIBS + correspondence + multiview + numeric + ${GLOG_LIBRARIES} + ${GFLAGS_LIBRARIES} +) + +if(Ceres_FOUND) + add_definitions("-DCERES_FOUND=1") + list(APPEND LIBMV_LIGHT_LIBS simple_pipeline) +else() + add_definitions("-DCERES_FOUND=0") + message(STATUS "CERES support is disabled. Ceres Solver for reconstruction API is required.") +endif() + +### DEFINE OPENCV SFM MODULE DEPENDENCIES ### + +### CREATE OPENCV SFM MODULE ### + +ocv_add_module(sfm + opencv_core + opencv_calib3d + opencv_features2d + opencv_xfeatures2d +) + + +ocv_warnings_disable(CMAKE_CXX_FLAGS + -Wundef + -Wshadow + -Wsign-compare + -Wmissing-declarations + -Wunused-but-set-variable + -Wunused-parameter + -Wunused-function +) + +if(UNIX) + if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + endif() +endif() + +ocv_include_directories( ${LIBMV_LIGHT_INCLUDES} ) +ocv_module_include_directories() + +# source files +FILE(GLOB OPENCV_SFM_SRC src/*.cpp) + +# define the header files (make the headers appear in IDEs.) +FILE(GLOB OPENCV_SFM_HDRS include/opencv2/sfm/*.hpp) + +ocv_set_module_sources(HEADERS ${OPENCV_SFM_HDRS} + SOURCES ${OPENCV_SFM_SRC}) + +ocv_create_module() + +# build libmv_light +if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) # See ocv_target_include_directories() implementation + if(TARGET ${the_module}) + get_target_property(__include_dirs ${the_module} INCLUDE_DIRECTORIES) + include_directories(${__include_dirs}) + endif() +endif() +include_directories(${OCV_TARGET_INCLUDE_DIRS_${the_module}}) +add_subdirectory(src/libmv_light) + +ocv_target_link_libraries(${the_module} ${LIBMV_LIGHT_LIBS}) + + +### CREATE OPENCV SFM TESTS ### + +ocv_add_accuracy_tests() + + +### CREATE OPENCV SFM SAMPLES ### + +if(Ceres_FOUND) + ocv_add_samples(opencv_viz) +endif () diff --git a/modules/sfm/README.md b/modules/sfm/README.md new file mode 100644 index 0000000000..57f34ffd29 --- /dev/null +++ b/modules/sfm/README.md @@ -0,0 +1,118 @@ +Structure From Motion module +============================ + +This module contains algorithms to perform 3d reconstruction from 2d images. The core of the module is a light version of [Libmv](https://developer.blender.org/project/profile/59), which is a Library for Multiview Reconstruction (or LMV) divided into different modules (correspondence/numeric/multiview/simple_pipeline) that allow to resolve part of the SfM process. + + +Dependencies +------------ + +Before compiling, take a look at the following details in order to give a proper use of the Struncture from Motion module. **Advice:** The module is only available for Linux/GNU systems. + +In addition, it depends on some open source libraries: + +- [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page) 3.2.2 or later. **Required** +- [Google Log](http://code.google.com/p/google-glog) 0.3.1 or later. **Required** +- [Google Flags](http://code.google.com/p/gflags). **Required** +- [Ceres Solver](http://ceres-solver.org). Needed by the reconstruction API in order to solve part of the Bundle Adjustment plus the points Intersect. If Ceres Solver is not installed on your system, the reconstruction funcionality will be disabled. **Recommended** + +Installation +------------ +**Required Dependencies** + +In case you are on [Ubuntu](http://www.ubuntu.com/) you can simply install the required dependencies by typing the following command. + + sudo apt-get install libeigen3-dev libgflags-dev libgoogle-glog-dev + +**Ceres Solver** + +Start by installing all the dependencies. + + # CMake + sudo apt-get install cmake + # google-glog + gflags + sudo apt-get install libgoogle-glog-dev + # BLAS & LAPACK + sudo apt-get install libatlas-base-dev + # Eigen3 + sudo apt-get install libeigen3-dev + # SuiteSparse and CXSparse (optional) + # - If you want to build Ceres as a *static* library (the default) + # you can use the SuiteSparse package in the main Ubuntu package + # repository: + sudo apt-get install libsuitesparse-dev + # - However, if you want to build Ceres as a *shared* library, you must + # add the following PPA: + sudo add-apt-repository ppa:bzindovic/suitesparse-bugfix-1319687 + sudo apt-get update + sudo apt-get install libsuitesparse-dev + +We are now ready to build, test, and install Ceres. + + git clone https://ceres-solver.googlesource.com/ceres-solver + cd ceres-solver + mkdir build && cd build + cmake .. + make -j4 + make test + sudo make install + +Usage +----- + +**trajectory_reconstruction.cpp** + +This program shows the camera trajectory reconstruction capabilities in the OpenCV Structure From Motion (SFM) module. It loads a file with the tracked 2d points over all the frames which are embedded into a vector of 2d points array, where each inner array represents a different frame. Every frame is composed by a list of 2d points which e.g. the first point in frame 1 is the same point in frame 2. If there is no point in a frame the assigned value will be (-1,-1). + +To run this example you can type the following command in the opencv binaries directory specifying the file path in your system and the camera intrinsics (in this case the tracks file was obtained using Blender Motion module). + + ./example_sfm_trajectory_reconstruction tracks_file.txt 1914 640 360 + +Finally, the script reconstructs the given set of tracked points and show the result using the OpenCV 3D visualizer (viz). On the image below, it's shown a screenshot with the result you should obtain running the "desktop_tracks.txt" found inside the samples directory. + +

+ +

+ +**scene_reconstruction.cpp** + +This program shows the multiview scene reconstruction capabilities in the OpenCV Structure From Motion (SFM) module. It calls the recontruction API using the overloaded signature for real images. In this case the script loads a file which provides a list with all the image paths that we want to reconstruct. Internally, this script extract and compute the sparse 2d features using DAISY descriptors which are matched using FlannBasedMatcher to finally build the tracks structure. + +To run this example you can type the following command in the opencv binaries directory specifying the file path and the camera intrinsics. + + ./example_sfm_scene_reconstruction image_paths_file.txt 350 240 360 + +This sample shows the estimated camera trajectory plus the sparse 3D reconstruction using the the OpenCV 3D visualizer (viz). + +On the next pictures, it's shown a screenshot where you can see the used images as input from the "Temple of the Dioskouroi" [1] and the obtained result after running the reconstruction API. + +

+ +

+

+ +

+ +On the next pictures, it's shown a screenshot where you can see the used images as input from la Sagrada Familia (BCN) [2] which you can find in the samples directory and the obtained result after running the reconstruction API. + +

+ +

+

+ +

+ + +[1] [http://vision.middlebury.edu/mview/data](http://vision.middlebury.edu/mview/data) + +[2] Penate Sanchez, A. and Moreno-Noguer, F. and Andrade Cetto, J. and Fleuret, F. (2014). LETHA: *Learning from High Quality Inputs for 3D Pose Estimation in Low Quality Images*. Proceedings of the International Conference on 3D vision (3DV). [[URL]](http://www.iri.upc.edu/research/webprojects/pau/datasets/sagfam) + + +Future Work +----------- + +* Update signatures documentation. +* Add prototype for dense reconstruction once is working (DAISY paper implementation). +* Decide which functions are kept since most of them are the same in calib3d. +* Finish to implement computeOrientation(). +* Find a good features matchig algorithm for reconstruction() in case we provide pure images for autocalibration (look into OpenMVG). diff --git a/modules/sfm/doc/pics/desktop_trajectory.png b/modules/sfm/doc/pics/desktop_trajectory.png new file mode 100644 index 0000000000000000000000000000000000000000..d242edef84bef20de0a654d5f1e1578b1f0dc482 GIT binary patch literal 11840 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�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 literal 0 HcmV?d00001 diff --git a/modules/sfm/doc/pics/temple_input.jpg b/modules/sfm/doc/pics/temple_input.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7f1fa07e9a1f9994bdee711156be9ea7868fcd61 GIT binary patch literal 20107 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 literal 0 HcmV?d00001 diff --git a/modules/sfm/doc/pics/temple_reconstruction.jpg b/modules/sfm/doc/pics/temple_reconstruction.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a273f75b83191892eb5c31a3026f104848390afb GIT binary patch literal 16998 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 literal 0 HcmV?d00001 diff --git a/modules/sfm/include/opencv2/sfm.hpp b/modules/sfm/include/opencv2/sfm.hpp new file mode 100644 index 0000000000..f6e24cd43e --- /dev/null +++ b/modules/sfm/include/opencv2/sfm.hpp @@ -0,0 +1,102 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPENCV_SFM_HPP__ +#define __OPENCV_SFM_HPP__ + +#include +#include +#include +#include +#include +#if CERES_FOUND +#include +#include +#endif + +/** @defgroup sfm Structure From Motion + +The opencv_sfm module contains algorithms to perform 3d reconstruction +from 2d images.\n +The core of the module is based on a light version of +[Libmv](https://developer.blender.org/project/profile/59) originally +developed by Sameer Agarwal and Keir Mierle. + +__Whats is libmv?__ \n +libmv, also known as the Library for Multiview Reconstruction (or LMV), +is the computer vision backend for Blender's motion tracking abilities. +Unlike other vision libraries with general ambitions, libmv is focused +on algorithms for match moving, specifically targeting [Blender](https://developer.blender.org) as the +primary customer. Dense reconstruction, reconstruction from unorganized +photo collections, image recognition, and other tasks are not a focus +of libmv. + +__Development__ \n +libmv is officially under the Blender umbrella, and so is developed +on developer.blender.org. The [source repository](https://developer.blender.org/diffusion/LMV) can get checked out +independently from Blender. + +This module has been originally developed as a project for Google Summer of Code 2012-2015. + +@note + - Notice that it is compiled only when Eigen, GLog and GFlags are correctly installed.\n + Check installation instructions in the following tutorial: @ref tutorial_sfm_installation + + @{ + @defgroup conditioning Conditioning + @defgroup fundamental Fundamental + @defgroup numeric Numeric + @defgroup projection Projection + @defgroup robust Robust Estimation + @defgroup triangulation Triangulation + + @defgroup reconstruction Reconstruction + @note + - Notice that it is compiled only when Ceres Solver is correctly installed.\n + Check installation instructions in the following tutorial: @ref tutorial_sfm_installation + + + @defgroup simple_pipeline Simple Pipeline + @note + - Notice that it is compiled only when Ceres Solver is correctly installed.\n + Check installation instructions in the following tutorial: @ref tutorial_sfm_installation + + @} + +*/ + +#endif + +/* End of file. */ diff --git a/modules/sfm/include/opencv2/sfm/conditioning.hpp b/modules/sfm/include/opencv2/sfm/conditioning.hpp new file mode 100644 index 0000000000..052a6cd663 --- /dev/null +++ b/modules/sfm/include/opencv2/sfm/conditioning.hpp @@ -0,0 +1,123 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPENCV_CONDITIONING_HPP__ +#define __OPENCV_CONDITIONING_HPP__ + +#include + +namespace cv +{ +namespace sfm +{ + +//! @addtogroup conditioning +//! @{ + +/** Point conditioning (non isotropic). + @param points Input vector of N-dimensional points. + @param T Output 3x3 transformation matrix. + + Computes the transformation matrix such that the two principal moments of the set of points are equal to unity, + forming an approximately symmetric circular cloud of points of radius 1 about the origin.\n + Reference: @cite HartleyZ00 4.4.4 pag.109 +*/ +CV_EXPORTS +void +preconditionerFromPoints( InputArray points, + OutputArray T ); + +/** @brief Point conditioning (isotropic). + @param points Input vector of N-dimensional points. + @param T Output 3x3 transformation matrix. + + Computes the transformation matrix such that each coordinate direction will be scaled equally, + bringing the centroid to the origin with an average centroid \f$(1,1,1)^T\f$.\n + Reference: @cite HartleyZ00 4.4.4 pag.107. +*/ +CV_EXPORTS +void +isotropicPreconditionerFromPoints( InputArray points, + OutputArray T ); + +/** @brief Apply Transformation to points. + @param points Input vector of N-dimensional points. + @param T Input 3x3 transformation matrix such that \f$x = T*X\f$, where \f$X\f$ are the points to transform and \f$x\f$ the transformed points. + @param transformed_points Output vector of N-dimensional transformed points. +*/ +CV_EXPORTS +void +applyTransformationToPoints( InputArray points, + InputArray T, + OutputArray transformed_points ); + +/** @brief This function normalizes points (non isotropic). + @param points Input vector of N-dimensional points. + @param normalized_points Output vector of the same N-dimensional points but with mean 0 and average norm \f$\sqrt{2}\f$. + @param T Output 3x3 transform matrix such that \f$x = T*X\f$, where \f$X\f$ are the points to normalize and \f$x\f$ the normalized points. + + Internally calls @ref preconditionerFromPoints in order to get the scaling matrix before applying @ref applyTransformationToPoints. + This operation is an essential step before applying the DLT algorithm in order to consider the result as optimal.\n + Reference: @cite HartleyZ00 4.4.4 pag.109 +*/ +CV_EXPORTS +void +normalizePoints( InputArray points, + OutputArray normalized_points, + OutputArray T ); + +/** @brief This function normalizes points. (isotropic). + @param points Input vector of N-dimensional points. + @param normalized_points Output vector of the same N-dimensional points but with mean 0 and average norm \f$\sqrt{2}\f$. + @param T Output 3x3 transform matrix such that \f$x = T*X\f$, where \f$X\f$ are the points to normalize and \f$x\f$ the normalized points. + + Internally calls @ref preconditionerFromPoints in order to get the scaling matrix before applying @ref applyTransformationToPoints. + This operation is an essential step before applying the DLT algorithm in order to consider the result as optimal.\n + Reference: @cite HartleyZ00 4.4.4 pag.107. +*/ +CV_EXPORTS +void +normalizeIsotropicPoints( InputArray points, + OutputArray normalized_points, + OutputArray T ); + +//! @} sfm + +} /* namespace sfm */ +} /* namespace cv */ + +#endif + +/* End of file. */ \ No newline at end of file diff --git a/modules/sfm/include/opencv2/sfm/fundamental.hpp b/modules/sfm/include/opencv2/sfm/fundamental.hpp new file mode 100644 index 0000000000..8dfdc4050d --- /dev/null +++ b/modules/sfm/include/opencv2/sfm/fundamental.hpp @@ -0,0 +1,225 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPENCV_SFM_FUNDAMENTAL_HPP__ +#define __OPENCV_SFM_FUNDAMENTAL_HPP__ + +#include + +#include + +namespace cv +{ +namespace sfm +{ + +//! @addtogroup fundamental +//! @{ + +/** @brief Get projection matrices from Fundamental matrix + @param F Input 3x3 fundamental matrix. + @param P1 Output 3x4 one possible projection matrix. + @param P2 Output 3x4 another possible projection matrix. + */ +CV_EXPORTS +void +projectionsFromFundamental( InputArray F, + OutputArray P1, + OutputArray P2 ); + +/** @brief Get Fundamental matrix from Projection matrices. + @param P1 Input 3x4 first projection matrix. + @param P2 Input 3x4 second projection matrix. + @param F Output 3x3 fundamental matrix. + */ +CV_EXPORTS +void +fundamentalFromProjections( InputArray P1, + InputArray P2, + OutputArray F ); + +/** @brief Estimate the fundamental matrix between two dataset of 2D point (image coords space). + @param x1 Input 2xN Array of 2D points in view 1. + @param x2 Input 2xN Array of 2D points in view 2. + @param F Output 3x3 fundamental matrix. + + Uses the normalized 8-point fundamental matrix solver. + Reference: @cite HartleyZ00 11.2 pag.281 (x1 = x, x2 = x') + */ +CV_EXPORTS +void +normalizedEightPointSolver( InputArray x1, + InputArray x2, + OutputArray F ); + +/** @brief Computes the relative camera motion between two cameras. + @param R1 Input 3x3 first camera rotation matrix. + @param t1 Input 3x1 first camera translation vector. + @param R2 Input 3x3 second camera rotation matrix. + @param t2 Input 3x1 second camera translation vector. + @param R Output 3x3 relative rotation matrix. + @param t Output 3x1 relative translation vector. + + Given the motion parameters of two cameras, computes the motion parameters + of the second one assuming the first one to be at the origin. + If T1 and T2 are the camera motions, the computed relative motion is \f$T = T_2 T_1^{-1}\f$ + */ +CV_EXPORTS +void +relativeCameraMotion( InputArray R1, + InputArray t1, + InputArray R2, + InputArray t2, + OutputArray R, + OutputArray t ); + +/** Get Motion (R's and t's ) from Essential matrix. + @param E Input 3x3 essential matrix. + @param Rs Output vector of 3x3 rotation matrices. + @param ts Output vector of 3x1 translation vectors. + + Reference: @cite HartleyZ00 9.6 pag 259 (Result 9.19) + */ +CV_EXPORTS +void +motionFromEssential( InputArray E, + OutputArrayOfArrays Rs, + OutputArrayOfArrays ts ); + +/** Choose one of the four possible motion solutions from an essential matrix. + @param Rs Input vector of 3x3 rotation matrices. + @param ts Input vector of 3x1 translation vectors. + @param K1 Input 3x3 first camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. + @param x1 Input 2x1 vector with first 2d point. + @param K2 Input 3x3 second camera matrix. The parameters are similar to K1. + @param x2 Input 2x1 vector with second 2d point. + + Decides the right solution by checking that the triangulation of a match + x1--x2 lies in front of the cameras. Return index of the right solution or -1 if no solution. + + Reference: See @cite HartleyZ00 9.6 pag 259 (9.6.3 Geometrical interpretation of the 4 solutions). + */ +CV_EXPORTS +int motionFromEssentialChooseSolution( InputArrayOfArrays Rs, + InputArrayOfArrays ts, + InputArray K1, + InputArray x1, + InputArray K2, + InputArray x2 ); + +/** @brief Get Essential matrix from Fundamental and Camera matrices. + @param E Input 3x3 essential matrix. + @param K1 Input 3x3 first camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. + @param K2 Input 3x3 second camera matrix. The parameters are similar to K1. + @param F Output 3x3 fundamental matrix. + + Reference: @cite HartleyZ00 9.6 pag 257 (formula 9.12) or http://ai.stanford.edu/~birch/projective/node20.html + */ +CV_EXPORTS +void +fundamentalFromEssential( InputArray E, + InputArray K1, + InputArray K2, + OutputArray F ); + +/** @brief Get Essential matrix from Fundamental and Camera matrices. + @param F Input 3x3 fundamental matrix. + @param K1 Input 3x3 first camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. + @param K2 Input 3x3 second camera matrix. The parameters are similar to K1. + @param E Output 3x3 essential matrix. + + Reference: @cite HartleyZ00 9.6 pag 257 (formula 9.12) + */ +CV_EXPORTS +void +essentialFromFundamental( InputArray F, + InputArray K1, + InputArray K2, + OutputArray E ); + +/** @brief Get Essential matrix from Motion (R's and t's ). + @param R1 Input 3x3 first camera rotation matrix. + @param t1 Input 3x1 first camera translation vector. + @param R2 Input 3x3 second camera rotation matrix. + @param t2 Input 3x1 second camera translation vector. + @param E Output 3x3 essential matrix. + + Reference: @cite HartleyZ00 9.6 pag 257 (formula 9.12) + */ +CV_EXPORTS +void +essentialFromRt( InputArray R1, + InputArray t1, + InputArray R2, + InputArray t2, + OutputArray E ); + +/** @brief Normalizes the Fundamental matrix. + @param F Input 3x3 fundamental matrix. + @param F_normalized Output 3x3 normalized fundamental matrix. + + By default divides the fundamental matrix by its L2 norm. + */ +CV_EXPORTS +void +normalizeFundamental( InputArray F, + OutputArray F_normalized ); + +/** @brief Computes Absolute or Exterior Orientation (Pose Estimation) between 2 sets of 3D point. + @param x1 Input first 3xN or 2xN array of points. + @param x2 Input second 3xN or 2xN array of points. + @param R Output 3x3 computed rotation matrix. + @param t Output 3x1 computed translation vector. + @param s Output computed scale factor. + + Find the best transformation such that xp=projection*(s*R*x+t) (same as Pose Estimation, ePNP). + The routines below are only for the orthographic case for now. + */ +CV_EXPORTS +void +computeOrientation( InputArrayOfArrays x1, + InputArrayOfArrays x2, + OutputArray R, + OutputArray t, + double s ); + +//! @} sfm + +} /* namespace sfm */ +} /* namespace cv */ + +#endif + +/* End of file. */ diff --git a/modules/sfm/include/opencv2/sfm/numeric.hpp b/modules/sfm/include/opencv2/sfm/numeric.hpp new file mode 100644 index 0000000000..e3c2f9ded1 --- /dev/null +++ b/modules/sfm/include/opencv2/sfm/numeric.hpp @@ -0,0 +1,94 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPENCV_SFM_NUMERIC_HPP__ +#define __OPENCV_SFM_NUMERIC_HPP__ + +#include + +#include + +namespace cv +{ +namespace sfm +{ + +//! @addtogroup numeric +//! @{ + +/** @brief Computes the mean and variance of a given matrix along its rows. + @param A Input NxN matrix. + @param mean Output Nx1 matrix with computed mean. + @param variance Output Nx1 matrix with computed variance. + + It computes in the same way as woud do @ref reduce but with \a Variance function. +*/ +CV_EXPORTS +void +meanAndVarianceAlongRows( InputArray A, + OutputArray mean, + OutputArray variance ); + +/** @brief Returns the 3x3 skew symmetric matrix of a vector. + @param x Input 3x1 vector. + + Reference: @cite HartleyZ00, p581, equation (A4.5). +*/ +CV_EXPORTS +Mat +skew( InputArray x ); + +///** @brief Returns the skew anti-symmetric matrix of a vector. +// @param x Input 3x3 matrix. +//*/ +//CV_EXPORTS +//Matx33d +//skewMat( const Vec3d &x ); +// +///** @brief Returns the skew anti-symmetric matrix of a vector with only the first two (independent) lines. +// @param x Input 3x3 matrix. +//*/ +//CV_EXPORTS +//Matx33d +//skewMatMinimal( const Vec3d &x ); + +//! @} numeric + +} /* namespace sfm */ +} /* namespace cv */ + +#endif + +/* End of file. */ diff --git a/modules/sfm/include/opencv2/sfm/projection.hpp b/modules/sfm/include/opencv2/sfm/projection.hpp new file mode 100644 index 0000000000..8794702060 --- /dev/null +++ b/modules/sfm/include/opencv2/sfm/projection.hpp @@ -0,0 +1,106 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPENCV_PROJECTION_HPP__ +#define __OPENCV_PROJECTION_HPP__ + +#include + +namespace cv +{ +namespace sfm +{ + +//! @addtogroup projection +//! @{ + +/** @brief Converts point coordinates from homogeneous to euclidean pixel coordinates. E.g., ((x,y,z)->(x/z, y/z)) + @param src Input vector of N-dimensional points. + @param dst Output vector of N-1-dimensional points. +*/ +CV_EXPORTS +void +homogeneousToEuclidean(InputArray src, OutputArray dst); + +/** @brief Converts points from Euclidean to homogeneous space. E.g., ((x,y)->(x,y,1)) + @param src Input vector of N-dimensional points. + @param dst Output vector of N+1-dimensional points. +*/ +CV_EXPORTS +void +euclideanToHomogeneous(InputArray src, OutputArray dst); + +/** @brief Get projection matrix P from K, R and t. + @param K Input 3x3 camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. + @param R Input 3x3 rotation matrix. + @param t Input 3x1 translation vector. + @param P Output 3x4 projection matrix. + + This function estimate the projection matrix by solving the following equation: \f$P = K * [R|t]\f$ + + */ +CV_EXPORTS +void +projectionFromKRt(InputArray K, InputArray R, InputArray t, OutputArray P); + +/** @brief Get K, R and t from projection matrix P, decompose using the RQ decomposition. + @param P Input 3x4 projection matrix. + @param K Output 3x3 camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. + @param R Output 3x3 rotation matrix. + @param t Output 3x1 translation vector. + + Reference: @cite HartleyZ00 A4.1.1 pag.579 + */ +CV_EXPORTS +void +KRtFromProjection( InputArray P, OutputArray K, OutputArray R, OutputArray t ); + +/** @brief Returns the depth of a point transformed by a rigid transform. + @param R Input 3x3 rotation matrix. + @param t Input 3x1 translation vector. + @param X Input 3x1 or 4x1 vector with the 3d point. + */ +CV_EXPORTS +double +depth( InputArray R, InputArray t, InputArray X); + +//! @} sfm + +} /* namespace sfm */ +} /* namespace cv */ + +#endif + +/* End of file. */ diff --git a/modules/sfm/include/opencv2/sfm/reconstruct.hpp b/modules/sfm/include/opencv2/sfm/reconstruct.hpp new file mode 100644 index 0000000000..2c1267deb7 --- /dev/null +++ b/modules/sfm/include/opencv2/sfm/reconstruct.hpp @@ -0,0 +1,143 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// + // + // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + // + // By downloading, copying, installing or using the software you agree to this license. + // If you do not agree to this license, do not download, install, + // copy or use the software. + // + // + // License Agreement + // For Open Source Computer Vision Library + // + // Copyright (C) 2015, OpenCV Foundation, all rights reserved. + // Third party copyrights are property of their respective owners. + // + // Redistribution and use in source and binary forms, with or without modification, + // are permitted provided that the following conditions are met: + // + // * Redistribution's of source code must retain the above copyright notice, + // this list of conditions and the following disclaimer. + // + // * Redistribution's in binary form must reproduce the above copyright notice, + // this list of conditions and the following disclaimer in the documentation + // and/or other materials provided with the distribution. + // + // * The name of the copyright holders may not be used to endorse or promote products + // derived from this software without specific prior written permission. + // + // This software is provided by the copyright holders and contributors "as is" and + // any express or implied warranties, including, but not limited to, the implied + // warranties of merchantability and fitness for a particular purpose are disclaimed. + // In no event shall the Intel Corporation or contributors be liable for any direct, + // indirect, incidental, special, exemplary, or consequential damages + // (including, but not limited to, procurement of substitute goods or services; + // loss of use, data, or profits; or business interruption) however caused + // and on any theory of liability, whether in contract, strict liability, + // or tort (including negligence or otherwise) arising in any way out of + // the use of this software, even if advised of the possibility of such damage. + // + //M*/ + +#ifndef __OPENCV_SFM_RECONSTRUCT_HPP__ +#define __OPENCV_SFM_RECONSTRUCT_HPP__ + +#include +#include + +#include + +namespace cv +{ +namespace sfm +{ + +//! @addtogroup reconstruction +//! @{ + +#if defined(CV_DOXYGEN) || defined(CERES_FOUND) + +/** @brief Reconstruct 3d points from 2d correspondences while performing autocalibration. + @param points2d Input vector of vectors of 2d points (the inner vector is per image). + @param Ps Output vector with the 3x4 projections matrices of each image. + @param points3d Output array with estimated 3d points. + @param K Input/Output camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. Input parameters used as initial guess. + @param is_projective if true, the cameras are supposed to be projective. + + This method calls below signature and extracts projection matrices from estimated K, R and t. + + @note + - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. +*/ +CV_EXPORTS +void +reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, InputOutputArray K, + bool is_projective = false); + +/** @brief Reconstruct 3d points from 2d correspondences while performing autocalibration. + @param points2d Input vector of vectors of 2d points (the inner vector is per image). + @param Rs Output vector of 3x3 rotations of the camera. + @param Ts Output vector of 3x1 translations of the camera. + @param points3d Output array with estimated 3d points. + @param K Input/Output camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. Input parameters used as initial guess. + @param is_projective if true, the cameras are supposed to be projective. + + Internally calls libmv simple pipeline routine with some default parameters by instatiating SFMLibmvEuclideanReconstruction class. + + @note + - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. + - To see a working example for camera motion reconstruction, check the following tutorial: @ref tutorial_sfm_trajectory_estimation. +*/ +CV_EXPORTS +void +reconstruct(InputArrayOfArrays points2d, OutputArray Rs, OutputArray Ts, InputOutputArray K, + OutputArray points3d, bool is_projective = false); + +/** @brief Reconstruct 3d points from 2d images while performing autocalibration. + @param images a vector of string with the images paths. + @param Ps Output vector with the 3x4 projections matrices of each image. + @param points3d Output array with estimated 3d points. + @param K Input/Output camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. Input parameters used as initial guess. + @param is_projective if true, the cameras are supposed to be projective. + + This method calls below signature and extracts projection matrices from estimated K, R and t. + + @note + - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. + - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. +*/ +CV_EXPORTS +void +reconstruct(const std::vector images, OutputArray Ps, OutputArray points3d, + InputOutputArray K, bool is_projective = false); + +/** @brief Reconstruct 3d points from 2d images while performing autocalibration. + @param images a vector of string with the images paths. + @param Rs Output vector of 3x3 rotations of the camera. + @param Ts Output vector of 3x1 translations of the camera. + @param points3d Output array with estimated 3d points. + @param K Input/Output camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. Input parameters used as initial guess. + @param is_projective if true, the cameras are supposed to be projective. + + Internally calls libmv simple pipeline routine with some default parameters by instatiating SFMLibmvEuclideanReconstruction class. + + @note + - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. + - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. + - To see a working example for scene reconstruction, check the following tutorial: @ref tutorial_sfm_scene_reconstruction. +*/ +CV_EXPORTS +void +reconstruct(const std::vector images, OutputArray Rs, OutputArray Ts, + InputOutputArray K, OutputArray points3d, bool is_projective = false); + +#endif /* CV_DOXYGEN || CERES_FOUND */ + +//! @} sfm + +} /* namespace cv */ +} /* namespace sfm */ + +#endif + +/* End of file. */ diff --git a/modules/sfm/include/opencv2/sfm/robust.hpp b/modules/sfm/include/opencv2/sfm/robust.hpp new file mode 100644 index 0000000000..4aedc6e463 --- /dev/null +++ b/modules/sfm/include/opencv2/sfm/robust.hpp @@ -0,0 +1,106 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPENCV_SFM_ROBUST_HPP__ +#define __OPENCV_SFM_ROBUST_HPP__ + +#ifdef __cplusplus + +#include + +namespace cv +{ +namespace sfm +{ + +//! @addtogroup robust +//! @{ + +/** @brief Estimate robustly the fundamental matrix between two dataset of 2D point (image coords space). + @param x1 Input 2xN Array of 2D points in view 1. + @param x2 Input 2xN Array of 2D points in view 2. + @param max_error maximum error (in pixels). + @param F Output 3x3 fundamental matrix such that \f$x_2^T F x_1=0\f$. + @param inliers Output 1xN vector that contains the indexes of the detected inliers. + @param outliers_probability outliers probability (in ]0,1[). + The number of iterations is controlled using the following equation: + \f$k = \frac{log(1-p)}{log(1.0 - w^n )}\f$ where \f$k\f$, \f$w\f$ and \f$n\f$ are the number of + iterations, the inliers ratio and minimun number of selected independent samples. + The more this value is high, the less the function selects ramdom samples. + +The fundamental solver relies on the 8 point solution. Returns the best error (in pixels), associated to the solution F. + */ +CV_EXPORTS +double +fundamentalFromCorrespondences8PointRobust( InputArray x1, + InputArray x2, + double max_error, + OutputArray F, + OutputArray inliers, + double outliers_probability = 1e-2 ); + +/** @brief Estimate robustly the fundamental matrix between two dataset of 2D point (image coords space). + @param x1 Input 2xN Array of 2D points in view 1. + @param x2 Input 2xN Array of 2D points in view 2. + @param max_error maximum error (in pixels). + @param F Output 3x3 fundamental matrix such that \f$x_2^T F x_1=0\f$. + @param inliers Output 1xN vector that contains the indexes of the detected inliers. + @param outliers_probability outliers probability (in ]0,1[). + The number of iterations is controlled using the following equation: + \f$k = \frac{log(1-p)}{log(1.0 - w^n )}\f$ where \f$k\f$, \f$w\f$ and \f$n\f$ are the number of + iterations, the inliers ratio and minimun number of selected independent samples. + The more this value is high, the less the function selects ramdom samples. + +The fundamental solver relies on the 7 point solution. Returns the best error (in pixels), associated to the solution F. + */ +CV_EXPORTS +double +fundamentalFromCorrespondences7PointRobust( InputArray x1, + InputArray x2, + double max_error, + OutputArray F, + OutputArray inliers, + double outliers_probability = 1e-2 ); + +//! @} sfm + +} /* namespace cv */ +} /* namespace sfm */ + +#endif /* __cplusplus */ + +#endif + +/* End of file. */ \ No newline at end of file diff --git a/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp b/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp new file mode 100644 index 0000000000..fc7166027e --- /dev/null +++ b/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp @@ -0,0 +1,270 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPENCV_SFM_SIMPLE_PIPELINE_HPP__ +#define __OPENCV_SFM_SIMPLE_PIPELINE_HPP__ + +#include + +namespace cv +{ +namespace sfm +{ + +//! @addtogroup simple_pipeline +//! @{ + +/** @brief Different camera models that libmv supports. + */ +enum { + SFM_DISTORTION_MODEL_POLYNOMIAL = 0, // LIBMV_DISTORTION_MODEL_POLYNOMIAL + SFM_DISTORTION_MODEL_DIVISION = 1, // LIBMV_DISTORTION_MODEL_DIVISION +}; + +/** @brief Data structure describing the camera model and its parameters. + @param _distortion_model Type of camera model. + @param _focal_length focal length of the camera (in pixels). + @param _principal_point_x principal point of the camera in the x direction (in pixels). + @param _principal_point_y principal point of the camera in the y direction (in pixels). + @param _polynomial_k1 radial distortion parameter. + @param _polynomial_k2 radial distortion parameter. + @param _polynomial_k3 radial distortion parameter. + @param _polynomial_p1 radial distortion parameter. + @param _polynomial_p2 radial distortion parameter. + + Is assumed that modern cameras have their principal point in the image center.\n + In case that the camera model was SFM_DISTORTION_MODEL_DIVISION, it's only needed to provide + _polynomial_k1 and _polynomial_k2 which will be assigned as division distortion parameters. + */ +typedef struct libmv_CameraIntrinsicsOptions { + libmv_CameraIntrinsicsOptions(const int _distortion_model=0, + const double _focal_length=0, + const double _principal_point_x=0, + const double _principal_point_y=0, + const double _polynomial_k1=0, + const double _polynomial_k2=0, + const double _polynomial_k3=0, + const double _polynomial_p1=0, + const double _polynomial_p2=0) + : distortion_model(_distortion_model), + image_width(2*_principal_point_x), + image_height(2*_principal_point_y), + focal_length(_focal_length), + principal_point_x(_principal_point_x), + principal_point_y(_principal_point_y), + polynomial_k1(_polynomial_k1), + polynomial_k2(_polynomial_k2), + polynomial_k3(_polynomial_k3), + division_k1(0), + division_k2(0) + { + if ( _distortion_model == SFM_DISTORTION_MODEL_DIVISION ) + { + division_k1 = _polynomial_k1; + division_k2 = _polynomial_k2; + } + } + + // Common settings of all distortion models. + int distortion_model; + int image_width, image_height; + double focal_length; + double principal_point_x, principal_point_y; + + // Radial distortion model. + double polynomial_k1, polynomial_k2, polynomial_k3; + double polynomial_p1, polynomial_p2; + + // Division distortion model. + double division_k1, division_k2; +} libmv_CameraIntrinsicsOptions; + + +/** @brief All internal camera parameters that libmv is able to refine. + */ +enum { SFM_REFINE_FOCAL_LENGTH = (1 << 0), // libmv::BUNDLE_FOCAL_LENGTH + SFM_REFINE_PRINCIPAL_POINT = (1 << 1), // libmv::BUNDLE_PRINCIPAL_POINT + SFM_REFINE_RADIAL_DISTORTION_K1 = (1 << 2), // libmv::BUNDLE_RADIAL_K1 + SFM_REFINE_RADIAL_DISTORTION_K2 = (1 << 4), // libmv::BUNDLE_RADIAL_K2 +}; + + +/** @brief Data structure describing the reconstruction options. + @param _keyframe1 first keyframe used in order to initialize the reconstruction. + @param _keyframe2 second keyframe used in order to initialize the reconstruction. + @param _refine_intrinsics camera parameter or combination of parameters to refine. + @param _select_keyframes allows to select automatically the initial keyframes. If 1 then autoselection is enabled. If 0 then is disabled. + @param _verbosity_level verbosity logs level for Glog. If -1 then logs are disabled, otherwise the log level will be the input integer. + */ +typedef struct libmv_ReconstructionOptions { + libmv_ReconstructionOptions(const int _keyframe1=1, + const int _keyframe2=2, + const int _refine_intrinsics=1, + const int _select_keyframes=1, + const int _verbosity_level=-1) + : keyframe1(_keyframe1), keyframe2(_keyframe2), + refine_intrinsics(_refine_intrinsics), + select_keyframes(_select_keyframes), + verbosity_level(_verbosity_level) {} + int keyframe1, keyframe2; + int refine_intrinsics; + int select_keyframes; + int verbosity_level; +} libmv_ReconstructionOptions; + + +/** @brief base class BaseSFM declares a common API that would be used in a typical scene reconstruction scenario + */ +class CV_EXPORTS BaseSFM +{ +public: + virtual ~BaseSFM() {}; + + virtual void run(InputArrayOfArrays points2d) = 0; + virtual void run(InputArrayOfArrays points2d, InputOutputArray K, OutputArray Rs, + OutputArray Ts, OutputArray points3d) = 0; + + virtual void run(const std::vector &images) = 0; + virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, + OutputArray Ts, OutputArray points3d) = 0; + + virtual double getError() const = 0; + virtual void getPoints(OutputArray points3d) = 0; + virtual cv::Mat getIntrinsics() const = 0; + virtual void getCameras(OutputArray Rs, OutputArray Ts) = 0; + + virtual void + setReconstructionOptions(const libmv_ReconstructionOptions &libmv_reconstruction_options) = 0; + + virtual void + setCameraIntrinsicOptions(const libmv_CameraIntrinsicsOptions &libmv_camera_intrinsics_options) = 0; +}; + +/** @brief SFMLibmvEuclideanReconstruction class provides an interface with the Libmv Structure From Motion pipeline. + */ +class CV_EXPORTS SFMLibmvEuclideanReconstruction : public BaseSFM +{ +public: + /** @brief Calls the pipeline in order to perform Eclidean reconstruction. + @param points2d Input vector of vectors of 2d points (the inner vector is per image). + + @note + - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. + */ + virtual void run(InputArrayOfArrays points2d) = 0; + + /** @brief Calls the pipeline in order to perform Eclidean reconstruction. + @param points2d Input vector of vectors of 2d points (the inner vector is per image). + @param K Input/Output camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. Input parameters used as initial guess. + @param Rs Output vector of 3x3 rotations of the camera. + @param Ts Output vector of 3x1 translations of the camera. + @param points3d Output array with estimated 3d points. + + @note + - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. + */ + virtual void run(InputArrayOfArrays points2d, InputOutputArray K, OutputArray Rs, + OutputArray Ts, OutputArray points3d) = 0; + + /** @brief Calls the pipeline in order to perform Eclidean reconstruction. + @param images a vector of string with the images paths. + + @note + - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. + - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. + */ + virtual void run(const std::vector &images) = 0; + + /** @brief Calls the pipeline in order to perform Eclidean reconstruction. + @param images a vector of string with the images paths. + @param K Input/Output camera matrix \f$K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}\f$. Input parameters used as initial guess. + @param Rs Output vector of 3x3 rotations of the camera. + @param Ts Output vector of 3x1 translations of the camera. + @param points3d Output array with estimated 3d points. + + @note + - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. + - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. + */ + virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, + OutputArray Ts, OutputArray points3d) = 0; + + /** @brief Returns the computed reprojection error. + */ + virtual double getError() const = 0; + + /** @brief Returns the estimated 3d points. + @param points3d Output array with estimated 3d points. + */ + virtual void getPoints(OutputArray points3d) = 0; + + /** @brief Returns the refined camera calibration matrix. + */ + virtual cv::Mat getIntrinsics() const = 0; + + /** @brief Returns the estimated camera extrinsic parameters. + @param Rs Output vector of 3x3 rotations of the camera. + @param Ts Output vector of 3x1 translations of the camera. + */ + virtual void getCameras(OutputArray Rs, OutputArray Ts) = 0; + + /** @brief Setter method for reconstruction options. + @param libmv_reconstruction_options struct with reconstruction options such as initial keyframes, + automatic keyframe selection, parameters to refine and the verbosity level. + */ + virtual void + setReconstructionOptions(const libmv_ReconstructionOptions &libmv_reconstruction_options) = 0; + + /** @brief Setter method for camera intrinsic options. + @param libmv_camera_intrinsics_options struct with camera intrinsic options such as camera model and + the internal camera parameters. + */ + virtual void + setCameraIntrinsicOptions(const libmv_CameraIntrinsicsOptions &libmv_camera_intrinsics_options) = 0; + + /** @brief Creates an instance of the SFMLibmvEuclideanReconstruction class. Initializes Libmv. */ + static Ptr + create(const libmv_CameraIntrinsicsOptions &camera_instrinsic_options=libmv_CameraIntrinsicsOptions(), + const libmv_ReconstructionOptions &reconstruction_options=libmv_ReconstructionOptions()); +}; + +//! @} sfm + +} /* namespace cv */ +} /* namespace sfm */ + +#endif + +/* End of file. */ diff --git a/modules/sfm/include/opencv2/sfm/triangulation.hpp b/modules/sfm/include/opencv2/sfm/triangulation.hpp new file mode 100644 index 0000000000..0f76bcd293 --- /dev/null +++ b/modules/sfm/include/opencv2/sfm/triangulation.hpp @@ -0,0 +1,69 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __OPENCV_SFM_TRIANGULATION_HPP__ +#define __OPENCV_SFM_TRIANGULATION_HPP__ + +#include + +namespace cv +{ +namespace sfm +{ + +//! @addtogroup triangulation +//! @{ + +/** @brief Reconstructs bunch of points by triangulation. + @param points2d Input vector of vectors of 2d points (the inner vector is per image). Has to be 2 X N. + @param projection_matrices Input vector with 3x4 projections matrices of each image. + @param points3d Output array with computed 3d points. Is 3 x N. + + Triangulates the 3d position of 2d correspondences between several images. + Reference: Internally it uses DLT method @cite HartleyZ00 12.2 pag.312 +*/ +CV_EXPORTS +void +triangulatePoints(InputArrayOfArrays points2d, InputArrayOfArrays projection_matrices, + OutputArray points3d); + +//! @} sfm + +} /* namespace sfm */ +} /* namespace cv */ + +#endif + +/* End of file. */ diff --git a/modules/sfm/samples/data/backyard.blend b/modules/sfm/samples/data/backyard.blend new file mode 100644 index 0000000000000000000000000000000000000000..62d317e45b07b1536f2790acd4400e27f30b8b2c GIT binary patch literal 755164 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 z5m_FQ<wFt9+Bk{Sssz)5m_FQwFt9+Bk{Sssz)5m_FQwFt9+Bk{ zSssz)5m_FQwFt9+Bk{Sssz)5m_FQwFt9+Bk{Sssz)5m_FQwFt9+Bk{Sssz)5m_FQwFt9+Bk{Sssz)5m_FQwFt9+Bk{Sssz) z5m_FQwFt9+Bk{Sssz)(YYy)$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?f zERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t z$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Y zh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Y=)#moWO+oEM`U?K zmPcfHM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+ zWO+oEM`U?KmPcfHM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+WO+oEM`U?KmPcfH zM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+WO+oE zM`U?KmPcfHbVC$x zmPcfHM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+ zWO+oEM`U?KmPcfHM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+WO+oEM`U?KmPcfH zM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+WO+oEM`U?KmPcfHM3zTnc|?{+WO+oE zM`U?KmPcfHM3zTnc|?{+ohgsV@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?f zERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t z$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Y zh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3@qEh&%4@`x;t$nuCRkI3?f zERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t z$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Yh%ArD@`x;t$nuCRkI3?fERV?Y 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�v|7nXavt@%v*JWx<-Rk}aI z82x{%J<*2To{NI%nu{??Tjz+rXjfl!@)! z8m)YbY){-DJ(=r~R$9UQpBm>_KhcKVo-$TI?TbWH)_si-#;)PvdfNRss@|6cGggZl zBCzz`$lgm#^dr~!;Tpl2mqzGfjUin<-JlulZQ~PT!(zCc{H2BHJ9pXovFC*X)ri0U z&mhi@Ij*Z*XGecRA8YmP=II9Qu_wm;_PtTnjBi2~OO&PUY>eXP}`JH<*#J0x~U zh=>S(Y^~YH?zsj>3tTHWA5|;#vDVYH5ABfHG(ILizkVw>QDLVs?EB_c6IywGa>}e) z%IhsS^IC7Ai#2ZQLC^E(7%a`ABO?bSJ)Q^TtnsM-lb)C88fnb- z9S{@tSY7F?@$|Lh1+EdCd1-_$))>{x(+!%@j~$}I!s7>FFaMjfM(=NT6u3rk=A{w3 zSfjl+#TiL6R0X!nzcxlXYxI5b#{$;~&b%~27i;tgrFaf$MjhKnM8;4Ef~%Xa)LCPK znwPI`EQZ$_PK|jE{|B6TX@oA;c$M~{8Em96F|2?!`W7?e8?ZJ`bJhsXyfi`=Ys?Iz zXAN`=wpR4qE%7ls(zze)AFeO(u?o(-G(s0^T-1l+)DDdigWFM<|FO30KAvyA6(%%t z!Flu}apvX6LKkZs+?SqDk!G+{KSm606UYVSGtI8i+HY-vYXoOr8lj6d28Yvk14%Ok zwV@}(`4nb=W!IQ-cYA?r1ZQ3vp^G(oN6@n>(u_(rkBxq8jn4D&=J#fNbRMIe8k&xF z*_Q)nUh@&USfeG9o^z09sWEO~bYgs5Y(!lCr8;X|)4brX9pKDMBXqIGqqGmr(5U;X z)@F~fx;ksL7b|#;;LJ-Sbg{-Y{YW1j8#O-8HRJ(}0mX^i7~Miixotc~In8dzW7STa zd1-_$);K#o+#7Pb}Fl&HG(rQjnKs!gA(ZeQP!iNo`YnMv$_!fqiaM< zV|)1Z5uADXz@LL$rLqcIBRKQY z2wki(XfRzjWjzY&IY_B&zJUwz7qmuj=A{w3SYzlAx^AK`X)BoLAlWrqiNByVf-^6T z(8U@D52fp-Z0jfU9K@ga3tA&M^U?@itZ~{fx?ak*elpKNf{DMNHG(rQjnKs!mky`6 zt8D8h^Bg3K_zPMiIP=m7U92%<1U;9OZLL2eDB$NHsl@;28u?oB@M{M+^YUY%i!~k{ zN#Ey@ZT)1PgUliRg4PJmyfi`=YrL95e;X^?`pG;8Sws8;R5KcRjB?6jS4-KK17}|I5xQ8T^(}fXDchPfK7r>Tr>U$*??=|gY0etKnU_ZB zVvYWz>3ch}9#7^u$W1D%pf!RsFOAT}8iU8s-{Z@AI5g%nR3{tV`M$%Q_zPMiIP=m7 zU92%`EZs+vW>k=$XFbk6ma|50;xA~8;LJ-Sbg{g4PJmyfi`=Yg{v)zUM02I!oi@4AloTCJ=u?YXoOr z8lj6dW=^2Lag%NRWS)bJC;o!g2+q7TLKkbqyCa|(YfiRjJ^385&TGyh;xA~8;LJ-S zbg@QggXRY`=5xe4Yuxls!D|F(UK($b4Qq6ttm%Wsf_V;-{TadjNd>PFoOx-4F4pKh zh5jBywzb95E;2GHBH0=Oy^pgQpU|C?ZD>4`e`fYq!I`s9PS<$-@3WwbHQJ|Ad{ysD zT_av2|5#f#Ma2K;^YP)uvPKJW=A{w3SR>xA0?lB5-1la14UHN-h`*pUf-^6T(8U^2 zFK9*@7}xKy-VFi{Y(|Z~?-sm9a6U|<3)KPd!`VX>L0#xwjdJ60jQ715_3POMwjLSv z2TjjiKi)^i?*h&19h9gek7IE1dgP2}jd-8UlhkN@_8dARca7Y(j+E~yId$YXkXyOm@AFdIc4vmb{Qtn6S zVvTsO4m5-Lu`ehfq0Ojh8u4d8quDtA&#tH3#smJA)PNR_e8(R5BRF}k^54WVjx|CT zYXk%LmsdX;;oN_m z8uJ`u6`T%@MjOXi#e1MwW9SD@cC1<@f6o1=)h;JJi|odl^FFVu;LLffF0yk!LKkbq zJFlP_JO#Dp7!~;we{SLKu?Th0wkL7z zNR|A?(aWWAnv^AVhme$073LKka< zHtx$Op>fTJxoaGpPmSQrOC#QOXVeIt*a}LcaXw~#l)FZ)ROA0VZaFpPIp!lc9U6@` zj`@i9(6L7AC)zlL<&&6?r>U&m#wyCx?v1f$+#Wt3!D*b24i3ll5xQ6--nj?OD50SG z(KsJ($~H8facGIk=d}Zzj(*H}K0+63M2Xy&PeP;nlHB`oQ$96N0Jd!tzPXN4w;=`2MnxgSpWB+_l7_tO^GQ?r@O}iRqaU;5*(r*O9VDP8~Ve<9P{A$Cx$RXd1og z6y8JIi>3{n6tcT?1T0U4OM~uXn_we=sCy#fI zwQFd{7=SL;i1*GyGi(ZK3>X#p62GG-j5_Fdz~p#`9^(f#57!7z#~3hT9U7sFHG+}* z@=0h6`XYCY=klo$oOx-)`+|)cp%Ys{X*AB|(Dk`%)Jiq}&;7@#G0!oV!RgRww9)zz z&v5Y$?@95#ma=Y6v*+?!2F{1+ z$NO-hi#6h%#?TD5f_lfOQPDKw&uy-13Ubnu(>X^UgOk^z>>Q4{3SF!bHr$s5<6~r3 zv~*L!YXs-RG*%-`c=vQUN{#Iet=MqR@f&>dlpNz$+Qs(++K~Zlv}erp`*ls}?{AuG z-!H=V7z%5UEDY=zgJ(qGfIWV%1m6k3^J8ZW>==XCAUN=QM)*w*{H-&dc{yWX#~8%g zz#)Ib<26d>(%&RdtkW3-JI3Id0666DCIK@@`yB~q4D1+#7&|yn4u0PP==W4 zFmRx6@cw>0BgXxpGX{2yfxj=yqB4L%>;w0d&KTG+2L3ZR@S9)w-2l9+7{0tS26l{r zKMD@U;Jvu;jh!*DV+^k8;9v~iLkj=e83Q}U;2H@IXu&(;aqo!hwKE2GjKMp|!2vDu zw-3m##Wmj<13SiGodyT&@mq4Ze&YS&&KTG+22%?hz~FuMz+eq#Osh8Zs}V)%-R5Ki zUp%Mz-KvfL3v2Bok_N=&@4Z$z@#@q5f64z^;D0UfzZQ6;7Qi}E%t8y6zCG+0f6tWg z3MR9nmZCtx&!gW94y1S!9i86k>GnLOIju`g1Dl4$MkIz=8YG}^jXt?=ttodA5pVj+)6I*_X!n7wbztkT*nIwOBa`LCEAy;u zp|vHqDW7$usp8-JSE#nLo6zr^)9=BvkDV&Uf3016e9EVa7m8jbn+DVl$hX@mCQrZZ z?AYuji)b1P^RHhc&rvphGuu&D>^btX?_2EIkJ-*j@3*3PM;zGx%(9?&tG8i#$8 z2irosFSC*@+P4&?Iklzpn$U&bS^Y5?dSsFxoC~H)yDssGF^~6F{haDT#mOzPZ?M9j zZyHsz@rU!Xr_N&l&#Nj1YBmX$R9XSEZ;R~IB6@!I96F*rYza>Jjxw})_q6<7%o0aF z3efDe-)%=9XurAsu(7Kl3hMuJyB%}KN~Ab`SYMa3;LcRrI?|VlvA+9%>*@9^rRWp? z3mTthL4SJ{5-~V|evY+wGQ9%(jU=ChA(qJKm5+dp)B*yor zmsuy(YuO>bX}u&`+19d$Z0UF!+1f+bx$>-IZOCWaAle5uwe=EL z@8(*4iCV@qPzU6*?KIj4Hj{V*ZtQIJkVyyXWJ;+2iAUq?5lp_T1TVJ;zd5&uAzNkuO`-ZJN?sf$!n|w z^4az#?E^c$^?KKk*iu<>MXoRM+19>~?v?3y5!GQ$$qTL}oa%slwjEFVz#b*r;KeJY zt*>u`2F#0mw%t$rz-}U4nSJ&?Fn*EGwwR;9x}T&t42{hyR0reOK|b4t(mt@EWV`6i z%cU@wbX7IUO%0+coW1$Tl{WSiM=-2>wc`E0w0_JPfOdAsZWg%9={ z^4azr?E@QfipE>vBd&wvdzdmYYriwZC!q#IZVfMn$WuXk+!B9ZIREm!L$!-(3C%2 z&xPPOrL>Lv0{Lt^hxUO@pgNqc|F%|xB6t8lpL1G^+i70ZlZl)GsyN_gCAWhkuA8{ z7Wr&zIZV3f_}sKDt{%6xmhvaNXAHK;XWJm!2iE-;YPY#pN@4sO`xyCbJB{{%T~vLO zt4HSb2i6DVv+YsZ2R4Lw6SggNt?a~$e73dzNMnqSmy+$G)-G<(k*#sQA)jrdXdhVr z!rpF+eoc3M*~u39Y`cc`fxSw+nLnL#t?Oiqe73zw`@jbON@Fv6i7Wi3h@_g0xqXq( zw)P`5f9ZG{*+$WC!r*TVjbjJ-Y&)LzfjvsLOB)<<^(9+l`y!uh_tQSG{=ZS1?LXm) z8yBN3^4ZqoD2+urUP`vXYpino8f}r!wxP5SY}C)UT<4s^dyTb?wIQEvm(o74SBclV z$Wd4LRmQ$RKHFZUePEY%J?t9ncj$rffPA*~C%+EZkl(4^6PLMGC0=8jA)jqiX&+eY z-(R?9zEDW6zea7yXIuD-z}nAMbqk{FH{<^eXhS<-+{4Gi zF?=R3tLE!kljE&$axI;!y1@>vC;U6MLyGfQ@8HYvc`s}IW>)DZM}%7w;-lk|ldSOX z!jc{K@aG)%b#vJ?dz34EI!a~zEL%&VTyLDu#*-L7$j{o?I@r%T#LqgozI8}_tB;Ql z3fJmm^|M(1c4aL5IY%7`TmPZh`qVOBz~Z_A|IUGpNbXAq$U|M>&t>K5=YuGP@0NAm z8toI|V-2%XvDSXk10#~G$x#t#xY&rWqydSt<&vV4@mlZrNV1ddXbnrUMkiaN$r!gG z^owpNGnh!>>p8fSqY~o>^oz36@Abq+B>7mats+667y)Qpyp_75FXhG$hzqwy#}WHL z`gvMd#90Sh!|3D?YZw{V_45HI>w=G%Rfc{Za~l3&)_H65FrtR4zVV5P5lIR0ap6?m zcq$~EezT0~5SOfp@v+d26m!E*%;M0w(U$ND`8=ia-UI6s{69V)9g90NYahB7D-J&7 z!{>9#Pa2Y><%1V~9_J$k&PpkKI!g3;K;0mJuOd3GpS4CpB8}u4niM%LfWa7qZ^sz2 zx9Xc>tx?13W%cy*wDye(i|ZFb4S=5(iccJ32?w?gf#B;g7Nl8N5Y@KU=tJE+BrGxO zRxNojRl%a&gHc~h5E17M#yZv-gKE^&d9(Twz98c)1GV{t zc7flQb)I%mPxuGY$D>qRA6n9@9r_NS?xntrji57w$X#lEpZGrVMz(tmEzDY@r{!K)(oYy?QkpBOmq{tMKF49+iN&Y&Gwm+|wsEEb)zq#3VUr zEMao2RwEGnIwKb4MLNp!s}rY*tL;Z+>g|hbD11C4PL@l)UUEcuZ@EHI1+-=}6i$P~ zM`mhuw-N#TKWCokNUDO(3fD1<4uYZAMk)M2XAH`hli9oKiw%A1M_RT2t6E>Qdef5U zTL%lDZ_PT^h`4a2Mva=R1@i#DVorR0!aWz9QQq#d#~G@CzxC^8!=KE_ zhBU^-CwqfY4rH_;#uR+Yoa~{~dvKj0n7TPvu5UbW;AuuF{LS2WavLLqYiWywbx19J zop1~l@InuK)7*Ho#tIq09`hdlDcd8(dGsZGQ9ciC*mA2^j$>EnLK*N?nF}e(z`TZE z%I6*YH1O%_6$ifn%Um7o#zeDf1cu#Yim9yZ=eP z^KH6cq!b^BmkppBd%POx6r*7P0~@?&PF9~AZIREm z8MF_q%Uw+y#@KCYK&}Jw+1BL})s>Dz4Ys(aWLxC3Z7}TvyGgf2Y}MEf$Y(a0ou3@$Y@NEvLA&$er5AJ`DxwytD#@FJgWZ_+-nAu}|;UpLLF1M=C{{uj+PI^Lx7V!gq} z^+i70j;DQKErqoDV!j#s4f$-lpZ0+b(rwYl`&+D+*Fels<%x ze75zyPW?;A8M>`=oDlhJJDB!?omNxG>xPRHFY?(ogZ6>V)NQez8taREwspBd>n|Oz zd8d%%t>9#fe6|gyePD0uws`JgRxhO`v^XZ|b(1rNb8aY`cl}f%R^#)xmilBcE+8H>rQ= zI6=2XJH#gjXT`3O&$dCd4{XpRt$opN*tovPXWMDC4{V0c3!e!a+ajNBkJ3J{))tO7 z!&=F<$Y)#YEgCm;9HrahdW?;2kR&pZqubUXTjMxGKHH9`ePFNZwqAOLSsU`%c0cU{YY)=u z0Miivb&mDdVCzAC9)-I1MA<)Q3sBO&$e{h0_?dQcyaw=KND^4Wz{2Qk%{rKT7*|}!l!2+6LuD>Ru&Z))5H7~c)n{15bj(NFc#<7Zfd*eBJ> zHWA+?EVr4_SLHTCne3N>8yoBqvtu6==MC{)8UF>2{Z5I~kmi1^qDKfTR4UPlBZ)5)ytM_Cq_duL_%o#eFf}*jI(EF<#Do zsXVX8JkhS~gW`OyaaqcQF4(gl3VXz0qLX?@MkgjE_ts*u)W{tZDY_`{2T>pPMP<2k z3?3_`>~}JcQ;b%R&^ltmz_9hlaHYp({I@y~X43vZU$$qF2!}9}r z*!MK%ds+M8xj}qwoj9EYXpGNz^RD;Nv_^@Q}gyf{|k+tgg)Z&t;Gy9-M z`ytuvy$MjWwx5nco3Sqn3^tT4$ARu28o9izox@_H!|6$x425U)6Z@S;TZ&P74_19^ zTJhw}dkF0{mi8!~FKY*cvgyekU7GzYC9?We_X(ZtIes2l+YfMT zS$)Jlrx9amHuGt4HlRANpJ~hofftQ6`c+{XI5ft&q0}Ly{ zv)Ye+P-h4y?uOe>!t| zSzBNV>3vACZh8nA9T>_DP-b)UQs{Q0rIdVBgdkgL*rGNLh=pm?Z5PQZ>S| zubLB9TT^|gp5A&(Yhxbz*>4378}y?t?4vsK=}+jia46M6E@AH?&tn4WAIne&wV-#MR7KIRs=art)7 zTHlBfrxuCasE$1Esvf1!PxQ%djUx(qIp@t}?I41YI0w{zL^FO-^* zetpDm>F+o4NC(1w^le+)!UNLxw!Wd@_^Dy%(y#6ArL2D|LLL`AxOIDnL(|2Wx2BOE zt{*IoTlO-voSe@UDlwWo^9^52YmR`oeCT#VWtE06b8tF2^|=%TzHlOo$M z=I34MyAsN&bt{#lwn`Os-4ioL7XDtm6|y}8<#@WMWwc(}DkHkr%XS>^pZeeS_M5)7 zZ#-+0#}mHjYA;r1*7n7%2JQg95PjP0*|j!fe$-2_-}KZwemM7+e=%GdEEC_}xb{Mo z)AjG&*UEop#K3jsclCH_??1J_(D1OLO&{^aU%LQU+mE0_}bsRpG zdoAJClB&lwi=k?vUTc8`(d*-3_eL$ZGO9H+G z#pleXq&>&=o%_iwpIQ6Ro+YyM02{hU(}(h(^!o1JHPFpYAC!fUcf(@BCGt&mXFy}8 zwVN{aZTAm8+xWxhw3NrngX7I%=bYz!3`^rVVt9b7pLv zYnmzojj!&VLeVrkmsWEBF_!arD)bUUQxGbm;tpy7=`; zxvsaczkXqw%Af4`2j)R)KbK^uH4-+)&G{I4#&gDf`umN8lhi+c954M>Skk_NbJ#a- zs2`5A>j77GJ`H2$oEckVjj*38T5s-dAN5wJtTsq}tJC(jbk5nbRi!@i+;z`6+e@Z? zyq)q>bFMq(nA!A^uCEXD27F(n>-RI~$`Z2sF z5Wo-vN@5-&JPa6ch;ewsCC1_c0k5pdUCvr0ac;>y4 zS5K>li{idNedh;0=i5dP{OPB(ETjMJ^3msB|GpC+_=4Yhxy${c$sG^;mmh1q@!h>g z9G`w4l{H;nwB%~iY%HD}KIn1RP5(tE z8}giFC2P=WO4(fF-|qC<=kw-u=DhyJn5g$#4%aKq{aL>!e4ytGkC7_(&b;}Vy{}-7 zWShAadK^$2!E*78!go{^)I#q{b?2*YU3lOoAPB+$bsW!sdhzLn&Jv09M3kn#TZ+T1 zcIw|g!ng5{Kkmgd(^uWnUw$@X*Z-T#Q%}JV)t}n&Aklo@iLZghc;?nBV-<>a|K{q| zkE^PT-9vZ1&1ELK?aUMPiZ;D>zP$WLpJ8*m_=e@>pGq{0a6POXI<-Dj>h#N8`G)yyuI@8L)SeP5mVy zBCb+ge|Py;Kl_T;@n1js)N6eOgDc1N%+>zgbkj`-_3slt;S-+C|8BYEmgSpozIj>c zS6kkdj(kFeA|9#>oe&QtmQ+uwY+~>=q zdMW?ePyh5!pSvp@T@eO3H3KI1bcpY~~=Ho5)w+b6j#xefXHe05yz z{!3r_(q+oO_}Bj0Uz>d1=Y8IUHO$H9fBxtDpW?545^%ZuUAVCX#DKwe(vW^zVHjbaB}zEcTeW#=KSwVzw}EdU-Bhi;D0ZfdSCOJ*GxFuV{+iYfyu#x2mMds{rmSj9dE!%ZqFBe z(HBj=;0wOMbP`Q+J3jSOKeg-^_0RLQL3QhWRmXkz-8Xst>t8?lim&*J$=~=Jf5ZP2 zR@#?;`Ik>#_qx})O=_dsBD%c#)vuns>Q%3DJ46rhi}*wQs=iPg#K-mbt%rHBJ`^p)8yYvN zUu_Xz*XvaneqPplsoo<;j!YhU=%LB+eMNx z>E0ucJmR(;J9fZce>s#MC`I@i!8n@~3#~&}-A$q94 z)F+~a_(y%I{!kl42la)<#%F%!XPOrzv(yLBWLb1nd8)VBY)+PzmL|)~%l@~rvf^vI z-JUEiF8aRO^5m0Gx*ck>`bq6q--&m`qxCkZFC;G{!^8_36XHk7IO5CdTfLj=U0q$B zoI7`JvbMH1^-pP?PG_R_D4*J?c8DJ87xjsFBlkycL+%U73dt4qgJ_`lmux4#ESjrK z)zRX}Y(*zV3W#r=EH0si#ag@yEi#!sO9MA9Wi<2la*cL1UUD zB-{@gm*T}lgNvj;tA1A9s&`{!W3s)yJvo2={N(Gt?(6(dVg1|M+VXwnQ#;=Fwzo~x zFQSF|ZnrjwCp9j_3z-Ju1C2-VAmjB}mGSh`PrLkY_=azoeA735)8udd&A&PM=5PLH z|NEA2`Ibrkr*!2}Tl7q~+jXDR+mQQ0JgIS|u_+ozHb^c=e@Ql~e&p7(dJnz#H-6(c zx}Ie6?(hEY$=~~Xe{b@=-}}9jcfRwTj(_X7e(U7x zzy9kd>KnB|{912=cv9m+V^jSgxveoNU6%U*9sMjkxhz_W)_TXczy0l#cf8{ruH%_! zo^gFY^g};1dCz;^Gx@on`?<-_|NPH8{Oq&Ox@~HM`a}IEI*K2}lNwKwVd6*8K;uEO zNn=6sK;uCC2Ok{l^?Ihc>ejpdoxk&UT<`aP|MyRR^hbYm^1k=IZ}Qu}{o9k@|NY;e zeE7p3o?N_maq^45_=}St{J|fbh*shk@uujgF{*JP*`B?(g6I z-QS)3`+xuMC;#Jr{14avmw)+}lYjlM|F!EEoy4o+gE|c|AE*zcL&XERe)YflUbN4D z@XW>U`mXOX-PPxM_n-dhpLXBB|NZZu{PTbQ&nJKQhkrQvkN@#MPCoLHk4!%J!4FP; z_Gf?A?=QYlA8c-Jnhzu=TdkJ)P%=s5AlI+{hxQjU?Q{L;|AXQs_5Hiv^{&ag-~Dda z{}2D+Kb-u+FZ{yfH-6(cT<1Uir~lNv_)EX^OKzjaqsFQDM|_yag7{E8p!)UxqQClI z_yoCs3I0$!7@x};bL#tCzj*Au?|rZNKy`}mH6GMAfB*0Qee<8{7ypO{BoD;Txqi`K z{Vy3H8Hf&^qI-V-e5I|=iU&o5pZckv@>tgxP&;&0pQvpb8{$2+H`gy2qWZ;ynf~HG z=~wkVa`)MnyyPXjzI(1;SLDXCxgYeNs#E{e9`S|Rrgv8!@vQnk(_dpi{V)ELUex&4 zyEEo4f<2$N?%WP^>9dl#>I;np)%)W={^PD&Y2tg`7tf0SGyh4JNe-&-_3q+3WbCt7 zQ+IBIuHs4Ym}G+9Syzow)h&6Uch7w<-qX7aOGy61Zx_)sCC;mtdo^L?=d;MQi|S|T z2K`f5a_7Q@3#BfU?9+QA>n;jcpkJ<--dEZl#_uvX>skFn=U+s|UF2Oa@~+Q>D$^La0 zIdy+8+sz%trxy1-6J_Wb*=}+?w{fb%S!70m83kq(m{DLxff)s66qr$9Mu8axW)zrF zU`Bx%1wQU5a1z_iDy~f0!^NTGw%z2t1^H!99{s57SbUd(=Mc}ZS)K>w1x zRZ0HahxgFvM*;D{ zyLd!>qi@UvKVEoX;XJe??qletV89X)pg3rQxgp++R(;$!SVa+FugC zIpux%uf((B)&CylJ)rXb`1ro!zY%{4&#PSJQX0=ar{|TX(v(I!9FMekHuJ9Jd*YC?G!2z5?})4zkFyQ{2jFX#Neph_JoMN!R^YcZzVxzE?Rd z=huD7UzMY@m!`1F$oUn{=}OD_bII-LdSOe)Z7pfAPQV ze((NYj`Zu9W4sX0YHVw~i|+aF!@NhmE~VGw|Fgomty$OS_WrMO{UChvv7p`6_SbH7 zebcXhY}zV%Tupm(TeA+-vyvSlKNPEUU&QLadETsR^%ryJdI^<&)40w0t$N~x2}ypu zFeT4Qy;cfHzn$V?^^NAp!6g@dvncd0{`OrES32#%lvJcN;um&H`^|d3jHM)ZGp`AU zy^w#G(^D^GowKs{rhxe19W-V*WHf&P?<^^v@36{vF)Z{d@k^G>8 zz!>hCf1$G~a|?INcJ*n`cP_z&RAe4E5zUx#C&sMeH_EvLS5J}I6Eh0TDDd%10b5ia z5W>7A0R`ENAK@Q+cGHiYJ4=a=fa?d`497@huQ2)h|T&+74@L4mxl*yi;MGEb}kD?!-GE!N=^&8k1kwbI~ft~THA1@{8EM-Q483kT^6u1uiPBme^EZ(W)QAODj@1R3wcqhx` zz2vrNSHB;a(e@p5;BI)QqISLfTuxkf;+;$EJAeFff_He2%i*0Xw(o#(O1$&`fOp{C zOk?oQU_4yS(QCS15#IT;8Qz&52f@cx+Rk|9{cGxy*+Vl5%qZ}2M}b%BjjqYQQ?tnI zhIc6T!UJ{Nj>1YS@eVpf+?HN1lk z+zszkizD^&bGdPSUcB??l}^_aH`ZUBKJ{?b$`bGJ9@mX`z&It|nSgiT-CR@Pox2uB zgHC@~T$|G}`1JYxcm8UIclI6^>XAAxWZus`HM`CzFr&bWn*vjK$E3JYyz}W5;V!{D z@7jEnwCAz!phISOC(GozoEBmCir4TCI&e3 z4mxl*yp#GRm6OYxzV5_3m-z2|!hEUItMYD?P@O*YaMivN@9-X%!#h{(zXQf8@y@4$ zci`Pz6L@FPZVs;t@LZ97=Tl~QXYX;L9;x$!!n3~_1!feOQ6N*GX5aaQ(13g49pni( zCjN|+B6wN6v*&siI%I}-vP`baX%Tg=cn$BM19##b`R+td=5ltw?!-HP*!)KyIPfj~ z2ma6h_nV&kq+k8v_kZa2j}yGZdt46hK$)ZywIBUem*0;L#wqd6XM=a(T~Sqk^QVtA z2j|-B#Xa{$!ZrL}k$vYgXLx7taUsIj$Bn|XzZnH)6qr#UQ{X!GXK@Z&`nxRNspL=2 z8t2>U{GIorLuPm<%jCM87OnP**YFNHa3|iWe0Op=yI*(WolERHpH=B}m2hMI)#+0Y zSFJ4VJG{r`@Xi(6cfdF$-uXQ64!nEe3yS}$+Q2)5=BD}}r(*{g?SM@WB{#XEc2chDg- zypv^eT~3Rtd&O&b2OYQ@-YHiaT~01<`nnVET(Upwl^-W~hxfP~-nruaSzw$J@4Onk z1MiBO`kOy}tkdnj_DH+kmyze1P!D6N>ar-d{u_Abi)MId?{OiL)yGX9TXj;-!ZQlY zDDdK?Ky5uM9k6_*ct_vbOMjQeJCZ+XAA0G}<9WC2JLr%Z-pMk#E~iD+z2Y^zgAUvc z?^MQudilBBxIQo5`Ql2a>xmoduTGzOxN2o--{C#38}EQ|O1$%0@D9A2YXa|do1;;C z{k4aC>!U$)IJ$b!b47UPug~z#-s3_&Qs;%t`?;rP*BJ$76nJq{;M(zyzA>Est_|;? zLuPm<%jCM87FG9(*YFNH@CCy=Usmb#+|f7AwN9UUxN2dEcX*HM#yen~67PIDcn99i zHO-%XXwdvvd{5$aGrY6+xKNMOc|qaX-;4q?3d|^wDG+!^-^d)arY?*PWP*V8kX z!#mlgQ~Ee7e`()Ahs^L!mdSNFEh_C5ui+hZ;0uO#?yGdVT6AOm)#+0YSFJ4Z4)1Z@ zcn6GA;++S;JMeCFm#XFV!Df3qAS?G`% z-pMk#E~iDSz2Y^zgAUvc?^M*Tm!Hdx>rQ{=OZKBbTIuwvyc;D{r%ydxwXeiGyvOD6 z&K2)R2ji4@=Lzr*yqjy9KYg;ZReTJ-7y9@N@9aG;)FX9X$h@C>YIdDbU`Bx#HwCT^ z?@XVsTvG1Z@D4g;hIg_|uFGlBb+330@1O%;FuZfN(&=SS-!OqXed^(=fhFGIJ+2$? zfN@H^(*WODos)If*OtS8mVn&feofJyPcdg=c>=3d|@lqd=y>wfpaU zaxNmye|_MeUA*XhSf3y1**_VXQ+3ZVE`m58Y9>P4lNu zb=DVGUwg8-vff$Vz9zqAhC?-b$OTtd>+NUOW_V}saUp`$c_H(DMaWrbMu8axUd$A@ zcDz#)(3i3AJV<)}x6A%4bjS?vWSOjM{wIFS;oa`n@D4ig1;ab*l}^9$Mo67L^>EeF z67TRH*Nu0;I3?cM1n=wmd=kIXab4}%o^9C(bE`xVM_FVRSWpv04?_`-Avh2Y< z;T?3~3x;<#K2Gos?{VFD2aHqVoo@o~z`N=t{mq|VSR6F_?bn`aH_r{P4fR|R-uZ?Z z-r0Lxs5k24CXX$p&;Dij=piOb^6r9RSQe|4)1Z@cn6GA;+<~?@4&mi{O0qnOn7J9?T`G`(5m{Y z3NZ?6=F&?Z^&I1wZ=K!^ z9eQhjA3c38bkFsysr^~i5owp;9m=T2OToQJ6R_0q}5*W8s0$%?uK_N zYS+tGY8Bs!cP=@9=esMNUX^#FgzEIEhpYCL_8s2ia(L&8&))&#lz8X+!8`D7u1R>O z*Bia?{yX10!#kJCl%0KFk1IU;n^9m!ff)rd1?u*lNYgQb`kvPE^0M|^y4) zLV6jz^C0Q@U#_pVKMNf)!#i0f>zeA zXO$j2m%}^4I_Y1ouV&vths^L!mdTk;R}!z`9dzJsc&DOvy*#B>@tyXaOV+b~s?zCI zc{fU^POo~nYF~+Wc#q5Bohx3?0^^i;=O2N0;N4skcxT)i4VsIioO1QoE5bWJJHtDb zJgNA&N)z4dypZ!;eSgfJm{DLxfsaQDT*vv!)r|Do@D4g;hIg_|uFGlh*&81^oD%Q+DtHIp%{9%RKGWX1p3PYl#89eS%yYrj zRpYC8=9g!9XYX+#D%E*G;o0Ae0y7HCD3B>IW#73~seA25zt-<(?Ych;9Wui^Sti%z zw0dE$cn$BM19!tamGZ2YpUaKwPW#R!{yV=?>2y7DWBt|XQx8|IEb$KSaXGwm#r`{B zoD%Om2i}2qb4}o#)$v;ET3vTs4ECL>%W}chHSo@F%<#_M<3a?h^FrqRijcF=i~=(X zyqGCa`R|1O+Z*pdsdCO_%TSO`X;=R}33SK|?_`-=m(wEZUhx{ESfZVFU*2RhgxXD|Cs$djO0DewaWT|M4Ghs^L!mdSNFE&A>i zui+hZ;0uO#ez(%;(c?GLZ=F8%aMi{V@9-Yiig%7YdT9UG-@dQ7>wo`qyXR|wERgu< zp_4~{jFh?c_SUGF>krx+#oSVJ)GX$fI|IPaT(`;ZR-;o{DYUK7T))>@ zAGHU?%Ahyy7aPs4{v9Yr+x>Pi#2-l4?~1Zrnv()PL7SE~4-L}hh zUHk7jKy6CvH%F^aMs%*<9JJR*#paU--de2cXK}T;zS3T*1skKzT6;KZuJx5TH)t=8 z9O$(QSLAnUE)5oYOYLas{sZ@uvDN2a`~0YYFax}xcr#r#ngc&Ubc0qGoqn%?+8kwF z5NmZtYt7-gV%Y60wHu;q3PIe(@jwKfTN-qD($Thli{WZ-^IUtoSR0SpDz4ufiZuI+ zLA%==ky&-OyY01NECOw|J1eWBVX@&(icU~>~_}MWb08juc;nZ%6hMWw7htGeaVb5 zEEap+-r!04idWEOPTg0mEBDaP42wD58bS=)-L43*SP)u-&VzI90e8piOT9*Gyj(aS zYB*r7TI{X$#TUhzTQ}5u4BPE<#nNbt8izyJV*m^GSDVFRx6`L}zN&o`Ff4k5(Q2(5NGm*OYNIuUhgl#+BEhxp1&{lT&!}TOq)*h! zVZTiXmVui3-S)4CjG}HpbJ*W1_}MOa!Nndu-yfyl_4bOnYspW{^;&OZycTohE5;k8 z&_QIpjqc`m+rQ^kM8C7X0=b7z9z-g^7rG804bQq(Gv*qjyj%36#<-};b@6q7$cwg% z&DGB0YNIzELI0vP7!Ow)+-vB`0?Amk3b?Jk+&~hD*_WG(5(>IdiZ1X;U)Rm%z*jOs zl|?13bq3C2293OIIOj&r&|d3|6klx)mUJC7kY8gU-J{%`oggFKHwikY zaxB5ly29=w#JUSi*))6TT-Q`S$wQB@-ZNU1<^}&IbR{SqLNdyad0c)tm+l z0;7exd22yrgiw)O>9rg=_*VC~AKHL1V`Q)QMhqx~ORGIV>@2nWoXmpgZz5+jR6OdJ z(Nql2hM&!mA-jB#R6{7g)InE4P9#GbO|;M&68XFYF^c|hn;<`p#pdE_yAcf3YfVK% zsWwJ~wuX-sY$McKuQTKkNw9SXqm>cvtS@)R?RD5O;;rVelWIMv7midB&;u?BwDKi1 z2veF{ike;QwS)uGJ4+eC&h25ZtKzKn`-u{a^F|W%$REjs;aU#?5VzHS3$A{*gTxw+ zI^Av~L`+brQCHASrWa`TUXWZ1u$A~=+QL=G~NV@{06lytP-Q|eBZ$XV&f1= zKp*3NX45mX4WQM_>ih zwb#LceW1ez{}^Q4Z|E-ixVMgT>JGS79P{}9`4vUZWoeAV@k&)J;7^_XYaW z8>U2hCG>{n@YpTNj}>b}WDF&8t@?pT>PsVtMhq0F*ly74Ooc*1GLYMYPP3cp27E98 z`DFm|+cFH%&x(Fp1$bhhABR>H5@8s604hBIRm|%`B8>Jx*O0|Gi}QlGu=G+;uR8_? zFK!nby>780=)cU{t+%_(h6IYsaHCVkRDQlgSa(9=jke%MwS+((`5G=spXU&|wJF4; znE=x!{T?V*7%M|p8X@J;NN!X&YEj*-k4ir{mEaufonfz5fc1ypi#{Fo{803-g@}Y; zqpNul9qow{=!1C>u#Qn9kmup&`yrLattzF}W3clSun%1hK2Jd_#F6QAvcnIWFLJdg|EgicdLE+3sbS~2aB%m&6R?Ork>9u4LjGieJJ~ zd@9Mu#KbI-!x#}(Rs&46QT>ZdZ&0fVTCAhhpaOP}peStI*YsWKL52vm+8azpnTc|H z5Fu1fZ#{rCQ)DI>Dy1N!4GZqik=7hz>KH+gv<`_Ju7P6~nQ>;2&f~Ig@Gzt`i5asp zEbZ6NfkX+-@Dnv01Q@LI)}GNYPOTq875uxX4yl5kV2w*_1@TP%xpmz!&y?)H*R#*2cJnNhihP0cJFd=O~-u3Y-*-^lLX- zBS$toc?-+rvcs~1G>fi(1$k8_S69e2HJOmx%GHg94njkS7PAE14qJ>{OP!5$L4KeP zkm^Qt8jxnGxixyk#vCjnnhVS733{O?B<_b;b7ZI)uW!mGxxqAsISdn+dy971br!*b zsEt+{kuqh#?{iC=YII6m>}lYx`&X@vZrUg)cOxp)?{Y!!K6&7EOw4%{KI>ynVESL& zJ*UX4Ln~EDg?J3@}@3 zZ+17jywXZrS5$>AA&(T&6vy4E9F~~oUc&MEd46wcK0>L*=${Kw&KT-ozYw7lu0#m- zG5gsXHQunXu2Gt!a>59m$OB}xEh>8Rj5KF7>_oiJTzl=X%mr{|Tw!}#VPsZnZfTy+ zBnqO2Z3YR3wPZ~~R>+1KT&vL>U=DPrU}}Kz89foOIFfyGE)0(fM#yg}v!?=UOuX8j z!veL^BqBXvZVO_&EhDT)jM`(H5)?|L2DPP7CO$(L3>Z)F znk$2TML%q+YnqPFEqBq~;)X6v40K#V(S(YIbAq+BT%ca)VFTTN57GzK#duq1vQXWT zagjVWGI9ls>&2Oh>VnCzjcL?EY_WaVYz6nxN1jh7o1-!a&PYD-pf1}*l9QMg1~im9 z=nh%S5Qi}>RjUn$yI95I71}bTc;wn@5*F0Mh+VCxH0g$s?I5v|(OLJ9W~ius_0*gh zGsI``DCMa$7BTy-J{BA~H-z4l0ID+eayYC_o?{gKk+0-H_--+N`0aIJr!=G*kygg4 z8fznNBZfYvAw z6r5z(&>sv_h!UO9S?kLNzl?bjAR^vjX<)o{CW5gbR1K?h?RNhN_=8C`>hzoiQ3N0B zBV9FI4oTW1HItBag=r`I-c{(fWtl6-RsAwg091TdnxZ3MyOW|^_xrTCqwYLaTbQ7bv9?jP7 z_iT-2Ons+Nb9F-juKN`^pr3>Kk-T6nS*!nZKu)dIi$*|ZUm7vHPLbeLWQojeEPsH8 z@d$80OPnkkZa}Ry&!5b116h3!2RjXmuyU$DF`d(U37APl3=vPPv8z)xMP=z7E7YPV zs7uMNEtw@HYV{IUv<5X? z7Cd+BjL!`PAe6+s!zQ6aERM;Xvfho=0oKAChjsFGqce06ZhIZQ+=r(6#Z1VBv8szi z5Ti;47MW01Slp3&1tvBDk&x%veQ3je9w<4S_U@v5RB%1sFnbR*fiK#(iD_BZyL4Hm<3INz=fPdD0c- z05i;%*AevNJ1l7ras24@JB!DXxkv?6oH|r@sm*ArRn9^dc!%1Mhh@PLc91z2I7i2% zfzj$MZI?#jel!5&i=zc7ZlTRkT}N&+a^)wobj0|vj2`Q(%ZCJ_dL8o!GtZN9I9bGA z-docY6v-+F6fD7QdLBIxK`ceK+4UFkyixIEAUxz}$#tzM#p-FD=H2o}fI#v)(fAP$ z1J5%c0(_>qp?k$^{#2!TUA#8hUnM|a&(w`py%sFnK2sqJe+^nKFZ&012MRfl-YqaA z=DE-^tE58K=rOQ1H#7lS1~_d32jEwmHQ-lYQ+mU9P=aD)UHUX5%5lhSABiB+wFrf! zFYedEHUro`*@PzseG4$>8n)cB6vj^^${Du20;N@SP3&VmUG0sRM7cj5p`e3aA4I_$ zvM}7xpcQ3e1#fP^uw`1VW#MEwdvZT)hv~WntVyfyI2?%=1vh1Yh{aW6M*VilGMlNh zxi60qVSQbh)IuFSr16Wl#9BNIs|-dFq(Lbl!vlua@bh4$2Hr65;Q)c#5kn!C+$7&I zU2atPQzo1=x2Zg~0{X;)F&Gfg5$Me}7Jzk7gF1z*F+?qlv4#4@4xcE_Ej*F~3psGQv2g0dnRK@nUZ}!n4<9Se9XZ9nhl+D2 z2%kD#oI87%IN_6LigSk_CV`@pBYI zcP1AB38F|?8?v4)hd2dduC29OOL$?WrLzw;5CKC|TATq8d|;lE!Vg_K7W4O!-N&VD3gAdsI)Vk zTDRcj#v{(Jg@AB3;9a!-%r6E{Y6&vU$%yI+p6OtJG^Tv(SS;OO=~9#nu)B-Jjp3sJ zV-+SDwiW{pG_lZn{>3}ldZm|&066{}b`)3GIDVw)OL%wWMWNE+-);}F0S02ex`;te zX45FWv);!QNXUim$vo>dSo}ls3=ymQn#N=oZO7F?BflJ>w&W~rg*%?_DRXqurt+DKn%=SLAPgZ zrYWP&UdE2H{)#u>2*=OnhMFZ;t_4X0hmInhG`ooug_L5c@K|_MtVnc-%%|JS;0 zv+eFyx^AcIdFCvGm6Nuq%9uJo&*XDpE9$ArtFzT|J!%F)#J)mO|HooRV`I^y%)b`p znHUn`IGXN^ENxOl3poD8>yklZt$hZVDlm}ar;@VL2TM*y)T@sVS#edZpJ(@>@N5T3~=>ZDT0>0|r197JvC^$ti1~pB4SI zKyE`rXx52hMV^2xkj!+E#?ouuo_%k!5;9caMdo{3seab$T~TjQ0uTN@4JDEUI=T+r z1O#+6z-W`k6eo;Sr>0 z1_=uLVFi#Qp%Z zMA=#Vuf9;%Br6@<6;;!j3=3R^ajmtegGcXQ3NSxc4R_#`At3gm;n0P94~cX5NdL399=+D_`V9?Q08xQIZf+ZKZBL<(=?y)>4;|<)R#s$MTl+e}+ zwl8a&0ScBGq90Y5Sz``|FI8k)8*fnvUTI7|Br_FvzFe)X{V@#irp9g1Bd-q;1{xQ# zJ8Ixb9a^K?u7uSPmch^qPufSRilhD-=RNOHh;_T}m|TQ~DG=GiJZoloeM<}TCOD?W zH47@#CkRH1<(9}9(E^hPiJ~l~w&l^J;!+qlVThX|xZQ!!QiRzgKC5r*ABg-~3P~d+ zGp?ccTw+p3QW(orO#hab-IamS$1ST`JWaW>dZAx0d*HgpP_p;5On11%g;MrXGG6== zSpq_*{rixA=P?t3n6Rg!Jhy}#if#XDg5rRb4>lUtX&bC&2?K1EFcTd$1{PXhMMR=@@I0`jgM5Z zlSB4Dm&F7^L<-D^K~c+W5ofGf7dg9hPZg7Z$3Btv#4v0?#r}owaMopx7O}Co>B%p@ zj|t%Nip&CRiNP?_s)dK`r{#aLk?a%1gea?68c+CAzD`c|h^@|Ya!4s-X*r>~Ezh9d zW*&28J~4;wBvnq7j)?BTRv%yW;Z=>U#DE%T$sr6%97K1sx=F|CYFaA*fMMlCA^C>n zJP0i&$4X>Ij615ZiM`IPS+rRuH?pBM!@N==!6$3R63@qLIRzye%g3&QCb)R*0&wy0 zl7Ot%ojhC=NR~6!5!NxwZn2dE2%BTHPCk>LT0k~^op)$yjIY*bw6uuK}cz2N(BxTY+%jWd12>#Fim z0nRD8TD72;d3a|kHhDM#=l8x$%Ub-voi2lWy1* zH@eY7qKW6O{UPY)6)giY^@iUy=lc-i7BRCCN3$(lTE#h^<~+t zVqR{{aSxL5Mj!>QwSHGD9Do|(`mlm&f3cHYEY$1{YjpCGmk4|m+4SL!#y*F`X~!=6ItO-a#Vkz`g*KEaXViBbrRsq}I&t^W7`fu~jT@I%RK zqES$JFIAh^YsXCuP6kGM`q>O!BC{|7?3~^r#Q?-?PGl10R|`^l@gw%DIn|U-ojn&B zSwTSV0yJCLXBtBw_2R08@pM$HH5N3Nl&+OV_CTd-%Xge^aG9(%liWgZwv6#qCW~WP}7zu%2k( zFaE_~&NjYoOgY$E8RJ3A(;7>$tXYP%3LIFwN*eWW86>KWx2zYZ{TP0b{*%5aABy5q z>Udr5V&F9ovU>h}XBPptYYE|gouArKC)z`6=v=&%6H&&rQesJ;fSnY%G9}lRDF(fk zJmD(s^JC@?mS0PkN=7GRj>P`cW85F}1~wUB=I|GlpAfGO6a^a3@r&A(|AE$z<&%d( z)w83`?6x%81T#buKtch~gC642h<&3Ji6WX4%}c7vr%lVantg^lqoz)Qi!n-grbtg> z2APU9n80FQsL}@GR+WZZ7w*0(PASW{-D1jO*E5*?2oQX!xzZV8js__c6k~d_abH>n zYakb;5P1JGgej5j*eJ$q*s3@K&#X>==YpJg86n6r9fQ#>>&((wvd1~4T3b`fbgWug zM*HBpl2_prtL~-edabnVobr}&H3&}!fqezFoFMCcI5;T<&+$1YYJ=DS-`%hyV_>qi zjvYa?r1R67PYZBuc;@v3s-CX;&a#8^5`ITzK8Ql2S;~a0;`{Y z^$N7$90dwpSU7k^08c1x4i!~ObI&w1V3qyo9R+OhK5T%lnF^Jm)oo@omkl0^K5cg^Pp-u+zu`%9;mQ38rV|S>vAi zH0pKfth>93`U+yUj`5{2?l7X@E%qep>KqElJuF}n<6}#Mgf-~yk|S}Ie>R{y+|LRH z(M`TW)PfmTEQ4A-*F~g>b342t>tESC5vI1xi z6qd+pZ@CD%9+{(G`=V%?Fpx)2XiZHYQwl!d1%7bqI+k3RAA!MLbh@uFBTM$1l~vHg zVeQV97##JaA(Mn1)+n8D3jRa(cYkE0QrwB#`64l)zO zi)l(=rgrzrjT?8M_LHwC1ZKscAlGhe7odKHsDPQ&&bV|y+z%^<_D6+VmZxk?ROF8i z2NTdCBnoMI!YUk7quhAb`LV!YXT-Becq14j^)GWOCZQ7D6r~GHfY`99qKd_-C)x)P zA}W=k=^~!oj9a>ZchHz+$%E}x=XB%*!BC2Ff?s4i4aSp2c${vsl@Le+@>U+_b6T(fj8)6ZzFJomlAM;`*4R#sz(-w5skIv^O$DtF{TmOD6km* zsH%RQchw;2wsAI4x28lfdf9;QD`IUZ2OaQYnE6VYh?Pvx)USo)eyVB}tKOA=$HrQl0 zpp`?d@rZ3R5yXoceTXt*P1kN@+h(37i{gd~*w$O}FmlMf5;C6SZP-M^42LH6 zP-tN~2!grE;)@>Z7ywc{m7+CRlUK$FMq84^?SLBUR!B=sF-oixSo~T%r%gBMYN;Z* zli?calA;t)^Em@{Oedr%#$wDO^E7dY!OGoHN;Hk08WCIFWf=#@oops#8*PvMieBL! zdW)2%8Xb;PL8Z0q#b{HWZC_yl!@tc*Y1^Q~Hkx8zVM)RA1ZBl(LfvKyqzX?n|Eh;0 zV<-t`vdYDrmbF?`N92xZFj(+Io)sl~X>Th9%vug_v4dND<_O)R#zZCu!znq5WZ@ON zESCXI!yTa_U8N85HQzI*Xz3n?(KwE{B(7<}#GHNkQ7(w2<8oY!W4V+_0ajLZYZjjC zmm@WPRt#Oa6sFQ5p7Y?L0LSXCy$B*&Y(g$Zg3VzO@!ZDA)^3pj+fgrW$BZy%U6Hla zS)^8Tz-JjDAyl@6RfKRX>*_R*Dm^wemf0GJpHzq%!MrT8Y8#j{#du1k4SFjwC`C*T zYPH8TJJ1rmJdLH1#n3V4e56z`p~j^<%epM}9s*oxK^?HG)Lbo|`ZwPunjQ!)Qq~An zkLGxKv=&W|s_lBv?@-nlvGhlT`8KLs$%Iev!0zS9XjAQ!wfd^I|?5v zMY}e2g}0bPE2LSZQ(}gspdBm~2%D)wU;}C7Q07YTa4rLl>V{FHCTzMXRLK7PG9-RY z^~zkJ8#WtECzC672**7Hfm`SpQwjm$^2yk3ps4QTYpot7b8wU2722`0+~ptyU4~Pf zC#DZ-Q7w)2G-We1;u^LErNo;hV}laH7}I0^SjG^^Zjo;(QX>2u+`OdYYj{Ib!R?iY!uW1q@K(!KM8dOU_DqxFb z>CNXiDN9bVVShRS|HN7bFL%@v65bT*Ntq%|4=&%{5lSj-jI@w%aIp4*V-3_Rv` zM$q(&pyui+gSSRT>Y`HDdSJpb;K{pE!H!Dw!ml3&ema}2B}xfrd4*Qt+Itl6ko3+Y z#jt3Zr-grHC#o@J>g8(GP9@ZsbVs_4Z9ch8B+oo5U>!X-LH zo~vlXbdXf@(S*jgw7#v{EMbN66Y)Hall3mXE6hjv2#Fz^&36J!&xzTV|b_s$pSvDsm)Q#A0OH zBwF)iIu^0S z^0FfsCL~uM+Dzwbg+xe27X4)Z?6qW`(DZ?=Kj?vV=RnmlWK=sw zsKVAx*#*Oa3%egxQ3Fl&jwJiTdDfJ~ScD~`9J1R3_&#Dt%jCEi*=(M5L+3UQ@M?u+XiRln- zUUJYf6EBFlDr!ZFY3)T0Jg%1B+K^;}%nF8(7hl^tlH(XkYIkV`^9^tHfktxj)2^T3 zHK|?=8O+SyNwkbPRFVOEoV(2iK5hC+;MT$9d(`S-Pg%n?LdP<4QVi~W`oRIryO8Xb zrGcb_6?H8Y;0W8%xYLc*QFk|6@tiOUi?x&aC?JyXci^tvW9^iofl=x)T|r6%4v`Fc29*Y;X)5H#B`c4L}wlv zJK4M{55UZafJ)8;*GB6wHw%fgWNI&?bS|GQ)Q44V>&gv z4Ur;HM`^Oa!rw^Qr^V+ws+gm+y$&GE<6Byvs*=Rc-jwe^9QB|ii)E)JPfQ8GCv*&% zHlgAXx5VJ-$9P*liKHu*4|_>_dESSfEgg}TUi#|fklT8+cNiI5ENCTr>p0mR+E&O> zhfsY=u)_)NZQ*>Rm2|Hl>rsZgCfFyDhr#~~-VP<9!P-h^>6q@?&?9dm;f=SUuAqz- z*yUDZBLFi#*7x)aTK3Vk=<^)axgUB*>=BFsO`*+PEPqKVv8Re8-4Ro1SS!D-uxZ!R z=vd zBx*e?54^F?XK!;vvNo>DT!4T84jD9wOe~UX6-i3p?$Z7Ny4kDd(X0kWJ=qV-C=ZQ8 zKR|{mLM^OhE#*^Pc`ct=SU#rRU7?)h?NPo3`O2_1j+)nGVaY}SDI!e^kQDGjyr>NN zkJ)!bf>b^vPS;jk2jb9SESUg3`9a&q0{cI5R41Qv<=ij)%hDlXsuxsepHjEMOoJ2! zW9r|sW}1s3SS7z>kHQ-Jg*pw!@WMU?0iwZh5ulpl zIbTl0nkdLXt_jp5Jgcp=5hSZTK0LF?2ndlDC*RT&5fG#VFUe5Gn6o6+y)vSuAy(nC zTRw#440D^MZ8Q_5ZERuGUy|T6c8BXrT4IynILLlGozJ-+FG&U(ub;L`ZEHyIcs+_a zfUSv|qi{S6&f#g#WDG8?i|~jC8slDJO5U%l<~U6-Ftg zGmLub=yCwy8k2Zde0oMQNeaB=er;7m_LuQgRaHDy=2N8SVEY)QB9uJ$81pc&`6W{Z z5sy=HCbWDft-p%!*Es`P(`o)2_Apw(eI`(mKlOl?$w$O{nuQyP-o9ibd~ki@m5x-A zKt{U2m@?IuemYVBa3Z@?W1!kr;hpL9s!o$Y97;-BWqQR@ph+DpFJ@hBY?S~_=MLgI zl(S$M;Ovgbrm%9w2|tRtw5>4cosWyoNaO51emQ)PiIoa+K&6<5aIq?MbC5mw6_6P< zz0`sw5kIi&An!z#46$O25*oQEju=iUJnzCWF{OZ85NXy* z5e!*OP1&n}kZ-GYPcN$++Q?AFQhQaU^QIQ7!p=EoYw8r3KxCHgP7G^VDh7)uP6~5D zYO@N@dYN~at{`ESYXu#BZ7|twkHae;Uam2PE%p_UIGS0>k<3e;CL=P$ei06DH{k2? zGLr;*cXrMp5bOZZIY-wf&(aQiv)5A?ml8yeG*~c^LYxi@0Mx-MxJ&5c5Fyr+&xlJ#w`_MJhbAsuc{&eJmU4_)ESQqK%l$EqrBj zg088kWnAIC{*63Ddibaj2~kN<8DEkvCSXDzW@@*nh}~MI8yV(cKK&x|CZIIFTOm&m z887H`V6xn5czd@nZn(>l7C?^Uabg8?BB2GZQF5{j&si`YWCG9PWUT$d^bu%dc+@Fs z>QfJBx*~1fpo3CKM{J=QkmXv&5=x7Q$?=$uA{Fe>@+cS9wBw*Ei#;Z{yo>n|qS$U5 zObINN2Qn+{xUpn`?6*=%=uh-IGseUh+F20AtG}r%t<78B2vKgGHxxc8>!@%51onqx zB6L9gM-yVKjK&~*%VBdX=60v!Ov4Eq4zl0RzGKK{#1&hF6NcbGe*C=posBo?=gs>0 znxeV&CjPyde_x|&PRL-S0Z4si*z0M>&ZCGns?lWciumA%8ls)Xz?>dJImS_hV;uQV z;?!~P^B4y5bBbiJ2DK3NB8Z)ty@esI@iR=#8z#)J$P zt}#FT!3IW?^vx)}aQIh=iM(b2ii)dJ;yv-I6J3=o1BO62jkdKjQAM{*Jgt;9@ILj% z(6B3((Z$sRvUc}kq3^3p|&iUlPQA;OE4EPx?t;R{3 z8WJ%{f{$%23;S^h`&b;*$wkb#0@|E; zuDu$|m=u#NO|dXSG+CRH?K*ty&;u9|G*X;Il_GFy zUwA@p$AP%+vNEPGOkhev)G$*}6PR$M4@^YH=vB2j^5A#^W1<|h2_6|FhFu#EwSOU5 z=6z_RsfhtV=lb#im}S*guHJ4uIdo4P2p_~=vgnWFgHzqR)Lc6d-8K8-!M=w#Gsf3T04x(k0VHL-s z1zSWw>mK2Gtq@|_-r6372u|lk(6nVua)hv~2I^Xjd|oX?X9$FH!m_ss@M}jNzn1#P zFQq_hlVTJI4_SpkIn^F8Nx}y1pv~~jax{65I-I;V9d6a~r2HH(cEHD4CkI^H=xffn z!nd@ti3ap^Qqwu%pB#ztnPdJ)RgNU-f)UO>zUgZRWi;J}y3m!^5)JM7JLdvqNMy*B zVeGhN_@EB0j#8r`$}FGV(0(e36MI2b`f3S1ViOsfz-J2CdyUP$c-uRuX}+dGX+b#c zIZc?5{R4ho2DD{JYp zIGZYX+2^-o#EK)77?JE!vxg&=6}F5rlhqPnC!7-~qp=jL!9dB*AZpS!2@dLuv*EHv$A$S3%R(RW95-h4OY)rIF~q|AJu3vbpd0hc`bF-!rrW6 zdgKr9w8p({tclXw64H6Mvfl}~=<^Q4Qsy007TCyeb2jh@*lmyTSp8&$t-)zKiX<>3 zLy(_=sJg{$Dy@n;6Ffrq@OdN6Sxqg6Wbcl&IGHDAToJ}AUKmFxQKmX}59`!OPM}KL zL4ZFXhR84ifepT;`hG!hF`u^53ePQW}a%ppBlk8wJeGB9va zk2=kJ#&`P@dt4fh0_SNNz&T!J|r#%icL2kJ@TUJy6D6~I{(O5Y7bfEZ$?Yszog z5?|ReX*HZsQB@c=Nrwp=9L6|dUSl@1ISsL52NA4rn$Buz1V15c^4`*j{*Tk~Y;p}X z!x$A;gbB%~m+GSe@To3+PMgv)BFNK?qrK!OJX%e5-Z|4SB4x7NiGsMk;V8Q$IRMWB z4~d3^OJNXAax7NN? zMLxwHAwd?ICj)@;&gp|m00J2oVjYb|9R+cES>Y@U)IZFIVi2e?>A0D$vetKWaxrWqrcchL}0OCX0ucr20j*tH+1+}oR7nrT#LF5g)uiN zEL@17)BOly=;A~&nw!M2Oc*wod0kXJZG%|)9F5}m5x|zdjgT=wY-kHeUMxrlS8LWG zM=BP5)A_i{;WJm&Ac2=IYtEf1e+G$<1L(K@2Vqp4ow1ZzEg;C@j#b7?nZ^SgW zuj4d?IW?&fl4SyGKF0V}BjcQy2q3>C37sFPw?j|y2)MhqS1 zQj~d@-xbvqr$NXl1jK;YVm*m@^(Ux79fzU}$WJ5yk-SxO3Xd%voX>$0@>V1PFnz(B zca+CmI!Py%+r+<5kK6vbhbkDd0?NmdjQ;@O_~}?D<4!_n05_I9+QpcRQi}7+^3#hT zlWb1iBhl?7qah=er*?Y@fmUjo*NWmXizF8o>`y5emvZLJBnjI>4=*p4M8i5zHcd*sptfDC^k0_WEF*z^)cDU8iso1gpwDZ4BuWozLX)z6xD zS}F;##zsD^2ZX;(Fr9sDIP7As*N4O7jCsZ&5(E?~y7JvicC1>#Qtvk3DU|7)nITo@4Ayj%ggwBMze^;`PKGv$8!2LYrpuKdFf@%*ZY-T* z&~f5&({`gmAFEoA3AfC*##M)90KujvLv3gae}G$%JVi0t@xeuA`%pn zf)D1&VGzma?R=a-fJsVZNgzHTA5D|@0Vl}XUx3XRz9#F5EO_{{F>dI8ItG73uckQF z;yG;6E=6+~EPN_(4s%@X`~yZ8OGIWshn$DLMp#?kNLj;1aua4prC;J+*};-w)enY5 z33AEpig>t~%T}R*E$cat14NjdFf=rulXrqwrsAWOu9uA1cgvbvnz|it4`ZQ*0EQbRZvS8PWPgmz)NKB{*)dDDy`*zes zBV40za8yjpGRW1?QO9zi#%7FIVH~F-m_tkXCWYt>t>(HcPaNK5TQCI{nzDh~P{6_` zj!8#P#Q?YE9R#Dp*iDCVf{(^CRil<`C+$0KZJ&IZxUHy)D(|T*M|LYr^Tl&X|M{Kh z!J#mjaY{yjQu8^y3GQR6-pJQ5JM)yy&qeN|(25VPPdFh@ zi&IqjL3lc^ig}h!SFs*v&~U<%L@Fjc`-90&z?*Rc`uOZ~&kA!8O_e#@>1CwyZ-KSh z0wGr=Sp^ZjwFEozL_#VtvILZkiQNw0O%`3495s^brbmKgyI$L-N^!lMG{f>rU9#!O z@XYr?41V%lSvGg)qv0GI5kVxUCarlDARdU-qzESq9Z&^0#FN@)l!Uds zsnO)2P7RPq%JfLd^p(#sQKg=ir(-NrJ(l+->kzCgcmLch_)n)5@R2UI6-iPHn51=% z;0oHvL4EoR66X{%F_VPLtC3UB<-{G&=j6T0$*nPV$Pc8pPo+)0L(T{dSdc6ml?#hk z%b84q)Lw_tgf5N#N+BllKGHn-_oARmMgV946{2=b1&W0BNReQjSbeB8kfwmR3RxcLO~S&|Cgqb>2~tpFm}i{q6&y^WiGRe5etUQZYL(Fl>J#iNZN0S^gL2N> z@YERd4KDtP)vfK**IXn;*tJzc0OS#j>}*?>*9ewppg%O3|XGl(jg4QF)}@Re(YbnpECS77gHZ?7~OYoW5n*16xh%L z#0hzY=;w$`TPM)F^D^c#mpPy_G8Ydl>-QktfRNG8a&i2~DJHkP$hM!UqTHbbjFs%l zJI3(!?Ng!jkNZQO$NRk_o;4JYSxyur9M(*ym_H@BRLr-}pJ7N^koMbw}9JE_Jq#0gu_88bJ zeqGf`mT!*AuYX>y*nF*_P|7?*sCZQ0x@L|$IIjJ;G+?CLN0|}%&O;B&6EQmB6w||E zq20|HT**o8OFKy_GPpQ-N?&9ajUsRY^I36HzmK1dE3Z|YJf_La$uqvh@5!^`{F6r+ zp2f){9uSe@{0o|;Y!~y~?~GjGVY?Q_y9tSF3Xz_BA`T5cc}$MhnH7tZ$Jc9-1*!3s z^5$cV-386C+@dlTtv`YQr|?vZ+f#+(O;UU+60ef(oUp0xXoVVg*X;=D(yrV$EVVQ>FOoU3%pO|QT0UC)>x*#H06jt>QeHubJ2U7(?o__Rfas}&C(x)<35U|Dnp24nV}_VY&=->AvpJ&T7&T*v0a5YBdRPIx0;d{Xci|%m?*&9pb$CCwdD(_LgM1TaGO3UMID)CtQ zP~NVIC2uVFi?{L?o5}~3Q5?Ix#e!B8P$AQ~b%Fus+fOHAklvh1u?)X7rEq$5+7ldO zGnFF*)Y*qD%<2O)-#FRX+VugrJHXG>-6Puowa#J)lzMUX8;AX6(vn2=Tk~>5Des)t zKKyA;m28@-Q4N>KDU#eNT0zy&Jqz|BSzxxISx4(o%syJD*ripp9y+xoAkmVxKHE88 zR@*x1`KC3@Jlk^HBMqZ@hLKr^@~vOW#K&41cf}EX$S`4r(~mw>98KTk3Q7)(Q)k=< zM|HAKj+{gd=5$`9SeTclK@F?61TzRNc#V#`3+Z!UX1>UJHUr8hd^)Zn(V>mbVVHQ) z!uzXrj;=uW<&w%5KX&Y7zr9jrJEYTZU4|h^V2=~t0$_A<%yS-Rhm}PJ6HQSxipsO$%Zg14Zy?9Dl3Z{vOY;2%VvX1uef7n`@%qphzVc zKo~D8;lPo?2` zPI&*jT8cm_TD+{b*mE&fQoYTqy6;U@BH1D-JXOODcj+-EM)=DIs$m47CePjO1Q* zQirSL$eA89)*L|{w|Z<9&++_xj-yrlVc#4-qW#19vRGXG+z?|^g*-MSM@+Xi28gFB!l3Q;!`eO+lK>1I5*iG6*{YyWGz|7 z-BC!T=&>@nC26h_uN zxU2XfJyx_H!BWBOq_bFMrq^xdIsQmJjgh%{?hI!kxoCOTwIcPi~-u)RAqNevj~I5()L%$094QJLnEd$AC~XlW6Skiej7oLdg7_hMsKPtntnoN#d;>Fdr4YQ zaYshxqPyfQCn5DRvs)yip~8+9hA8Q*2%+ANYV(z2QP5eP=WtxIO$FA{Y;L(El_Nbg$Gjx{EVFcJ zfE|ULerWzsp){e^wnIj}nl2PpM2E|7V;Y4j?~ZgoHLra}Va`()ELMg>3Lix|^oQVH zY%hvCS0HR>W%or{^pW{`Y~EWs_!8t)>civq0;>>ZQPSU4%=6gGB&Dv=lZRKCl{ftu zvhhuC9_FCQ8nK7?3SWDK@l+4QM1)s&O!F@`)Hw{w0FE8e)*xkkh|>?EJ!cS!Ygj0i zdII$)zIDU|%<#djF=FzLA4QM&y^jtEI)6zz?0la4C==lYY;-ADk)HI!It>|hneJgI z?F{%z8PYx{J(M>0C*M1ncKqbHFh&laS51c%Xw42TPCOx zWhCGAG($~%`0*nRFz*v*9zQ+*_=%&B z9zM!U$?j{_#69LU<-{W1DOW#wsYPHBDHgzw-)u}WQgcS!FFY;T-7T`7V3^aGYThtAE$sUZXU{t1v2d(5c zBU$oS!9bg4tH+<%nNo{8Xu)QSX%#Kb&|CY8eZ@`ucT4*3)Wj3U*dXaad+_^o_G(br#|@)ZlM7F?%DU$zB`Ls zZ+;KqGsPYI?z!be@j;%x|K@k?dlO|AH-CN6CGVMHwfG%Mxz+U)#XI-;@nZEBwL4MeMuFPv22INLy~BHMj74NAVQx>yz)j{(Tqkuv+{Y z|3<~d;vVi5`~H;Jdw7R0-1l?EgZrK;zMgWQ;ofa8d4|vy{|cTGP43;dRlMS+5oN9N z-^E*gji;U}ev>Eu!tZKCieE?BQO0*^65Rl z@JlYd?CzJn{iX{qxf{CNTfCxJ-S?)V%Uj=Z%U#7sXpw3Zl2{BDxQ4@ciu_ME||s_iHk49AwNK$L!W&g zB-cmw-9l`&xQqUL4cB*4%FmI0hVt~^t(3Mzdlh~esZUYDJLtzVl&t^Gkor#2o`K)q zK?(1r{@aSLq}BSLH$}Ig-c#fi zFa6HVzkl<8zWI0fcah(V>Awfb`yhRFfihl0&ZVNbg`O?$B`nT<1=nAqO&4x@$}Nf3 zsP^}A?<3s%ft0QhcLyyiQtL!{)q5w`mr=uq_Pv5WIzm6c4C=lK3Ve{zDtC@h-&?5b z|8L|h;G@{Nhn<<-?slaGS}3wm+})i*ad&rjcXxMpcXxMp=i=_J7q{;@GrNWRzTEfw z)89j8l9Q7Yog|alY({-5+M2&bsmJ(ip>|Rk_Q_bFG--p6{iJofX-gZhpbhDjuTU=k zLrTi6bP!il0m=djH08oS5M21VD8Wcv>&g#oSgb2M*LJR>5bnFSa}|WF^m?mufD>FQ znE&ng+3~aEXU8w95#lC|0ImWdl8Q!HG}4bo`euKNLP|kgiv}r?Xt*H|o&R0@DbTo% zflo~CVj=H=*hW07ii2z@vEmYLLoOb~M>+wr2_X^wiHYflToOo1ykwA^>lA3Sp)Do% zsUS5-&c&WIq!0}hXrz*sRMKH(ddTpbd`7M_L1xGTL69|~46M|iU1f(HkdyRsVX57) zGf?G5S03ag?J&p-9&!*F6lh51Gvb+cg%h41qy`E=LCQwzsSwh^P?+l?P?QpgWTcTm z6+=&P!b%`t5bg3iHJ~OXZ`z?$EyLfcYLk8)bk~J?_|=C7_%%en5!a2O3HfSDYidS~ zS-5WwEsVS-rG-cxOTNtZ)6#2qD{OBKZJ;f*gZ9t?IzlJt3|)-8dsJ8AcZ2SSBcZ<$ zM^~e8WxN`VI|jzWI2aETU?O3YU^021Lc5)c&C|G_PS^~X3A0FVHq0SxF3h8~=EHwJ zEP#cu2#XifYGwRc3d>+QtbmooSp}`5A20~upbV!HoF2G-K5iY@HxB^$<8eE4P za1(C9ZMZ`Zwc-A5?_KWmQGR*oxiYp%|GWp%@9rc2fZiO%D616ep~|QpA^#Yj5H5Y= zDc8Ps^$b1F@p}O;x$X~AkFVf0qd-ht(f@`xZ{Z!+Qr~|g_Z~hN=~&fA{64{F+VmIX zzQQ-|zrzps2}-jo4Ro-8Rl|NQv$APfj6P=97=txkIY82M;<_}cbGvdA7C^@hBwi%0 zBSU{`OnU!f>NE=XLExc%ghlixy9!1=Dnx@2hz>CzCd2{{grYw-ZXCIWxDXHGLjp($ zi6Ai~fuz`#43a|%NC~MRHKYNt-B-?OkxvKdAp`bhgiOd}hAbd?>`N|W9QxHyX^Y5b zgK+wCb}gIAp~?6r^(keRLFLq>A7x_RkVWOzvZ_3kO&D}%WDX!dd5N13R-;$O{(trr zDJOIjo*xQO#wi)i9q2B|{jai;xQxa46~^u&P*lswxa%9Q%zVn&U5tFJBj3f5{k^S9 z-ztG$Nhk%Sp$wFTa!?*BKt-rTTd0hlH|UW%@wL$^gjI!VP#tPOP2_4pZKwlv$$LGh z&vgT62#ugIG(o;8G=t{Q0>75f3R*)OXbbHKYY!cuBXok!&;`0eH|P#MpeOW#-o)!e zx_yoMNu&C4-yftd1{ifDb(hO1$AQQXg26BZhQcry4kKVBj3Vx67z1Nr9Dd_r0!)NS zT5d{P>V@%?`j`UY^!#4G)yY)iNxl7E57US{9cI8xm<6+84$OslFdr7cLRbWgVF@gS zWw0Dpz)JG73OiPFy$068I#>@IU?Xh8hRv`Awo(?`U_1UhU?+aNU^mx$U@z>0{rDY# zgXF0g9OC*g9D$>744LC_0#3pyI1OjuES!V$aDlY`!o3KW;4-?d;CB^T!!-y)-*vbF zQeQXW7TiYu4%~%%a33DvZ$5|8tA~tPkBI*mp1@OhM)-4hf$U3orAa&R_1Q4>+Gq!M z^@gyw@DBcl_r&=C($+t6{|P?B7x)U_;5+<)pU5d)SDJ3c(Uk?PdZ6;t^U@N0&ue*N z$}={cIYl_VKAibXeq}>e#v>V*>|Fcnzt4S{-*WE+7q}q+0wEHFU|VF|D7vgDef?f^ z2C5(khN!xXO?gx_Oq8)EgfyaqJcDJNk+Ddg%Q7CtKvztNrH3nz9?H{#v6uTe5DM~q z$&8M;=!ysNAps;+75a~|%VCsV5tUQ-s9ca6@)+eX7Ro_+r~nnA z5>$pNP?bDY(@Uu8dP!A7@~7ujwV*cCfx76ghn&p2>vP>eFRU8kHiE{KWfN#hcr$3O zm!iCXZ&%WmeEBb}TIgj|OTDaWrI%B!_42BXUO~0hE2?&SCDmT9tUBmbR7bt4>ZDgw zo%QOfi(W%@MQ1m?rs}TOQazw2^n%{d2OBbBS6|$I&>sfCKp2EQzn8VIoCkZ$bO`QH z@;eNMa~)l;twvyjKdpEqaYvzJG-1*{#t<&g#Id;Ju$S468c+BHm80Kl7A~{--Ru(6}GV=l6B&2 z;tcerX|~^T)VNj6!GA90Yh!LP(yQlp+db5xtjFdVX;v`w|I#gK)u6BO?9fXa`mD%B zW@RP)bd>&Qo#XVnMw|tDJzT3=sMp6;YLVW+@E@f&G~9W*te&iDF*=t}21{|5>9U$) ze1>1ow@qIH7B*^#A&Kl>rK=e!q*Ze?Lyjw zv<(mCyN>z|4YTYEar*FUoj3_dE0!=$E{;H1-;#td|&i zTN&lKlj|U6I1b>cWXQ@IN}hYW3^`f<${J3o-Fh49r?uLnr&W6yC-$L#KQag4pe`#z z3DeafSPzGxI&Ja@ef+52jxv#ObDkWG^fBV|ZQ+0T>*_fEC-e?pfBHGHCrRTJoYp%= z$e%$@Mn17Mh*fBSSN~bkI0xt90`>J5T!fQw2_2W=3P>xxs(1G4)73TXmHEnb;@!}@ zP+np$>mWn6EA?gG-{Sr@$T(LW?hx-T+(Y(0Ha*b0Ma1=xMr3BgX1VoH5A~kvk={!^ zM)nChBC{fP8G8Rzrcy>$_0-U5SI>+zW#7y!$LF-`7x+m&UZU?6yoNXMmN>q;@i4RZ z<>ejnf9w4s%J#jX+Z?Mu==~W(e09XU06p?NlUDk`C>t5~2k>kYnLpXqkPT+HKr?I{;?*hbcc^k&hAEe2xN=)Yr~nH+$}-a1W~!)27WV2P3IstgM72~@ z(a;+L(a{|PVp>M2SeDUVy=FX*WsHh#8H+!AW`_JYYQ$HLjN1|~0r3+OFA=Vc4T&uiR1(X0m6ZErkQ`D#JY-TrDo71! zAg#rv(pe^X>vgh9Z`f*88IaEinY?LbWwz$4d)c#-b+p(ZeM0slGNUVtWvaIwTUAzX zylnVqr_7hKlVZkKDhKyDLB^z9xVb_0tyb#Oz3p&@%45{Q%!oP-vv^cqWf5=xUCh7F>JSd5UDD`{#bwlJaY1 zk#(z?-($pW?bZ1Py(jcV^j)#rY-4RmL-tbI5~m$@wTBMSkvN@5ud^ks>VnR$TzA8- zJ8lol;s_l*@#}?rZ|K8yU+4$@|GzqxMCf=xSqwn$K++lXKjX1hC47isGjkuyQt$Y+ zObxRvSHsaE&nyo+aAq519gF-(7==wQ$-k7Xv=a|Ibmnu&u0|7P%#mZ@p*tJPR^ znRDgU)U$6ssH>#(1DUgr!v<+H<8ddzL!MDe!{lk&Jy)Nq-tlhZ!&vW?AB> z*%sg2Qs#>0-trv6=2}*%d6qTUw+4-CXvgN>v)I_3^^?3Sn2&w3=JxQ{Kf=DXY5{i0 zI%6T>i(oMx+Ol4)VVsa1%C(k_YMo`1TF>~n z0XBlHtv2CqMyEV$w^+iJLQ-|BIUFNIXad&{Mv3BC_0$FSA#+9|*9^AdK5B9?W zI0!P19|GAMJdDmGTpuMrQqIS4kHZN#38&yRoPo3C?;M;b&IR}jF2W_^Uxq7i6|TW` zanXMR_a@we+i(Z&!acZ;t_SFSi2Dd0!xMN4EvbWN$UKJ^l*LPU1+U=^es76qrG32P zdNgJ7H+Hiv?bqjl08h)k@gZu zT!&>lakmq9yAd}fa*-rW?2!18k%m8b}N2AU$M&jF1U3Ll&#- z&F@fIxz2`-r}drmDcS$vS%qH?>=Ao&T6f{UiyZAD-{u&S%PRd~H_w9I`0qCSbE6{< zgh3EbmAuI0quj%-BX|Qg0=W@}ob=25$P|ErPzVY`5hw~W7Zg3xPKseeR$|J#rQ(!l z2`CAr&|BKNN0lLsvev!mm3@ZIj4_fn>tXCK4;9c;5h_7tsDfWrs0P)c2GoRFP#fw% zU8o23p#e06M$j0VKvQUjuIA8!>y~iCvXyslrroWq`&4V|e$@s$J=oorJhVfmJ@*}O zJ3=Su3|*irbc62D19~Fg3)$YdeYo!n{kZQ>dVNS^0PaA-2EkzRK7{+BP?mfTLv}cf zfRTicg3&Mr#=(S9ZjW711&q%H14Ov448@DS=NI_`Odb^U|uy{ z%^|MziMhD*U_NpSa2LWNt{3Ajfu&q8gXORSJu6`qtOgnP*Wj)tY#pqJ4c1a>BWxnC zo4MZtTdnd8(A75lw!;qmb`ozF?rzw_^u5jYCR;5eKh z{3Pxv>mgMt;`!j)6F2vnPZNFy&cZo34;SDsm_r|#2XjH%+(rB@!DYAtSK%65hZ~f| zO^|u&E!^912kyc>xR1;OcnFW+F+72%@C=^A3wQ~y;5BjHz*~3+f8+NaKEOx#gx_cQ z0$<@9e&68-`~>C4dmYfh;>UOleqaMT_=A+EgK(#xl>hJhKLm&2h~HUt6!#c3M$d7-^XdeyITo7ZgN%hI z3HObMr?{4VqJNHy%wh4D{GTEISvUvhA(S`sHsH;XG4|x<*&y?_AhcZYyGYn2);lis z7iDpgJW2n(gzMogzCUmDFQZrHHj?HQuCKy1!owMJuKQgfzS)NJGk)HXaOSEqCLYtT zG6yu{-o*bF+(!NmslCk}qMpR`EttzR|u&amMoZQv&5a??A`@b1cpe~UcHIToH3 z=#=+_p+=rW_ic7hZ>SG`H`GVJYpjv3t53*$CU0Lr%Kt0(-?*0Y_|EkY_z5hIlm_<* z({U|e1wR|}X|RJo_YQD^3)~O@fe;BI+b*jpwyP=#*P-SO3mS^Atwg$& zp$b%mYQ&T0Om*BEhF*E+Ezj`#s;2F>s%3kiYTHh;N;#qGpr;`%wXV&j>Op;I01cs$ z?V)N+{3g&8VR_fiMW~vgTdNa76iOv)Bzgb+5gbvi% z1?Ee$DZ@FG(Oh)(MrIy5%zEQ_g4_aF2#Y|>YjP-@=$lVQY6zHbwhanYZc` z>79l%a2C#i*mNE)5MSm}9>)AI>f$f#xo8Vfm&pHR+k2jw|CYAs4OCZbAJkQJT(f;t z*U=~Wy@7iZZrMK30{&P0&+0Zh?jS4A!n>p`&zF0+i)>%8=-=XstfVF5w&)OBzOv`_ zm7IK~-LXGo`^J3YPw`E=ACSgFBfanF`IDTqSCRGgN3#qck?v!7;q#lUPh5Y74V1|j~@>xZ?|g> zyNp?^d+ffv^K7OZT->{P+{xZ(06Jyf5QrNIzsL{;f?$#DhYGg)bGqn1ZT5`=iB(iP zYaR$8zPuNUjvIrxF(DTI9*7Nb@DGK!5D(&GLjrq{N(hMvPYg+jlN6E>o*efC?+{bi z9h%d4KDbm$yGx~l)Q|?!5=Z7j>5xqi8SGAE|75E}%ZN_XK674_$u6h+{v_*bFCi+k z-8|DPbt&_PEZCeCeB-*5Wj5}!+vV8<*priVazSp8=Sfj5P~|b|!Tm3`NqS~`Im>g$ zY<~faBWeFV zMu|M@GJ9k#&L7Iem)|1fwJ1F0`Buy>&$%eHGwJJQznA_~obVDL`|y>G{4fXLz7%q$ zDU&iFCvVDfzX=06KsYpuobq!cGv+sVHfO%J+K${!G1UZ2jLJLh9htkj=^y_0Vm-UoQ5-S7S6$W zxB!2_MYsf);R;-ZYj7QIz)iRXx8V-lg?n%x9>7C*1drhfJcVcQ9A3ancm=QF4ZMYS z@Hf1N5AYE_!DsjaU*Q{khad10m^3J9P&!z^3VvV%JNSbGoZtdC1VA7}g2)gBf*=^8 zLNo}0=n%s{md3JD#pGJ*Z!PUn`ZMpEv>3pQ!stIM{bFdb{9|e!hz)Td6yicWhz|)M zAtZvtkOY!KGDr?7ASLOg@@J09vKJnz)$;nM zBVKxJ%>Wr86J&-gkQL->vFwloxt#ut#gH5FKp1{`As>W8e*6kRL9PoyVJHGcp%~<2 zj4Doe2`CArptOIWDg$Mq9F&I&P?0n%5ndUpKvk#))u9H|gj(dUHf|lL3-zErG=PTC z2pW@a6KKkHGiVMipe3||*3bspLOW;=9iSt0g3izdx~k8P4|zaW}q|3I0YXc|M-Ug zOyp)E-;MRTIcH43>DB~S8X;Lv}tafQ7IK7K6-pq>V4(dMPX; zt>yj+v=!L1lIvBl8rHyC^sMtw%=ny`bQ1q&M?7sk_H6Kvt8MfTQW@w&Q<>v!LZ5Gq zu-TiIltW&lUnRlDK()mvzd*GWcbk7w$~P&xlcHPZsjNxRx8pZGJGtHkyFupF<$3n` z@+0NE2c&F^YRL@!d(pcOwqpB!@^rvIIr9a^O=J$iVK@Rup*3ZBj659oPp(do-;;0( zPJ_$|%GpyG&#E)rpM`V&DcRjL=X~cyhCXt^U%o(K&B6Ue|J2ka?+<7@m*EP2W?iM> z8P7P2O>g+tb13D1jr3*T^g8Yh|Fk^g(^3v;DF^0^aFe*V;I@AX?GEv-`lr#BTT*Iw zN$(!%-1kqXW#9`3`5srkzk5Jl<(oEh@66l}mv0;7d#Z=%c@&|~svdJK-<&+beTtpW z;5od&mY47f|JU#ayWaZCdjoUd>z%*YE^{AQAFv-qocGxA0Y1Vf%Kfu{dhH9gd?ifw z%fI1%hadR;L?)Bj?u>0T7!R0}R*k+!C`^X-rS!Q9RCF4?Fhpat5uny+^3FLFg$*kPuBsXd0 zCM{{>zH+87(n`V|d8ixlH}`?^Q$7X2!_F8jEn-b7<8&w|H)w^(=1~Q)MfQz6oZ66m z;zHO^7-S7wg!~qTVvcZhoBc_~1mpcR{v{mw85@50FJPoqlK7>(dEs0Z+>O#%j3Lp$3@cBlgOffD&3whxt9L z?3*va?pnxr_@c<=&6Dg2)W*-Wn`b-e*M)je9~wYIM=7Ju8aYa1r>vRTuVoxC&#;!j zt`gW)0+|w8V|4lU51Mc-Hi?~0Ary<`8Ex8D2HT2j&G45!{N|+7!co?!4>@lpXN6Mo zl~W|XjB1IDsngeo%=&1Be`{z11JThIw;f17X-~W8;3#j54;{Jg1f8J^bcJrv9eOw_ zXaU5P{P)BLsSmMpGh?GU_Q_aSUh9Qku|eL0oo8(7?Wjl@GX7Ggrfp(xDb!#u-(>x^5Iu7(C6!y@}13G;!FFK z^Plq^4QU6gEs+sB7LW%icNvowBDV+@;z3a;fExBx;32p66!!T#0^pKKt7ED$5pQZg?=lTZRgj?vm4R_!!$R61}-23nV9wPGy9>WuO z>S(4V@|OoD+Ob*}j06@QOUYCSGFVyrB%G<(%SP#(@3kc?i-cKjQxh@2D* zPSY+KkE~7^59M1V&gD6Ihv;Muho3(gV>s8bhiA<7LFnWa#s#%(z)dFDppD&4!zuaC6+3{@jrz zm$Q>M%&Kxz#(BUTgT&U(jIk2Wv?;fdUY9@kb^U{1H)AZ8@uh;bJJ-Iv^k57%b%tS& z{62$>y-`@B=EWxS8OJ$ZBdwlZSu-z#IKO26J_YX;Y5yaPvXVK5*xDx6D?ml`R)We< z1*$p+d3A`ae0#*+kCEETOn$!8e$mBl|lV~%`hQPU}3f6IE7-xTq-F{z{4l(D?St>YX?c}ck0{ycmo zZu`f*$V!=s{AkK-G<|I}eeG8ttxI??sYE5+5b|9Q*_3=`9s+!=Xvms&vL8lx1Ec>+ zo04-T=C@$7?rVsiM$j0Vzz6!7yk}@lJ8Vk5G=t{!+0B-*%qe8w(AP%IF{1^#TS6;n z4Q-$;tklP8(fHb(nHRQ<)7qg&<`C@(Gv}tv^|+R?yd&v$V%+Y`eHZ9TnRVlSHSMuG z*FBu$w4ToKS}*5Vt+#UmC9hN;-f0tJL0-*qY9@K$_XC`>kTd(mD(7t4viaK= zeQ?7V!&XyPYp~D5saV-JiB7wf-|kq8o^`Mu`#hYKwGqC-IY-+Fn_x3xTVShm9{tRG z_qC1t?XUxOI_DeuBuw<~!q5CZPV_DKA7Klz*Q$1t?jGkN#=l>Ce}z~}?Zwu8kRSgn zw3Yqnm2dbC;2y-kF12@vJgp`EVL0Mk%=3`*!-OA$RkSNvdmrceDf7sRj0q=@_i(C8 z_L5HGe+oSnjd{^h#sYr#06*C;3*?s>q z#u%xum(KO*aj93d%h%2g%!ACctFrEta;prYOTL|4iQR9A^A_a0q<6S~8#*=`V|gLU zU7mf?t`;Es9``QyA1If|{DOt-*?h#FPw*K${Gx?CN4_8@-?o0m{k6x+yp;Rz&MlNZ z-(n#DlY3tDD-Cq8xV9Q)@PmTr&M#s}o3gsB%Fnf(>+H(r%AxG89n|l3tpaOzf8sb? zJF!FVVEFHkxDPb$4@BHYGVTvX z+{+%VhhO6`>+G=CJz}_#T}P=yzEi>0AP6RIRNQC~0@1mT0Wl#Kcp$dxm{AUqS#-v6 z9VZXIHe!wmp{^4=!&qY*dr`9A#JN0l#e?{efH(;u5hQkHrZt%3U>@8g=uhejR>>ea zdQu>t5>i2GNaM28W>_s!$7#7w2k9XLWQ0s0eN&!R=3ar-7$Y*fZ0r%qZw_&0n>4Z_ zmkl>NZVt%FbuQf8xOs5HNGC6DJ_v{WP=K(4;NjOx z!sIETD~&4Rx}=J_GOA)OIUmoi8L}l@yl-NRD9N>)w``6*GPf*+-ZI>m#=i`dg>oPx zNO{}}lyya@1eKu*epR6wR0kOcYoMbh*K(e-7H)0VDeA#|hM4nHe%XR?qz-a*p&k^( zE_1Da+Gr2u?6t7wlvbax2G9^1L1ULoHF2HRn!3&yWAjYXdjg?6W97FLJp6)-j1%HN zoBD1>`pw~qe$JRPwQ!whejw)-S!Lm$m0x+0aj+G-TSFU{{Nf8|zPWA(?UCsK9ifvU zf04d>ktTc*J7w-;{$`aq=P_+5<&a;CxrEFmuZ*12HQS^WH!Hs+6GeV$#(GxkOg_4} z&awx6PU}i~@~w>IM={QH<6i9O{#*J|Pd%tRNw25t3hNm28}DAow1VEy2l_%k=nn&6 zAPj=RFa({_28X(?YJDP}_t&&x=o{{m?`+KQtfV2&D48#hAWiv=qmj6>t{#Ou8pgm_ z7zg8F0!)NS@PP4mGVT9?n}8|2Fqau{CclozB^cn-zr!QYhW#`BmeTwAt9{idIP#P!Y0CgfB&$V`z^2) zw!wDT0XtzA><0NxQO<GS@tsWXo6H%#tJ*`?W$h7t;Elug4cm3?vFp0_#1*KX!ZX(p_1rZ^ zy?~eKdIhgR_QcZjyp;W3`3^J=`eSE8od~&zEm*V>% zBd+Yl-~R0xM_&0$>Au4};SOWX9mbm5#=hNq$}<&lg4A8cyt{-Mt2(E>^5_= zd-&fo{Cg3e*6=surNa*Sjmq@y4a~R9y`~<_31!U5fZmL5m&)Y6Pr89BGx4%ORwKSV zlU}K8?gv`15$~av-ThF@;SN+e3C~5`+>nR+FvyFJe7NC|9|}N0_am(k6ow+)7j?f< z#n2H?$?vs3#9o&wjxITuPy$_YrlF)eu2zZ(U}^5lKw0p;Q!mGLc?e_pxJny19AQQwdBL)HwlHcro#hC(^>PY-f zZn5LO)|oh6+!n2?Th3dUwieZ1GZ%YJ+}FgF8H`JH!FIj zb|>u~&=bseVsB|DoL8Yu^@cvsmoQmR2Js7K@~rl~YmxUT@;h7!^uO_cN6R-apI%fIP z<>aGgn03YUo->-s*t73tWV|_?Mho z!pEF`ib()ah+aLikC1@h*fD<_VJYPz`CUd?EXQ2|E4_Bhb7vL$R+INNeEh?XmWrnm z@GEO}^wJqX_VLZSV;$({Pd@GXTDLjxTSvV0=-L1wPKVAsk}#_h|BY@Z$NYSGSXR#{}zznrjp;*$;z+inYzq1{Z{vRW8B|{%wC>}+p)Qr7QnAM z1Yl!;QBFI^*G||)8Lecjj%V~Q_8N$@C&EVaJ=qWaniidKv0*Ra`#|RH`*G#{nWS?7 zq|apI87}LlgWMm2!*B$S!ZA1wC*UNUg45V=#@$0DV`X~Q9jFgy-f@oS*j?Q7?nwFt zcS^qPPpSUGy@>oJxC~d|DqMq6*l-sveAg)PNA$viPx<=RRDE&UoNbAzVj?7$E!f zF^L-sWM9^UUu=j2p`;_vkGNdNgZPlZNJH$5rpGXTEi#(X|79#oNO+&LxhSkD`PZql}9Oc<8Mj#siPHEKHe^JO@e;r({5E!@pEO z9NodMWU^zzz0{M;*<^fW&5y1!P!`Gsgi`L3F7qey5XAFC_BtvM#`!erFos?+Ai7>D zz^6Z^UK!h~a9h>+}^5cu?Z)0 zjI-2-%%^ITZXKu#^`Jg95WU#75xX05-3WZ|sHGh>4oIt-prHrmVvHYxEBP5p_%Ij_BLaSU-~Gxn zDo~9if1_YD`1WSac~5+!?qtjv6JS1b$C8I}=olZ6K%OmX0@s+M{LXeWs%fkf1q*+!=XB-F1sB#iF|4f%xnv;cWClNhjm!*4q|ZX%Z0uM0F`#|0Y@;;FFfxHjoeIV}xc^}C8K;8%P zK9Ki;ybt7kAnyZtAISSa-UsqNkoSSS59ECy?*n-s$ooLv2l76U_kp|*0F z`#|0Y@;;FFfxHjoePHM611&8r+uc`!x98*CCx_%Q$bE17KmYmb&%pL~a{uT1{I7qX zhx<6W|MTO2_uBvY@xOcR@9@|+&X51yw-4mU|L(i*>4Nc?Nj~c^}C8K;8%PK9Ki;ybt7kAnyZtAISSa-UsqN zkoSSS59ECy?*n-s$ooLv2l76U_kp|*0F`#|0Y@;;FFfxHjoeIV}xc^}C8 zK;8%PK9Ki;ybt7kAnyZtAISSa-UsqNkoSSS59ECy?*n-s$ooLv2l76U_kp|*>@B45(j`ogf*F~

_uoktDzUo`x>&cUvu`UkrDR$bb$s=sg8%{XdJ|LV29T|-9=U9{$? zq0Th}HodxYxbvvhT|<`)_Yb_}!rrdF)od{z=LzHq>?#SIdwLYLJ5e;fV`c1z+u@BF zSO478&+X|uy|Zt|g3}ami;7*9EHeI1tVgl&EMIv2{u}4mpG2{;C)=;sCthCjTQDZKy*d5*$O}i}<%Z)Wtt(nh%-p^^isZfVt!U59 zjt6?2D?GGnu&b-8^rL9m?4Q?K`!&(*=ohnQ+iFE)kG?T8&qD5PzmB)7{v9`^#*?!S zjO(@6V%+4pFy2xh&mVudE3U`w;CT5NQ8ekG;oaE(kGN@DpUJO+SuPweKYRX?#&deQ zUe|ci+TPx9ZfVSnlch%=K@JV?#q!ttann`c4Sw8wclP=f&bPkNxHBdfFvGO+wT3ZR^?op6unhS@FPnEXR7|z8>3S`6z0R_Y3Q>9P2e-iRH09)>}6>U618hZ`9Xg zd#Z;iE|29{k9o5_){CO&)YZ5ISdZmckLB1NdEH#qYjQ7gKmN!~$NkIiSC;2?hU;z1 zwfd93JnMJA5BacN<{Pd*>$5!TPx$(5m-WN#V11Tn{kHdG`D~Z#U#vdMv;LT`&vv=p z%$K=v`7F=+JRaCCx4T$>P*j_xq&-wF=m@{)_&h?*0&dfhvn{{7U9IflVM{BmOgU!+w)Byn!eq0PFZ^H{3RXBR&)&a_xBEU z^k4Y*U8{!OJIk)@<%F+RTmQ^>d5tS<;bGgQ@=yP?eY@?F?Y6;*VXwqACz%s-VNUC> zMNZ6*myrgi=#UJ-M@fGHi^+tj@F&E}EdL43Ner${5?Co5&cJR`YVk(kz>Gc$jG?q;So}Ym4Oc zG!-dKF(>B2oVq`XoS0vsf}aSt^U|)t;jWQ^&Yr&EuxKV%TmQ^~;hz4!icfX%I$h(= zcjoc;2Wz-zz=q6;xiF{k8;}$83#*3P8K3VuTvWqr2WRX|uCZ$CuPAv*;hKwIU8Fx{ zUG6a_=E9tsZbVMZPpxB0+c~sqZSTNvM}K)cxZ3(VqCf3lBq#qiEVaqZiMcSR^&dx0 z%r8~R!IbSBx@^swuHnJU!h%J(+WO1OTU_Q^{K+48oXPWDJzq$SnGuqJ|TMo=c}D~3jNU?8@f-pU-bIAS?(t& znSpjMmiJ?`?-QEc>)d~^{FaP1vR)efobQic#yG1?DX$g!qi>J>vHtVZx2yhyJA|by zD_N%6`YYVK*rAL12iGJUEpz$}?mE}{M=zqEwl;HOF3hR>3w}TN{K7`Gofq4Ob$ZIZ z8C7lllLxyxhq@YQ`@b`iTQ<9r}T$4{dVK7V|cK0)g?WB7l-9TuD1T^ z@!}fYX|JTkg^Q2*L7$U>T@$e%O?Tg!xiF_uf4#x{;)WCdXge=-YkKiu|JuIQ9X)G0 zFD~)mtG524!crSgv89%F_DF1io4mb9PSf50VlK>yEiykc$J$QUgK#C&(LdPJ)i>N( z(hcEi>ldz{8qX|asa$)EZ%pK5udqKAyZ;rxzx3DdkGt~8!?oUD=cDDF``_uV=k3!e z$+ZV3w=_9-$4!sk0e_j_*0~cY`HOB5So*sbhD%$1@%AaNy=Tt4JEO>cFg*Q%)8gAK zOMdz71@k}u%}rz1ofX$P>2*B|uRQgn1&17YYdrsk73baliRX7Me9?(NUckCGe*Odf zce(Z!T79c?vnyw>ztpw$9#`M$7~ksJwYHA%^%rz3X`MgvnaxA@f49Zzf8itlvEc15 zKmE?(Pn~tATZcQ>o`3nm(;xiGg6m#(tF6O=_uaDQ_U#*fyzt?+A8&H&P`EYp{7?6` zx^-w>{i{0{^bN0E*mCPhZuw{5GV91QHvRABe?Re4H~oiO-(~Z^GO%{b7w(^EedM~? zTYmC~>o@=K<%5f!^Skffb^H%!EqZp{#+GWgzuNV;jPfCho_NVW#r-9jMX9e@KYG=I z;}$l5`LRv^{f(wto5c%Z}$X$2GyBoBYff%V4~2VdL}nT(ok-KP`Ig zfp1!ro`?HBBd#reKJ6A)AZR+Q60?<=KY#v|ZMJPmS7>bg=Dnva;Cl_LXZI^67kw+^ zGKh6KPPeop3F{HL&q3Mx%!=w8u69# z{QH=%V9ezg8{2x@d6e}YcLi;|$Fu4;-t4peb9_!Qs;lI4ik8=L?k61V6OXoK-1XqF z)KkaInYl7&E|K|z`T5VITaCAG|8JN3%`NUToh<{dPh8ugLS#A{PTpJC{Wj4vSicMRew4ZRm{cwA=oYultDrbJ5fZreB_X)bs#P{L&J%exw z%g=7@b8jo`S~+^j(MKN>&M$?t_DA#Aa2$@_k8#7dF>e1M#^Zk6d??m0T+WXAJ^|N* zpPL``>lH4KZ2h&-0n4#o!`HFiY>(yH8(5F!SZ}?r$M#q+{5}E8vEHPw$M#eYQ(PX) zv0nE#u%2v>^}_EHupH}6_6~kL6ge>6=&{+f%)XxEpeLEXR5qd_A_udh6z<>#-c`)!&EZu|3v{qIboUTpr7@ z-iWWq_E>MpoOC^wW4&#@9@}HRn`_hcSdR7DzlHT=d#abtljT@%+}C4!tQSRZP36gQ ztk>+1YqrOFH`k`?u^j8s2W*e^mdrUVzHP}oS&sEsj_r}x%~d`7z6w3_BR6duu-a#rSPx|_7m-WNrg!NgT^}8Ryeqp;@?v&%jFQ4UEf5O*iyIgLu`Yg}- zZQsH2*)IJx<+$_9XL;5i^Yz&-y;7_`%d>vdgIGS><$6y!e*N-Up7l5Q`fQiW4Uc2y z&+@Ea|6MGf?Q;FYXQiWmI$vpnm!e-G==c9~n~ z2d+QMv;MfR&vuz#vHC2}`ppkv`D~Z#U93LKv;L^B&vscq^c2^h(BD6-}W$;&vv=|DgNd0@5{6Pm}j=jr!rTTvvDc!<0oH?>wk{N zeuU+_wTnKSnV^N)G+FWvig8xC3& zj~=u4@sG7c(cZ209^Lwd4Yr?b;QMxdj;Jq~k5c^CzmIpQ_wno8d-(ppiudu>pEtT~ z<8ik&-cI*ZmMlHnVj6VM z(&{Sx1Gv7Ss_R#@)bv)o-RE>-`sIQfk}oqS=E9uX{tG!VzhoVo)^@rN6Lk%i{V|Mc z>z`K9Qqx<}?{ng-b$+6jFC@myiMcSR(VrnF=9j1vPii|?_pIsa8!Gq9fYsJtQqfY= zTk$UU`A|FVzL9=8{+(a&l0N_Lb74;P|BalOUszAu+1WST)7jh8IaI=@uGC7k^;_Li zU));uVzmNp>Uf`%{gT-}f5n0Qifm){C+5POx_^P3*sqdxY+BptKcIGD@7i)CRc-y{ z@pA`PH~P=3Eh=y6*qVcVPDYj!^U3%{b|EL`!kor`iJX`pTGqeX&Y|wk)n#?1xRGk> zFRy5+T7R3`BaxFabDHk+e9VP8H9dixn4h(i9JHP8)7bWT`%=CYGMW4 zoGPooyrQM1S8Gcmr=*{z zdoBTUVNSfxXMX7=By;LtJ3O$q%&YP0>z`TCQqx=U44>17(=WTv^h_Oi+%XsC#FEU9 z%(42zg`K56DTOsLuD1T7ik6yQhu^x-`Dgj5*!MK;xa0kfG1rvC83#IV#)3O(0X?rQ zy@K1_L!CCJUy8~4lfBOSPg~uz<<$Kr_=)$a!ryDv``@qdK9#Fd7#8~z>pR^m^XA!a z#F2dRepK@x(LTqM{{Gj7-{bW{V?`!xz3sj*>+wEGX8jA^zXZ+r`%&x0(_Ca3e3{!5 z-;cV$>bm<;9B1B-S~BN=$bL#2Qtby-(273aReGyILlq)(X0FVc%`ty>t7vl+y~*F_ zYg;sM$3B~Xd(s;V%<{=Gx10B)jGyTWyf!Xm_xRctMQ?b2n~m`q$i`L&Hq_R+%eZ=% zaXHuQ*1qi%>zCmWwiI$$en+$A{FrN$$HN_N8b{6aOPV+R?45S*<$n9_{c(EVTKm5G|=c5$=#qXuAb#I33_YUr}+3q=*C)Au*V?QiY ze4Ol;$7JT5Zl$zVi!ZO-Id&W#?Y4u*!>z7?5;iOI-c`BF-WkfT@8j91{IyBuWI5V% z8`$2HZrbKQ!~b-5ekHy=L*JACn;_qSj`As*^ zFT8EnZ?oJ?KfnImZ@RM~2Ae-}s=ohVykSLpKFiuTUjC=k?I*uKVe?0C!hCziNnGCl zy$<@Ge%~6;cW3y0;bWc$_&FASo`IhW;dQ62hYg>vjUwA~?{?F8?(tQ#-a89>Bze8L zejl{Y@rK#phCMNk8=K}ITW`DGWIcMQd2UAi@VUpESC@6Y`F`&Q{QlGGn(zHM)Av`+ zIv}#2nTKRvpU5bVR&>2tTB{iiRrnHfX0FV6q8>Rje>6XDany3sJzCVf#oI3j+jIUl zx*zlX5kAlG`8vkQ`3{qVyZ&^~*Kz;&-+xAPT#HA}x-vQ-!{5n@Hf=fE&nMk<_VY|G zb*<>R$6@`anwc|mWzHjeAZO-}_1JrH6y3Ll>-3Y0#L1lbV2ENlb3WVg<1lA;Ufmdt zL{~-^1qHJ(nX_db4(1;B*MkzzF$zmOwalEED|4oIm_OFy5O=+DL83p4KjsSD;(n~Z zUgi7W4X70H`o%ao-_PbK%-N-KOLXz)6d0nzG{|vLqo`#vty^m_JS8I=XGuk$kTmqy5XAlTAxb|2kn*q-t?&t zRrkH=?|lc~n_e1xZ~A33d~f>33zoF@U-p^Jli$|&rhj$LwoOOhqVG+A|MwjW4p^w~ zO?Px(vG5%$(%+kY+O55MQ@=G`HWrH(ky8r*_hA40n#tYY8{M z)Yl?+Z5DoS+WH3DJ8`o16`ba{obOFP*L`pL9QVEH;c31%&Ffn`SD2A!8m!D;)%T|B z-|Mz0`Mv4iFD{;e|K4=UsKrZ{Gsir+(N*C4nyqfyvK~JO9_9O=@bmus+&16;xGII= zbG3M%^A^`oZSBpqzw>)I`95dt0JP6>^M2rlXJcGwtjGkI9N+@%YFtpEcMheb7rp0na2b3f9lp?$FyvH*?x-U zjQ2S^!S%QI40GnzGk^CTfxDvU&947$-0Xf@F#q+A?e)f1V|zct{%qs#`F_RMjXA&n znQuAXe&XK~En9rD)wiJsBm1|`KIv_}u#~}$rRj1GTMD_9WmHqf`m<@De*dy-%*Qir zv##sxl0&^eUrt?lw?*##CF1%05ayxn)W^e1U(Jh4M`K@l+%J4Y| zydL29yZC)8-sj}`-&H9L)*s*I8nOFGd+vF2?S}ZTT-x(93Pqv~2jjfK@z`^~lZ_eY zZB;8w(UYwAxSM0^-Tu6c`kPpI(jVAxsC`^=R&b3ZYEtoCuvi^=nT zo8trT2{x&KU-eVGA7pHve530>QwN;)?K5lmeO9eI?~g}ssvVDdGs{nH!P>vx_seju zwUj*XgTqo!9kV|(SLVzmGXE%Qyvu#s#r5aS~{f+c712Zf3cjymO?IN8P$}robC6e^v-c^+WkM{ zu;+{=cJ2aC^?Aj9hnO7P1C8Py!}ANzCtF>iWZpdQ@N*LUy&1p18-6dDzn4CJ7Jq+s zLe2fY#pL;=`AD1xIBt3Yc>IMK=ZEBq`)MAJtoOKI@9g>)1?QKKn+IETzVVF~8J*$- zd6vyzccZIozd!TisqZV@=PXaHX^4M{G?;ifnU`f24!91t_m$i$rM_DYTdItiGjnCm zY>oMoch+$-=d9nKSuafvAt&eU$m#AT^mohI?t_zgAN=_3d$oki`^l~6PI>Lx*7SYw zwwlv7S-l@#bJW6>Z@OVq{l^cB@14&->G*|P|8V_+YgQa|r_H~!`Iy^Z{<5xx$NujB zEigX+g`e5<&(W52d#;j@3S{?6b0{;)gUI^4PW#`_k2>HdFQc*~6kEp+R!@bM4b zbNeALY;CFU{qZK(#-?@qx7>O8Ki+WX#4*RTx^-yX@8s(ieEg@MT+njo^|!h2gdh9j z2RGmGt?%D);>7m1yY+3D|K!O2TmEf!?V^*`fA_9me((Ctvk%*M(Y()Yzw7&5548TE zX=6*Z+h6VaTSoa1MGrjlfR-?aQeU%v^u*t^Ej;6f-)=gx{`^g|4*9g}+jwtpZO;0i z+B`j>{3JUY@6RxBK80 zWBmNkNcX{U4f>b456sDxCIdw&1CDJjcyLt!|qGjdT#UU z!PjGZtas(? zbUl`1y?Wo@*&gfNR-3NJa;(SWh3%;xrnsIg$9gQs_Q+SppMu2qcbnXcJPv>4rftL9 z&p|FM&wd~FJ6o>RXL;5i_x0H>>$6|7UDjuL)^9!+%V)b>ZrGn#pXFJ9)YoUbTyC-Y zEYJE4?N~nBZSeg+>|b0y%d`G^U!U!=KNqXd@~l7U>$6?1ci2z4e3obZ?(?wzY?s?# ztUk-L{)Dg3cDeq=>a#rSx1EpWvt6!#vF&Gh)*tir*)G>VJl?qdEYJE)e~0C>U9NX{ z+_65(v;GEOpY3wF#p<&>>({>u%V)c+A0EG4KFhQIh_BCfx!hv)S)TQ``TA^^=ey7Y zTt3UQe*3Gj{%n`^=$G*LWqH;g_x0H>kDp@oS)TQqUxVedUG~3X^;w?vM}2*^%iOpf z;rg>Y>+^bq?K1yj%V&AkXZviI`LiEzzU9Bs0k3$~vERPNy*O{);WZuckzJGez2UZt(LTqctHEs-m3JJn z9{WdT{dL3X<8EE}oH(w1_PEK!D>@EKYc<_QHN@kPxiV+A$^4_>d$`BWKlQF_zx@`Ml@0Fuv>5|)J;%H!b$B%cAe^$AyEU$2&f7loQQvPAC%$e)S{K4k+6Yk->?U!G@c>A3#F)wf% zaHijg_xbI7rRSu7tZr>a4(?@he9N2NtzbQu^6;8jv+T!eO+O_2<%JpL!&X8r)_U6- z^w;h;l-6&HwPXI-+vUOb9(4sRp3%PP+pYGwlGWDVQO~8cbI+m0!b!Z&oR|x9svkg3 z%r8+Tp44+}cJ1dfFRZGZcHQSv-sql>XZ@+1=Tb5k=F~KdoS0wnoOa#kQl9N|I^J!ZeGi`l z`xV*7>`%;vIjvudoS0v-j!mmS?YhsUwC8tPf3m@HVm|(sfBZWCVNT42Ic>WXIWa$$ z=U6%Iy3eJw=XWwE+b-thf0f2fjmON1xiF`;5#+@DQk5Jir(O5Cl=l42teouA0O7!# zm%eu}GW_rv`-^M2HK+;?Z~XXYW9SJwS-w4(drrL{Wq za!W12oS7?gZhs4MX8vez=Y39)oFL}PoG0IkoS8q?Th9eD z-kF{gl*~D+|Ks<6fBEMGF<0hH?=XMl?4Ap>x%VDS+rN&ZvAb>RWA4X3^J>4pxx)9S z8{D)FyuWIkoFC8BKMUPt@Z76gqBqxk%zq+H1+%8ivG!BEKif+E<-e!QT$wYsh53_r z)-nBDEa&gknm06rtT{V&s(C%UV1BmmN09mbh}U%er}eMYaPIn{medOlcGmAl95Ls* zg=??Aw($Lk2XFl3!dD)%q452PrpvFt{pzQmU-*8+?C&0U=fGuODttfUTMc(F_|^a2 zw_x2L?s4CbxbK!-PeQW26lqk{*E|8VUpA%GwV~0)feGcE(Y;`SL*8Khf-~aG)d;A<8fB(++ zJINKY^Y3e2Bldgbz4yLy_MREf3z+;MJk9agd%*1$< z?`t0We44Wska&&n+v4{j7yLWk=Wv|)KIh8W2SoN$+Q7WtVZjFjTG9KQ(pwE0st}no zb7jtx??cYqZxuGblU4i6zt3T=%$dgn^G9Iw7rVcvc{jt`zJ31U?b|0~{+N5woNB{a zwHVvAj}5&3CO?tU-(0cy`aAvkhFhXv*Vs?o%(VafpbppH@ASuiSQxF?^*4snT6Le9 zybAqo^6HG^J6y;#Z2j3j-@x`Bb!Ba{W@`70GnXv2zb5JaV3hks#&A#9&@>Clm{o24 zMV+fIS?!jc(R9f#o#XyaqV4VOOKr zar=Y1^wA%3(9{k`%lW--J9xcd&weRov%=?C?C=$vra{{u)6AZBR`@+ndtS-j`**ti zogCIJyx`^icRlvy+ZH8X&6?)7S^Edi=wIEnVz8?#t5osVO3B)4+kV>U#=L&q>ZX%* zd7T-4AB6YMc|YA%D-2)u=P|oKIcJW2QxGkt?wj9;^FqBJk6#P!zM-`91&?Fa<8j>m z;jH?Ti?MS4bDW!BvLwZYHP4>l_Qcndn-{sd?!Gz4nb(uIxqIgJQ`(SfKd6FMbUj&m zt3g8*B6DW0g`BTP&dfh@myw z=Unrud;ZiT(Fbb2;eHa0%rIH({ul1&);SZG(U@CS{dLHJ;~5rTbhhPe*EwwGQCG5* zH96(<)|2B4or?#$`d0Py7F|G*8P(Q5d9bT2XZrp)*Ig8p(hHPO{YQO&^kdB_Z>rEAeLH3M$Dvj3!n! z>N}&&zi>`Fa#OVK8gtu>!)>m=*pR+ckJom@zti={+k)Q@guEk`KV2J^bNk`WkN$dL ziz{5pkr973Zts@NrdKCk)$_L!FHV{KRja*p?T0?(?!8Bm)wk(nJN9}$nn znnnnnnn?4AkOJsD$P>sD z$P>sD$P>sD$P>sD$P>sD$P>sD$P>sDs3d{%?kC!Jkdj08rzrV%*!XwX_;=Xajy>0X zTiE>_%QLgSXAwoq&tB4XQRmv;;p8I9oX%RKk#AvnP2a_MgCE!b5In;1e_;K>MTXzc zNj@`Cf6KvY)kM!pRBk!{Ut_Y*pEkNFt_S~K)i%FgaiNTVSdZmcul;_%-c#!TJpPm~ z>#-c`jr)3RkBeM3J6(_ESg-lpSRUI`Jxp3Sy(oHDYCTzw^%@?)^4K2h zEt{RL$8xN<-q&M$tT)f~I@?cNPnKi7NnelcsouNXx7k&X#9v^Yz#s>&=_JG?fd>u^x{X zw#Rx=^wHG*V>#AiIkrdsaGmPe-%;an_#-!M8(#lCY#+|)V)a>`_1F9QY?tdD9w%Hr%d`HZug`Y5 z++y`vp7pyQ#`?2eu77yEarrFI`V+oB+hzX6>a#rSxBURiXS-bQV)a>`^~ZdDw#)t# z9`{^-mS_E@N3eXh%lyORpY>Uu^*8wXY?sR|R-ffrpXXz?%l^l9=mjpHX`QU`iJB0A7Od*kENGuWo_7Y%>H#YZvV=c;`+AT_Pj^dd)&>7y_r>i^B0y_-NN6o zZ@ekZm|65++a4S6yvI+uy7s(BKc4cv)u?Wd=q&dP6#FS{U|yey&m`$O){1?nhO@#} zo8Eyu8{T$Rd@06px|ONabVz&r80Y4>2gbQhErC~ayCn zD2o1Oaf{3FET5yF$tDWph11T*_x>#h_ji_OxpAEHNm0w}lL{?NKVdn4(pAJ2Ub^gA zu9b$wOUB8e>7S5u^0iW?x6SE`_e=Mw=f~q>bu8zNZYGaA9*50`;X0hhCp{GUkbY(R zd%JCAzx{zbFzV`BBfAoFM_zoKw7mt}Gw}kn&+&%Gar`y^IQuxPe;WEreLcqPAFTJd zTY@bmyZ*=g_xAkv$D=nd!upay#r|#aGjJTf&9!C6p&w5<4)=8Zqt$&c)P80jnAaA! z@|IUPSS$9OX3h#*t$#c6oc!4j<6g{h*iOi8UpXx97n4sf?Kotv%$e;mf3W3x=G~lE z=W?DKZH@WU?#0{vj63|s%=KeFZ==P}zl$5|*^lgfZ}4}3TB9vB_T%>Z6KBTTZ_jPW zdJZ#lwzjg`w^ouuLaSC9L-$*e^XUKd#mnhle??q;;y--9ee%3G&#^;%ziv7v_T0qN zZj8$}&zm`C`~EoFd(+h()1Jvra^-x6Z{(WI#Dx9$6 z-g06t%xS|mDi0qXWSy(7r!dDG;?T$s~_|3Oa7 zZ{m%`a@uwO4$u~#lf{zs)AOgviMcSR$=@I+=C^)bv7C0@zXN1{-^Px+YlB=44%m=> zVlK?7{kO=8`E7e!v7C0@zXP=LkI3m`J{S7wkZE#aF3f4{cgTtPbzhy%Y5C%%XT;A3 z8(P)X*Ok%m3@=q(zp}-q)~e4vkLeQkp6#5}t5M|s6ws7`{fW6Sr-uJSPRy_2gGF*$ z+t*Xc@2(3uRak$eTkO!3ttsz?gM3bQotYe7k_11^oR|x98u>kPVt(TvDw5MBU6=Lr zUEDF$Ro-eBa;mWYE91pBE-!PjsRX|0{yw1fr?dR4JnoK4l>#s)=E9sN{(zjA-})Pi z8+=ZOx+=-{Eyrdw!JL>2b87w*a$1pOytVy);z{z?_&1bK3AEa$gPCMTCF`tw5CmVR&y$qQ8mpL&P<}|q-IWfPs z+tN9$SlYf~<=OEWZ&iQaaM#FihyAm5u*7p;we?dQQ6W6XdHfBoKiwJBe^J1O%!#=$ zr}i4$M`nIu)x>tL=^PkvDi2Fc&(+pHy^@6nt8}{all!AMk^OEUIUJD$Kh2z&3v(K) zMNZ5wteV))p1zBE*ShDNme`ZfQnmF@sbrzSMm*}SGcBj^xsgW(ao-(wL&JleJ$+?e7*t*V!oTlYHQeZaolwETeGbRC|Z-jPOqxA{yFh-8&58GxmQJT@&M$u-8DDy_fVmfPsw<(0YINiI4~#X!kk9-Mo!ExtDYTqYx-CB zT-4K5R$sEVm{XfeaYr2L9FKb*<_M!_bX1|w8p6}S74l9(<1ao38%&B=_AIWfPmDz~%Te#CaFt$$jX{g=y4j#s+t0_#tD zAB?#NCJXs#=EPi>Q~R@!6Y~qJay#u)82#mUr-H{Tt?#ZgD_U-HJKp8|WI264`J$Vi z?(-_lg*lBiASdP*G*#Hn)OA4_or^hFT7O4e7YzHHxNY?Kbf3duF3hRn0OZ8{*cQj! z&QACDi1=DL<7(@-y5%;;Z(hn-YP#%2KBw@0!E~SNVJ^&R4I(C}rwW!=t9d=9p<`X^Pi)O1b{yPUr0UrK%sqcL49Cfl#(apuCDCJsVQ%rC5p zoK9;!Z|T`~xmosyS*xvoTIXfuU)%;8@g{e^d&0f;n&9<)12$w%%!N5MKNmSMzp!f7 zc6Rg+4EMMjv0>RPuC{)hQ&z)eyk__5EGG^;V3NP{Jhg@y_LQajRxdqzi zF~TLx%=-=Sx9z$wQ*&|E)bHQo-%Rz#zfohmGmWdQKU4dq z%(wT!c3p62P`Ex|L*~R>m{Z$NPmTK%^V{&zVmZ0rarO;eK77fJgtnSCN|tn z{?486?6~8=oSx1X5@Y7XT$oe+#1Cd$G3Gb=sbV<|cJ+3ae0f<|vT~}d{@E2RwXpbj z;*CD13)3%0_MOvkU{1`1IgM@YiF0Cp?f+6Nr?P*=8LxtJs;quhzu@#CwECPvkM9+R z0VM!mDOKT(NfcE^k4pc@WS-V(K7-z zWKPV5IW-+N66eJH#y(#(r?u|$nXBSMFQffpFC}uSsQ!|QYNglavp%P=Kg~-Qi-|cg z7v{8WulM4(^Zly(mSQ;-{LeqR5p~W%UbwYFt{zQquu^AaP&C=FsDNr;EkJ zoR|x98vW_(;+&XY!)Vn()LB2oJQXAnfN-B`HkONET`n1+l&Pic}Y1{R)0s__qF?(S=R;6%vfjU#9WwD!}ZUK zyCL&yx<37RUwy9Ge#76frn9f};;uDaeWkt~t+syr!2MPwMF^S&G3r zb@-gZ=g`C(9+YKH%!N7CzjI^UpC)~NqaT<)r*hwJg*la7zuXGJb{l@fT|b$h-Vn@- zH#~TaIWZUJ)Xe8f`F_>@p&~gYzE;*z#z9obslxg@;yUw6pHt{@e0w7u6mw!O%!#F# z-^lIh>+xl6=Pf^F@p3!mb*^5`(xs29tzY_*ikH0JdE9=75FU5#r745uH11yI^T-}^ z(^hW$Q2buXO{RwA?@3mk)`5p);kV`;se&a!);g6~wWMO)K5oxru9hux^i_D?A-9{2 z1>5I;%QjTewpp8huI=OYJm!}<;h!tV?XI7HLVS8!c}j=dZM{81!}g*7O1{}`TlLfr zyP`7+w+)PbTU(JclWKhzUTMw+(x?JZVmPJ4_ChLY%8}*Zwp7o~grq32!v9!fmw! zg`76J*ZI8Bt!~cked83bgG|iY< z^j~gI{CVIDtS$HaQI0d8KRVAnz1Mz98&d5DRjifSZp-+dDr~j>9OOB6*7xGnIS!hc zg5B@J^&+kw&(t~EsEao{x%zb^WJ;iX}7V}fep2F?)GZE%lHUzN&i~=wom-dPt~!O;se6J z8n#@&GX31oROM-)`5fdsa^B22Kjzxu@oVi2pkz^b((Y%;%XGdoDenGy6l=_&eP}Giz3B^tpIRc>eMDGVI6kqrGqZc>RmP zO-E(>XZ(EZzxJB`_&DQn!FoI{GV8CK^v408cl_o>ZZq9L1{M3a#m~U^5sq_hIsZf) z+r3~HTI`preE~kNhW;@&|8Tx9=10i+ zS{H=n9J!q5xE8O8j*i}vE|^Kle)-zWoUbXIv#kMZIXP@Q%lF$0ABb}v_v2)ltm(16 zUKML?^n#glKH6;?kBeJfW8CLi?eaAj#4b5(xF65!=6Gz6m2s}okoz#+s@_xA{#s&o8`vxAm((_nU>&oAJo0-@^9B<(+?5r00))TJ^2P$wkTXHPPrz zm~Wq5O|H*#-Bq5o&-HnpZ(j_Ti0z6sS>B$up5(fK?P@4Fe@?)21BUmtyr%{8_Xzmu z0q+^`UI9NN;CTV>9q>K@KQrKc1KuxS+vCaY|C@lH6>vkq&kp#2fDa7#pn#tf@N)xx zUcik3KR@7u13o0+Lj!(6z%LB=uz;HaK0M$T1$;!nM+W@jfL{{uQ2`&F;{5o?kB{{6 zyK@~M?4R}TxiCIIkQ+Xb=BDe?+%}r#hG*k^%KFWRr@8HzG<)gnKhkGX%%*47`zI3J5~J{IGAEXMg* zjPtP==VLL>$6}n1#W){}aXuE~d@RQKSd8OhVw{h~I3J5~J{IGAEXMg*jPtP==VLL>$Kqpx{(o%1^83~SR1BYr;ZreuDuz$R@TnL+6~m`u_*4v^is4f+ zd@6=d#qg;ZJ{7~KV)#@HpNipAF?=e9PsQ-57(Nxlr(*b244;bOQ!#uhhEK)tsTe*L z!>3~SR1BYr;ZreuDuz$R@TnL+6~m`u_*4v^is4f+d@6=d#qg;ZJ{7~KV)#@HpNipA zF?=e9PsQ-57(Nxlr(*b244;al*sr|areDPHix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ z5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs z7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4 zei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU|2 z{X6|4hF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4 zei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`) z;TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc> z7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^h4%yL7cu-IhF`?+ix_?p!!Kg^MGU`) z;TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc> z7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crA zh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ zix_?p!!P{(0{tR}U&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLd zB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97M zFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8 z{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkzGzptcU#PEw4ei6ejV)#W2 zzlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY z@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb z48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5 z#PEw4ei6ejV)#W2zwq-9^otmN5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-% zG5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ z5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs z7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XE0o{D}E!!Kg^ zMGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKi zU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH z_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-I zhF`?+ix_?p!!Kg^MGU`);TJLd!p~>YFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`) z;TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc> z7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crA zh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF|!3 zZ~8?Hzlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLd zB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97M zFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8 z{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&QbWzdu61h~XD8{33>5#PEw4ei6ejV)#W2 zzlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY z@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb z48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5 z#PEw4e&P4g=oc~kB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-% zG5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ z5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs z7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLP1ek=VVhF`?+ix_?p!!Kg^ zMGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKi zU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH z_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-I zhF`?+ix_?p!!Kg^h2NK_U&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`) z;TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc> z7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crA zh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48QRC8}y49ei6ej zV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLd zB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97M zFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8 z{33>5#PEw4ei6ejV)#W2zlh-%KF^1K5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2 zzlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY z@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb z48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{KDsh z(Jx~7MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-% zG5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ z5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs z7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8Ff1yg~X!48Mrs7cu-IhF`?+ix_?p!!Kg^ zMGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKi zU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH z_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-I zhF`?+3!h&~zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`) z;TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc> z7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crA zh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=GdNkm(mO{33>5#PEw4ei6ej zV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLd zB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97M zFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8 z{33>5#PEw4ei6eje7-vUB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2 zzlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY z@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb z48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_=SJ3fqoIgFJkyb z48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5 z#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^ zMGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKi zU&Qc>7=97MFJkyb48Mrs7cu<8zyCtNh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKi zU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH z_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-I zhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4e&OGf zqF==Dix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ej zV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLd zB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97M zFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU|2@6*vQV)#W2zlh-%G5jKiU&Qc>7=97M zFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8 z{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p z!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-% zG5jKiU-5#PEw4ei6ejV)#W2zlh-% zG5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ z5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs z7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLP1`?>Us7=97MFJkyb48Mrs z7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4 zei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`) z;TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc> z7=97MFJkyb48Mrs7ydnN`b7-Ch~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc> z7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crA zh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ zix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PG{l?eh5VThlLM z_(crAh~XD8{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-I zhF`?+ix_?p!!Kg^MGU`);TJLdB8FeY@QWCJ5yLNH_(crAh~XD8{33>5#PEw4ei6ej zV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-IhF`?+ix_?p!!Kg^MGU`);TJLd zB8FeY@QWCJ5yLNH_(crAh~XD8{33>5MsJ!wH*y30B8FeY@QWCJ5yLNH_(crAh~XD8 z{33>5#PEw4ei6ejV)#W2zlh-%G5jKiU&Qc>7=97MFJkyb48Mrs7cu-I_Wu8LdjE_S z*!#c0-v0&m{x7iie}TRK3+(-0VDJ9|d;b^M`@g{6{{{B`FR=H2fxZ6=?EPP0@BadO z{}~Aslw;20djQuUf{uX0@i?P4O*xzF8Z!z|_ z82ej{{Vm4+7Gr;lvA@OG-(u`{#`#{1^Sv17doj-UVw~^AINytLz8B+s zFUI*^jPt!1=X){E_hOvy#W>%KalRMhd@siNUX1g-80UL&OR&FizSsOk!TiMmF9~>Q zz$XQKa=>i?pAzt?0lzZf(*iy{;4=a~GvH+bpB3=g0WS|2{;WUun{$%aGh+Bt41bE@ zPci%{hCjvdrx^Ye!=GaKQw)EK;ZHIADTY7A@TVC56vLll_)`pjis4T&{3(V%#qg&X z{uINXV)#=Ge~RHxG5jfpKgIB;82%K)pJMn^41bE@Pci%{hCjvdrx^Ye!=GaKQw)EK z;ZHIADTY7A@TVC56vLll_)`pjigEl*E=pg2h;jUgar}sJ{D^VsFAsP{z$*hjC*X4fZV&jpfX@&3?*e{Rz^@MYH34@7d_lneeDKwksrRFk z1@`BI0{inpf&KZQ!2WztV1GU+usnFzgiLriSte+U`C&v1Tv3_E#pBU>W#`?7#du}Q}G1gCv z^%G;vb)cT3BeqyYj80#m-`iZfAVyvGS>nFzgiLrhY zm!{WGjP(;^{lr*5G1gCv^%GnFzg ziLriStlx$e>Gx}5te+U`C&v1Tv3_E#pBU>W#`=k|eqvm2igCRu#`UHc*PCKoZ;Elf zDaQ4t7}uL(TyKhzSJOMvJ{BV{G4c{4FER2GBQG)X5+g4$@)9F2v0vYt)Az5N3hdXn zz>n}m7b8zG@+R9oAj_lu4V&WoLFBf#rg{B)(mcK)%@aTQ z+f@CAU#GeKk7*ve_N+K>E^qXPG;g>GyrgwS>qb{-;LAU_|W7ySte_G+ri7?9J^21FCJ%=vDcV$z0Z|7Z+ikcGk?^7 zw$I-)g8~@4uJi~U78@}krApQGCKUrkH%Q)Et>AHSu-i-2Oa#4rb(vpU1so^rt?D z6Zgu@v3dVP;@6wbU6MJU>tQ+X?beU&J?duIX4U^J-JiP;xZQOz4U11ZWm(6v6&=I< z{k=mSYdQxn=^E7BnWw6)e|p(VoVrezZr{G$`iEBhg>fP7i)0Pv#9WwD_s@|N^J{p{ zbU6(VcCNalr|;rq%hOM%b1J|73R~jziQ`0Z~aqaun z$idU)G}PaFY1h=or+FovQ~C9mm%YTPEA#O`p+EhiFbn-DOH|B>xiF{ozd}yTujvKT z<+Q4|tFv$IKw)_^Po#6IpuR1!v8+W-S*hpxocjG7_9t8mr;9Tu=E9stzy94gR^~Tx z_VhXRloOI$g)pbG>-UyhBfZ^5bEf2kgzP;+I4~#X!ko74gX=ryx9zCua=Li1t8=KU zW1y>VRZnlYh)hoBRDS)F<0UpOD}9MmSL4I(eD{ER`LtkG>Vm`1V@}M4Id%K%4dyp- z*t9uy^{?p~9=t4A;4~QIRCfK7%dRnXWj^h4vg^$gr_P%43UgvE%!vh=-})C#ms9^> zPgmb?=WtJdA1lrskd`zxTAldYp`>;U)RMfReW4+{pGzqtGgQgRejg0;l^d1!`(wsRL;fgTm1FB zu80mRy26G2==&f0WBpv*2Vg%%14|c2E$0{BUp~3rakT$E`$Uaf{@oQ|KRBW`dvRa! zFBh4g(H|d*j;#H6_mkaT^3`T{5pM6}FK{nry}z`U4vOmBe;ADYWISpfM?V-_)g50a zZ2QtL<9@mRx9E=}haD65x9&B#FT`=vYii^2lWSfbkCSaCrwjejx5xgt?RRLOWt+d2 z-5)P5;~dMjY|Q>xY5g5>zTM{fBlrD&Zk_6)7baIRHO-uu3v+7wKko&f--cte&m;X8 z{=GYD+yPVOz?>?re`bZtO|ItsiJa_pUgs7&kJ$YR=E9ste~+A)U)#&FbBf;Q%r^GvGF07<6bE>rd zj(8v5>vQ7!aQ6-&UibI}8f*n~VlK?7`%lP;`Hdc*om1Q&I)=K2huv+RG7dlHRB8RV zKe!kn5S|N92tuj*T}b6VXq2b6Q`6oS5I(qU@Y-$GM~I&1FuN z*2fiUV^wke?vLnC7Zf5vLRlB~%!#=$r){;!iTO3OO_x()K_yS5b1J!7p`gE#FK{Ij zxA~mtaUOS1%V>-_F&F04R)?IJ-}tH7ISmZ^WySXll`gE`X^zz z)tv64=lcHiKA#Kw)6=KPiMcQ*z8_+KP0OausiUXwBHq5uSjyCwf}F~(&zw$i%N<-( z&K)JK%d34($NQJ+-0wYY*wb@z#Qwxwm=nt|zwV{kISmbWUf9#y^ZIhvlsQ#e|JWss z%PU+oH!a%W&Ue3YbeKQxIHTBo=W$nn@1GxY)BbXT)#7pe{1f8Kua&2CtURrwx5wR$ zNo^v2DOSdXW~%ia5A83&eFN(Uc7KoePab!Rvh5qK_g?Y$S+E9;?*7R^_h@Y#uX|R4 zHOHo|_qdNA8$Z+i^k=>C@t=#ZePEx9uz%-78>4~RjnQi|%lk(C$UZAzKNmR8x}Sni z8CgTNby3_hrecgnzLma@fme6jzs#ArGG~5%h52KNuXi~&-sOH;v)J-vjyC@1xaUO? zUpMCbC|c)AxSuz?zis>W%P)5j4?UcS#~-d6C?R7jT3XKL9i(e5Cv$H8>YpcP=E|Jo z&2;}TfAGd77{7GMJ)iyh9kc)GeG6ZI$H1o7{q}~1EI-}&MXs0HkiIjA*YO<(_>_qIoX?A99a(EXC^Ox^mh*9S#rw0h@|;8iVXMvmURlodkF1z&&2E_ZY&=dZ zA~k9Kd4pR=elF`?H`n&_*t6k{RN(~JbSSS)qq=ZWm#6m7VHucX*O)g#d1+l-g9=& zFV8-ceaa^Czufm`^La8myYoF~=C?Dmvz=6@b2YxCj(Lj~b$p0#0HTTW?VtD_E=Fxle!-y|$@|68TM{r)#D z8T8=$-?*HZ77i(1y8s_9L_ZH*p>u3Ctuyr3b}G~U)3?QMlj6QVHv4?>n;)cw^JGO| zDZpHbV}JU9v0kDGxQ-gv%jWs|MLkGABncg|zjlSgyUapSKK*}sI&nZG_mSLnR3y4D%`Ydbt{iQfd96=%kGI;+kA(%I*8>Wu3_rp}0C zJ?u!Rb*5dO|31Tcbl)KVBAeL$Ao{g+*)H0O|GK1UHFl7@&i&hTw+|)}MwXMJsZgJx zD|Ak)p>>A-n#@V|`ChkmEsWQR|NBmR`xz7rv^XM{x{e+JD zm2TAkE0C=)Ruk z>JOS=ZOJ~8cr@xJJAU!=cdc*!>JC-##vnUw`OmGjKP6^ZM=#&01hs>Ie9(0x*|X{q z--MXMyDb{q_4eu_~<^ zz5eL%X5>F@d4t%i6R$YlPTlwEyOiIz6J}gCG`ViKYf}1E{b1wFWApM_{&UdA)c3F2 zv}4_ltBy$WegHXSM_k&UEZIiU`ecfKxt`;8IgxDP_~A8L%%*ee=yr?a42+-9PjZ@sgoGkx=CWwZ_#dDA z&fDD;b`{L={u<9EA(alnA`D#ncgA!+eD*ksj}v3#W|8?yq))c>&f9O(t!(-j(%olO zUqxSeIlOdFQQW22A5A<*>yQ0W+_^d)Xm==$@p+Qt1>fUFT(1rGe^nX1=4=l3-AODR zFCetHquvhw=Vfxs)bjB!vWe|?rli-qB-d8_#|s?iZG!3Ot0!lF1pCk#x0HYak*oc>*qu3(){_nfTl{m^0rcJm!v4H zN4wvutX`xA%jtIpt*l8u#G6yPOBg7fN);dlddtU?gI;(1NB@VdS9JFFA=R=SjvSN#-vJ&#+G zrUaZ%I83_nPrxuiDErz9?McN(|Lw_B& zsQ#W~*Izr%y65TZe7#A-!Sv(nNmHq;JV95Sx8b;Ry-tPyT4!9>qoifZk;S{C2bUQu z_K?yogwDJU{+;RAQmD9d-N~3|oioTV#t|E7-nl!+cmw?hwuf}Jz5;ok-D}>We01~e z34I=PAN3WmlPCWB4!$`(K4nDusG;d&;=5#yNcZX>O!{US^n_5e^f8%31~(g`Yr z?WTDicci_j@9W3=@+5g-(6>)ly0bpMd)AGaH~5-1Z?4D2g{vc)agJ{QOivKMm&o%M z5@w|6c!7jR@6d5@2%Yag;$?34o+GVW$m6hhT7i6gPV=14qmnP0b)CQ=9k`5EI-juT zhv(RbPT-IZT!C<~2QIfA_DI9(KW-^$0xDgFh-f?82{EpTHwM_>2xZ z|F8?c!FZ$xUm!f}f;a0W{3AX1w2s<8?1D4vCwQa>pDR48~h_Z_=Cd3F7yk=BR%;3 zmd-!yLcd@<(u2kGAwBrGWbGez zvE9vn1o=mL@Y98dUHA>gBR%+|!ox1wANn^l|40uW;|bV>Zozn@2M_zOi+sEBIg}XV zmi;u({by`ftsl+W6Y`IKFj#-aiF0XCa|ewccqCB1{OWT0P53@KlcR0%|AM=<9fl)z<8kPA~7xxPxf_N-(h0;dI3W7{3_q) zxw>2}`=_~Z|Do68I9crg*b;9Mocz;qM}m_)3!R}WbcS2#Z^sXh>`d2A^03ag??=(u zmy|{4?y~8}6W1@Eco|PPzdFiTuh-(g)|qvn8v$Y{B%QPALS&Y{7>Q(ILavi~gc_L8 ze?)DnQWiVJySdPVVTC**KEx7;o>Fci{&*i zSJOnN#K6UNJuwy)zLx^JK&Sq_v`)~^^*+9cVt+kg!95uMu8 zQs;AOs8`O!&ti9;OG1dwC&@Q{k1f8G@bSmhlb%K5-=r8BkjKM=aRVCY0N%_9T@)}r*dJdg< z4RmrlCl8&V3v_CCrPc}h1$uDSCwgb0{mO$;H>8`1Ld5+#6_4*-EU$qXsu)BkIa~`! z44t40beeOO)(QFrKooJ5GmG9SK(8ygA$_ceE~=z_Z}J*XFFWz(HLw&%=zR+qJM$XU zC&%TiLI65J7wB}fzt#!*6#_EjFDJcrVdQ9Yb=Y`Gd3q^DF}wz5YnMYOXaD4O4>ELu zF3<_%eCQYG!C9ZO#*Z64-s5Pzi!Amsc>Bc=htyw3g@W^DV(Ot0EEx4RIA2UM78qH^HFJH zA7SkE+TX$XEJI8PkJ2Nt6|`gxu$srLD(eG=yJ_>+lFp+y`CV~*fqg!Tk9qi> z4xVP{>frlKM+?sjBkp#-h>}|LGwvhb?du-JKQR<0VEepH+|K)HD`g6g#UizuHdxm; zgkiD}bT#^Q*fIO{U|{!NUAuMS(=0TSqLJgc%ydtO#lDjAG?Xfi+koP1q4Nh^HyQ*i zb&nL*N2!0Pk4TMrYRB_tQd@njus$w(_|?=c+qT;Eu`TscY4qd!yip(9NWX>iqYKMu ztGYho`p+L-=$#hy zI@URj455F{r}+qqRoIq`=HW!ZVFcUHp+wlv>=*m}N9*>4{SmIm;<_lVFXK8f{H&vG z#n(Y@q)grxmb=}eZIe_KSW&5h5CO?1h@A)d8d;tx(8H6+|5<1L-6{3bOslUn@qWi;BbbRD@z_kM$2YmuJ4d>3v#c{;2Z258cQV4* z?bo?~zY^?rd?n@oj{OdQH-zg4#vP%wf=mc^KLa3?H276?G`B7vmMV~q5H$^U3NI-DWBb6A_NmGME{7;na=(B@8ePW z&zaJF9{ppmcFT60q#1XvI~nt=Ge7^0{n%!55|E)FPTkJEa8f+~&GYB+Kbr8KRkllA zSVZ=jE1gOe@GF2?q?g$BmS!=|+fVaczi=Nt#)Ia4Y#9GxJgBYFF$2MCsB&W57Zo)p z#%6;e^wko3{-j0cSZDqP z+kZsSI9kR$1lHeitvHS~OpILnW`v!ws zIyq~gGju&bZk*Kt`kx%{f1g$K&%tz_6B9V@G~<6?P691u+@kvh);T+d#+?$!`v&9w zeX)6)luyljy2!Gu>M?7?ayEtX!?`tCQyB1aa|*UB*z(BuV&vapINN%E%(`U90(*8= z+slhAJ8|Oo&1O21!KIu-*OK_}1+8F+Y5_KFVItc3(@;KL;SQ+%EZjgBaiPzCv?F(>j-M zn*XofHyAsMN_1+xZ!m{)g5#R~H1FIVIR3%)R6KWs=XP-XLs;R&_jKbpCnl!8>-p_Q zcj_=Vs?4vY3;R*NoKNJ|(D}(;$^6+FI=VU)iEZ^rZ zq3dx@eLAP;JG3oD;d#$b5%O1)ZTQbOs0gb^I~X=9f)+zG^aE)1vsV zn>o(+_@~m3k7IB?8oFX!$Z=lpcAgA<){`;#PDv#if7hq8TlJ&9BQBDO?FSpLuqCGr zGwxh>GUi$5=9B}pht=dHAVWc%k{thEOzj%qAGm|@P%5WRtRr3H^ugX=G|%fR%P;mK z?T6Ftqh*NyDeEbqDawcUBAj8z{BgcNjE~i@zNQ_cYkChoU6_Af-)NbBPo=iz%%SFE zuX=~B0_us=PrUTq0Dext!1YMWq3wThpnd22bb0;4MS6Wrq?h~^zQ01=SAq9e7$4F!6GRXXR6zsN7wZ1L-BKMclrV0k><=VtbijST;MAQh7K$1{ zemDu&gLn#&kI!kI^LbSAMYFCGIHUuY@si}b2(O>=1BZ0r3WS3_I4$!23P}epZISi| zdwx#O!5`9r%M}iO!4-Lbg`@-5XtDMOd*F(^ze3W1nggtQdV&!O_hd-nPmoFUb zfy*ry$RQm#v=`U|S1~4#LppFs2YZNDj4|F{A?*;)Z^!*pmk;StPtAJA<+R^lA?d+S zmpIxtc(WdXM|$u_g-1T%*Q`(Aksf@;GM#_eh2LO2(t|G$9(K`RnC%Dtksf^7E80Ko zf;a0Kc%%oPD?IGNuUX%~BR%*=uWJ9W3%|j5qz6Aoc-RGR)?4^TdhoH!wSU-!{=s;p z2R~7G*u{1;>p%P>J@|vd!!F7lj7NI#{a@4hhh5}57?1Se^M!|9@Mb$i{*fMhyA|3$ z?80v_9_hg^6drb=Kl%r>YxqZc@Yo;2F7yw^BRzQ7hh5~`jnARP(`CQEpXPagocp>i zKh4?`@{fKbSbxBY`F^XS?|+C5c>hE0m)btUiK}!xZgrqv?Y-!K){XD;1&8A#SHAT9 z4@Cuxa0zsVuFx4c^ta=AKc(vBbiB@!{r-o2N%WPuqCKpmdEIJ4d#Vz8^(nh{vXl?~5BeMQKkeSv{Q&x)IJAq28{PP?q#gWU^gsN5 zBJb~kV!dv5iYW7^O8*00p>y13tuyr3*Ms2#_BA-rx7)eD~H>7ei# z0mKixH$3W(=y{(QZkOe`pR(@@`Bzkq?_cie#kxOW`#;f->!mqqEB^0&=J+yQQkm4> z7cU%diLQk@Z`C?Of9)~wd!IfZ#}9Afbxxgee+_g+KaV)p8>P@X)6*GFohSPE9-PP~ zw$HW?xg^(C{NMYG)N1Y)tph?A(-AFVo%#ND*x5@|B-N)=_inxU{`L`r=_z%7#A)!j ztT7RJ)QL*U_kzn&9-JCU3+Vp#99qWb?ZZul^-<~{>f^*W^>#q}*LJx6RkhoBVLYkU z7M^$3#{y|lsDEaC%#iikM&Wru;`->`?zx@weM)+Y%qrR3COT}_ zVPS4P&J@;1v4{E?7sf8?(~bN|ip&unz50A5<-3kaA3QcazIXAw>+Bws`p7Z9-h*wR z*9QKFPS6E9Ar-a<;s{aBk%Pw!PaiXIXy(|_^kOBf4Ih@2?_v9mPxb28nX}QN(;(+U zns@8B&~DLA(Qf13mij8~S)1bfWk=cVRL7|u=VdzLfezi;EgvuB(muK9#K#ZWRxGXH z?;7%dzK?TtOpfnG*YtrFawy8bVC|N#y|GPq6=?BEo}e>yh0eJ$eue%z8L zVSJT5Uwp45Uv{evzNB4L7sF4tl+|h6Mt<(k58YBWGn#+lZRb#uxDfjx(~21n@1bNV zSm!ykiE%vkHkpfLi*vtSbjr5e*ht5ZMeTW6qI-s5M709F#y#J`sQ>%r;kroPUOAL4 z9H;N6dDa})?{PeDp8v=71RTE;Vo#@$LmnsXr@G9~OV_BeH0Eik0nX>8)As582*O4m z==j1tk&T1Up249#=YQzNekYb#SUNwAu*m&neB8d2 zo|)la_{pi)A1>`*Tk+pd7Ma!Xej`l*ouMmq&iGjC4E=3;{JgZU-zL9p8W%|1Ieu^D zPY^JN=R1O|=e{?|@w~J>4ronB2CW0ExJOuL{v9KYxn7!+ZtdK0yY)C`>c2k@ouO-? z&IMX$=x=+rb=Jq}Iw!1i@Z)wfx6qmQ)h?5(&ivd=B>iq=I#UPXQRmp5S_gzK`HpB2 z>&(aPu(LP9oM8O^pE_>unLZ)D?+s(p(@S{V&h604aeIc;zrybSGrzwA#CFo*gWWW8&BTtfA6Nq`miNM!Y~48h*oee5o&j}p3j55KgqK8hW$ z_3^*`xSi_L2Q3?B`M+rJicuU;lKR&nxZQ6wLNKS>Zg7#K)s|x&lRx zNA2^+Q|Rbtv}^jngsr9f!_;M$ci8jz9O)ytC%uI2G5AabFqkOT%%h(@6z#>OUT>=z2U_;M4chBaHh(?^oKL(BE5k z+H;#ndj^O0-2WFh-aH;np<_y(B0C=C^6+FIkLL9!mX1dex*m^Kq+?P3MK(b%x8qT5 z#eX~+xz)&ghf4*Wp(}Jg`m5F%`rCF+;p0)1GuZy=R5>1nu7x@u)jC6ezs{%T@n~c^ zdp{nX^KY#KLiq6-a((9GQP|l_2Aus}Fnj;2$D>E3{uS28V|qKFp4xhy!pEc7o}t@4 z9|=WL3t)}v&mU4BCG@ZHHdk05#g5nd_`h~MdQ|Ek>f@Y0r9MhM)#}sn=qY-A6tyFC zeT=4L-s&UlmNdlv9=bwjjLV?E_7nR0C?9v?c#}hnqp+OgSWm}Sl!AW2ua8nAtr+p~ zC>gW;1=Cqu@*j_Sv&_~@HbH0T3Y}pU`XlZSaU6=!zb4q+EU8M7ACJz8TH@nh$){80 zcofGO|9>BkM*Y_xkK*}jJa3KXuM2LL=db0tY_n$e?L%klGe?i(FB{$1w0ZLuW`YRf zZawbN80~jq1s%p!lzg0_!(0gucGGdw&ENI>HS&SyR5QxB`-6Y(U*ai(bl?hvgFU3j zS60Cx9k{fz+8^wJGoQakI&itd!JePfbMS|B;2M?F{$LNB&v&VPG!72wz|9d3_Q2(q z3*?XvTx@ym5B9*#EqiGU*9-VVI&c$(gFQc|_u$}=4%|WEU=N(n*VV3u;E)bn|5%+* z*aJ7WY}Y7fK9LSwzHqPyZb@{YKcoZKPU=1Efty?QIs54VA@cr9_<^vS&zUYJ@|~%^mc(= z_%-Vjc%%nkAUy2CZ!jL|!KYQy{$UrKSuf!q>A~j;54&i0X8i<@^xzwvuKmL<`WLgF zf=7DrbA*Rols_1c^x$JFYyYr|a+~!X{*fO1MB!l<LA`1I*ZGHC=ogGfdhi9p!!EXaFdpf_ zr^z@3c2WOOkIeidJ$S5#U9?}+Bdq80=THRWp8Yh>`<;Vl>GIR8JwZS8qrv(^PR!R0 zFQdIWzX7Iv`PJom%CWEW{VzM;R4<9XtJ$vXaVst$XnETlTInokqcl%NA2KahHUi&dsplpf&)K7T&vVr?H`L7a|HtmUm8 zfvq}m$QE6t#;bivR3KWL8Zp#gC&MLRaVvi_l-k?k1mgqQL%Gp8U zXos=Jdf1WBqA+O+)i3{ZiM66;L|34nkTZj;!7~ zS?4_K%-54(59jYEo*UY3$`$?k_3GJ|A5FX=Yt*>(iQ}AB!_SwL?^GP8Mz(g-^G$J7 z_6Ejsw`Fz}aiXy(ZDQDf_bry!z-;Yu=;Z95+`fSaouCVJ!Z;uL1$uC{ zyR7l!MvwP68ZSBDt5{wGOVLPldNOb^-CtgGf=!eAMCS zT0Z`TpPYIP<^mX#w&K5!JTj|>krG6qGjxT{jaq7*p}%&)_wRMt;&*rId=HRy=HC#h zm;OBJxhUU3TEp)nbJ+-H;*$`E&d?P)=O<{Lp}%(R|NbAxPo?hxI(25P%}JkG{m*|7 z5V}HV^gGaB=bOI&m;IolKJ)hg^?SCSqXe(fkMD!Lh3XYg^L0>oorB}f^|Bg)MKejf zkC*eS^ql@{zDe{wz##AC0%wQZ$MP?DeP;3h^WOu6uFx5Ufc}V|sv-L4U^*X;=6=IJ znQ{M`zjrRSt?n1N-{9{7BEFp5=nUP@^($c7wRUHbWxb=aH~4(~)6@Q)&#mRT)Sup0 z39r1fK6mcrHq&K7rZw}@E~@^;tJm}T`Tee5yP$5mby4D%isP6*`7moE*|Rzm&&)DP z$Lm^?tp|x`hU2TrF57A>{PTlSle2DFl6Um|kCT{x^_j2K%&VGg*pqYl2Fk;R@dGAX zU)Oq3RcN}J^PnDjZRFZZ<2G7%T3@cGJlJ_+yMv}?B~u=fKmB2YYBT-{Yu|5O*81|| zS6)+X-1>>#zE6DPNO_AM3vInKOW{78f>ac$Gqj~vVXAk z#b3_bBZqJt*X*Zx);hM6?niO_gZpR9`*3hQo{++c_rE-KAw$)x<4(@NI@2y$+ebJ( zQO6ruI@A_||Hrrx9QLE``~uNdj%)Ik)3FLqksartJo^1j`NZ=3nYagw5&MR8y?8iDi zKy_lS)QgL`g1JoiBAokrxBFk_mTeOC0R3Eyxh!IxSxv5&=ERnq%gnfQ-N~3|o%ufA z{3Kofx6^z;hQukB^*?-j8D~D2=LOE?NXzS{Qv_}8%^Fli!28X`El{df1>MO~;PtQ>Q!snVKbnSz^ z-}}URt)rhg;oc{#`cK{a1YMys@(KNQ-1$vbT9Q4Lw9?;b#l275uJ02#Ryqmiy-&{d zl1u{K2R})SewQwPleJdV{k{rOlL8aE#!xTUlaO35&512JCo}F`cQWR=9X6-3pQ+qDI4#Xshb+-hXL!=>W-!Pju0D|E(og8sH0epf|O)h< ze62ypo$pRe579fZ?r8TPq%3l z%db;_)9Kzst{_71tNwLtKUljpt(bAYm6J2aI_FUSupiq@ZXzj`+x<11!`S8iZ>!gl zELWm$JMqMJ%Sgy^{{9?m{xkh1(eF0;ALaB&l*98xZ%H{S(;bl|272YcYmcR?T>xTC_so}bfm z$S2Z)%eY1K6&{?==l>>qJS{{za0SA_9=P0cfgI9-!}f(eaKjznfMA}a|rv1Y%{F>zlkM!Ut z3J<&R8;nPK@CSv5UGS!k@Q?K1``@nf54&g|*ghn&J%LAh@cF{SE_md_C&AY)`-xbC4`fuSlKVQgWZk~on{lNJTT>n5E>vihF|MvN? zDRgM)KOeT+cS8*S3e$v~Vf(yI+`b{Ct?>CUJwkn=15st19{lrsj|@*i z)?2j7xGu8W7hUEp`q@~>f4r~dU$FgvzAjRp&O5rbs^F$$XUcv+!r&=GuPLmLV#lnH z!RW&JIQ9l=I|Iksk8%e~?6SP1d|!4Oub&|IcuA%(H(O{w!1bd+;gaAph4oSDAL=6r z)KeX&Z^7CVhvha<4{E*h_J9q;hW*HODeN>;I*v%k8DR}N67YU6RDGNo9q84JJ4~IF zS=PD#g>;@?#_OBNOC&ABJ|9^%$u&z4Mbb(96y>rP&utlshKaT}_dnqBe!**fpUfHelRSBv5K-RddtPx`eW(~P1 z{f2QPvxY|a@J~tkUbesZe(XG0*}^UVlAa66p+sdO*pAQ%x`3U^ZYTP3d=rg?Zc(&b?n@tXNuaIpw>0z=nN@06 zTSNy5T}(%`sIWeY9kV_LGvcpLBL>qq;Q0Bo!Q-;V1WR6Ic}e+Ra2Vp9wMCp73kvA@ znP+JkzyC4ZR9GLS{-Hi%e~)^q?eI58?r`i!>UTP^LC2q?1o-AiC20Wj#X0ID$N9ac zSTCy)*!9u;=E&(~p7R|;=Z};wA&+hN7y5aw|NJ*cpeuAnQRayLh@YwZk2;jt}W;reAvMZZH*`}DwXj$FF4`+A0o`^^#G*#qjsK-OS_64FptpdH%Iz~`Q`|YD@(sQLT#GfW9ak!XTCXt_u%2Z zcl`XRbG(Z8v;dqb(s5y4#6S( zyWWF`eBk|S3ngFhV}`uHiKm4~2QKb?oln^Fb93y`3^=3%H(fZ`16Sldc#;m>QHjHz zpVM>jhjidFKG6AuUvNdUAKp}unW$tN8phje1Y(=i+l&;ksf^7F6|$7p*!j~>LvUmJ@{PVVHf>SFdpf_ zH~LKbhh69wj7NI#bA*RoY=7j#%s9kTcDV0H zjwjQ(&g9bfG-_pn{b!wXXeHVm+Tp>kb$dYjL_cQshi1RVez+a-bPfHgR9Q_U4sO|j z*9CLG()JNfJfP!oUwUhY;7~tY`F#&d{gCT`@jC0Y@{J{R^6zqRkubWvs zV>(s(ALv@B^AB2Q=&!TAi29pFoBc(g_XGOo+i~an0Xs><;&(ang#HKb2gG{4w(vin zCrz3{tn)pwsZnqFQpH|jN|%|>Y1GN}lCPa|y)>uYwiUjfq$eFWQx%QJeJ}M^!lEf6 zTf*&-?@NHay@a`Bvxu?2oiD$lbI(ql`xNtCu_fjIuJ^=p{owb+hMQO?9{*32`iJ@$ zC;bNMsn0ih3;n3wm#45ig=RdQry%RIJ9P2U@8vfxXzS~}xvNe^6{{H2ZmN@97v1V3 z-dCx^Vi+$W0-d2NbcR{zuj7-bo!e8gTb$cBk1M!cbI9f93ClT-^*%agpjDP0clc8D zcbD>0GHt^CN8^sq%SO`Xfw28x?cTIx#$n@Rg{*UP(gpj&_2h`6VW-%zDNgMKD5Jio zAv+22;^vxl%pn-#mi;u(HgSCc;~R`$a9#uFbbH^!nIkV`?k@`zs^28kz5Ksh~4-h0YnjYMr6KwsST2XPf*s zDW3hIJ&wtzg`d)o`>WrjoZBQJ#xVsFU*MvHKCa5P?xpwL>+k*g=zG7P`d*CUpMYTk zw*LvGb-TY(TOrG0BXX-@oJP1BIzw0JjP?NiBQ*CPOU8AXf5CLdcQ(DgPx|jF5OjvF z&>8ljKixI9(dU~&^*JYxeo1;g@2`2ey{|3Y4|9FxdR>po%@g*|9Ovb{KCAj&?fGZ# zpL=(b@sH2v+&}w#^`j%L%iNYi>1XBSHWEIys|g*hwS|o9MB=VWTn`N$y$*w62$d1o4o2e5y~{vOvaa2^AB z{F92w$BEeQ$HuOWaog{wmDATT5H38Xbz4|QFNeKgA=)pv1CsBwKi%}NX6)y)jCe3F zdifgJ8QA;%L3iu@K0??1{#tsbf`8#Br(SOReQm|R-;c~{c)yXRfX>hrI>*N7?F9X8 zd;EO^--*qB+kE~)$DQXd{&ZF_e_|ibUj$iipTDR`+roMN;x9UX@mCOg4%2p>bMFC+Gs5 zfI>gS5eAggt4L&|r2Lh%UE=$ukK^yk7WYA&Pw0C<+~4#@p(LbTQ;`Y%8~QW!Z`co^ z-=phg)UO?;{%jhB(>m3-e$y8ErEc?GyoG+UKPh59U;*|c0mn7L&xe(vy=csfQTz)q z;~K$!Bv}8ZtXL`h8M;DeScd*O9@+V@%Saad`8#dCP?6t(x}e-70c_&Xl42G|R{uncggYOy-cm%~I3H4j-2_ zx>?CRI=z?9mnu-Iz^SSL_iMX2bJQ!nXLoY?{+&73O|bi^*gYwZvkWK&_b5qL6`whB z)a&_t6q`EBj_PyRdJX>%j3*?lNyf5uuS~WtBYiyQtkgGFEbr8G=5yJDx-t$ zH;?A`w)4fyoD=7$%k$+dF3U0c#cgP94^E7}FNs#kq|3>^ooV`Cru`sQ{*&4cLSF7n zk94JBsRE@6cu`;gwIhAE*45OY(5A-r>6+s6d?f4l%i~qPCWQXtC$T-TV_>`PH)ik+ z!~NJvn>$XHxlfw@)=aw}{d43db^qSV8?K+{%ge4k-wHRb)Vd_`xhi|&^7$wRdxt0i z`?z*y9qYE%|Dp~#Z_VOG7p~zmI_ZPu^R{syFq0&-`h^zrMMSHR(0)d?n#0k^XBJ>HM4ealPgG=T?7D z7kFf^yiT4?^oiV!o)L# zuYF@3>-&kjY~G9h{2g@mpVqmKRr@;k{=>|_v;EW*e%Xc8f0aMrn*UJznZiH#)45i) z2fuRVX*&efpU2po|9cmoYhAPFTUS0*{}(6xQ~l1h7CiL5XP&QNvH#p7wXFp&{otAB zYg){|Fs-(A*QbYE`B3FQNBGANon!rW*qslhe{JDwj6cWfbgSNflE1aQ|3nz7|36pw z=rhi-DhxPc=ijVcZ|Y~3-`W1_3qSv&IBQ<*{dWGL z8$y$JmcN1Un_fQ48oX<_Yxzyy>HmD;&#Q2j^;<*t{?pXoIeuv<{FO`2v@*7S{EYFMLcc;_z`{=SdTuzv2YdDI((rv6UW{L@_c`TMI`_w;+uwf>L}0s9|k|J6eHnYUH5=4{(x^Uw`pDE(Rr zKdWIit8z1bUq{{=a0t!q@ARMG;P+p--E;o=lsfN!#@tiYYSZ8?&wOj)Gw-Ql{nR7h zHUDP)cedX)!XKMo*=lq64Oc#ter<*SPF1!(`(u+UAIg6_;oIDLx;5c~%{HGS`#*&F z#`w#b|4W2_W=SP$RYT2VyCDpf|MtRv^W$mOy-o65^B;=uApE>@PqSuRpm|Df@4pdJ zJ_72mv;EQvd;2dPQPDd7{(9TLx&JZipOYuR=0ALm$xI@kQ0{+;7zKDo*DuiX2w zg}mwCX>nl($}uU*lSSQ-A07PZoaqjB?iG`?Y^F z|Dp6t5&p^N%UV~wy<^NLQ&r6K9PM_^we@xz4|1LxMYs6R; zcDiqWQ-3GlUHI1fW2|4Zb^A5zZ>aXyL-_fN%UBO>bZ`Hm{Pz_8{3d0s-tW1W-`xJr z`qNAJxI4>Of6n#ppRaFo{U6>r#!9`>z5Jp4UtY*ZTb+c*c1LJ#KWF~?2;b$FC@a0! zhQuV7{Xg@(oWs6y{*S_rWGAt&@XN3DS((r3{g1i*ocV7lJcTyjPxxUi{!*3IHoN|# z-6C{uKa=NY*ELLj?m0M*MH_IOzbcG9Tk34KgjtTlpCSR^Y&w&^}ky9i?04zz4^@NcKNBi zLHEC$ewkKep(ziWhlZ^R+BbeleZ;)TCf_|FFZs5_;`Gw?2R3g}+|-r$+p!Cja!Et)I!8^~bsW1`5CIl^@irm+SK%CQor1=IHa6rv8J3 zKd1ipYVQyF_#gEKq3Peb{RRvFYLo9&@7+JS=AY`3?Vm&T&*LAiKYadhi10loeX9l} zc+dY0!nf)Dt-4}@=8tM0?bof928#R8cKL26rPx-LR&mote_upK8 z3KNG3|J2W4spjW@W9x@}Bg_wx{~Lv0f6W0k<5ld8}+qM2U%g^V}Sw9Nx{(E!@`F{}4)2_6gD)|R}{vEm_4CS9M^>X=- z?%Ap4#&|z}#`p9xzvn=KYV?cy^%v7W*IzC_@BhXLKRS7rYCO}Or*agwAJ)$~{vI#< zH5GQNwN2c4=l+v<=lGf5F~RwNuH7CLwM?JCgKh}T{5!Yb1mV9vZ=bsBu>1KVGyl%x z&xykKoV!;o{m%XTPpJIgB7BqGdsNqN+|NIS@;^!Vkq=S(U+F&nG5tHY->t&`HFLlE zXOuf1O26BLU+~#J_2BvMy0)KC{%;rlrpEh}^`hp@{@>aDdHXxJ-yOmadTO6q{hHPv z+uacc)IaC;n=JgU*Y~M&`sw=T;MP*V-yu}_vxR@^o_(r9ru+3Xv;5Bbd#CV+*BnqA zpU~q!(|^8W|7F(yDZ<}<@0V)n6T1J+G0s1k{+;^WCA{zAuhfK!?$^Ie{hjT1s_UiO54-$pHGiVM{$iFtl>d8#&p-U7y7b;ZJlDTz!XF#|g_?B!3D5j= z;UBJkKwUm6icUv)JO4UE_#S2VtFAYdv3W1s?_S{_dttAtSFXIPe{=gg+y8ySzge(H z_1;s#=FRqJ^3M8uzwpCT_oy$YR`Q(x2ZV3(?dR&6%qp(_&F$~3zYhvO_sDKF{<&(N z{m&GB(aO(M#l)JP`B}mrsr{LHXGEN5{vqMB`+TMv{aDMj{Gs%JSoj{Fe5MjVIoC7) zi12q*+^tSjiT9lU*}|VO`7>2+aa~vcp|;I>DX0G`U#m^Of+0=Jcvo|#F(B0k+ChzRO<_Z7s1v^yJr<$uI+I~5- z|K#Higv|4D4y()fgF<`!pCkN?i{4f(o@`#IU!Fd0Su3HfA8$vKe^&TI@!Qpx|Mc@z zkNCK!NdD=#H{kr$eBsZ%WUFems70ZFC-1C3%ya)qp`HKdg#T{sW_4bhmNw7jW*#Az zo8or)P5yb|2Q}WP%0B7c{|mwoeSE!II#BcQi!hY`1;QWiu~yCK?VW#7_zj(3S1UGZ z{oxm3DE|wEfBnT=mD0q${3g%!kM*Z8@g?C$r>s(k*SqK6+$DZSl(5SscsxBn}`e>de-)u3u? z*Zk*5`{R(?pVR-V!Z*F=73FK`&YSsn>c3q00acf&7H@m!UlV@LiKS|LnKrKandNu- zUm<+;NlR5@%R9eP_};NgRceyvp}Qlr`!CkP?7vnCzdvn>+HjkD`9tZSEBwqlFRLio z{**qT|1|Y?Zok#S*KWU9O)KzTe_j`U)Z2?x<)-eu>EEgU8sS@hwMcz2+k5+=g4*X_ zUhKSBB|fFwuS0iR2Xp&7>;F38kAJjS4ISy;e}v-K3;)iLmsP7C?)(2x<=-IuZ@XVs z7rf{`{t3nB2|uXX5;ZCBBG2`IqwvkQysXBbuE&3-exd5$CgHQMd0E{zP>(;o)W6Nb z*Il<*?dcqT{A;$KEyDkD-C}k7dEv+3CjW-;XRcVJE<4b`RXnuGRU7Zr$M2?pv;H~j@B6}6Pt8%s`{?rr zUiAM!_;cgusUE-AwDa$U|4{g>&U4j*bG`E)2|wbCr&Y?~8m|6L{ha;($HJ@2o>Fa& zdiVc{@XeE+P(Lp_({=lW(toG$R)xn^#U1YYhsu9}@E`4;tzORbpMP;4|2g?;a{NZ2 zJ^uex__k9YQ3-wB&%ZeH-$KTJ6x!qeUBVBU`jGlZXifCc643dmZ`sl|z%?D|~~hGgOxjsh;_L!dHH8nwsCTi!1Nk{_Njb{{6x?9&(SW z*F43Q52gPB;dhR`TTQFf!RAfi$6b>%t#%yY;*=bw3QKi>&o@60<@ z`>5J#--!+O`75gL0q1XcIrDYJKZUmc?}h*UrEK-tDBXWL@{MxX?T723Iez;=_@^3X ztFP9d5w`xC{Ex!NUocq>{h^vGpF@7BJa+pv#}9{upOt;Py5a+U{eaTj`9{d)W}ZXS z|4+i7e(r6m(OZ=Z{gYny`8N*9PNDyLq#yS`6x#jIVc}~wy+yseQ~M94pLzcCU&6mJ zZi1TCu4>r!Yw|~gAN}lj)%P~<{LjKij~u6ZeHDKDnf`wf{>PSMRP(5_J?H;d;j1Q( zRtK`qDb%0qFLZQnKlab{pF+F-|0evLI-}I9E8MT2IJY13y#1Kx{l~wBKbCxxs`l$y zuKu~+bN%6vdG7z1r!euT@LwDprk-A*dGZ&u{+aym!Y9oes#aX>{rb@#CFGA0A4NYr z_mAiN@!bFPME%@9-Unbm_usU6^A^OM%!zg7vE9UL_4`9ko3(A-ra|4*!{5};Ydt7a zMTc?DW%AKGR*=ko?w__U?D2E|?Blwb2h^)yo<-@rJ@;RRSoTp|zN}>IuY(6vgVEZ5 zw$vMhzQwxUame-NkkmU06U!0L8hml|fZF$r=JSMigoXW{$(I*CA%Wd zy53V*_}u%Gr+=ZMj-F}j=kROSe~Jh7UqSq*KmCR3J=;59QTV$){z9!t(|ooE{Z12p z`I;}(lRdrjm4qLg`GtBa%X|J$7yd|#FI3$Ry!)>#{H2LssKHyk^Hqf3b-@?vm1W-Z zUsd?*>R+h!zj^1Y3BT{GFVuOzc+Y=z;ZINgLS3Kl-TxWFFH8MGot@%d|3lT^8sN|V zLRC28ov$hUUB4bsqejKq?Z->~JyZDG7aUOO$23p*MY}^7wEdkWeC6{FsBiB%+q3^T z;X5qcuipPs^IrU)Eqwnn`_+niwLJT;C4Aot_NkutXx@webA-R5_Fi@R0`Gin;U^{R zQSX#F$8-O8uJBFo`CQ$jH1B2m*Ac$atlcU#)4Tukgui{=XKLBa-uZap2Q1#Dn)UR~ z*A>2c`CaO~@4RpSdcqHB@u^B4<9++p7rxQl0(I4=?)5j+{;z@XyFS~g9=+9_r}`MQ z{hcrTt-C%^k5%)|Hx&M~37@Ep@4UDF3xsdF>ti+Ouy?+Z@GB`n<8+?DdF?a$E`g6qtND?3cs+;`zq=gzkeFX+WsXh^l$RbgwLPw zp87e*yZ`3GANu}Xb?e>U{qykyk6)wdzMa&mXIrG#8n^Ao%efu)k@8b$m%pX(pN)A} z^|>m1{`tHO>qnu@CkTH}!}nC(M&9{W!e4a#yDED|`0|_nTMO^2x|RVDuv+WBuI{3jLPQCCFJ|1=k#LYr?Ze9M~es6RWq=ik}?G0)?F=6U?z4*Za} z)uBh-d1?oR_0RNwiSV;Vzomw~8D4*rZ!i2~ufD0Gws`m7LHN7g-mbp>-rc{M|97bV zaQP`rq=MP?cSPKFl^GR&|7GSsQTQ`!hd&5xTsdlW!(Gg*M+!_&T*VsxcST4mG%=XS-CVbWJwx|K?z4P6L?{xb%wKL}2u;YI-|2>4iw(Ohgo7?<6>rVYnk?}(> z(T_q~zn;P$`t>bUXS$!K{e{g-SlIto7M?^P%c*6X7Ye`98w8=$o&0?()v}6@Gfk zHudGq^9u7Hto)|`e!}-WcdHuEDL!odHTf%q|7FS>>cn2nv+lvRUnMC&g?9O`6h12c z4b^g9-LUz;Sa=F;{wm==K4**C`j2{^`ToL}ePNT@->kl8{%YZWIGm^YpWVP!KhmSH z{&D_!|I7L3{qF$b@2asusU4bk)Y~HU*DU`v!mr6&rxLF{-!=cv{)>4Y|FC}^|6D74 z`;qI^RR`R8GygpPWS+U-Cyx0ZR&{|&-d{9}z;_OW+a>w>XtV%iFJpt+u+Dq^pCJ6M{u|Y0 zH+$zN3ZH$}M%AFEcm5XP_k572_LR{)l^6SMgdM3rT*Eq;{m&%f+pXH9KDaLY{@3Jh z75>Qn&Fak);l~dqf1B|4M{QO$_qmT>Le-z!h5xJTCe?njcm59HUpQ;Cs&eC0j`=28Gp}N~u)5G5V-z9vl3*J;;#Coqk zQ-zP6@s=7f@O=CHom>5-@qk@_E6Vm zys5Sy^3G2a{*?*aRjc~p+n?!wy6|sK%U4Ugg>U~RKSTI(vH9w{=iL1}+Yj?R{^s)Y z`1@YrhhDx-)rk(@f13X96F#f$Hg(ys@cp;R-!FW_YqqK1-t+GN0patrx2eaQhu{C1 z{vQ;6Q@d?y(mme!nZnN>wN?F*aG^c^@KXO~34eX&R#kJQcm5&a-}rN@^0mDv?D)ql z|HHzk{<2MFzN~pK`F}+C9kcS)?8L^N{m&M@-Shcs-V2)d;{Q?MtGA@~Q~hGk{vQ+m zj??m0)H=<3@&CB+o#)c|m+no%UVo?{{SSq9|1(GUVIOW+X?vQ4&HshMQ)u%~2>;uh zH`TX;n|kJ-6u$lAZ>mgRGtc}}!nZlTU0v|9cm8SNTgPlyTgo)I{fE-uEdMjY&wgZ^ zN}i_qyb$9blb7{{`VUJ+emaY^-@N+kb)Zch`JftxI?3L+Ssb@VWoWRnOn+&XXSY_?ts6{|-8T zz}t_)#D&6_J2O{p{=}UR<^Lt&hYVh&-a5CH=k32p_?6$URDTWd&My}Juj4D#q($EO zmxZ6-VU;TXZYztsRj(we4e47$@BSN&Oe|3eO35NC#_Vo?)UD0x$v*%u24(AcK2`U$Nd-d ze@*z8yRT5!lxypG`>hcE$NnqSmUA>uKY=5W!)yV&$*O~IKcZ`{T3o}OH|vj6|4qUl@1Lvg`$6x2c>7a->w5hi2>0(^jldzt0GN{Al|BQ23jgtxyZPYaY5GH2pjE|48_r9bZ$mgwK=u;|T5jAH_SG z{y!GJ;U&w}nIpaD{}bUqIrIv>H`ARr^Y7Ger|>c5mZ^pf-1X;t^Z3mz{{_PDxN)iK z*vxzV`BeDmeM{*6Kh0-*Xn(te@4D?})#qmK_5U;Be|~q7%KF-S|Fc{87ltfS@rmyH zuTc7ZF8qc8FR5DF-S^+5hpj({Tz`1~N1=WEwMY1M=?m5HmEp&4%=7q_c|QK$EBv03 zFRHkkF0se2;q*Tw{wYk{C;Tl(7N}YqHBaST%l#)p&NtT|4%t7C-`PKp-}ejOD|La2 zyRV&R{|AKsbMXtR%ggTLFSGtT%m0P&x7K|@HJlxO{KNTomj6rPcddP1b&U1Sev^@eUS#_pr~j{o|KR=SR7*L2C!KBm5t`+9^4|zQ;-2SJ+dp*u2Zt~ee^B^My`EEB z^CN42PXFHu|H2>hRp#}PwSOo7o$z(OoUhuR9a;b7`Q1EKGtoPLMEGyU&r{E~_Rjw-{FIn^>Y-Tg+wT|QhcuY0s$T8B z{|&YMe-(bvGta16yWM$ehe7+#--NI9+taFcwmTon|G$NwH|HtU=UwmRKPvpaS3aqJ zou_%qZ^Zr2@4`>p`Gl(dl6U`ql#oA0d=&lg+&i9g$8+yc@A9|s^)u+09{!M;|)E^2HD+vGB-uBk>|McHC z?$qDpo%OGx@FRR3tiL9C=T8%U(;w}vj61#am4yG`)Am;Dnc?p{H}yMR_}ky4`g_c~ z|H{HI`mnvV{kV7kRfPY?2ekcS+_#@uf1LVP6}}1iKWm`(`cqB#U9|lx-{IYVb>YVx zYj5qk+dF@T@DEq-VC}8y-u^??zZ$~F*X&^ZnD3phDg1f0J6QLn>HaG_#D3GPKW7TR zs9XnY)#u*(zq5p&@nw7Kk?G$1-#Fo)-`d`?{^foDaklVx-re46VugQhz$||);VX7* zZ{6{_cm5pVZ~O2P>*wh3_l=qUYYYGV?Uz`$MR4Do$)79y!<{d&TJP2VslM6cCWKTU zI^wvQd1wDwNBAi}wX>eB7yiC4)BkzGuY9_l^?H!!9w;BSe-2GPUieN;+gY=U!Pgc3 z=3{NGtu?*pzn<`imbJAy&hWnd>I=UyyRFr}l6Ss=@cA9uT9aP(UjNP){;yBlSe1Ku z=Nk%tcxxN$-_z4I3eU-s-a)(aiH z^A`#K^`X|*<9)rCzp?N&Hng^8P4VvkV&O;9IirT}dFPu5e_(iPE31Ng`w!LrnhO7A z{npl=Hs1MW!XG-)$|^tBJKtRR&+}SYV;}b3ep(2B)9bCQ1q;0MeEh}Z=R0?_vc8<= zJ^u;9rzE$wt{v*#e=Fhl)o5*1-RRwaYvF&VYo_1N^3JyrepriE)`tVU=fAD+ztKH2 z4QhJ#-%j}Ro3^rUt>3`P*4GCD_Fr6oWqHS2Gyh8X8^^V@x@LLj=~RH7|DT(+w0cJH+=1yoN%$Q7 z-6U1`ggMQv;ceY{bNd|<{}d*67XI`O&8_I$-1$)cy9mFiQFCkiqnfAk2HpR2`JMi| z3ja~V=GJ|Kz4K|pM?c%#8avE8-%a=`Ra;nlw!4=7DN`{FN`Zvbt?`=V^OTH<4#w_hS9|x);|UzV6jS__k-XvD#J)|J;GO{dx+2 zNz1m@cHybKYpK7rue(WT`)3^{%J!$wzVEM>@E1k5wH7Cae{P|T@D$p7Z{c&VZevyK z;GMr*_=-QbwrW)K&i4`iiuYSvk4XMW@1XVH%zt0u9~|7;x?*5>{Y}1~@JkC?S*wI+ z{b_p_UiW0(dHZu{@>dA|{&TIYzlL}(|CPcop4Q6xe2+Wt>_6B)_g@s+{nu5(&!&5B zt#;v`8!_|WU-%10Bv_Ycd*`nfz8l?h^l@4J+=v(b1_)p8>lRjWR`};m%=}*?{Nl70 z))Q}d_kXSM%Nw?^cH9vDxfRp@b;4gewT0Dmsh_^xlauy#)h|J;ko4-&poY6~m=FYo+d;mhr#{ZFm%*X>OILxjI5uetSQTkrf0 z!oPl?x%K-v@BC2V7p!S+)t~O2PZz#zm*&{ zpCNq3ubWxV)%DJ2qWo)`S!W*hUVm;9zI(rB*4EkKpSv>a&v4-z|IpOxI@r7a5yD^m zc~h&&#oqam!e0{K%o;bt-~NN`Kg|4(5`OBH&8%x`d*`!+AF#ZcHRO5s{?EDpVE?@T zpwQlbj23?O-e%UiYrOOS5dO^O&8@0+!}s52`Ns(Va87gUf`ah-ACn&|{POq~R*fy* z`EkO(yt;*zlIzZg(r>)*KR?jY8j|CkzghS*>7JjVBi(uD_`@v!1mUaRM92RPz4H@= z-`2R5)n`Wd@ssKQ7U9<)NU$Dk=01K2mH$b?Pt9#*_2}b1{tm_8D*Ur`TU%S+41fG$ z=KnU~rAJ(m^!{Hf`Gitrmcw6VHe9^w1aGb7gy@$P?`@F^Lst(sa{fpQirz3qRx^3D!pu zT>mur2ZV1pFu_t0Tt6}S2ZjH!c7pX?MepUGDSXQFEv+xpHSeYV%@Tg{y)CT`d%W`x z34havEv+h-d+&c97Jhr@1gpx=-uXv_Z!$l@>OIqY|2tdw=*0=v`>Wmif3yGN^Kbu; zw!46?;&}fCop9Ev-E zmUm|NyRhBgu$SRIf6nQ74m6)U&&bZs?!9|2A4l!_YchO?9!2Q&3-$a{;K%kaLLM#D z&wo?lLv9tJ2V>OzH26Pf6{YI<+%(?auipQ#&fn?qi!%n(k!R}pXTbkZFqqy4sqY_V z!k7D4lu`{;-@nX)-!r`^g|3!+>-d|`f3x8?CMZhlUdp|7|6ra!bBz2;icsd9>if63 z@YA{!p$p4(uX6lH!^eFJqLfXMX>O-}eyr$^K{l;NQc0;Qj@V+VL|V zK5M4Jv|yt1>xZK7JZkek*R4`uMFM!`RtPll-JHP*8&A$*n=Fb4S(%AX+o7FFZ z-{2lVb9<=gUku-Ts6XZV%JnB7&v1S{s@=a9`NjMd{U`2UFM)5L)t{amRIh(2{IQFE zRJM@w>t}2Gm%+!b^&|I6&aeNiemVTPGk!$l)$^}_|CHRHYClo;D~OVuN9==@5uir{2!|dQqm^s?cW0L&3#ZEb-xw9 z*L_}pS#{4(RNCw3%fkFz`OR%-($d*$v;Yt3TB# zqQ3s^f!|TlpUzKLU%&UlN7VPH#VOVOKKKST{OL`9_4D_B_}$h0sqqr|{a0)MiT$IP zKRh}Pz>lu$Poqky`-AX_xF2@S`TonKo4J?fU;1e6_^<{M+97{@>dE(X*C28dR{)5$@g1;44fWlYj(DwgPlKWp#eE%TY(H;AD9<}*< z8h%vI0<`F|^Y_nNzxVPC{K1?B=*T2>e-^&fsQlEkwcJOTJ~vF{7wb2V+WLJCzTVq> zl)13no5#;u|9SY+{`qLuJLk_ISp5a~e*D_`ZDTz@pRZqCzpefvylbI6^m|3;@Bg>@ zzu*h<_x@Dxr0y@lFY(Jw!84rSzq97Q4BsqWE~+}m`TVu|EAX#lbJDrB&W|6fzY0$| zbJC8J^5fUMepvlA_?u&L(9m}J`k^v@*WsUh%1+AOg` zvt_5(>71{BR(})Tb9*)_mrlL^Zo#)~la2b~{r@WccN^X{Z#IhRuRee7!0$hnl}7bd zpZ|B^i;m1n|J;)wzt;7`y#CySKmSu!`l*fF+s(iG@cl!x(!pHn>(2xDu*bd>f#>H` z`u`z(s>{B#I+OG7t+CFZzu|*6`%?bV&cAob>L0;p9^gy0_UYeS6(u=;iT$e>2djS! zKcI>)b;I|DskHwI{Gm@-Xl9V}?>)2Te+uupCks_stNy)>&)^s2$Uf{jd1Y z0$+9i0)FBcADXws%jxxpwf!&QUojurTT(s$EBGbbys2-vdjG$MpI_UXl7y)HH}He6 zXQsKu_4-xj-&^<~kIeKSk=}nQ{vG@kM<%*mD1&nUzlT3|G$ZAilV0=7ar~H~cKyfy zt{p!Y`SlAQ$8a7U@!X3)-|Ihc>&pK#p8GeR^EaORUqbqG|HkJ57|;C|5lR0K|9s@X zTkLJ>7x!}0(oER9z4nh8sMwxNvD2qd{_f}gjo)WH_g{bHO_u3OUFCikHHm)vUN5Zp zb2Y(DHZDZZ&(}w7-)TfX54CX@(R$n_;8y&X=TIEGU$~A|zu}B%=M%ywS{=tqCaNv< zv8MYDBER{(DF#L4AI5!6-&)E(5qx>~n{3|Tno@69e`5HS8E&$Ao78<0_@8$2@7o@y z?vuh_dKSm>d&<3C|GC32>T;948B;^remkEGzQ?qiEVQD!_kb@Ib(5W}qZ^Pl@#LH`;APs~5+Qkv}zjr)hDlgR8nv1Mk88xN~3Xk3#!JH0SSz`gzpqPYb_s zbR271M?Qbe-n#yzgHK;Ajtxzre*CA04^9`yGLBLA8Q`nL++bZY%hxZv`n}-0X1Kvt zt<}9TZbr0v^ZJ(&e#WTltYvEX`WtJrerAF%f9e{$Qcc}whM#%qD*NG2b?*(IV9gcw z`xD(8?KYxa`+eZ6F1pNW*OQ;W?Ao6N{>+6-ti=f38+narm){qD!oI)Qg5ByqEBvj~ z7g>@x_4>2H|F+-)3tgw~v%?>JcAjOAl=}$G9}&gzXI_7Ez`w|Lo;mKSkAF`1=D(a{ zb?U48T=0E=JI;;{3(uk+%L9gwHwP1p9bc-TT3p zJ$9UVzphOY`t`lGe{jJ*K#afmcM)sh{L7&??t|dRPC3jjnvTD(?VnO1KaW~|as4Lt@40gw zVa0dXcG~||Ule{z^}{TbkDur#W892r?!Q3f=TXZa48QTtK^Fe6^Z6&dn7_h{{Z|Nl z%;N*>VnX%&q42IR53u^@<@xREF9zR*e_z%jfA##u;X8!vXRlk!eH7-Oh}QOp!B6kK zk1hO$^;>u`|3v@s=qLgI_u#$Ed!jtQUHkcgq0OI@hxzyAEmijp_+>M8v)|Y0KEiVS zU~Rv-eg?l`=q|P{mHhl^S3jSyTK#3l#0{-s!ovd_Dd47HzXzPcFqW{J9 zkLZ7K{ZkVD;?y0iPzSlUtG^Wd(#Y*BY@@m_4WF|5HrC*Q+*|wKeEgMxzfyH8OLP8< z7waZ(?=}(5^;gII<58P`W#L!V-okE3SsS?jL||LDS2 zb|<*LwEyhdUkUzw!X2#2k8&SnT7RtVuMB^_e=O@0BlmXstH4i8xQ9*6`=hjeyZlw* z$2{4~MhC0=YVeP%?`7fR)O~gMY3p|L&x@6NyY|wEcFzCj6qNyI9-| zxwq@TTJRn{Vp)8(pOo|0hF{QoCu{Xd-PeJiSBT%t`b~?Jdb|8T!8bp!iLI{ORO-$1&)WWm@Tn_oVku6^y*Rx8y)O`#1RUOwe_XE1OJAYZ{PfPe^71y!(f2ikg1z#p|E!$W^ z-Tw@KGTmDCQ)PAE8b0~K7x$^PT7Jl4})ojvH zb>9wtMy=JXcd-`A`P;+)b!|19JXqa#fWOgb4Wo6sSDAku;TyQcu)90e^LK*J_gf4r zb3om9hVR4Y-+@)?z6<=#Yin6Z4RzlYe#)nH?5Bk4z8m}={|zi~S97QL4^rU#$)k4u z><-`m)<(9psq^{g56`3Kd%)*8zL~vvEI)qC>%Z{g{42aT|MrBxb!ZFAF;wo&>$f$3 zFZl8cx3J+^bRUK5*U!U`|B3wK`mZ;9l1W?G>NoQ9r(OO&@MC}7#?m>|eP8$^ zSGKcp>zwZ&ME&Oe>j&T0bvtX@M&0*^UtDb)8+6R$?1KzQ_kWY~@e|kY zJZi`PaQGS1_Ol@w`^Unw&3oACX8QVV_15_#)^E}OV*MTm|7Oh|*6ES+^M|$n z#>3yNw3qEKD?k6)jsFDrIhpsds{7^MTE94cMEyKECc@u|*~e;>ZsGLxo60zTc+~tP z_#(UaF}J18_YVc(dDQ%5_!6{_g|U`S_m5UT1%6|ZeJt@oxi|Np@Z$Ip`Ni=w6+ZW+ zeQeEuR?7LO!EgAqpFPd>v$CHK&#oL`lh>&G8Sn+~9$;O6ZmpbuCj9G)2iV4pZIt~i z_%xOFv+cjA``PemW_Y2_j^Y5FDyRZ8w zoBgk7zgR!T@h8^Lh44Q;-^40Xd*%8U!S`smk>%?n_jcpA7(Sm5|Gx8R-CNgxs~791 zs9&s~OWI0e()@PyuZB;XY%O!^D)+J2zlvx* ze%HXKxfa8g?oszK@Yy!Uu(OFeOY67GzZSk@cntFnQTOZM>r7q45)anB%JI7%{_lTR zvxvFs`8U9q`>>kLJfZG4!q2(8n)SG=?l-}&?6aCJx~}dw!$-!hVwW$g`#<5A=U>G- zen4&1&|th`QenpLq9bR`Htp@v{TI zV#FG@y1u&K3EyMy8dl?i`uY_Mzb;D*E0j;&?}DFIFNOv0QeS^}!_R0N!z#6sd%N-5 z1MgNNhE;thKY!Z!z3`7`$FRMF)crpAwTEI@?)vI}KYU-mwJg?8-5-GOIeabK9;EIM z!oNAVmenk#?hnD2%Ds+NEU)el!@n53j!i4BKK@7GUoKw9hO}4rN8w}Etz)sF>i!tK z*OGN?&2Q@MKMwzEk9BNOg!=yV1pG+Pb*#Y^`SpX{`gsyQa(WCq{6_uy=M?;qs5R`L zI_my3e52R=^_%(X*MDc=w>MkO+?uQVv+#Giu3~Mg%e`IyorA9$wUUK*`{K>-Uo`t< zxPIqRyM8|ppN&>9pMGEb*IvIbfcp#eMt8!7k|FHAd;Ri*{XWM@4D&2qE`5W*X zvd(8CSIB*=>H5Li{y6yQzs_S_R&-I$e-pmK%V^f(puYdHyMD6fzXhMOc{Hm%RNnt~ z_1}iibbT&+c~gD-@4(OKHkVa&SNC_}V;;?618eB#50&=cgYPwP4x6@3eg5Bv|0Qe= zE51s8{Mq&21Ni>WX0xdw^5frb{yl^*a%naz{YriP`x`!t`>7M<_aE)@KZ1`RH=FIh zD!+ef=N}vGuQi)_|0wr%{r3burN?Zx>8$v{~_dFlJES7)ok+uKc!#6xVg>8U$ zvAq6i*Z%nbPyc~?SN@;z+`sXhzwzAv<_P_{f8+B2jOYG~a`S)r=Oh2+VsF#B=Bz{_ zPu)7LY2Ez1G;BuB*ayB_zx%m=uIEYvX1_K91VDA)@%cqT_tu z#H03od7>uKZ{O>MO~C&hHVfb$)f;iTcI&m5cg$bR>jl z)g6>@qyF55ig$yrR>?sXUh2=y2p`3t+cshp`cK4HL3;o3sP&&1R8jxd?hZ;d?^?oMz{P%se|B}PM z{oO$|63FYf^C{r__j6E=KI%Rt{4WC?bQ;f1^7ejn|9irB>E)o;*SvQzOT+-FZg+U{Y%wBe{Mx3e@4S+b5Q(c-ShT- z^Zd&MKmSoUEeO${8&S!h8NSqvaJsWc?(N#|4L>MfIIT&kKR2RMzYl!VeI>|kfx6EE zKYCCJ>Yhx0ZbYU1zVH{am!NTN)qPg@kfUJ~w@KY+gKt$MjJ9u;d%OP64qwqTj9yOH zy-NS*fG=>MIOX@Laen0q0%|hwPJ9Y05zp7v;y{)J|{{!H2To0ktGt}pQA^3Eo zLTK_`_56YG{py8~S9blmHGaHk>%S50`mZp2o#G)BS6ST$!5^y_LWAIWzHdJN6oGfF z3Zd8v^8CCV+WZ&Mx_=hee`5b$u~P{3U#jkd;eUG(OdThy`w;j66N2exH+3HhpLItt zrLU@cmHsOR|9WgNrT&im#o-fBFr```ubi6qggx-&m=eK(E^<#wL^B19?wyOJ*@T>XveH{+apBv@*{?mTD{H5Rvwhf}; z!{k27X8x3hzmhPB_8*jcejiHfKM_U$iTiduYWMBR!2h$TF!@~3Je{a+UTe)Yn1 zvy}eafJ*zz!B;O(m`e9h_dme@p0hArY@~aY`pd(6Pbp09gXH<``o98vx&%SgG?V_m zeQW#ed`0*eK7R^sQ1_MKb9ok}W0~~#&8y_E3_rVbF#R-8?)mTg&+%tIeyYHa{VRl$ zJyiEq;RoLcrRy2++?B%os|Md^S14WRu6vdCSBF2HI+ULMs-C|FeD3Wbw6Kpnzg_>; zgs(O;gl?`^_qE_7tAx~LH8=-R}cP0dA|S1tUtG4_5AN&oxkP@4EpOnD)}42dkzeu5eMYnE`KBVH^+l$ zLwWh@CU)&_44))<5h^!N-8V7ne-K2c%ImKiS=(<{eQ{2lf8STz_>b@;}gC~V(%mUr3jDI_Lk5`3gTYGtayYX)i|KX=Vs_<5R{Mh*p@Y6R3(u;NK zz9amq9EGWOF}b(f|8{~u-nlUC_0+ve|8<6+wZ1Urx~jf@b%EdE6+~TrSNC1v7fuSI z$t`rRQhzu2#J)u+S2Oke-Qg?q@4IhUOFe%N`2Dd(DRU0>{5|2HObe#vSLEj}yZP4( z{+AxXw82~5_lBPu7EDWH^z*k$|M!8vnks}=#LD*{u{P^xU-&75Lug)3xwmV7Kln@h z{>{fj>ie($@P9N4Cf^{rx2t~ueCU*5I@DHu|2YtT+xlSYky!5S@<+jsI224lt>xD* zcKtU9{#@EnDl)(UnYvnFRiOZ^A{|$kUA5n}v9;;vf4mG?- zaXNHV{rYzpeB1QJY0|H9Z*9N%`f)h?@fyYG`h4~Je}%6*B9z?vs{7yIA3hGD>OS)N z`8a-c|MNTi)e#{yH?eyD5%3GLg;0*&^7}V-{WlW+Ktg`}PnP=#)GwmAep!Y0Pw?m% z1wYm`gvPg)d%OIj;b;CEOm+IG-#;1yf9gmuc~n;SW8qgd4yLY))%`g5Hf4k9K?3#h z8xNm%ZxZ~nk|A_4kG}pzDXd?Ujr!Au zkn1dUKLvh5mJrIEO1^&cdcJ!6O@-exHiU-Y{ta)hw*H!;=K0^X`EOo-rolg~8A=!b z*7Ngxnm3|wd_C7b_u6{>Ki%+WLg^8ypZ{jS4}Kd;BPOZ)nef>ThtktL^7Fs7eslY0 z!S8PqN>jh%{>NV7_a=`%&h1@GJD^=k9a6#p~-%;Wb5e5Ox9w56o_ z^~(bIe=-Hp)Q$4%C%g79gs)brFn#=_?iaz&=hyFR+NfW@E{31{x)6=ttbYBv1pe{J zLe#@of8V~T-;HtjYX2{VpH!|84Oyt}m%#_5C`7fh>dzgh`Fuh&(*>=T7*~YvX1_ z{`>wje&+r68hHOyg{Z|)-SeL}#@+Zmn&-dof7YKE`1pi{sA*FDxf>O~7XI~_09r-r zejWU>o&l7iuex6kpU*FVk}Z;ZYyX+opAGQq@&wSNhw6SK{Q4{b)Ye;n?n$NpHo>2I z?oVAKbkE1h7&l`aweb_}u%16Q!`B_-PeGCD`TvAp!M|_5#%Q^>>%T4VYjXKh(?8^% zx96+#Z!7%qTK?p+M(*wM^A6HpKfgEDpQi2BJhyN;>*9q`rN z0%%OMy59+ZBrt%&MydN)_(3%TC_cHm-v$4sUI6v@U48!VhEH9YA3r~+`#tdWa|F=x z{p#!2Uid!)0%#+Xd+Yd{kNF;_QR*GA3!bLNQi|O8|+Z6wE{H?_GGmnl#@EOJh(9;a^{MP!P!1L%h41acg z0Cn#x_q>k(dpC&!LuF#G&irl|A@f) zVMME6f%IJzHR?z&VK^FBVYf$lgjs>*8JxFKM5b@?N1dS%J=Vf{uF%O zW`4A{hVG-Bte@ukPs4ZkRFL}h{i#nP?=N#x;}P=LPweWy0zYR-ZmP0Oe*D;t-&OcwS#wjxxHc4} z-zV8-e*R13$G?a7;P)TJ{NYi1?(`b`mN~g7|2%#D;Q2IfMB$D5FGaZ*^Pk6X9v#== z2WHDf!%xZAKmL0(FQV1ofWLk`CtbPbeEqZfIQVppbJCj8>h<4*-}5>L6(28O|E%p7 z{U_SbqvIBQ&v7}ZW}rTPyq(|Nf4AW~Q4U(WL_UA)`tJ^Wy|>w^_Fm`nSM;B`{=4vb zre&w7ue^W7uKoAm+c(Ni8#c?2U%UG6!%xbaopwe$Uw^FQ{{Vj9<7^c2QGWl@uKtJc zeUE0Npn1+;f3oKP8@}1bY;^x$=dWK_{Ui8ZQ?rq~i@JXd-=#@5I$2)+`hi{lKY_m+ zn2jcPcK-ffYyD5*H+;-WNmc(@(p~=?OA9-KE3~B`Hl5oc(MKqFV_FJ@EcNOq0@);=T}tx zJ9z&eeQ4D_=g$vW^S_6WN#{eqCfEIP^uH-;=O6xe?R#G@qJAD7@!X3)-|Ihc>&pK# zp8GeR^EaORKUh+K?%()40OPs;V3G9y@Xts7yT#t7SYSwEk*4a-Ce*mm;2rz>`^K(c zHkuNMf3*1{+T`LALB@}W_POxC8NbhX?muKXqhGFWVq$)n`dgd-qQCL)|I_c{_lg|f z>-G9vT;jSgTH~qbkH)wgk-KfZ-VJ_VCq^l2uGM@j>Nlb_zxlXJ1W!vDEvy@(oL@`|(f)wlj8eI)=T8Ekc`>7U zX>}iM>3{xrt^Y-|9=A#1Lv}H$+eBW!op*=#PC^tsZ;f*QC4--ql_ef~F$>HDJWpr+Vdi^QjpPXTIl7HusIL@r~+x1^cc#kWLK2_I!tY!X1qWvOT zj~`F?o!1#nZ6Wtjmi{x(-&F9&Z!o(1ue^S%Hy^*L;XA)(d?8U5W|-Die>6~yRCApg!% z$#rw2P5*ntA3E%y*zvlLwyb~F`pxs#2flJQ{<$xWw@CZnntvtEUpzXpz)uL}pWBdV ztJK@&_k~|^E}VKc)II#y=PQoPWY-Xddb@|1z9XSj{)&42LGX|F zgp$h;dH>niNa>qu9SU$Q?>emh1WXIBV;-5$);^ zfuFr7gjzjN-@k;yPhSv1m*VC7CtioPe-Y6-|BAs6`+>jj{<7TL)n6R`&HiAzzE-~f zi$s1At;bK8QGcgkTIr(hOTe#qT9kf$puT_Q9ixrkn3$sUc7eKgz|ZH;{aiJ8-=X49AT>LZtRri0T;a5%I&)xS|&tC?<3%`IknMa=A+JDDP_ub0EH<%Mh{R*q+ zF9$!PS|DvnsqTM(|22CcO|7ba{aYTsY2QF9a&@)x{+XCV3Ky@tSB4LL#*e=q^8T~)Rk#;_!gBKG#yiRH zA6Wf1QVuLJ*J zZDH!*BlmXo*M(o!h|mAoa&Omv_26@?38Y!2)#qP*_;DKw(UVE)^Z!Tq7n=j9=>+-u z8G-Q^QH;NN{x*QWxYeKfzm^}rcJ2QOKGQotN-#&he~CnX5v}wKl%_Y_jcpg9KN%UAGKN|_fhCS5v}V_3wZDQ1!??Rxwp&T z68?JIf)w9d_pz4ovwCy?wSxCgT#(#78anYbLI2T zn%`W18~6di1t`@q`SBNJ)BnG~&mWwh!ufY5$+C?!EdUcj~bs} zuIxL*drjp1UqtTh>hA*Y`z#-IoVZLme^>YeUGh`yV(PvdeD`z(s8Bj}-yMF{qXHD{ zA@_Fe?*Sk5v>@#owNz_=tit-y6aGz{AAbQ(_tEf1jKuLLqV@dO3;s!R{sP8#_}<)$ zKP#8}(Td$ml*g|Rw_^XBp}RkgYrI(6{s`1BqP70M@ZGNR^XG*{%Dx}`oa+7*_)_=L z3jNm~{_a*ksxepH4}hP1!H+IIT&UcC1L1SV`cb|x_4Y@>`;O!9+YMH)e-M0{-~Fj% zAHDuq%lx$)zrpay8U#?mGwOZ_e5#27lq#Wm`-j4RdLKX@o7LMt48G5+0J`F<&tH}K zGaUY4x&W%+uOB}u{r4+;Hiti5Sgn5i{RV%#w;#D}QTM;Y-@jgv#@3RrKi2V|h3j7) z9V6felqg84Cd$`8t2duNN5a22Ux5BRs-Az8QUB-yG%BBb{f@L*KS#qaYFdEOoYcL_ z_>FuE+Op>Gb`N zO8Y0k58a-hZWqt3b)S@3xt=A(8W?zg>uvdwh=F&ch)^E`B{s@z-q-#q{3!Cwl=O)m?{um9}&Z$5li zpIj8czq4I-{b$W@9{)e!Yx?J;+6m?NU+nw>_#J^cDA6T(e!Kb?!k_ogPTdB}y>FTMXt{dVnN2A`~^ zFWvnlKYp$Cn_s_Q4&OJ-mqO6~Xeax3^ZN%@z;~+UOA&7J{ zDfRnLD(znjUwKv*n(`g_*TJVxn}ys?%G;j}=RXm}^`m+G*2AY+Ls@>2zy1@6_KPUmZ_d9H{^zwm z^!H)){dX+gj%x68i^e#AB(DpE#%{bA>K!>5?)Lw$Pa_YY$g`hO36j(R?H z9QWT;{9gDA4nBU{zFdEszxOY~H2+@k@BI_~&!hJG@jm!Xuf6F_tn=%C@!XQ|JZgSF ze2F#Qbg7v0`xjP!06uAdZ#q8M`TZlSKM23Cf;WvhxOVPl=;&BGtVF4#rnl# zIFFy7`_CMeiOzPPtL#r8|Kuc@D5mNxska-ylkmB`GSaB<8Or_?eD2y_RN=uiskdwY zY53o6WuTRTQ#G&B|7YL}w97y(T1}DWw`>1d_(ki|Q+-c$e-6IJqjWUq>SSqtyY`=l zf0r~Jl^iVhcJ*I?4?3NOHa1bO|04XunAEf}uYCOM^8W?z>zkT>81u!8^)s5U<06{< zORS$fYU|%6__i}WsbDX4f0=vn=SA6+RAuj%`TMQ;uW&0~f0(f+1+99ZA3w3;{Dbd( z6*0oJ{;x&-JZkk{h0pOKInC>+AHPxXrWh`+Yx&>9t^OK(X20ar>cp4z<7@Sc@0}Ir z5AnUTJbr%ezj1R9dQn?n|4ezcc8I)2{&ny?YW@cDpSqrm;v!A!C&o{-KN4OZ zES8M&4f|5RaM9?82zU{N7wezMFV?@C@cVbUQ&9go+VK;Gd1H#7>wk^d2m zI~{&H^ULvP${%T}e?2^pn!gR7%)_19opnBc-oW#y`8)6{mL;X~>%PoibNkKtH^B3# z`MdCLO_S1z_WJr4jeawtoxcZvu5eOHR?Bq!f2IA_{P*Ec{gZ@TE>Ha2e_xw_Z&5#w zTKx~;6R%1_Qx}bMI(}CF5PpAD5<0tYv~vEx;XBq$LUFT3DCd6!ADJ!*<$Lzq=lowA zzl~@=k6Qa5!#CNRm;!$LRhr*Ce($&!^Pfj;{y%{qQ!O#|NjUs-{;&1F@Z$IvUL5~V z;WK?oME70{)%-ZjA0wLcZ{mId_dJI4=y(P{yI3M>eM|SoyfdQJi~Pci{LkS#9CxEZ zKYa0DtN%Uf=TY-7;8WIeqYRUVe6C-3QNM`h{KAX+g%|a|gx~rkA$>|P%xV8w^S?6k z*GWj{^6KL!+WoEdzlI-nFadoU_+|WEc->JL2Xpy!dw!FQWf=)cWroe8v(k{9_{ZFjLqCua>pP#R^@fXqT#r3Zke;zge zfqPf}pYhzk@tnW$-2cT=`g8xr=K&bc{fBV#fBEMh{>#PQ%6BAEx4fHH;9EdqHz58iRY;`e-)m`&z~D`nEP|?^7kEC zy*YnEn_3l=zwR7mn)hPfnY|nQC08FRGf95kZ}sN;UWwor7x$r)#?ZyV-ARp*%YonM(h*8Iuf17`E~SJHhf&o9<(BbxKS zIkl%MJBKN!>wBt`i;ji-k<1w5^M=JPo1$^lBCiVJL z!{_4pt0#3n|E%?=fp1*KhX(Fe&z}}PU3nksaZsM$I{sq*iuQ~7n+|>euYYf1`TI_+ z{dWzXM@M>i_e?%?J+=IOBi8)K;dyjqfRBFXO{cG@doTF=G2Z0;mG_NATjq~Be@3JJ z-rm%ptNgyNozDax>+elzPO1CM@bA`Trk%ga?_1mD_lCdgmzgfase2#z8{0F{FB9eO z`?brT1wOKECR*SkzwdA7ec?y`osr@lavz296Hy#LJ1~EEbYz8pGc+SL>?MESjn$jS zKO6inAH1k8P`ddj98M>&_520lTdqw@ zu4UD|AAE~8Y3bQm_5SmR@AWASeH^ZyKL9@ExHROlQr#DVzmhu*71|>AQ8w#GAbg6w zscHWP_4XHr|F>sqdf!r>-){Va;Lp@eO%GD5=Pv?(Vnk|cx>J4r6@?E`(w7ty+Y^IHj;zxZo1dQnf^ zN5Hpw;Z7NosQZ%evs$`SiCJH~xNhb3ZbSTh{_KhKFOT7T9ym(DkBLc218#ot;<`-Ad*_CGv^i~Ub&_#YD|r7@S~-rRq}i}@$K$X^CNQ|Bb)(^}n^g{LivY5EIwUk-j+ zSYmPybbkC>>;D0M<;z5LtC>816y}eJ!i)JU+AsRAJp2I9#5A(5?qh9^Uu*sf@DGY6 zraGQ_{VKj9{QN_SX>FXkuLM7De-dh)-ue1%t-mt7>$#-#=^OSBR$m1^?wUJIU*Y`x zXZ2O#t1L}MY5J!N)x3-`LdG`TpP9|Fz*W^W&#ve);{&D9iCV+H?M8j>$**7S+FuVoPZBrEmqC907mfNwwDw=th``+x@|08_a zQ?4}cE1$b#&2R3%2JjOWy3p;3Ygz24o#J~5wRPW!!i#?wF+Ikg$8a(JKf!Mv`iXs9 zEPvmqaQr-?d2#*}^M^;xH-vA!>tFWfPx*7#QSc%PZ@z!j2tGFXC+6)ff9~AQH-^9Y z(z1&;t7xzC!{o?*@6ZnyF|FUb3zW4~7KM_B-zYecocpfz$37@;qKWx+djoRxr zJl{6n-`e?CM05S=(0(4Z`)5tzV@G{te#5_bao!fcM?|w1_kTtI@u>M`@O|HXU`2v- z&wt)A(8=3P(sJdcsrs3V-WV=J%gfAY74 zFP%M}ZOE_gTfuKG@SZhI^JV+*-f6|GL4K z&+wXMFQx9g!~c8z4NF!={=Ro>eslYKz$f!~&w7v3&%e=_KSs3kJ>ma3AJ0A}mwWzu zwBuJq>-y0P{&Aal=FwQbf3W5^_g`=Lk>}sDb-CsDk7JQvM3JA*du{#Z(a{IKeDnvF z;;6p=;XkLXyGD$H7tvaOU-*EPA6ZB*`Ti*yUPP;N5NMa^?~ipFTa0p*Z+gyOT7MvwXOHXNAUB0EFVV^ z&Av9y-#lvP@4@f|j(lPxyEvbJ*4OWcz&9)9LZ{u=FrH8B^R)S6isAV8@LI^vqn3Xt z{JniHbSS<2_>aW=5itns7mwQhWf*+oD=yS-M2xn7HRaXnh~iG{Uqws}&!gst!+Yd+ zp$0GI>mUDp;V#&}7DoL%YW4pLzvTG8EN-HF{kHSJ!9N@R4||*3`T571|9AM~(?7Bf znVj!mtbPRiMn3=Bo>liF;q%>zXZ^1`-~WmHV*M5U$D?Bue87l!wrP(1bE9L?{~`)6 zt{;RK*B_(d>y(OThvGMX-aqs4`n>8?tAv;SLdIbE%NVx=g~11 zes|+{?9Dy>bGvz++PpJj6zUgIcys=7@M}HZv4Q2cY4sb`FjTJw*GPuueyd(dFJ zwEg_|X!BP@;jg299vu_lZ{&H;dd}P-^-=I5TJukYZ#m&Td%1k4vY!NhKi7K}H6d2n zPln%@?;R_hbeFQ90>5nYTb3%{Zq4(4`p@`9qx~XU`)?}z@l9{p+P~HPH29F}@7R)Q zd!+eAzl-%pM3Mgl#*atGboltO?^uOGd!;@SUPR${!t>~u0blyvTbA*z?xQX1x5#VG zZ}u~d_HTW|BHr$k_CNo9nitVp|19`?#a^?eW%o#4zfZo)&x0>g;}PpxRi59j|K`IVd-#A2bUUQgA8VQa zkr+P_t@Gy(_*?7mu{w=(A8naG{P$_&FQV`_F#mXTEP(IQ{|@U?LY_YgUPR$f!t>}@ z2tOj{E%q{-dj3W5X$r=%S@>|; zQun;Q+xU9@dH-XVe=Yo)9DlK0z100W_#K%qvNu!Y-md@F!{5nxfz8e`)j2h}QgK z{Sf0P)(`%J+Uw`TcARC~PJB6j#r*viza9Q^{d4SoMs>dfe#^acELC!S{W9_zF$(=J zqUirqsGmp2PWaNz&odV$KmSHs#?S0y;V&*f&r{BGv0q8|(U$eguKs=S zoBhwRr&sj-x7G8%YyBspHUED2vYXGc<1gjc53%qf3U8jj2jEvVILkI3lY6`T2jMHe zIm5#5>7M8L=HurOe5)&G*dZ7B^+zP?7g5x2K7J3wyYx829^{bk|9L%H|A}aA{}K3y zhflMxvT`2OuBkik_e6(fZ$rRxj3H;l=uW9)8oU z{j5jOm-=~oKkuLT@6p;XqR7wJP0jP@xL~w@?p{`Nto;6yHUCX`9vv6qUFYp)+jcp> ze-b%RpMT&_Hf^>1{2gU8{@3A? z25e@h9M1QD*8Df%OElf|T|Vw}{*7$4x4!@3{jK%C5$)=~`8odv)?>8u`zO}=Z^3t% zw4T*&>wNvU`rDuDU(bRn$j@Ka`pw7hozL~JV|gaZ&%ai0K7Q}QpX1;8<)NcfBjzMH;>;V_aM;UDMkpR)QV@K1kQ&Cbu1 zzkX_$|0(>O>8qG~fp2^L%-sHG@L>s8vMn{#^FN2*)?yXwT7Ic^|G+wacJ;q7+TVO7 zTeeEwzx?c%v()LGzy59Q|5xxe0++FSkDR~$X7#V(hc;izUd(s?`kU3ifp7i$64oF@ z&mZgL{KfYjpZ6bcKl??jYLtBb^53V;UlB!qvwsJ_WBdYk;hg&XeGlJ0!4lT=E8m-L zH~#V5i$AS*EMyJSE?1sEAGmep{~4bfV0=!1@wox_OY5H-V0@l{@wow^BI*C(pMUu8 z7JHL-?*AqhY3|%V#P-r7$JKue#9s9o%o2!ywD}|2;GN=iL*`TOL1uZouGo8EDY?lv@2NUi6>%Z^E+-wBTV1 z&ATku_Z>!z!n_wz%zJbGgz&p>XP{Ye$(6kue89sDG{aNfCxU;I*^7b~cqr!=lS;Hd zMPV;G94GhI{`VZBuNypm{@j2*8NA5%g1S$N{F8b9m6399*Z=PDBfERi0XN^8h zi|VPjKPCK(nqKs{hI;>d!cVB~MU5-SyrV|o^G7e5v`jsJ8u$h6 zyr}wgxwq^8wD3p!@c#GGk6+&2Z=QeY;B$2FqFl$+eR_EB_Fi3i1skHTn|GYMTjL6&bpY=<;Z<3#fwD)ag zfj^%$Jyou*d;as^JpX**&&8ypxQV(q>NX;;L(4Cs_57C={#gBVG-i{!&j$bKa$3ra z{3`WlhaWdHExCoO=g$G3k)@>ztJKFYC;U6Nv~(%2`uxcSe|%*csJL{+)e|g}&Q>USSva26|dEx7yOHBhasr!8Jm-_MNrhV1x&kx_Ccxv(wQ1=Dk zTfIp|w`-~Ug7Bxeq@ooa)!Xj}|72h)dNobm`@{bmnu>z=s@ER?-{Gz&wR)nSzYzTV z>7Eqyk9z(<_;>X^sqA;G--Y3ug?Un~1nS3M5PVp1Pg)+Q-u@!+SuLd3_jKC6g1}#bzdC5 z=!g{Lc2?bo!CwhVK~pBH`x5XwjwGka2h}}4v1Uq9|0e?KNr*o(M2h{toEc}!|l2U_D^89=rY5O-3#s1BF{ay~f zaL1$+kX?QM_yc@=jihwLMctQ&Z@4ijE&dK)0lrTXck0H^q2m6P%Kot;eCw0$l+rb| z^8ULLe1b$CbU(Z9jpNpccE@jJ_|57-CwEauMWR<4FBAgMEtXh6vwXye7#gD=*D;Wn(!VclGBNX>iKKI&kjjW2`}m1 z7R+CO#udz{)o(Z>+WAQMy9N2@txr(*P2tC^PfVky zs{3Z}A!8F$nsMsBIefi^iK$k!?p6A~1^nJFiD|<;b>9+x#oI)bcY(TZ1>bvIBKr6p zgmk)%dj9tC!yYB1Azx{~UH^B0_jYxo*Y4`|cZ9!5Zgl&! z`ufoc-mRq@P1~iueszW~wA_tKPE+??;Mb-~L{EyV*WVSs{t`a_Jk|4egLf~RnD)I= zKYw(G&z>_0bw8}`d%%~;o0LX%SNA>PE2VL#3{38=$DjH9)eAo0PEz`7srvc5H~gLz zNooH;-5ci}BUd z|Mc#Z?Qiw{-vIcw{QGiNj#c0P4TK-j!JQtjRQFNv)q1(p&vVu59|WIbTQbTSF3)eb z{tbpNdEA2nJIK9V{||xB6_lKwj8?CIDE#R?$!Xbcbw3Q==VWsFbWPn4hmXpVoYt05 zpMSr?S8U}$S(>WP|KH$89OvT)Z_Ilm+V%hM@O9cHqs#Nv^N)b<`@x+CZddms;e!sl zlS{n19|fOyw>xJrT7CT+13#s&JN>mlp5J=>nAgv-@M+xLsZbI5 z`fumQ!N2>EloD@N_v7JnFn4+%qJI9J0N-JyJB>Rc_jdh15q@#PWHjbS_5Ir<`0TF9 zXyOv}{nupp5&Zko@+ZxteEl^Ae)eK_n%7VFe7v@a>rW%vwSOx7?tk1V{F-|HY4E*f zB%^?8nJJ3j|1pkxBZ~au-$m?>_h0cC&gbFh&keZ8-#fE?NM^15M%||P`TCvt`bpF;-hVY4 zzI|7B`oO>YM*N(q-Nrb6wf%G8v%XDAbI0l4=yxMp^NZu(=)bw};p>x<`%!s*s~78+ z@H{%A;jiXTO10dwDAzv^K24e=w5YD`jk=9!&2O%MK750;iOKJTdj3D)7nM##iT!=G z`i;Csw9CH$zGqW6nov*ov6kbH|NX1uw-7#}Q$q4Yle(n|DUE)^8sFCGh)KyHfI7>iL(#x2fw&=fkop&!1)RlXJP!h9HM?azgq==i+^9-gnjCMHT)v(Pq=5Nh_9?a_;>BOKhb}+Q2!eEirnw5uI^*ty?Ou7 z7@OVc_y?i?c+~oDEqtpdE_6ORyVn1FzH0N=6t({6f7d>DOVpnlejWVX@h(*IkY2wr zZblU2C)zI}Z?`sojP|dG&sfoglH63Ue*^rAN-k9Yk-FaqpZ5nBTJTc$M%_jfb&K#s5HMig~Np#Eye&!d)qKfG5pSL#>6 z`Ti#Wo=43efcNL;uVUHN{XzJ`bzJH8d*}O4YyLy<34U~?R{#1qJ%6S^{XA;*ABKO? z!j&E!)BBIl^Z%KDqW}26hg9v3&zOJK_8)_f zOzTSJV&wa8QMd3STK#eO2`63X;g8-<&wtkbI|09AfD4tnmr3eH{l@-9cyauQ{ulfI zlkg`Seqyg4JHP(*$N2H6jo&H5XZ@F@sx0^B{u5s07hdE)4WFa?KWynl=lB1u`Om;7 zIQo$dV(R`Z{KUf_*t;8l~DM(5WL*8Df%cMN;P>U~i6aq!;L|7Ne2%g^7|`o;NI)GyAzH{mNje#q)< zQSZN7@F6uHvb_DAufNvz--chi_W`T-O27YOtoufcGOhnse+Pa^zymfSmGk>gR(}`1 z)WQ2~U<38}dk_9h+`r4lZI-`&V;z6<`Rg&f?})qXL`rr4 z1pfTHJ8XJK=kI^B*8dc~(}X*0QaW}23_hsxZ8p1*x_=H|>GUm@Af>v00e`F5Ef#V? z{{Bn5`STJ!{l=TD{75~&G4G6M9Y6E>^9p|C+Bg<=NFP7L8PU$ahW{=82CI@xpMSzd z;rdfVvwy_D_gduVQCt7sz%R>sgS8wipFigITlbG|;g1Zv#-@yL-v3tr4!(}>RhBcK zy#K8E#qrC3k9Pif55Kv>6&Ci~`S^+aW*`6m=|6Dq%KtMyH^BIu0ONB5-j&fmH^BHj z0poK6igELQ`R615~8FK6LuSjPQinvd7+d`rx}hH^7DOE{)$OJ~u$* zn4Y^VJ*}QV+jpvbZh)vs^xOA(Va1;<_sbAHb#=P$wchtkz^(X?Zk3@Sf$BaXeAt;X zG{36onb@t-xNbBeKMupizl$jH|I3d%9>aNbxWPBLP=-8mequ7ue~;!x6ke?R!i(#c zMDQRyZTeYZ;U8Qt2@a34fMZ= zqW{HtLyVu;H+#a*;Xb~%+}q_(W%7vw_4&iwtJQBrt53<-eUYC>M{4*g^~#d>FY@_k zt^YCV=h2Y{em@_-bv@L5TKGky%aUtp{rHbU{YJFbZ_b|%KIxdUbn3Z${owuZ)#E2U z{P~GxX>b#L{fbr?{|xXy4J}Jeo~e5;_=b(j(%Q-T`p@hA&-hvEH_xAp@B@mKrGkV)-K(@eEBv7}rD;@_M9TGNgMYuI6czMV z_u1i-bm#uKdi^=zljSKz`|_#xUrzY0&r4FW8S?SBn}50B_bez$txC%0pLP6?WBuaM zksE$Ycu8uzPd|Q~jo(vv9vyk$f6iW#g8P3t{-W@@7vksjN4)Pwc=5g);q$`Je;7fn z+J5ok{KM-u)`8DnylyVMc;AQc`QS^zXQHyfpA*&#QFYB9RKG2;}=X?{`b2|&?;Z``uPc8 z^T#`spdOyOx7N?+!+*w~uiM)E<&vJ^o#={_*Ij0Dpc$ar)Ti+vV1 zzf<>>;n%+lr>^Pr^*ajdpAoI?H`iYU{@9OyzGpM!St@*ZvytfhQf5e~o(o*MxsQ!a+xOtNU8;^`3{*5qP6+Bihwp z8{UtF)1*Ju^VfkNcD@AFUZC#l!rz@=g7W{Zd!ue6##+|z6F7c&bku_nNMC|_mr|cU z_2F~#^|yTsb^jxL*e}JY&UN+q*8o0ezhV@Y%lY-6IDeXtpP%4|p9rO^J>=dx{;9Ek z@#ts>pL}{K-AU;D`q!Gj5&Zt!p|q#Cx^E00S*RGzY?p}m^`3Zt&^GJ!8~#1K2inhL zxL7}%!25U=ql>Tf{KmX7qPhLS@H}ch68_fjq13c{V(tEc;f!eKo5J_a9ZDl7={{Cc zKW~rrz9(z`X7CAb@oXgU%sT z@3^{e1wYs$glcw`x1aat=lz?t|9*zg{wSDQR8jY>;rm_)rrSByeH-|5zXj9LtCkQJ_f!%a(%zGnR=bu=A#QYP-UwinY zm5b8lee(6w>do`F1ALeEMQMJ3y6*@dHLWPM9U(ve@OEhPM?}&8Cs99-j!y8I))%Fe zfx3^jT>r&d=HCr?9vz+G9j}X0i!08re?)#)9KSp|y1<`r7)-wmaV7pb`Tx9rC-RGb z7x5K;-CX47QTx8duJF082UGo@oaYZgejdX`{%-JB`-V_FfA6eVr>yNakDt|dH}Y2x zrJnzfw!46?;%NH-PSN5H!QB$vC3hcOLI@!Q3nU~Y6p}!&7cCOp3dNyNAOtBc!TsVM z+}&M@7iqtl-T#E`yvv5+Jzvh@JcpKFo|$K4<=(xwmf=}D|7-si`ycmzvi9@*EIN9@ zk7-hw++EatZ}{VttIz@V?1WYOdELzU`S%6z{46^9z+Zk?nd;Xyyh{7~!q=TtnNr@4 z|MeTW|NY=swXH%Ax>~>fD7W8Szn|e}Z>d5qgW`Yvj^{V`zdwAsd{rprSNsjsk4L%v z1K*<@(9(H}`)ie4_A+s~{KMe4 zq^(Bz(|=HI|8V#XNvhFY7j-`Zen^q3l;DE3m-}y?za!zZ*Q-Lk3aXFaDEPT!D$`$= ztn=Tnng65V=fAB)u?5ugkAdIUx)O~}X?S`3<@^b;epqyjg};%w5^a3^ZS8-F{f|Y* zFYpU4RHV;e@py0I*-(*k`+Zyg`S+Fa_0PYrZ9IH=?~3H|9sXDN z70wE@zm)as%U-uv-4Bn*YvMQ$=XT2TSaO=Mcq$>AC|u&<+-VT z{GATJv|U9i_(t8&fG_-4MY@wi{ruxM_)8v@C|_oEKNEgUwMz8PRo%~m&vdUMJ^hcm z{~f+iKt(FrOWn_gPdUE=dH!PfD4X+VzJHkK&m8#RJQe8V8g)MxzW#;sRO*$wkAnBE zUY-Udw?6;3TR-#QZ)Gb-m$Iq*X!w{+Wyz=NweE2)1%1~ja;UiIh5#{!q z{Q~$#4N6nJuiSr>y?Os%2w%EcDe7}jJ^v#3;87*1FFfn-Hg+Cp`T9MdKj!xT0q=La z1i5`j{};nA_Af!b&#Bjc34Ga)#c6#~>+4s$@mmT%#95p!xv2YP@bC8)rz+Ld{c`xI z>&2*M9|kk6Xnl_=iSr{{W0(dn--_Q@9=BkJ#M?vtmo?a*TLTz?nalcsQdNs(|Wp5 z=tXtE0Y0d!8$G(D?l;1pD(FVFj~ia>dm_sFmwEr#1ixpGE2aBG-EW3Z+1-`?n5*9Y zE%05Mxl)P&>V7NyvtM25czt!xHd_7l^K<81=|mBAza2hHJ~w)w!|>t93XyZA&+*(Ba$8pUvxMAN+t~ZnQDR`ugRDbp34h`{B!ccBNaH zt>3@xl9@{O0jL0`FSHm3AezZa?dfe*cR{e*8L#>u(kvN8#VTDn^sM)Z2dy z{`T@>biRf4{VTin$HG5pRE+%czt!(QITg8{5U6cmDeyMxbPyPH+L^;2C{+)pT zc&7-}aK2FXC*l7tQiQsCJXiLo;M>F$rmo$eD*My$>#7%~WOJV=`!nz*M-`&S9)?$` z|5^B%2MUt&2lf2t;HTXvK#9X1E4TkV{GoOEDX5Zq`!B#BU7nA;9~kvl>HkIeT>0|R z^5oBy+kXlEQtiAnYplAz4F4`|9?JZi`ux2DKV(sEdift?{mA{7*N=Jsxe7o1QZDlS z_*%LD*WjlWWxnKlWq%#Me$SkAqLXp|Q*OV!|C+B~Z@^!CnuFH%QNMqB6MlA!98^8( zopSqc!T0<#JNfl{rF*&k?C<*i&7*w%aT`AOi0m}wruz8bfv@D2ohocK_AizEcj5P3 z%tj%fefAIdZ=y(S2n2?oR#$8g*{~SJby{vSh z*hOXk0)FX;Eadz2g0lY;zE<8W)S!~#<^Hq3$E{y^{9nSa*_D|Jzr&5!4l>-Qdh$o2G8)a#7yoeJ~!FZgEu>FMabQ!qV|@_{=R zUH`N*Ym(RB_uRkRm*2;q`{y~LyCxy84-53VsXX`p5BuSD`(Drc#DC15trLCSnW8@K z?C<(>%j|i1{kcyT9XxkJ_UBNEB-HuCe9Li<#Ju5=Klg0*-10xgiYB4f#iMm^$}8IO z)%=OzXJ$%5g)>Jf`^4}ovnHWkesh#PpA@|P47ve-<6d;iJ2;@oW3La{p7nzZsl_&VHJu>{G&L4^Bb{ z607G=1)r*L5*pva@J?ypl>2Xn5V?&HGOt`20TqXw@1TJ}RF2n|)sRESdh+)-JYgKl^?E8b7no2fsAe zXRYwPZyP_e&ktYg!AEW9FUI^8{T5Nqe--P8MMnYn)t^3S+Zue^`Z4D(2w(rnU)r9+ z*5?nAHseC}BG_;gR6YQMloDXjm} z@VU=F(XQ=MuU{GX!YqDS5q{C7yIRB5U%dIgo4J1c zxi#)t)O{uR%c<{b)vK%f%J4_V-`1|r{^FfzKVn?_Ga^5WdVYTW&98rQ#op9n&wue> zYd=5!ndg61_=K%)XsFv*3?W%S!M%_E$7xlfY<@sH` z{p^6R=fAz_qW0T!bx-h_3trG>#(weNI{&J}Zy$M1E7$#tH;*5yr#}8X^7+S)KYaf2 z<8KZ4zZ0F+rhmirt2}>e!e^;;TAS1*{`D{WTJV{BpVYjDT6??p*M=W+{J0jA)9`ll zN6uddzJyDx=00YQR^8&c&q!7`{@;1@#r$VcUq5w4|5qK=-du@4zr23x!Ee}jM00DW z?(4(9nRrBt>S$fRD2zXka{dPJ9l9OSoGrc_KUshE{SPs2|7eQ-v#9sq13tayQSDRN zFXvxh+kY~^v#9%q@YDW0rsavWzW(BMPk{QDg=bOsp76O>9@o;OoTst8|MlE1_x!)} zm>!-*-8X{YRPUsgZCCu~pJm`#)V&vc(Y~j&69*0NwAsI8-xxkT*GcVDf%vcgWbX}M zZbPhgXk>J}{ZEJXv#7Vf34BlIQEkGN_|M<@_nq+lgGGJ+@PVJ&@rc$2*AG!P=P%sz z;|KRFI+}|7Z4YUw9PwZO$lez|S^fjsr4@_x>o1l3&ERhh-lsjwvRK(ShhI}>uU4?{ z5@p{4eqOWP+WJJxlzmJ14SRQLTURbu_O0MOXuCG(*Oj`ro4<1X{otPs*`i%Kxk}l$ zhR@Y@lji$rwX$!+JpUQrWTUpiH%8g}Gt19^GW%`RKJ8HV0r1lYZqx=jt$iT&FCKaQ z`1K2)|18FRZa}lS8?@^&Yn9s{i2Q?-uh%@9uhYFe|09u~M>&5GeDYgswauT6{3^a3 ze3oo$wNxv%2-^pUZmu?ecek zj~cyF8(q%uqTeD0+VsC8eDLTM+WT?V`J>=@7`oQMb`5_N~)jP_ks^jxI!Cuc}=|g zH=lp}b02tq{<#mm;iEsU)bbBh_kG}Jk6Wo-x)uNNQ_kNPeoU^FTH-?L`TM~q{CkzQ zx}JLepW!>zS)={^EdKKcx&8g&TP|6xeR`zs2f(k(wpu$pPu&lM|LyK-?f6%`Jb#@S ze-<5s;J4RUqwW1uy?&AKTjsCPj=!)TKfC!m7`}alby~4m*7ILpKj!&61b#%X4cZp^ zw*ABGhr*BUy-^$6#Crd;%RdbM-ib}xyiFUF*WYmXeY9D-vTUR7S-rOL^9K>-{O0i+ z0YC4@P1=ieo0a`Y_}H}@v^jaU=>A4L`xk$1mG2)cI!3_<{<>Z({lxI1-6Gnxe>8mO zUF)>O{@aw>KL*}q*IKPY^mg4l(S8x-{O0i=3*V~cTCHb}o!``d^Zxq_{Fc0HwL2r6 zmOfBAew*`;gU_FOtv2QTE=yk>o=3j_n8$xS{FtB^tz@b_mfkM^ukd|}uhGUF-D~M1 zk)KDN-`xKR@CmN2*80`nuluNY=CAqqIT3!nwnj_3;(&7gN$^F^uhC*398}If8GcCi z7_C$N!^(aN{My-Tv<>->D7Swq{H6}8wOi$mD(9aDe|+^S?T6rF%6>Y0f_|&ClZRrJ z{S5dcXIE)6lbq1KGoJNlKL7d+e$w()+MHL0SD8OE;h)E>)GkywrQH5m@L^snw2@;^ z>;6VO`=5FK{|-N==Q6E&l{3ouXTyirTB4o2Yj~CXbKui-{6pLF%UL~teDyc)KXc&& zJ}uNDOB(MRRmmR(KZCt@Z%-|CKMy`O!94BW6zlh`MoRmSdH;xppXxeCtJ28&eZx`k zJo5d^JpbmyPg^=mOEb&b+vQ&XACcuZZG?y6oeJ}RA^f?4)3kfNt$iTc&m(WYx&Mpc zuW3`X>tn6G+jyzf`M9~kfZEyG{8{{Q^p`vSi<>EnAY3C~l;x0|+S^{^ckJQ6$8uz1|F8?T%3{MFfYzldhnh>%P4IEb3m|w<{aK_MesU zziuddao^6PLaf$o*V1_FFMDy{u4((@+J@Fkf z3)x2^KaV{BRJJJRQv<}ABiIls7Xm#`>%-_zI~@z#%jPcyF{|DI>wesSL}rpGZY&3WU#sj1(3 z|9QLl`sI;(UO(=6{ltB{l$m3-m=wG8_OpK{oF3Wli>sd(Jd3&)_wAwrVzow1cI!S; zs-Nt)u>9P!=n(hqx<5LmwWw#@H?_(y_8%9Fe>iNZeyR&DHYR3d0u~! ze-85dH`=QWZEW246;4DuFYen-`n+2^dC~g5vFy$5k3#;z#dopy9jND@2Vc3+4(*bM zao<_ATSPg(x&P7dsakE-79@*R9zSv4u0Vp#T1*3VFYepbWXB#qH^VzIej>{4=kt$` zAD@5XzFqC-?0ri`zU2Sf`t!v6V^N=f;=bL|Lu<4z{OmmgczOS-t+Xepns#`Ol-=etzGMpMSr9 zxlGG(+S;4z&pqEic>DSOu?*g|%Q7uP%H#U{2}FJod0tiz{rJQEHh2~t%i(X(GOdti zc$V*9?Pq`2J&$t!74W^zE!6_{sQZ=hgWQ&C-pxr=g%5=&mD`kDXr9f4E&qeKeWN@9wHwn*57~CpVdLH zKaV`Wx&Le77yhxvgp_We`xxAtww;l-^o1x>78YPb|~=M_HT23C$oJ2jc%|&%ke7y z^9MeE`TOR1`}zCkcfse)yg(b7NZs#-KOH+?E7;FCe`58rU4Q2G?}4A&Y`(UotM&Pt zUH$jM`{tjo-Hb8LKUMPYgKroUt=$}`?)Sr=DjTiM$o%E}mmj~QzSKeAKX^ZQ{muP9 zApC)O+F$J11*`p&{hojAKj!f}2>-U{JS}@)_4XfvFIsb+w&9X`{=@Lm*Q2!BF4psh z_uG8@HuwJs{KA@1+J~L${wVy1n{&1GO$^WSee?V~1|QIDuIByHn13oh7Cv;z9IZ>M z_^+Sj^>-ZJ>(Fd1YqW9wsFME#e4c-1X^)S_fBh@ZzmxDD6K85!XYbbMpGy8y@cm}| zrd4cbyzeOr^*6<@&fn7_|G^nr&>rJ`S1S3>z%T1QT}ye$@TRl3wAC_+$-~UCFy?Ot;4*z-LaLxUR_4_vL z{0;c-vxaFWk63@+pX|-YkDKs4x)0TYb{p^85$zUH_U88Ag5NrKh}N>8@xCke@AdwR z$bQdP>wg*E)1H$VRI$UQ%Q z<(^;v-iJTuJ4kEt$$I|V`3LaNrVZ3?osIwaBj^Hq%FkL;cBJaW(H5BI$OkKwB}>aQIcAOHT%?mOz9-+$!(3H+;m zKWm8!f4P6n=8Jy*g&0?Vjd?!*S=7&epTdWG^wSEJHSVAD_J6B?20!jyA8oaV@xEp5 z*?3!?|CL1hS=8JA96rnG-deNYt=~6ouAl5*z~BC{ra$yFX0<$-L>vNsry&(LyC3Ny8mO;pY>O-pNMw(U&Eiv*+u)*KmOyd-2ON4qb7FN zB8ONXf93pq{_yc*(eW1k_WE$`Sz_z+r$E$?N1lH>Jd2KZ@H+-})N;?ap8t0F-@_kv zZ?A3fv-VEp=TYweU+~T625awrQ}-YKNB@!eAJ`x9zCZCkKk>f5qV@^rm^@oeM4}b*?Vs{(bNJqc6XYzweLd7?{J822?Jm zpLeUg?~k{M*X?^fxBO?!t%lU}K^Z;&YPRko*}f&BdEWG7^Y$K_w=BA|=-~Gp_@9>d z8&YVNQgNQ|d)yGka3aSA{LxZ|*<;oO0fO z7WMo|;Zqgyq`p;*{CeG3UQ>)~{~P3IQP0mO6|Z0344!mm@E8BJ`ti>>=I!U7GtJxo zBm5jUPjbspB(DG5^ZN0~`_1deqwJHzpAGjU=kY?8{WsTN_9@`!kMN``p9?DcliJW_Z>i%+BO(kh`Yobe|5L-4Wa}@_VPpK+zZZ4Wqul>=WBenHb*PU&|2=&%e_7P$Z+dvG ztS4PP5&!(FjQPi+KL0Ynzii=2H>#=ojPR>Fdy;zv*LdfToIex%#SWg7s#Ebe&(}Tc z?>2e;zhmoKPpH=gu?zOG=KlAukVfEwr zS=94q75S61`QO>tf5p5J(VU-qzW;E~_g@$Ikrx}%NUiLb_8a3a_VKv!{~6=QqTc>& z@L}T`(wGFs@rT!q?;EBV=c~fAsQc{jd#W^K-!ola&oA07qPhLt^Y(Mk+n)n|{&o*K z(%A5(yrLan&7TwgS+ED)Jy9X9|KHmFT<}fYJg8GtMP;8G{_vItROPDSMZZO~>wg~j zH-QZ(I)5eQ`sIb6`My4_>Z9KNeDE38)~CP5tB+rP_#%$_)Z69D`NOx?zX1G>m-Xmw z&yvdZF9<(vZapeE)L8$b?jlB+j(_s}Ed*aVLp^G6s+eVd+4J?w=P%zs3d5hiT9ynfpTvLs;oh9TDEzeob*X2S_>Vtw{$lXC4%MO9L)OPnyZP%1U$|Wz zN}E0Yl=eE(&?N8f*n!l==Hqu&__D2tK6TAxnVxtG z`x@{M`hK6U$vpolw7)8~d!O1ezuoxPVwUee2Z~muVSTN=-T2prcO74aVpFBE%x~xG zz;8TTnHHu^sqE{*ht#i3#TO;l{bKAtBFg>e-}A|jUo1N6!KZmri86OgrtIs(CwN(j zcFs&<+5RZ${KvfiH-MjNl+@DO)z1UI*^J6Ge6rz1zeSY&CG?*~M??65zgM9W zS=94;!Vj8Nl|DaAtX#iF@aKN3MhEUEvh;TC_kurF&z+iV{z2I{hR?RI8eN)gc$QB; zev2s2AM^g{4gc5Ns^l@_AGV!2w~D%pD0}n#YXU!FV-=cM<&&jnzenG{dF1=IdH(po z?@L>SMtFSGy=b>7>Yn{w_vZb(DSVxGm8e+450?2iAwQ4u`I9ev^y!N9yux3W-md-4 z;4}VNfhJ~tZ|UvwH;2#Hqyi0%Q1>n1*K{aP7oJ%6pVy6#tEiuO{j`K1P^27f9%Ak7 z+TRL(%*!$q;QiUM|911o4}RvV(zK-G-PdUg5dkPl%yuT)qOj7ubU<4W~kxi@srzc-oJw3qfeKhj2_nc zWpCcULf~ukEAQ1{D+E!!{G&%FP3 zhc7#-2>B#EXqjIgf3xoa|LjE(I<$75Wq#S4`~M&Ky?u((uHJ@c?bY{R5$)>N6aEM9 zVia0k-S>k3*x!{V+4He%5Xg-SOYu`?K}S+s~qY|Ef2X^48QoTD_tmWc)9-O^(Xg# z2>iXJZggOZF@I%m-aoiEkKa)EfCFwcsn34P{@cy}Vem7n7pFp5k6C)V`VEJ7$z7aw z);q3ymG+N-zhA|TMie+}>E-QdtG4M0k{(ZRkEoDCz-qEE9)$VcE(%X&yFYv9C6rqam?pu1h z`i+BsyR|SqJo?1aAH@3SkG76%Uqb;J3ZCCJb&!g&#&<3S`?xYcdXC9?ED1y z;i(JJi^K0M+b_>Q^ZqdrzFWpZL{mRmwqLHl*-wJc+_?}%thB!VlJlGEHyJ);U?JKw z*|`2;`Skr)M7jUw{8QiuYK3S_7whW>*_-#Dsql9f6#Onf4ZeKUg48QR{P&;u{4uwG zI(*8k1!>Vm>+2`E{rvoauYVTfp8L;Lyda&Nr{4eHkiTEPf;1?Zb$+|?n+acbQURJe z(HKA0UVZ#b(OulX;QcqZe-?bBbNMMKt95?6{{IeN;aNU9U)#tZrEvV74Zn3wUTV7} z{_8*9e)Ig91D|DS9x6HAnE!0Q(fco=TtD;p&xJpfCJ*hIZ@qr(`X2>fP0LOFyQ%wm z@X-r$(%}@=_iyC<=Ke>+AI_G8?p28Y{*gTY=ff}lkd5yCW9&boZX(M2k9qzqfd65s z3w6C|Ip?fSn6-lJj`s`~M@^8Wh={N%iusrC=X{xAA1qFwtJ z!}s#bM4djqP|m*ue)!Ccboj7w{Vwu~XxIOx@Qbo#q!CZmkAKVHuO7)jpO;%7e_1>9 z{ewq7f6V7U%i*6-$v`nx9$Oy2 ze!J7t_F9G)br(_g=Jv0K_wJsadS9}xpPgR=U$9Yn8hl&b$G|t6myYTVeWYCfweU4w zrlm}U3@`dEqFwvf!I!9&mfjw+KL4}x>*0GOO-q|&ti9d(+W`OTsx-8}igEtR=9|9% zo1#8{`8<@5e;eUfluASS%c-9~Z-T$KG&Q{`XPm#A@``qRHUDP#!>n)`lY7c^{nsT9faqRd-M74PWU#BS^ak&v8*4TH|FyvbABg$ zPUZ`yHLjmk>bDDid(PA}>&Y(5{C4BN8-DARRP>^b_5BMwzX$$)*HrWn_m83!&foUJ zr%95E?v7up-2Q#=`?{v2xg%Fvdb|0%AO4plDaj+nGD~mQ{{!%T6H?H_dWjgzV49$H^#prf9wWEFaqzoYh2>*N?gV$KZeJpN!@nnW^0WSon+glhTA;<8{9r z`9+lb&%bYg?F0JvMIDEqNlB?+zz}7B0{&fvB(kGS@m-~YZ2`v;F7*!$Oceirro zC*fuVw$Y zq5V9{`Om;lE0~b{w)j})H}{|W>u5iVjfw}{;H|IT9$coy~V zJ39xz{p~-RPp8Il`PskM>&K(He%$l=bI+pVJp7yvpS3r+TgG{F{mt#K#=QCb?*e@1 zs~@z9$$rv3`}g|%H%0yU!G90;y#Flf?Y{_rs`_8rxb>aBDL;GOR`>k5+e`386TZ`e z78~)(9*yb9l_ z_Y2KAV7l(vabB;Vh;n|jzXpG6@H1^kL+kz1F8_7-$dOO9ftOZWwqMR~9{(HgCz3wa zQsjtHZvRdAu1z0mN!|Xi%x~BJTksi+KhTyoGwLVSjfi&bzYSlr+3${ZC!*Z`3#cE9anJn^y?;}??vq;gG4LYF^Uv&`Aiq}sruMGm zKl(l+=ADQeu>bJL_m7Ln&!Xcge6B$^v^OUo>R#j(QTFEgKZD;AdR^=2eoFUi(0&o^ z`u`mMM)WmpW2Qa2Uj;9soZsC47w{)OUeRuSGQ8-wh<5q^gbzD-S-Tsu!?J#?4x%o4 z{m!F)EIMAoUyi<{UFyHtvj6h@GuQ7Ge8AF+T1t=OmiguWo5$}p{Fqu7vYBs{HqG43MTjo*9t zfvrz!K`VCaUd%fY?dtaze8ZwAzRQ33AN@z>e_(&abN}KwfAQRZ*8DrseN2m~#7*Bma*}Lg=Tg z>itgvpJPu5WpCQiGQVB>Q^L325<)dvT6??smkR#!$PkJcWB3!Ozld^v^ZZQ>pSep2 z4Lzma|1|ImhlbFIlh$6&Zyvw2@W)1n(3BkNL$?CO^u{`7(nYLupv z^7v(d?|MFjPA0PUcKI{HySxmcyXj2ppIt9I`8XQa&vEbP;VfC-mQ@Q>w@INgLq4W)VS$ezrXM>;9D};t6>>cMLQGXuI?SF~SJz!Daf3m~B zDjPyKgZspJe%_;xpK<>vuKw)vUi9(fpZmhbG48ql8ApO?daAy{mer4Y z79BZ}f6RbjdKK1BIe#wrz$U?Tpu^9)KOyZOa(=#l^Zb1O&MoqPXh*&88lKfljJqCX z&&Qv8KK^;&hi_;{hlcc5&Yu@PVXJnu`HYcY)Lle5KVLsQKd*m2cxRb*eyl(G z`0>b`zJ9pp$DjQ011<$og`QvLk9qtj!1Ktxx&H;=pDqfbPW_GZpA!o8F9@ICKZxoz z>8@PALhwmm2GX2sU34$%CZb*a3d5H;7f2UwcGf+s(>ITQ5%{4~0x9Vw>;040ou3!- zDA&Iz{M!bBRIsSw<@(9qJpRSt3#AF9lxyNYe(?Ne?+PEjuPr@!6aVo`_HOV`r?jO8 zFAcBK{^IZvp=~MCJN5h};GLD)(&M+*UalWMez1P%^S>ng%2xs8l}^2WrQpl%3ZP5L zt-W3T((p~E1W={f*6p{Ozh&SL_6wlRudUBt>^#5z;^)70M+DIHpRLc|?Al)rzWwt6 z`swvg%ImK@e1W+EG`FMSS-x*xe-+^OzxStSULltI#{_BrGLL^n`0nBU)ah`La{DX6 zU+&>g7m~JB_LbrH{NPUk%lwsn75EZk+7MA2%l^ybXI}qR;rkVCLj{MlQugdpSf4+4 zm$#;&Ia(^WpKXk~uj${KYK>{G?AeVT-4}S|N8JZBv-EQR&EwC2?wfb=qfGaFExq0P zA^4Oj{Al%{rpmrLe4jYRzmif8k$A96?>#sh1<)kgBQoVZ0z5#sQ3N0um zrM0)4KOXR|k6O^Kyw={X{SD!J6>i1u-_*5izuo-vg!c>bqj{TZTY9_pH-hgzr8QOj zrKY8~Yrhx#oS|)~)S~LjzA=2+Ty5yd6H@lx@GpzErUcs@%DxGFp+G-6b-Svv_kj<5 z(TX-MtfK6j!dFYyik>g4q9NsC1Z2i;BD>g+TRj>NQ!23r*>Jr{U^|W5#{!q_m5Waj*Crc z!7Fv|2VdZd4;7wacu{u|?b_cOzI$39a=uabZQz5qG@-{Ut?MWE-@O0&!}odBgx-Br z_W|&+^?hjWeZz~oizxTseEe(+-!r!lwGT1ouW%yT`9S!~!hsxE*@wX=$n8bm?+R<|e&JTu&wuT|JU{>MJifyHLl*Vx=WzInu8k;rp91mbuYmI> z7IohVzU_KXDw8HpoR7r)M;^`f>y7&tEb8~aI>Vp%k0-sWmOak1^R2l1m*)EM&wb|m z2mjn>79A1rzj%4l`Fok;{MYjLL4FqX{9WM37y^Q?A ziO3xrPu=s+4d$Lj-S>odcze-Ec;0{Z@8ibb+)HKyH1jn55JX@6h%;Np#G!8_w~w?y4Uw5wk~_%sh2Q=e*ymHYoQ z{ENcgRCc2A+#h?NhF*UW<@%e)uRnZ(WsPb4JR`qow}^J_9{}%>t}*SMqu&03@cZw3 zQL{*+{VMez1pgq$i+W5@&mRfjwYC>kYoYE3!{6QMMUO&^=O$I!KLp-CvN8SPQ1Aax z_{w7&)5H0O7vm2i-|!nO|N%{P@TBKYsih z1HY(#L+Y68%kjg!|JnJm@WV%X&@@kLFW29^|Na8suz&~o9a8t>;1`Z-K!dUvpSyVi z`;Uln`_1{s!)ryp&;JTvHl#k)uV8)rm-CzJKLLJBuKF~2dj`w#v#Z}k_$~$N)52Ke zb6cGX$G=JNSw_~Ub?dVz=bsG!)B5`4);<2uz2(PWbN{Enzw1|@?zA$z7&j5+`kBXX zD*To7^{Hu0{GWR(AOEMp_gYr(yZm(cO;O+HXE4uyK0T>NtLm!P|2Jm&>o-aNu16I= zXH*`)neg?N)T95jQlEdb;P?Jjmsa9)cg47gXg7Yp!)KwoRCS%PepTl0Y zFXzwZ{cAPOA9<9=e-3=r(AxB}hx-0G7e3-5``qr)*89KQfAjp0g5RB?7PUR8e*BpS ze=Md3h3EQFAAfP&6;aM_KK@0+pJ`W}s&`jE|C|r+9zeA4rE&aK8NUVab<1cJlfXFs zi*}1>*Zzg@j+72MpFsWma}oTkAKYn35#w_sgVs`_t>?68T`R~RcL2F<8u$hxQVzJ_2W@qf6L*!Ca*&KI~kvQAo7Z6mwyF(-lvsm z`Uq<;=Qq#)mGJ9USEk1OI+uCED22_}m2HL}cgD`uyjSkDvMceJ%W>zbn%9R}Yli zzYadxPZg=+#k-c?uKw%cv*fKvrF$En8!6f?qFw(tzz=#}fesfmp1T)LM7#VO;d76y zKqV_()7yU#=U*bq-hBSD3I4;|@-)4J@ws0juZXfY&)?1PTL+e>q601{*KZ5_{2Jxy zU3=qm&qQ7k?drD`zGk)ZH1Ck{+`Moi+O?l;H2V3=(-!4v{A=TLFNG7)F8_A;F;mLZ zhSW!u`@aKz=DPAUz|VN@UW}WFa{JBWw-f&D*{o_iGi7E!L>9pq=xaR|QRw9?cs>j=yK+xf%r%@da za{Kvn+x+~EKertVfA2;KD(-JQw=U`~qWQT|-hTevJohX*j>C5@SAr5$tYVqp&Yyrk zoxV6#+HO2|De{VF=TE{9E9^#1K4;bQ@5cNUQTFEXI|c6-?n;w3|7hv$>USFc*`8vQ zJXr$E{>$TMUO#8xm$T1}9=7hCIM22{|1|rv@DXQ=(6F9QExp`+{@gqtKmNG^=inzT zC``%j-PFCPn~3cBSN*^9$j9HD|2%xt`h{rLrYDwu5j>CFoAY0Q&;54+>bL#}y?$cd zi71bsIsZlY{mBbZ!R!f@>wgJ;-sOC>`e} z1^#gVJoI5zUgi8(;im=Vrc*P^D*J2j9s#+?rA$L*e;xk4M^5T-v9<2SxQQs&&%FL_ zz&rcrpv@CoeN%pO{cgf9o1L9judJ?n_W2sy`27zN<@IOwx8S2bW}`~6xs>zYh9A*C z8>py^5>Xz1^ZtJazDk;GE-&H`+pC9mHwQwT=!z!MU=fc{{!avPlfSW>Fx4ix<7#N6EPb3dF1)| z=N_=Af8YE=X8HL~Y>})~)VHMW55kMM0G>zg&Gml-|KVm98mBF)#;^Z{6Vc8;W}g3i zuYbbq5A2V4Zdg1gES?*#?_oSQES@J8&kdL7N&g>zKC$1;_r?c*bV>v{`Dx&cRe?pfWG`b@qOV#!XwDh+>QO8?|W|edp)l?|5=tNf^wuZ@{9Fqiu!zF zfB&!NUiqBke>$d&pgIFx_4b?GHopIG$NOdF6T$a<-`F-%Fo>< zhOhgvGfhooc$P=x74fV2lfVxz5J9U~6jg3NpA@|RPs>Np-VEyblZpJs?uB~$lf%CVi=bXh)O`y0eZNFdj{)jFCH(r45p-jWx=#gPvttC!o2Kql!(V6< zLF1FE*FO#X?e-CrDyO>y>zoPClz+YYzLCI4Y z>tC!}5$)D*MtHwNto{qs_m52QE|()HO%wI~D>Hn$KO-pnIm3%~i)h#WEbt$mN6?tC z;>!C+R`^#pA}C2tcI{|!-<|DeU){f4;1leRpt-};eKz>vzeP}%i|Rf*eEYx%I`vaY z<@V=*_fNp)&sM{Wx{GL6|D5n?oSi9`M=9m}x!~7N?o3bj8(!oU(Jp^(_;j9~DQSVy zmic9WjGedf=f+u#dv5qms?Oy6+1lHUe_rIjvAh$Fo?&>=ZV~1D{BOq3InS!szW{vCvYlvANA>y_g!g+BPJvm~^B00I{YN<6Sz|qa<@%Y& zuP}UgbU3B@kF~cOzasEkBU$@>)O}I-eLmqdsGa)yDF(l`WH@<@SI_SX-!pAERhp%q z-wpor^DxTxR6T!j_;u%-e;N3x0bz7yk-9Gn|8`UuWm&A={&Mge(uGrtCF-7E z|MBzh_V2=I{C#y_0lwqNFp64X?b$rikH0+f>ksq%sR)0eUKsuEZ|&vzXWoA+!QUGm zMjMl=`^xa6!ow)&tug<^zAvKOeslgR@Ud=T)bEbEuL@r+OBkIUqCWrGjRt-EO5P8p zvE8im%k@h;)Hr^z=wJh*d#@v*6x&HXKfBST`y+!xsb?Q`&)#UG`wG=VsrY(z&rTS0 z@0vA~a_>;@e|7jp*E*8dW%c|u;FB)yNFQsd&%c`R&)RgP>dn-BE%*TiJJQ(E>b^F7 z<*OZN{#e6{c`u^f{HX)~W%S-b!OiUa_qO4yuK%T ze)_NDmwEqg4k&#Wb*#Nz`#Zu< z7!^v3QW~D+(~ln_%HEtm6kh8ZN-4Xk&z~^(q(wq$_)7Kp8x9|Hxg#}xqrQGR!T)@t zBVA+f-QwpdV%$WO`)@w}c834EW+;VzP~ZO|;5$zYWygQ@{jUrBz!#yksigY(dsld` z;$bxSJMQ0fgOBMSMm;O5-+$>2Klx4=H9xO@|F{SIso-$Bx83k!+(cyaSYN+9%IDAj zf%o_`oa!RKa3b3Ip73=xvE%0}_4fCIzxqdKO81w#?+rh65PSXcoqGTKz(?heph-2< zeP8$)+dEV5mB#BAqHZGE)vq7?*`5*fdbj%PFF(UiJ{Un0*mo{ltzWzR{o%uYh@fMC ztH1s<0RA*}ra!u>zy353{sQw&R;a&zHVA%3`p#6Ll;K6)MYQXGB>e5uooIFo_18ZK z!_Pj^nc8|6u{{1dZH}Kq;4jQ!uRmQWtn7!vzt|l?t$tGX!{Ae<=|a!_)%|dIx0?}E zsIcKh-9?o9Z$5sEfOoyynKD#R&p#4A_w7!!ERDJ!1+S%L``3m-%Ijw|ykD1a$~)fh ztiSsCgDL9!FRz2V|Biv*$L^m;yDAT-x%Jb(J;o1Gm-|MRTaq#uuhf)~( z&S%xvU&q5Qn-NNV9~Mydzry<`52arD)$>n)kG$TIrgT;J6XD%5hSK7{4KL=sh>88UFU|P|EZj>vszL;isXre6afZnJWC@P-+^b?x(@0yc0?ruB!X# z@P7w}(dZL~7j+lWuKqLN6BQ3<@7q<+{~P?XUE!2=wz{7QU+rEv^|@Ek@OK>@ zDe)Y2KOesN=nk|cQ~c*I^5-MvD=;O~LubgnHxsm+aqtbNiRUPw)&O zm(uZ{Kg;=-!yg$GLYc;@`xWpj7qRc{s1X18znp)i@QXv}^G#*+~N_<`2uZORYh|S;Ih8OEzM7#OF0sdCv5Xz7#{`ddM_1_48`${mC$*Jx)!O!U% zOck=nfBi1!-wYq91=G_K>V6A+)6&5-5$zXs6VYz|ZiV-2A4~;Hspn@KjsE(%$Kqhh z+(6xLhmU6Sr*S*Ov-axymnrJ|AMb};za8-Y^+Tv%8FjxCK44e~_0OR0o$$TpgiwWF z)aUOmc%NU{{_#+K|Jp5l5B9xJZPfi9_}tam_x>zW-@o_5KdKNySC6V6|MtO8$`nG2 zUK!^vV%~}vX>0IzkV0vE~4zs=Wns_tB1CukVbheJ!^-apGV$) zcHS6w{&*a|a*B5Jad2+kvwV8{P4QptH~SOtZ_@=)otn9n{Ym(1bpt7Acur-13jXDh zwv@P64(0xz7VU4+me#(>uAKi2{N$(rDmz!*pN0Q?+Mfp1HM|&i5$(qB9Q>YIT1F{#tYkx*ufBKh|Eo{igV@_M6wwRrvkqo3r;%8}q-q&HIP= z`ZcfrYw#@#G^eUVjP)nxjfkv{dVU_|^?x0HQ;%je)yG)>!ii|-Z@|ZV^rdI13}0QL z{WsxT`}xv|7V7K&7W@|Wx$}NijPVog7SXQ#x8dLX)RfXZbWvXaci=yM@*%H4b$?g* z={{84H>+~~d+=*(`_Pr>EXw{q{Pv_iv^tI9McqWStKS3o54)St(}S7x{KAQ7=O4mX z>)nKwCC_Nte)fCx`OBj`{~y6`snLW^horakPHF!zufNCe7cw@XKbNFc_D|rSp7N$7 z^U^5$r|?aOd(+L|Q|n&TO+>r;J%b;Y&zrO%sVu$RfAjwF9RBvz#O6B&yfPb5} zG3`iic+qYV?ehN#KX$tp)%8fBoc|?!Pfssu?vtFXJ~y7{$A8y9H=d6_|J-;M9k1XM z+-pRO=Q3~c{taG#{@;0&?_a)#cdgQhu4gvdFZwMacl`X1M|uB!1D|)fCtaJETzUN7 z!kpFX_@<$01=Isaeq6w!dXOiiThKm3pWBlAD7 zKjOK6@tnVS?!RS2v96E>qWwJb_8&!l7URAzd@&#YU)0crO9?-`9{axa^y>Lj!Iv!*LRGU{d%OCl zhJTwjgytNw_IC3p4ZOzkKe?*z)55=T4WUGd)W<&^eChJ+zSVAPZ`c3y@JD>v>lV3< z^%p6vf4lx?fNwWAgnHIi_Zi_`qS^PgH@>92{xiW(UB~J_(%65hqx~Yv?f)I?k3~mj z_zFits9iJb{ZIDW;aPNKfj@RAgtm7!_V37e>Sy*@;UC0=(6gv(-?V=0Vn z_PXw!$St&%>B+^rvo9kBt{<0&0W`-L1S)IRm{?vre{m`F2S6A4<{OMjklm7wt zA6Vq$F3x|}v+?KG&n&w0>*w0=9Yg)8;STHmN5b>S=g%_Ce-<5e;BOW5r=okUeH1*8 z+;4?v(NPz^PHKOu=&kPS!6(Y-PiLBc+x4S4e|`9jGyQ4dMRcP7Jo5fuLH}8Fc)+Ji)RvOXQ*VDm_(|OY$!n3dm-8P%eij{`@cEwxk#B!% z&-$UyA0FlLYXo1mQ!pLKrtZDqoijqH;B@u+H-?|ppS|y9l)CqZzjYv(yw{)ort1&$ z_&0&i?;A{sXP&Y2cJ=pxPmn*D#->yEP2qihYe!e=pVspSV*ZIJ=Qp?C7e2#_Aj(nr zR9yQbasQIXDAV}!*A2L5(Vay{Gx#yHgJ^8^lX0HyH;PH zx~;W0=jWd1=bq(?4SW8wh1bjI4-)vpbFmM8u+aqO4zH;zQ+59ne4k(Zsdg9Z`Z=-x z@F>s!4)6~~_>;?(`1eoQcZ4rI(w{EpwD$7+G4DU2@R#fR)0>&<>n9A}AF(&dN+$RPN|r zOE2d)??2t)E4K8f=;wPZyTI{XO9;*KJFmZ(4i1 z_VADEWK0O zzs&o`Q20}+f~ZXn!v`uHKZe2kH4h@cKv>44?+dt-YMzeEc5`KZD(W$&kYEfeQ5>13&x? zJO0g6uises5<}V$B~tglz(MJ8RPG<^ z{o8K*X28#$-iH2ZV(r;{a%b1WTX~evzkh@GN#IXcCaJIgnI?boiuL@n%RdXg-R?G& z;5+t@-{C8_XhT!ps;{5f@Kcwyrop4E*RNcE^Zq#peyL|`%9=$z|6KS{*;-R|_(-fD z5$)<11)p$(A061bNqPU92OqVr6*c;gx{rphe5fTQAFuA`!{2aeNfBq%{Q~$xUM;Bm zD0ROO-r2u7bzpee-;8}F6gio5F85Qnf zU4Og$tNus78vau9W|U@(_56|Zo7=wzK4Y0?2ytu>F7V{WX?e zuD^Nza>8ft)QqZ6UTx{^^6!GLR<{||E4fP9?}qPOqZze%w?g-U3hQqVd_}f@rSMv= zoPRI;X}14_M=VwL`{1*0^QF+Oi!Hrf{rAH^>g!91t1q(jk(hrx%Ezw*@GENh(t@8C zSbDqs2jQEg@ul01)NAuEah^TrsK0-JM{|Dmyrcg5KY#9# zwZm~9e*EZ$RG@79`77Z411#$P0(_%z5Ateh-G3+g&m;Hz{v-D+IxfQhv8Dl4I%}Oj z(lmbDFNJ5(aS7geyFO(ZVeQTR=Y9)3i;m0iXGYeeH|31+XaAlZ*7f&oh^U|c^WVe$ zVR#lDSKuf8U6($28}l#FX8p_gufk7FSCPMD&5mHgM? z#|*7aEr!Lv{^k5P;NLx{#Xk2*-QR>SU8)vMk1^K2O8alYPyVAOm7QTd|M<9x`%iNF zZ^PefSd*?^8>?LZJMgtW)u8Z2W0d_}`25Rj(5IkL%KjewvKBQc+u#w({yzMxk~Jvh z;^CIwiTd%#>-T@O-353Q*Y`K@5Q-E{0s)F9xNGt3xxuZtdvK=|ilsVFJ>Xrd4cMMqojl>Z5QjiN%ldeBzcKZUPziA21}R<_=${%7#Z zUbsZ61uc~QbNGgnU1Ia|=F0vB{JS_Vk#S@bW&aX>Pv-zJ|8-N%2U+%SYx~z?{>te3 z7ryAZl4AHsz5U%R^WQptX8#KQxo=4kuYHhm{jcGFsarzyYii&AFo*T~20nkW;^JzY z`pWtLgRh^yn5dkhwz7W<->GR)(bKoOt+)1{`TG6tfAsIAk0t*z?)x|H^N+gke@Bft z@_&06p9f&v_g{qn@&E7-Ul;gnGV=bw?>J5T+yOi5p7q|*bY#Y`UJqJ`*z(`FZvM~i zkN)q0!uWsOzQE$qkH`1@bB;XY22k$I=e2%Ux$pn8{KGlE)f;u0y&UIl*Y)$N5u>i# zndH9D_x;GIeO@l-_LTpXzSEz2Zi&$9m-BoZpPP(mo;Uowm+w2_*IoI(6Sn+coMHp0 z(n$UH*4S}=Bbt3?co{X%{m;HpkpXnStNwdy^5?buMwE}E)z6WyTby4;&GVqLKRbH> zZC`S$?)dq6gfzl_@W`@qkY z<6mjL{rCk*FXz)%j>V+kF2`TS02y7$;HT6YMCX6i`_Gy`44xx=uv-t|G19!8!;65ITn|mKkrCJ?emUOz&G0zLcK%Wxne&s@FM6mt-XU<;&UPjHQGV)IyNVPJav0cAmsGlQyp8xD+ zjQZSw#vKOGi1yK5&NprSBWmNvbyPuq8MXYWk$+ftKbqmK@Bi}WzSw`w`Ew$_j9UIQ z@QsfL)80JM-kjg;E5pmE`Lys=vi7B8e@9<`CYr`h6p&x{ZDaknPddueJS|;giPe2p`0+zJ(&6>`_1jv%{JT~^N3P%8|JmTj%v_qpNEylO=)7O49?@O}2Rq>Z@mLDp;3ZNvbcf7}l1_~nH^ys8DgJ8eII zWPfO$qjmi9!Pn>(MDvEL*PkEWYfE$LUP|2;fDdidoGy`l{oL-D+Fua9M{sirPp0k* z!4FT~g8Cg+pMO8X$GO&=4joc&e_{AJeVTrg=jX5d{2_Q;W4fJ2-@oKIYxBm4*8Vfk z|Dy0dPaD(HY|;B)7@ogzl#dfNe}2IAPe$$fR}4PEltz@?-~IW4&o8|H@cD)JfB95a ztABUAhSX-Cx-S9mv7ruAP^`p44C7$BpoG<=rJRjB?a z_vaV(oS!}CF9YAMLS>p+EBf^ZKb+q8*_dV8Y{;NDa-LHEiuPJKlSN=VKJ+D8`&+D%O{HJN< z>CGm4FYD1fM{E9y@K0)0q{UVA*Pl#zjdsN7E5Rr9tV~lzT(CXAa^1%MZ>_&Fe3vOz zX-ct++WfQTXD`Q5yM9(h`(@PHUj;tXom%vE-9@+gUGOq${wMf5feq-p1($4nn5qBR z^ZaAa^RFuW{BBLDlg|~m<8SrV;8XW)LGfB$p+LQzTECn6Aprj#&=mE{sMTK`K0$a8 zEoq^DZjG#0^G1}9^F{x2{XBoT{u=OWUo@pgX|K7h-#UM4!YBLKm^%1fciVqfUkkos z>&A3*qW-yIrgj_s@J0RR`Cl7;U)_e(VDYV}{Bpi%&tEvoe$YHeo&^9Zey*SMbN%(< z_b;hUhbKO?^|C)>tiJ*LyCXGd%aX^o-YI`W_|QM9(uYG&-CjScp?(>)`WwM7e^`k& zis!cZ&Gi%dUq-F}8^a$ST7ibgeW`g_?=~JcBU(N8AA9bL+^!)PY4X4HHXg^2xk7fU}m(kS{{<~}Csb`Al z`oA`REBJ9sD$s~l(fN7&xeksY$j?#8{QP^TG6u-#Y7M`&NCo=X-rmc{(Z-)6d;Yyk z_A(}bd ziq8PE>xY{~3N{KB5e>KG=G5``L5*IX}|6cI*y4Rpw)7{UXQt&crzBl~jg>`6@OWpT@U*}ba zI)A5oIbO!N8Byzh9!Jj4^M~{E{OJqdrF?B_+(g|6!yhYGpW22*ufLe)zqS3p!4KZh zkoKlj_x+6a*JwaPrn%ogtnKd)-}Y5KYVWCgr}<~Ce*pZm{takvI{W?ziEGS>V4V$ z_{(+w#r`uG{(Rrol%c2n`ZL#W^+Vvd%xO!F3fu2LA!t8Gs~-v<*|7tCEdNP){~HGH zH@YKrxTfxh!^ffaR3e^-;BgAG?4M5ckAQFbp$)BTtNT#P`jw9tHGjDM=KXgh{IW`| zDdle6%Y55-{Tb2f&DW1n@Qd@dq9#Ab(&{&y5uN;K_+d9%(97hWnh#Z|e+>MDc`fKr zgzk;JMs&(Q7Jf{kmNa>!{(UEgGoq6p2mf$zOX{9l|GpK&8PUm)htHCuCEcH@?th10 z_Be>z^oe6Tf2{fW{4M8!cK)6KKRjLwy6vHV-;7bW5v|@l{uALdZEs2YLUb>GUYkFr z_{ID)=br>W(z6Zaf1sX!GJMeNwluvp-hN#Ag4P3O~O{ zTT0m5{`-E|@w&G2(@Z`^9{u}<2M8T$m0$a zyjcIfBo+S${Khk#=*K$lzpsk-AM^OngdZQ?iFRkvzb{MHYt(JT0PKs}{%!WN;CILC zM8_`Kd)Xe%bF}XNv*ByB?Le7}=->CH(*8f;&wtmB7GKc4wSK4kbKnOLZ9_Smx&OX0 zYyZtP+Ar5n-sAS(DSs$@aNSl^@RROU+CR_mlbch`PVT?2&07C_`1GF})1Vi+SINHs zzG9<>bTp5b^8U9F{_x0pl(C4qUj%=rQ*GMZUEME+FPW?+1su@5O8ftU4=Pig2HaQA zzXbkcifZ&@I&a};bN&dE>jwWGz|UWJ{qge`8C^@^_gAe-JA3Ni_vci<_58UEzQ&WE zXwgJ(ab5pCD`VXoG3xiP3Lw9XTK?tm5tFKt*KYgo8J*Si|Gr13@w4Xt8@^Dh8dSGhGPmvL&t2yJmr<*KE&SsX)v4gG_TM*Y z9>22iGHQMue8)A_XxwFWzaG9*zH0O)d2((3+qK`A|82p1b)hPC%c}0Tz)x;ejhcS6pFgrcqSinE{x-Lte}9|XzZJeu=^8ZTk^T6yH~POk zyo{Qc8;th;d5L_r=*7%rw)>wPPi_C>SRd_|QEUHp_|a4A(7(cce*XPyuAhJZn(N;I zUpcZKrR-$yIWO1Gkv*>;_A zp7Osv85&c%8R~vFe7B>GX<-lD8{gAuL~DL?|LuXVU7-m*Os$@OFMRu4O^G7){olxI zM5p}w;MavVr5Z2P{eJkC#hTHaxa#dc0PlOO8P#nN-G1}yH|F}YV*bde&7Xtt35PVN z;nUscx2~T<@J%ZO(c7cZ`Q?0#di~yxTN0yC*X&? z4WjV}?dM-0_79HM{3qePer-nipXujEqu-5a?LTw>pMs}JO=#*b>i#sm>q29?{Mi2a zgEhZ-{La8vY1)`(hN=5-_yyq&X~`bl8|^ltHNUz2XAS>j11g%{{`_tA=K3SxFP^AN zb84#h-#Pe$Giy=$xc1|3&2O&%JbaR2)oDXI_4RuJKIi^wwEdI1zX<=|^`B_UP4)G2 z2|hAUCCU`ytDT>XaWkS*`!B=4nqQGJKC}P6cB?m!-xc^+m&#MzCHnWxb6$DgFKI-x z=lj37|M~te8C_T5w-zi%!?vfkeg10p*6aT@_(T26kZ<3#ZrjhE^Yi(E^IwPGzNj>v zkDpFC{|)${KT6S}(CGYra{uS{b2QiA0QqIq^52x6|9q>zC2cJEU(|i0xKGr$Z?yeR z{k~D-ep2JU(W0F6|M1TT`Pe+S8~ELc%V{2`%qm(gJF;WU8t<@cVWq$M`=X7pCjkz-+Pi#`@Ns<;RoF*AO?N>&9?m$;5l0R zF9H0~PX$DHaow-6jGwjt&LY2zu7vPA?iUcB>)Cs2e)IfE1mAr}0r6^$x=##0b729I zvbx@X*81h&wfW1@+J8y@N1qgaQfL8jvax-Br}6iKPdh`dpXKWF#~VK5Dw%(ty7z&f zdbohtHBt9+ytVafMC=K52>Kb~DcOwXWyUW<{}6l2`~Qo{G?SU`*^WWWE) z$BEIWf*+hq&i|#lSE>I8`0Cg4i%RkJ>yN2!V;p15pBlc{p!{O(E_I&9>4_k(}(U0#v4w7s{s-#q{Q;ZN_%Bl7>O-v1fl``61OmSFy<%)dOMF8)|)v*>*n_LTk~`O zaef(HdEh?`${~sjRL`FmevDrZ@%LDDpAY`wvFzgTBz2!3-fuv5F{zPy`wPI=Dw|y_ zjIDb)&f30j#1PZ|$>V44zk=|){j!U+zV_#DtLOcP`(H*^A^5>{vWr+d?a!|hke?&x zH_zW6;Xhr=CX%OH81=8R&Q>95%{{TvWnRA-Jd_L{m0K=`T4`e zfUF|P+`ewFKUQB1e)N_sqS`QZUmSjDnk?c_QQh|%QU#_#*^`0@Kby#JJh-~1+%s58&roBN+V?;q@W|BxG#)__tx>VdUN|r!Wo!uQ#f zUc8w7tL^wZ)n5+2q*r>;{fxRV55IeII`L?qy_fx|T|YVU{JDbpBV*KkpZ80p6UA?I zx2-<}o+Eqn_*F#ypBttVMGNX)&UbD7nWC0o{$2Ct@v8*CY-l>M*Sm-9{9%XJh5kQZ z8NOHg^didu`}RBae--$6Su=+1V&efT|b(um|O)USUH;2S;oL7cwW$9DaOp#L~>|MB@tM(zC7 z5PoJvDlyN){rQExdHyzn@3A1I$egyH^8VEre!-3u;^#l?U;pZc`Z-$bZvwxtehRU< zf`0y#^W>}7UsL$Ry;6wj@6~-X_%};ah+c2)y>j|@cJQGclZmn&?O#8&_P=@j z+QWZLkxXnk=KlGMwf+w9DF*n6Dr5BZEAwgV$A}ZK{y4HX&%ciF({6Z+tJ{NZ*T2=9 z>+d8z|2eweOEm7Q?mJ7%^Y4Lt&%SlF=;tqA`~0H|eD*6zMb_&2{%f?`6t(M*{JYkE zbNyZ6Q!Gd-c5PGN|9^%*JTa;0yh#1}-wmFICl#qS+FyUI{cj$>U*J#Y@)9fR+WQcU zKS%5S+g*D8lPkWL@JiE7dHj1w%j36lu$TD0%g@UGSNPvkdy6e~b#EFsV;;viem&vu ze&-{)?(3?YzZZPP`pJaK_;#6-i@uxNEBoK1=kc%gD7iRyp`Ehthy16S$o+qq zeSV&|-2WV{`&WPXi8GRk>6Puh)A$WQ{mqUg6Hot9uYVwXi?zu_u59-G@033TKEt|X zB1>HT^X}!(Z{z*Xh}Q8pum3^P^B>pL($(KQ@?UJYO2UDtm94uR*$_3ww5(KP}-d`NPUeV6_77biaw zzC-%t;=(}t>yNd5bNfe0&wtiuOeP-v^>xob%b;>&H&@kB6_F z&093b^ABtNR&O5v-{BJmdx;J{`uWxB<=?-Uf9Copz$cKubC@!h{rlHeZyvvi@L{98 z#Mrv_@4s2=H|L)uJ^yKZ&`T_uY5)GSQ~t@)^86|M*h_fh{lhSfzY&AbevUl;JFtFa zbWP#p@=v>yUgEo{`uopo;Efmp&(XU6rs~{dX<09^Z-V>xKdtk3n)F-|SIRasCf=KLfs8UO9ilbRTBvKW?}A`ez=$KcweB-a%es_%ZwZ^6@m! zk?S|_zcY32F)OZ@s8meyQc?Pl?n5o>U;aJD`9B+ePunCSEcYnw`k~_g zl%B`0Ps7AwcrA552fp<9M51tQbw3xr`tyXM+Ftechf2?X<^&}aS-0ulnD<7s_MdtE z&(pcb-v7QA8F$-{pVgbkf4=nGfB6^27XelE_J>*KpOaqzpXQHvqRs&I{#yv2qeomZ zHc&nPBKUvH#}NY_s<(eJ{N>W$iJph;z3h)K*3T2{Uou90U-aS@u|?0;_TH)gmLUJU zb)I4bzVAw<|Chp-PU9(J_fpTl41RoQEYYT?x?c{TwOcHaB6uVP+T6Fw?dN~zSQq<` zjN18c1^kYtvBcB?BPq=0zEgJm?;MlE%c%L4@bxOh5(zKc=MO`Ej(p!7k00MR$K$sO zzU^lZK~qOX)z9yr%AeQXN9DXm{l3UAqn3X)eAh!B;_kj^FZb)H`)zt z=vo6GIo(6}CK|2nf1KCs<=>;`AOGGu*U!JV&h`Hd|FMUMSQf|LbAI`FTK}=<{OmdZ zTKF3OeWr1-)%`m7{X0I9e>`=+9=_K4k2L#!^!hjVzq$RdskUljc(qvkil?|%D%UhIm_Z|;Aq=l)~Q{r3-iRq=s>tK0i9)A(8QZ-UQN z?mgZA&wl+m`OWYNett)jm#h0N@Y&jD zqcK(Ny;J_}@P7upr`AX9e}B*^{|@*DE8f${z54l6{`?o~&nf>-_>(z5(1K6;`B}w> z!LMoZfmTk^&+jUJ7kqHS57h1#{rQ86-wog9ulMwRtN#2&#qWW?l>9x_8E^mlN1>+u zhv&a}{p^KLx9S~Li><%@u9ANr{F3kAQI_5M>*wr4u>W$D=O}Ie*g zmg|Q#|7-N0jII;#C3Cza@tgko?@5LEa}wS!`*RvNsDpO>SMjId-%Wc;Q*N}iJwI6M zH~0T(_=FRm(4x1kG_TVBGw{Ci9@B>YEp79Mn%2K{{)fW{W_m-=}>|BLW< z7GI~tFZA~xRQx6QDoL)=ciDeYuKzN8v&)yMLJs}+=dAgi`tJ(-zS5Uy{sn#iwtA=b zUxiOS{{pQ%>Hhj>oxj)M-`zh)^(X7s|Ld0h!VE)V?#KyBpSlSJ+B|>f{QU168{qsSqjvsz2;aW-3A)y-p0a-gKj7YR zYLTI~R{wQ}^<#bh^ceniw&V2ugc_PZ32#Jm``PpLPe!f&C-5KZ9wYykRo(WV_5Au2 ze(aK?wED-NqP%>)LVNztk^4=ahqV4nf&4OR`JchJOmu|C_l@?lzctU%?5+L(9KLeV z!&IbNw3qp!UVkuqYx`fo_bGdbM$M?A+ z+B3Pjt+%${JpcZK_b$JS1|`t@kJ}&9_}9n$kx`pJZ{d^qhtZp5_Vd@ApI`ss{QUZl zjIMY8qkk`bEcu^t-@kF6zj5DxpD^6_kIw@z?)xt$&Hv?}5AwnJY|~&^yttg_+3n*y z)*sri<8!4HVXX`0|MvU-@p#64|IY@lq&dqbY2*Ga_x*pX=RW5@hy7R5xGod5{Kk4S zMQz{V`OEjs^85ZWYWF?xHG}_~S#~9T-{p5@9~(YNm6dd*$vDl2VBH##^U8Ioz3yne zZ}&U+j_p@cw&7!x^T&bDdu1ivU8=wCDD!=>?^yGj+s~7N+u!f$N-F2Ao&T{TK`hL{Yl_w3|U3-E~)#Z@N?U*qN|J4 zy%&6vhO1~^UiYt?bN}&uC%k_7z7ucwp24fgJB|AM^MOCSWEHKNsa}6F`2KrW(aceL ze(U)0xbynwXdVCL@YH`51)Nb|f4=Yu)2yN9dP)a zpGW&&yWc;o`Ln{mpBzf{N9bN9e>V6hFXvL03F`T?!(Yumm!9=i&z}Q6cjGy<^mlci z6MkB^KdIY$_4;$ckA6Ozl2ni0e|i52#XcmXw*PRfh5bWDZU4v(zqP?^y1FphW8cvB z5wqvdo96w8KX01%pFHsWhs~l+OWe;NtIrGHY}-t#AEur^AAId+f6&qK>OMbwqFR5@ zyjJSI0DQ;KGbl%A_4XHp|9!&@N|M7qf0*g|!TrbQ5AJ_He-wh>?)rnaC$!IR9lvex zGP-_*zgv9Px_vEIWxpDysXE@MX(Qq}1=+ zUq7t*<;I}3e_Xu@6qM2Z^~>sA@S`gHPE}f}dwJl|^52a&p8Rh|pP$U<7pM6r;63Av zqp*1Huiw`C1L1=bjHTW1Ar9v!_U83d3ch`YG1PpU{rStO{?hP`ZjYkco%HjMHNTTD z1JA!Rmw1-@^OLpxW#PRKj3A#s)O|Vll81)Vfgt_$mr(SdDMnp?toh5sXHGesx_{8U zwf*vOzVPP$uK-WWhtbJL_CCzAf11~CMfi_?!)Zj<$t16v{5r`t>-7)+u6^GF`NiLCD($Zhf75>g zRcrr;a{twUPgi$5^~*j}x&E5)!{Uu2m&YvI{MP>G`OD)cqpKGD#>!*qSclol`D?@X zyE>Zk1KJE7)5o9h1%BdH2>Tr&xAvcT z{?>IQISNAR9&xZw5;4Z!WoLBajmLD-HKfiv*^~y4V@A_ew?2@N3-Y8 z-QxOX)O=g`())YSyV?5uGn^5fd^`A;NqbSrH}2=JHGg~fk)MC12JNHk4@CVO&H3w~ zei^m;JHW5W(1YTiQXjvL@Q*8XqXdW5$FCE7Esri#sQTKd^%qnBTjx(__>#FgQT~qW zlzkWYvqwA9!@%{*zAJo+ogHa>nGMSRXZRyUJJHO8x(`)YKi%NpFYZKT%f`UQUG{LU0FvF=s!cZXj!qAL~bZQuUuSbrRO{LJ}#z^9VG^R>5| zefwp5wE8(({jcz20)M4$N$hlPH>O*UmeckvUftS(M3x3n8ew65( zKL0{3``-9<2w;4o*&#oou{=f4B*U$gXk@sKjfA-w}zroj=KA1|4vG?46 z>^ZVG=kI6aPcWEPR@J@CvyJx;BU(N8Kj-KE?+@Rx!yrog`fu(069jKW_I?<@GBW=b z>17O%(KP^mXokVmAlcXLUx%fa^B_P**FgAO69-f3hF>@SW*-8-cIRNq>sqhXA8Kj8 z{JT~^NB+Jw_WXTooPQAfhn~ZzRDiyIf^6Dv%wN9#aQkJ{+CLaR{mK#4^|<@}gFWYG z&-sVIH&{H9DqsIc+rRAU=lop1)enU~?>U+>#NTY|!=y9Ue-Zg*jJoeX;o#8}a838} z=e7A`M9yo@Z}!8HKYO)NwE3s4w)w5z-2M^plf6fhcZzMwekA<<6eDQO2YWBu5o7yD z!Ix`2ocadu(DH|%{YJFbzZv}}qiZyL$_2y76}~g7{y?lh#HjwOBgg-c^fCs>=o$l` zqR}w&Z@f$Mvfdc`pZCuT()0R}(KQynf4gC{>Yv?i>u0|SUPjkA_+~SPQHSh%ZN01~ zs{hy@gqP7Z9=<@bVN^bF-&fUt9$rS*@9^C#4yCj44=CrK0KYN&P#W6gpyuUxY5iwJ zYyIZ@6XEBc9!hn39J0+XA17-3xc&d2ei>bp;HPaFMo9)8w)NKh2jFFNO@`k+U^w|~ zI->a?)Ne$qH|L)M9~3g2Mr}K)dHM5>^T*u&sqhbO4x`uSj@i~9>d^ja@c#`PMj=^F zXkPyO7yWPb=JrpA|5e^I7QFhTt(Wc5`ky2B|2g!ZjIJ5*L$(g5o_?pls{W1eGP?eN zzfgVzm8g2g)?4%MhnLYc6MjIXeEslc_*d00e_vBuzcRXJ!N)E=oKm%nQ1-LoT?L0x z=S=5py|w?%_5TTfsB%HO{)S-ujmY`^aQ))z?*`d^ zzW&PSnhXDD^5_1rm(ev3 z{!;q>^!bNNQTb)PQLlfP^YizWa(@24QqDggzL>mcDrLdTnh$eWe}$#z{*zJrz1;=y zeeU<9YO{17V(CBmcv178J&zxIo_`DBZ z!#6nIiMqGFqTK$!;60jkAlDq-hgjMlY8roTKleYkpZk9ae9Kww=xMsEQR64)OVsNZ zPJStTs={q)?_%A{pZ{Y1gjxFEJbugI@Ahm%(_g6PUk<--LmMhy|5{Z2G0i{zzC&(5 ze_tfGe+7J)Ut5a3A=<~(e*V2>_WXOx>{r6?uiKWISGXRP-|WrpXV2@0J+Gft@XZpm zrFiFbZ|y(%_o(%2^{e4s@!HbcUN>y>TfMpdHSkGdx20>JbZ^ZcW*R@v&*R7S%NTXv z|9~uQ>2&p*TK*u1^~2tre=YL&FV==)t=7Ft{&nyvR<@${ZEtD$Wxd+`GopOFFZ$11 z|9bc>+gnnS2;HmX-vHkuX)CIg_qLW_#cwq7Cuv2q3+g^dq5uAYzcRfg70G6w-`alj z{M!VdrfCam03U++{#B+lWqn z2mHq}?P*EtuUo(7_V0v${9gxp(NEt$!raV%bN`3IpKa2K4(HPMKUuG~eoXO;^}M!!w)FlnKqPhzyGs0w|@_O-m;yk{6P2DKdavhpJz>HdYVJs z?}KkMxHF}$rSA8`#~#s{lGoI|so#xp_@e*K^Y;L}$3LBE`3Lp<2jLIr>OzSJ>;11X ze-6QaqAnE6SD!yYZuT$p_#K9C+oKDKvFh{x2>hz>&Xlmf{rZ#b(fW@gkH5M9j>4}k zB;P-%sqT-#Z@Si*3K!Drch`U6*nebn9fu!Qw==Cs`gQBiT>lC9x_vs)%|rV6Gt|xc zHT#qBx3;vWS$XyIyNW*r|6pocTAknh^9O7HpN22LTAtr(Ua-A>%6ej)|7YL>7qzDP zJM`yYD*Yc0zkFXy8hz6K`I}Szv+xNn1ktu}di^2je#5`5kIG3UPopRi+fnv?Ff_WpsaSF7I?quxKrD%U^fmr*-^UxqIoyBf96 zbWfXqAr9lm_kC`VUPkTwe+9nA)hhJl_XnB}bLc7}y20pI9(8A{&cxw5|rA6CCKUAp~P+24YHIl2^W-u+P7 z--bW>I*^k8tB;?`_}_uQ)l^XC(~-*g@0xt7wDw-kCvE@Z$n%HiFV7ztUH9NSR}hqA z(_P#APCgR;%I`#R7wPABmG<95)0RQf(i&kvZ_Yal)58?Y{cG1Vl z?$1A*-@JYw!7r~LKzFmbfBnW<|6};8qf64IU)=A%*8ET4=lxxh;x|g(L8vkeT_4XH|+@sXrbfV`eF9`xf{HH%c$+&ui$%TDJbt> zwx9p<@wD~Jkv-2p_A>NKeAN-&zIcfO}_t#%*``^Ns z7?p!E*VF5l{iR)hjc9GZx&Pk%kN&;%vE+ZoegDRN{>FX(BX{Zd{TrVLVBGg#T$=yO zKOf|S^Vw!okY8NRGcxyESHp43=;Wb{Vb3ZLAy58Chd1LJ=QqaN6r-+N{Js-^UXP60=e=?J`M)7+ zJw@YAd9?aX&X_+j`q=P=mU@Z;t#T{-@8FLw_Z0p5=hD2#a(&(!F$C+DqqY7x@UEkt zqVoHk%K3RxaQpqvdWsGC)$_-LZ?@A@luxO9YyVm6=lj;U|M|YP`0%&FJ;l7)di_Sb zjcE1e@%tYBV(Qr9a$fcJCxFjWFt)hxZw}@DO9-Dndu-9-le$j?|KNkC$oGSK{fXgs zT=Nvq`m6gS@IiMx#rMCc_kU7&-}9d0Qd@g3=ffB4C+QG<{AF}`!5=*0DL!nq_fF&Q zZSwEoWjh{u^TY zylHd$`TN4T{rr95GP-_%zr8n>$ev!`|BbvxH0S5{joI`2#_UtWmuwhIEbs6B`eF5H z;Cr3+5IMHy6@mKi*BSH9hynQbfI7%8qn1A{yl;?)xRyGf^8S+!{$3pUdEL!)Z?xNp z=KkaBhk5;_hhOFQnOe_P&z}K)PT(iHzr{Ykx&N)#FF*MGxj)jRN$TDoe$40(^s110 z{Tbm)Zhud4x4WM|*7`HS=Slyb?&Nkqf2=+;e6fb_D90A{^^*lYQ`5KP+cJ9n$a5I~ zzI@dD<8v9$18e@Q@WbM~rKttg^Jjxk-TprsUPRqzhu^p24aIiZd#CxE1Ac<{8@g3X z-RFc))8sXE?P>3w=5H?e9{XQW{%N{5^}E~t&kaAM{3~)DSND0~%T4*0io90$dExWy zd`U->sn6eh@B<#dpoaeHK0kb9^%wLerMfQw@AL3Eb$~baJtI1eUqSdHSDw@Km+Jjj z2!2oR7qoDfy8jVA_U`ADKa+a<3&YoK^o-JcukMS$&u{XSZp7BT(Qig{>c67!HQGO= zdI!|oUkrZcwkK4;OTB)6{>;x`ymmdN-X-kom+LXWy#JZ6eZTlM)vi~e$?`F> z-_YznRXVHQetBTg{L0>uH1?i){y=!IY4<4qE%p4R;Da~br5gFv&kv>H>&?7F{v*|W z8Th<&Z`0-V>b@*|yNC4jk$V1W@VRb2rhqr< zzB>G?#*gWfC}`V%Jnk{=zct`rZhT1NgLSXce>LIT?|eW-mZ|$%@D)owpi8L=DbN4f z@Nx6przSgfZ_FDbI<>!!QU4E-RI<*G%K7WU`}Dd;-|bZQ_28>yzDL-wz^e>dA*%8;{&a{Ue9z2@Ae)z{U1L->dnH>tteqFR1gr?&4HG0Zam%&$K-g3prb z2DNEaOu7EX@PWs!(ZHv=55()YM&y3u`OndM{ci%_sKGS~>{VPje^dB+cdk+Sqq;Zd zoe=|(pCjitx4#+u)@s)&>qXtmI={OAn#14nx=wFPl~Arf2!7_dtMq!Mx^DsB>&z8; zI!*URyNwuz_H(rMe@pl~-LFuIvFg4Re3b!L==Boy`dh<4_PIhU)~e@k1E1;MB`Wx* zeSSHfU(CPbI6unhY71Y@`x5m_XP@8dpTf)NY6rjZ{6$)rU-yA-=D!zS|CQ0z9=_3E z7b$&5`}*ZLYV~vE@iY4l@XJ43po@dl>+c9(H~s~hveDjK=Z`smC-_L8^As;jNp1cc z^UjD)zBByD#pmc@Z{5qE*VdmALoDNW0{t(es|$SU6z9ozu?pld_b^LK-<)!+iX9jJSw-;5~xK^uRL*75%ZKKRK6TG&wcfeQ1lJACW| z7pcuN`}t?hFXz4X{7Xhx52OCGmng?R-Mj05^ZNVM$S;5AxA8>v{5|2X+_*|>%i7Oh zS&!C#9J&9@_4k5LcJDeBx?_L+u(sbk|9ivlIChiL4*t69hk5?>fzLklCT&cnp1&`A zoP0NF!fpHOx3&G|{K4=gX>V5$H@}S$~vqwLF$@XgbjVSB* zBEPx+2EwP>dYfk7)VU)_M74t?Kk@&@S$xVQlUphgnZwMUuXaSJpMg^-@jtd?_bI28VX-+ z{v#@!&VK%IyN&ZBzyHKuM$Hd{Z>+KO6YT@>{sCfC z`{nyqT7DU|{3GDAjCnveS44YRZ;bChnEP)e{OD=-Y3@pOKMH=$=SW)dS>2C@U*d|S z&1Ap+<#ig$-_|OcIbfmhv{~f+l#e3BLlf9Sy5H)|T>vsbDrIPn(Zx8$Hm$m=Q`^QB1JqPYl z_ziVG2|m>ykraUQhs>vqpAoI~o5yc5{J8x0spvcP^UoCcSq1OYxn=>j=SORP^Zq{- zzVX3GI(1a{M%||P#r!qZ43-a&D zg>5yidq(7T^S>MIe~R@lqiZ&Nw<-6jMzHQ>d$*bQPpdbdAOD1}nl+L(Bq*hve-3=D zg7;`#4|P8mK1<)b)b^FVm+gsh{6gVh*1bay^Oe@>ch`RN{Fw*um*N&RnWcN#Ut0ee z(VE}v=fj64yg~6Ym9fol_2%`n0De>8HCjF*+M9oWMb@FUpCe!YIX_?jWsJJ-e^2Wx zRDOl-jd^24vzOQHZJeL4-!ews_djywgqP=&je+m5J*8Eog6!~RztwsKvea_OJKh^y@_*?74Y3C!|2Rgj|V6A^W{KmI-w2;1RXE-KQTH-mjQc0oZ+`yp4}9Fe&rsch>V6Y^p2w%@ zd=C5it>eeM4Evo%)YI_k>@6=g&Ri-+z{cYVV(i4Ln1mr|90;H;ia* zKl>!I{p@9QZHGTxD4e>sazFp9eh2)>{o!=(boBb=c5^>k+us}Y%c#}A6TWeavvho{ z?w#7t_uX>)Wz>8a{DQS-sp?hx{Z~Gow*EO<{Vw?PSI*MSM)v!sY=`DKvgiKe{M>)L z;eWexmSSblz09M{A0t}5x&A%y%Ql~-w$t?MkKv5y_<<3W{!jPk2W$QV@FhA&(8lTN{vdqTaS`%+pLB2Zn-QJ*?+|>t zZ4oqTfqj1YI5Ezj!|T`v~%0XYZ}`o5$}ceEf$Il6zZ39hcAcfqpWHuxvF1MsA5t!yM#r;%{v_L>)z6VVuV2p3>-Q9V;{<1@ za$o)VoBX*i+HdubQNN6?)9|&2pQg0C-9LY{=05}9_SPv{`-|?a`9mD~KO8>G{gafk zow`43wEx@*YBtc`Tib6QzX*7rw#RAdVBO1lwf-}r)tl$fIryp*j?x%kz5fkoL??e9 z{@&5U)FGEX{_Fzv>#i2fzCPx!jN1IY0DrF7VM;P5dj7EI`ODGjdH%5H`EwDzZ0bXl z-{t=KEAM~odH-d92|l&|0s6Sg{`sppKYN~k?0NoOhCecWKm8Lgdi{H#{T!{HKewH| zjIJy2izn`*BLlzg`j;5>%NTXvf4?bvseBjv^GAqj{&M|~kY7gEHRLZebq}q2p`V`u z9nQb(&H1mx=Zm|C5)`haoquI}V_d)1{5RnLuCklLQtJ6t{7v{yVY?_x^62vq`rW7_ zK>mFzkApS;E%^P(c2TJpUpIdIxzF-(w9lQs4c~WG7(ENpy|M2ak@K4KC&Kv2=(+=+ zDs>nQ@B4MvKXd-O@HZyzB=5stH-F9Je-D0Dz)sp+LfuEg&;GQ7c4pGopUV8X58ryi z4w}Bue*X`#%wM@~qSns?_+CHnpzPK4{m z{rm4+zj^&Wh3|1^8x6Urzy5B`Z>`@vf1bfV-@TPKdZ_1r4nMiiR*HOUpP$>!>&LGB zFW`&6*+Rvy*n4aJ=J9(8UvttHTC!NZ|Nn*mVZ~;8dc%JHSo53v{}ueD)SIbg8T;4Y zt=`=Kui1;Cr!zM0=YH1DJR_;J6R``?`ZKlrD&HqgR3U)O);{p&4! z)#e*$#Ta|<)c$w>qkk`bEcu^t-@kF6zj5FHjNSTu|HkJ5;J*KY`K9^4{PRIRIG=6K zN5+oJc{W%0&sAoJw+NY&Hf+w}8Q*;0zwvm+eg9bt#TIw>)zYrp-*Vsow|ee#{?qfG zr&yC#&u{G4Ml_E*zwgNBHW{^Zo2Rt=-{6y;qDqRITK$GIqLYsee`klMn3%GLvi}ag zoAizHSGV=%b;I@ZzQgs)=!ygHbJJ4{`m>s?cdDN!1-HLTr0l;4bsrD@<^fMpcB8tF z4`2C`r)Zr`_kj-QM(g-}4_{i|_n&cfRps_4fRB?ew#eE?-6w=Elqt3-(oNkbf)9P` zDcX;;_fF%V82-ZrPciyGd+#*k zd}Vpxd-ja>-l_k5;IC}<6f+a6`(#G_|H#h`m}>8x`ae1Rwt4b%J1W|*e<$w?zjU~# z=zCG!r+_bB*Hb*|tG<7wgx`|PQxx%1-#=5qk3AVn{5)FS{{Ua8dn|GCoV|A%|J3k- zabk%#Mbxh!Y2Z%=dx*n5)qPrcIgVoW1$CbezGb?Mc(>qTo?l1Pb@}iVZSF-D2Dbs)n5d@nEzv%@eRHxd`Py( z6!N2b{l(x*{`QDI4p8^S;rkDMNSFUn_a)#T?0G&%R@cSa})7zWsUcMlr&Ho2J z_o=Oi{q@Uf{9N#tJR-?EuDU1qgm>=J?60`~TK6A$;Lz%?^6(Bl9i^T>5I*$rZF)3X z-Ip@_%Ue|Ts=6-?zvJ9ZYEi6C)cMK0|2pj-W#Ho;zCrUl+Iy$*D+`}u*LAAZQ1>$5 zHqLKEt3QV8w~VfG@HO^dqwy=$^OuL8l-&Gpw^t=Er= z@V|AwM)SWReAsc?0G8Yr_|cxI;B|*?Xt_b>KUlxJ};G8!G3o3%{x5Z8~|< z-aF;52S51LEgC(jk#hd}@WbQWqDnOyYhGpi8o-ZSaf33v*S!Z`|1+Y~`fUjBo9H^N zI@3fserOe($0=yl?nrx;Dx&n&)WyRQ2|^L;kiuoTJUl)qQ*T zxJM#rP7LEO=b?6f;ApMC1AMEh5wzk0tly|;soy+*eufW8 z96@`Vs^{+pKdoB?J!-D*e}TU#@B4_G%icTne|PwC^1hQjXY9w%x_|PWk)8Uz~lN^4GTaPWcDG&l+`uvRrU~{<8M}K=@Zl zZc?Gg>OKVi&IHZdH)#%KWU--+<=<)`K|rOzxT@Pmw#`0FnqV{k@TXE z?n4yzzaj90tKO&7!Rq;k!arX1fcz(``(g0ClFR${N7{R9|0Tu#C1ccm|1bWP^*^xp zPW?9m`B&|Wq~#aY{Yd!8hxh2ve%)Kg-y^!D@L>doUn8op4(T}ofV z-aGZ*82IIv@6y$F>V7QzO!>KMdnT#-aqtPt-=o7X)ctt)S*h>Q(D&;8cX;30cPaOr zuiO93<2M0*RmHoMI=TJ+?KFN9;r--yO+6iM@14eP5`34CdlWaZ{q@T!|77?Y=_Bdl z6m>rZer={mYU5#l{dTHDgSi%k-6pP zCTzC%PW?9nzDk|@w5WQ^uR8yl=g%MTYcoHfxcltAQ~sIo^K(6*_AOf3=6CY5;M2^$ zPtAQ>+j^(|n+?BvMkED}QTKns_b7Ic&L(Q3oPQ4d_7Zog_#|~d7e02^J5)1$Tjl(r z@Ov`eCa?DP-l_lR!C!rNgH~U*_fGvkA3pJ^YxI4mc3S-^*PjLOldoQ(na_3a;pY5i zzWywPA9mpqHP6;Qs{cap`x_k1^*@pKeewL4QM>PT5q$gC7ifF8Xm370nmxb%&R#~% zFNV+3LC`uVQuv%j&eEZ|x_25s&Tsb1;2%#4rx|b5^Dl?@8y!vy zOLufTf2{dez;F6JoIXy`y>{|%oi)Art}|JT7U&VHJ*Way$? z|9bct^G;EP!s>nleAO|h$iJ?=cWVDe_(qLR(V$=Ly;J-Dfq(qsB(>?N?l-~j$a0c; zbW-=5;p+`OL8H5>`z`Pto1dT=4b=Ts_+gh%(1vvO-l_lPMytJlzPr>(I`u?-{%wap zDeoJdxxn5#<=+7xQSTI$%3$xE#(yXL1n#1Lw*0+1%D*}Y05EA zegE7I|69J(l&`J2-vi$x;c41?TK)R57yf;@)0C!zy59$Xse}C7jBmJp?uW0s?ld*o zWqT-_}97Q^<$sCm)CRc{J@c~pEYs)m(g{|X#X!~=;{`G?^OR` z`0cyTP}X(o{eJ}BS6=^$+*0>P;nPUJW}3P`2LE8m8EUy+z5U1GYd1SXHLAHkzjFVZ z&u=H-$IH(>xg6>K`GfWRa}wUG?kVc}N`L+%$5}gn8qvCcna@9`;2Zm&q$9oDKYz03 zKMntJzzGt^TWRlq8hMS#`2%r&t%38SjN1A04E&u}$7y3F{rRJuZ(9APsLfybckTTv z?mvG0k^t}4XZ0808~uEM z!dJVWe^!4H{+~|!X=7^l&mXP+5`3#+dntIJ{rYig|7G~#quQhkKqs2-%5MNxPSfFI(|>!2S3|Fb(5<5r|_@- z-a_H~>|g(OYX39%(+f9~>%6@W#QNvR_4DgbJbwK8({uPWtu|BNtM=Y0{|oqx-*2WB z$JPBy_?w}ds753E{tL0}U*`GuFZ|#G|4@r5_VdTdzk>g@@jv99#{Tthr}n>wPxxvh zJ!@^B-^ss$kGEh06`f|^ekcDQ{EM;c=|v2`f8*5txA2}h)|2lK_W3^>Sn@yPzJKFBf8)OYC42Py{*BKAFz)*=AkF{fpAYiE`E2vwq5g3>&&Y+I zV&vhZqEH?Gur32eeDi((#^V|H{nzR5FII%;_q~40egEI;xzG7e&Eo!IP+UE~oG07( z+-XGfyyN@E`S%w2zIhp4p3?GvS%2^s8NI4%=MMSvnm5G&`FPs7nLV#t_Aql=-oWvX2A5IfuU(xTUhKm;IpC&(Yd`o)p~v?)m)1>+jX`$Aj;X zz+a?!XP;m8V~qV5AHImczc@71-aFO*J^bI*<@jZ`_fGi}z)$SpFMhsP$+rKTd_wre z4g5uuC%TvQYV*g4R&SnviQq>BN*_zF-*85B@`>SJW%U;$g4Ele1in{xe=)JSx=#w< zJ+;4BT2sA#FZgru{Kccc)$@D9Z~R`4-x+o9179kIznH$;-pg@_as4ENADz};_}0?b zk1=jWbQ-_p@COsg{!gR6fB3@ZllxENmG<7L{uJ=NuKI~ZP1N_ll<+B6`-!|S?Y&d} zRPZM{`-x_K^!;1*m$rUPF~JhorI=KSpW{KcNnUpe3(RZlH? zCbaKAbN^fO=Y+rIm0GO+(cU}d&jsIf*AHS;FMIElKR5i%{y&Jwwdy_(e6|8Vh`Ud9 zFY{^Z-iX%v&HbMjK5IlOA#&Nzf2aEM!H@2cN_YjS`~2|RQ>7AhJL=x3+lWr}^YbS@ zzczoCQf!}UpWo`u^QRzu9If-G5d6F%sYH%n)$9KezQp5{V$^Z< z{Dt8sl}jlSu2;`r1in{93Q=jfdj6vDkq=Uc30>5EG5DY7rV!m$sn=f|{$RcoV(E2t zUjlydO<&RCZ}s|18h(JUIR8RDznoaw{Eb)KS0wb%KQ~0qv#(yiF8K88lZ$7W)jh$F zE0kOun5=ubUbOtCsLg-*cWwTg*N=R{q}AW%crr0%qq+}-pU^Uy*t=Q1{!;LBUiyf{ z_}mjy-9|rZ^@rH3-_r0ubny{S@VO%@z6^Y>7v7@K7X5P{WF8~07Ukn<`8itmkFxL` z2Y8Fmt8}lDza0E0Z*MU%zW%ufR&UL39>4PN!RNfhHev5WP(Md&{T1NHZT1omQ>y!l z@cDhbMb=WfmwCRr|0=6 zA4@Nz_PI$_;6Ic|CK}DsKlec9GsfL$hc^BpvJU>fjib`bsC{1dPw*RtBo}Y*+k12U z>^VPs8C_N3^PKh-(_84DJD`%k8vN%IDa62@>b^RBm1)xNQuj6BYwhmgHi~K6PIQ{%W!0VqCKk8Wy-NM{;HO7QF*_44mu^uKxjH-xYEz+0@is_q-XcTM6gdUn@8_dwRGjk_s+Q9th=y#9Fq zXbhjZy_eV?OTTYPrT!-H6Y_eAQn>HUlvk@mKAx7Jqjml@g)b!Y7mBCfx1-{l!LOg| zC61H2Zw^1cvzN$nK=-mvqi!R9QNMZog5XC*BozrN==Tk&_!jU8oQK6;1m-WP0e=GRGK1oHaS-O{bw00ZO>dpIqYxpYXlZXTVsON73zlxHG z!{6ZB!sk7nShQ|ypI^2k#{O#u@3SSb$lcH0Tib6Q|Mu`1mM0eP7OVGP2l(Ob5{pA~ z?eja;-x2<5yu{+zB6Z&he%#_jV%1A^-x>bN#6%){QvJR)*3m=evs|`>iPQ{{EIyD`D-P0-w%HEUp`{)P5u0&lD|Lvj=Vm?zm59&YXE$S$v)!Z z9{cm3)A$dBFS5}`d=6FjA@Dy&`iP&)MSI-urhV_3oDTuU`|tna`In5^^PfTRo2n)k z}~~AEPQsy(`P4Qcl)2&J&WtSaWCWV^XK#Na}@7)PRyAzGrK!? zd*&dCE9Cic$WKnnL0khZum5@d+VE)^q1E^1^J@Z zPNZueF>e(AsmM=xpPe-OL!O_8d?4Mw*>sZke>(C_sr~Nr#rlonKLdG(hxGcz9C>~w z@-0SYClT4y@k{mnvVQXYKMVP?U9ywK)8+Y4$lFYo=RaQmT;#8Qq1O*)iub>~|N8nl z4|%`NPUJ#1@%+#8`uY`t{G&8ENU>C`A9(xcBmecU9HiVwv3{D5%KX73&qpFZWn>Q0 zEJVD1GO~XG@=+uQ*_g-j`jhF``@azRoBN%}{yvu1zr6j6kl*RxL?R!F^&9ygh5X#G z>?F9Gc>iJK|6=6R)}Ysa?9}IG>E}~D|3)J}Cng&i(o)PD>0g4pUszUhdykkm@_#Av zQ^sW>clxN$jq>&z>0gHY%ka!3;DyRleW|X0G00bqawIPJy=^l3mm}Y9rvu3yfX|If z=wE?+h5Pm-E}{(J+s@9k>M&YnKA?duv8^NKjr`w* ze40BMNkD6rr=M5s*Ch4hC;RpB-;KOuWJWR_zqf^c{wM!wI||Pv>wi5TtLYz;kzD>m z-u^h`opxppXa}skxVWv=8f#%gZ$J=wq)LS`TW_7e0VEc(rLGt zH?n^p@-Wwy+#W6FjqFcAe(82w;&)lT{_ID-@lIQEp}Ckhvi|_`TQ=L0AvwgnFXj)E zEPvMF{+mkkLFB(quq6&5YW=194D;_K@>H4+As-fPODd&LUH#VchmkM7(v}R3Pu={b z=M#}nqVcoKD$gH5e!wAH(&cID=3l-3zmaco#g^-q+6bQ>i?EcntZ-+?hy*uHyNZ_NP)mm}ESAeuD8-nvWyzmyXUKJuJtM*M9=} z9j|OjkBnmddjEO;B=T{`ZOPgEKjO!pzohnRdH75FPa%J4sV&JJZh8I6>pzWr*Lt>O zKo)iVP3=|mYLeRVlYV{t&mjLeFe54KAl`q_b`+jTUjJF->t4%1N)EKVf8zOb$bSyX zKrZaIy#HgozW>i7e=K(f;x$a3zkvMEx#`J|BJ{U|D2B8t1Hi6LcVl+{D{`us{QPqhd6!n-Vb1g)>wl_GIe*8b-v1n^pGrmlE#%Am`wblS z{g{7|`_Fp|dHy!?e`Nj!@0y6`U%h^I|DWYAl}i1-gM1wM3h~W;)K6cmpG?wtrqrM2 zXg`&T{dbXn{nr<$RYkmi*6U}_&oTW}D*EpsAARRDEZ=PT`UB73N8Y)|XL!HGa{c9> z-+O@kwUwV>d|`S1A@cRBe}Z=5md78j{}J+8{{09`npnPm#q&wX_n!0-h8z=L|1*mJ zW8~Xb{RlIrY1hRI!iX^~mz|W5(|ZP2e{Ye$ z_53yLIH&T|U#0%*q*A}=zyI_6_B-Tbd%Xsm+p7K4-v7)W+Wl9)|KB4Y_u(b%yr{-c zhW~*4gM%;NR4sY_Bl3ap0?MCJpP!Y{|LK3^KU3bC{?X3;Yv=s6bN{;zsptN+?*q`z z{gvKcXbJqVQ^l}s>wTK?PT{uT?0W;KG}|CQcZ3)5@93fMGWuDkGW(}*@FH82+@<;S$fw;#{r6M#%fv4O z^1By!k+oIj`HaXvSnov|oL23Z(Qk{q&jT+qc%;1lnUKHu#fv!Bl-F;Eyz6%_vb~W! zZ;$+n3tnVQ7kSWg{a{-<=`% zr~Yq~_rC)2B^#6_duR>E{dKDAS4HG~k9rW-M`Hba|Lf!Dh5Wa^9%SJjdA<_zmm@uh zUmyASS4KX#y$5j%6YJ;uU!Ol!kk9qqoow7H&wC@^Dbbze8zJV6;^%|BO^`dOxKzvs zbMwD`{L_h5$-lQg?!p6O>i(_anwo`p-3_1DGv_5SmG zb>vGNa3g+syoB}NNPi9FoA+@e_p+-z)%Vl*r+z5$W0L9D`(G3JOqtwBruJf<*Kd#4 zU8ywtA^+e(DbjL+m^ad23;AP7rO3cW@_cRN8`pCqU%QBT8jqCx;p6X*eET>z5<>TY zEYGODO8hj*`>*f+I>^7G`4iKlk~Ciz`E|$3kb`Sgp6XNdYm&F0jX#!uZ2Zf7v*VZg8zP^5oF_RtQOpM$ zU@_14zdrs=ke@-yl197a`KHLPyW~L}pQ}9e zSBaY@dHYXb{h`v_4EZ!oJ?Qrqi1qV4o4;B9P-$+C{FMS8Bx}YhO8?W(YyGClpW>(I zTObcLBMtMc^oTHF;$?NH*+B&%O~{q2x{ zu+ohTZf_F$Z^XApzST1~()OU3H;P{e#E3^3+}}?uty{>W4o5osduSwG>I}BIfz{>Fw`~{FJQnpciFu>= z^+W#1l#=B5V|D!V@#FRD`@cW(iML9Uus|_S{V{3lf4=?=K;GA>6!G#B*B@TLKK_3p zU!zYck}0!1KM?sf=SmTqZQ}aR>(}>R0P;l|xsfU}#Py%&_4W@!zQqGKvUrqOzft@K zBfn^SX=2w)o*#nzz;$KF{wiYLSGWIU{inBoDDr;O-HEfc*ngw^8;1Pb*6w6sYx((m zxTZggJ9&0Zy#6rKABcS3C+?&{29>9uPj&qmf&A7k9;C!C)~`nWKN9&z^!me>mg4mz z&+GGV6!Ir4yOXc?Qn!E5^P`d9Imn$nuO{Ys{rdh7LO$~tcVgqL@-p!YM&5sfJBeMH zy8WBJ{)|E1F4luYeiQHCjrxBq@^$0O64PBVZ{+_t)@Bgdo4*Vp+1{qL@$M>bGA1MC3i}%91fh#rFFe)Q?HX zSL@+HDu#-ABmXBOKiS%Y>5u0^ju zHWc%G{Pq1e9r-HW?xgZ?F>j=Q2J%%umLW~M%kwjlkDO43WInC()Lx~2>f}%JzdnCv zAz!n98PeNVeElaF^N&e3|LFY>MLz%1GGx|PG0*$2-~WdppP0*?G;1%ef7Fkk?0{Cj-i+uKw%w&q01J&7Ym4Ro)llpCY;Or|0J)zr2Y% z8U7}9*B|u!Jming~$iD^B_*U#XRqSGUgwZ=0(W=li*HrQnGe@iv{SG$o-R;k;+>GOXX@?rN%5$iB9Z{&Xr^25KDB<~W%`!}QhTaJ9E0wqbs z_wxJ-K zpS@&p;+CBVuOIRH?eO{wmF6|bd%trfH*2Uo%@<|<(xj38wa5?2Rh*=qBd>oQ^5J!g zlPoXf`Sr+8tyP?~iSQNrPyJBlFDBXisgK_VstN7q`(K~GTabr0t|VIrmA7QSzW!`Q{&}P;IXOnG zpT!-oi~i^S-8SSmv~(rKW{PJCVOx z%#{?mBj%0t??V3VX&2J&uF6w=Kjn`vw|>$0-)`gwPIVzyUyAkf_UrpE7Wpn?TuARE zc|H#LPTO4wxi998`j0xQ+&_=};zF(*6Z_A{PjCMoEDO^w@0pIbrUgfq(1@qvhQ7q?>_PP=Xw45eLwOuY>JbPCUO1YdAo2_j`uJT&er!S^QgyRfzY%{0d51>@$M{oZ>$j^^1Nan?gufOo|JAwI6rTHrItL_#cW(WEFyM{cR%}*Q)srgU!{nY=w z|9buZBJVaiKiN^m^8TOoAG?0W#t)U|>&ScE&qr3TKg z`8z&;+4X;>pGxyh$m*Kh}?Y{O=;~{)aPZk|6GXK7aM`yNCSO%+6$amDJTw zJ%1nh%)9dtKYad6XSbGziv7W8zdrsCkUu^$52>+OJpTCjvHLHq|EV-TM80jUJfvhv zdHxadvoq!)RbPv*KeM=N_mBDfNkTqXVs7Hx&hqoOJpUN^HIcbV!4Hd&p${0@Sa>`41ER~_qkf$Dbgr^ULZdqe=btEn>_y#`6@SZlCvMm2>1Vd{^_h!GCt@3o7q}u-1$nW;cNzcz%K0nFF?+x;wF4Ol86_)S6x5zIYoP!)GD9^t` z{`w0idVWOS{`bfacXc8m_VV%nfPA@u*-0gj($e|!5&4~YvJ=NyZqodx|B?Spd29Md zJNK`h^ViP(|9x0J_pf~)fOhV`JZ1hrf48!Zp(nY{h2)Eth>DZ8IhlH zkJ>+5Y`=cqVDV$~9@EdBo3us#VgYAzu$q|n#rQMH`1NQ%mF7&y`&V`*pBz=5#!JZ` zO(t;tcM5qb&34E`DQEJ%kXS!$=coMB^Y+LGrgbLc@``z0|8vw&rP%@b)wKTxj{Ly~ ztKYMwye~tq{}p{-2GdWaiP`Une8AH@q;TL5Ucc_w^X$F>)eis=WTJ$d9Jux5Q(4J{$6BZ{;ETZ^_%A9r@=pf9JIm=f6?>oRF__ zB@bCzT&*7oT>YZ|PN^R(eysml{8|6!K>pORJY?cwc|Ird)mG*qS$m7?pOOAt$Tu38 zhqOzt)?eyxs{21T@_`ldkf{FR`fa2?5At{KTZdu6rNJ^ZAkg+nkH!^6(SdZ=}Bf^43?Myi&V z@Bh-s&!F!cPR9J9`jq%-GT5O1${=6vWLEMuSX@7h>~}~0SnsT4&OUkjJ&@maxPh(uYmldQCUb#8L|CF{a+FJ##b{FM?3lY>4khqx6C9kgFIge`JDlo$;s=g z|1{pI&fm(&#}~;=^4g32H|oDC$Zy!@NNV}W^WMnM`_qwR^_1s*kT3GVftZ`f^Cskr z#yF6OAeE>6{nPm2{nyW*X5>c}rteD)mFEHZf0o*l#5-d9sXf%p1a_YKKl2A&a47k| zrLsNou&yOsfAIF}$Gxyg%~&cG2(q zPZryspj&_Nd>!N~_s>KIcJe3GZnn--^lFmE!^D2iBzxZgv!6;ue_iCShuIOAt^UIJ z({>d5nPlJB&GMg0W&KtU`NXUCWa>?or+PHMH9LOdnSREz_|-@LaS2C~rAr;5erC5e zewltf-vIeb`7)EEz2y0Z$d~)ak(53y=8gPsgnZV_j>PVT%FFoQ82KFw9mv}+KlJ}9 z|K4H$QK`hQ3G&P6`=Z?g>MHT$_3PtTnZ}P@Kcdpat{*kk^gp&I{#R6<`m6PuB6*(0 zpYg2!nj!zPn?3RMt|#n2+FnZkGyN=o7*A!&x&Jf8?8((|F>j>51?u;CYe%Yk*O%7c z68ZF_?a0*oDo^!kers{~$$q{6t&k5nnTae8Y#@w3@4udJjeHmDOk`xmhC=&|{BMK& z^a8fz;88Kp>(|G>E%L1fWh5)QHj=i#9r9a9M$+VqJl`Jql7ll6bCt$I|BdYLfP8^X z8HvjPdA=j^x9R(m_PtekUwm#wlYIQM(CfD>f2lP8f&A3F8Az3(O{DGr6Zr-mGmtUE zRi5fgb^dii-my>yG9+AHe`n;gm&`zh?~>=cAiwlQda~t#nCIiC&;PE-&uN>UoID}V zcSGLxMLN=TfS5PRpYF(?JDHBWn4`6MKgT{D zu|=NxtJN(nk4)P9$?C5@{=JcRUtvQWb2pV9|9y~O6=Flu=TmtZ{e6+|eAI>%bdcBI z4|&^k=}3)N^6~4ByknDeq|I)Xm$82U@-QtOX}MmW{|ou<=V<=^M*SFw{J=`-iE9CQ z{{xWE8JC_EOj7HgO#Tl-zF6Z7WZyb*{iW^wGXDl6A6O_O={8DU{}7GOVM|`*mFI^d zA4TV1kK5|}#rHq`w_-n&{Q6}W@?S67lF}9A`QgYXZ?Yv_FUil}fykd+kcq7LEWiF3 zfqY^KJ2Gd!JUQ3zOGB3Hhkw_M}E%d44kTe~q>$W9G^8Q;Y&-b5x|1b^tKqqSdIeGi1BR@C4J=u^?JpPROZ-%Bn*^Yd574t^+&qO}& z1Ur&-wLCuy`P~6_#HNUR{R~CkX|o-mk^h9N&SH;vzK>>tCCU;C#$Nlp~cKSuGN zjr<16r}dDZ|K=dywYWVgH(ksd>7R>yA!mC1)>FLxFzWw#$fxgXPxeJOws`&QJzjsI zQn~&Sf&9eG4y0UZ%j>@?xc;V6;pZbiW0(W!7bed~A|E)yfegrLdHu}mUx56lat@@; zM$7AWo?nRkpWEz-bJ}LY{ja|NczzM`UK#Akj=o}E-+zo}^@mF3`cV|}t!LR0r*HE7 zV&u&g?8xG2%`NVKc>AM~FEl?BsdZoFslCelr<2P3!~EdwUxIw6akivG`4+>mS;V zGX7U1pTBWha>TKxCY=j8bv$a_avlYZ~T zJhNN7{>9tB6ZwoCtVxxJV&2I9UC57nXGM-B%k#UDAGOYk$Tw(eO~&>i84sXZ_FGVf9;I zfA=AO@PIXWby|M>CLkaDz?wXAk>~d#zx1g!xwcTg{vAMm*kfyQtd2Z?5cv;>tjX&m zYWm(f8WOf&o|(k9c>W*cYhQc^6JLt=-@JZS z|7bf({I4RvY290BQ(BzA)DOjeCVBnWkRKfV8gfsty#M9-f03_Q;5BT#X?g$3c)k7C zk-wJi6{PjGT)%k!2J!>ny?`us;`z_W|C`8{dh;CGEVn#=^ZwsL{!X{&u=={?^#{-2 zM*h>1XV9pRy#05OACdeNf``k;?=JHB%RGfWt;G9pqx`#ve7T4xkoJUp|KCSGN1i7z z^|XBcJwV=JWHKDBE580>)c+5Wf9;SAoi>ZdkCFe6ke{^eF}xosKmL=DFVW;Ne0ut$ zeg)I>Z`AJpoL}LuKR!mjL&3)|YMS`^sos9J{?V_Wl9A8;JqhmRuzdZOUq3xTe#r79 zco1ay`Zv!%MZQ7HB)Gg!eEnVDe?0$8(|_j?9Lpl+jr@O({G}<6AaRZO{)dtN7s$8o z@etw@_hsEB5ovq~a=N!<&b|4eyn`bRtWubuPP&i!9WRL}iu-v^+b`>#Nm z|IZ(`u3~Gu+WxlbnV$2r^6xu2X%*ZHH76`7|K|73{d@grkDdExI`$oif*#X~D%ag) z&i&g^mc{LN`E-d8VJ8o6m%N;Dl&sv`EbB-3Jt^yUX8%dlPi4xv_Z%&wp^&YZH}XF->VMoQ8n!-__dg5rMH@sz za#2;kO#HGUAKEt>s^*oqKO6GPH$}so^YZp*NB--HXfS!m+wX*Ywr$a{;if#F19|&( z(a^;I$N2r#_~-LCC-T?2MuW#Oc|I5N7c)e|nij=`sH z1Ls!D>vuywaqVn)@f-ECH1b}(XG61F^7fZOe%P~c_+qW*pG^GRk%xeA=$%oVzx?>o zk3SFOgB`-5&s%x>%OamHAq+Mp%E#Xm`N{{vpyLsF{pFC4N*504H_GcTk9_BBvms%I zyneR-Ve9YJ%fq3_eKBto|BA>59}I(P*W`J+l~MGMcMgNkpTxY;_^E_^r$u4V@})dq z8F^dpFc{lZKL4s9|803FbetsSjqLYEeqp;%@LM83eteL>b8HsWKP}cz$Kx;SAN>y{ z{;#IZ0-LX5-pGD4@^xO!gauCW^A{lBsl`lK*jt{b3ns<>e#d6O<^J;XuP^c&Th9RB zKzaRDk$?4WI^3l1OrYytc0M_tt$#Jik01T~Uk&*X|LHIyzpHTlXB7YH$WLB94cb&! zc}=e-jr7+*zJc2`2rDno*F^sQ>Z!0}p}hTm$nTmv6;_;(=W8KBzqoY&)j>Yzt(g$^O69eF(FBuZ@)hN4Uj*XZUJ1*QBqoeL*%1wMMB9S zdAAb%*`d~mv}^1%}Iqbc&6 zdq%+VgKpCCYleL5b@L$Cg3>AW|LXc%6TE&#rE>kOIr39R%!A&I%2?Fzi9D4G-vW7S z$`{V&Zc%?@dZh6B>ks<;D~tO#DwXSRt&qQda}IoYr}9SeXFMB! zjHlAv8ux?K>nZHVQ{~XJpUK+w@!z_xt?PCdHwAE2b(|G z{f~jjm%SbiHJs)70OU8i&w=M3#PR3*pS`bw>1Xc?8HBuF#9S~Zih17tr)WQw=E2AZ z^o{_Zf%5zii9-ZvJ4{O;N-pweQo{seCQ`~>r# zO7leI?Oc~bzXUPQ$6v3167oIk$H2U&V*7bsuYWS~E%q&gD?Qcvr}?c(-hTGJGUh*( z<|)X(XtfM(97(Eu7z3d$m4xdD zUcWy6Gmv+Dz6|QNQF$$Hn&f%C{+Y<1Z?O!#FWWQ&AG@|2= z@l-1B8=Q^2cftw?Dd{cLPx~Qd{CiNI={?0+Z@v;@LV6~Xn+s}BWpYc?h=OX_s zaRpda@)7FS$Di>m{*0&6JP-LBr&hxAYw~;q@_tQM!sCRtF22J2;q6bx{G-wwjr^3H ztH5u8m^aeD1o_APS3peOszUun{x3y-#Df?(w_oMy=YN_%dHeP8Uxs|*p=IFpRjl90 z{utyJby^B%%T^QGZ^SQ0epj(2P@=0mzXJL4d7~j@pO`m_-%8|P4q6NofAPL(Bl}k& zzw}!a1ed5T^q-HvK7UptKYw`?oS7x&dHdP>x>^2Gnex8-=_{jPOoGbO&;Qi_zPj}j zt3P&_|5TdSqW+{pi(yZi8mY4XG3uw%ybk%kYZk-uI`aH_1UxIG^$n%?!Z@4}h z^6i)BHzR-XWi*WWBIfn|$Mm!QWA-!uw;~R^)F^i-sWqVxIS(fbix(>IHTtTW{K?Z|J~91S(rt2`fn*6-~4Hj>*1oGFz*23!XD$n;H@4w#ulgNkcSqs5$#QyWV-u_d_L;PBJ zupxE*uh)MX`EIk;!r(EM*T1a)_4>~s|FG^FxVA#P{x^!>S>#^?tp=L{DlZeibI3>J zTMb(msQVuo{yg&0XIFu53(NZ_-v0~8ullkQns<@ce-ZhSo-3j5Ofk>L?&IX*`tm1Cz{tJ%1VbSA}EXLTCB@yMlcBwM*goIQjhf2l-6&`tRCu^7ZHH z|HxmXd|LWPJNKrYbJNbfJvySEd(+OtY3JT5Qs)2j=PPZT*%sk7BpuTeu&2eo##I)= z>>6bgK9)N9Tj$)?NC% z=g++{-D&8b?Ux3^du!Exn%_UooBF!R^NeMGzP%X;m#-ER?i-Bsvz%f4hN1yb1)qDC zvEK&yq5}gU*XbgPei{2&QZW7IKL^3u>MAdzKRxnwFARbVJ>~ff$bVfw2v)ku^BIwM z4j2qImK2tbzb*0uHx7aIndSLR$barO6q=kbB(2{L`8ExP!j7|Ip3gt_+#bzC<+&+) z$)=$nSkO1h!QD5kGpJTljr1^t`C@+!mF}b6c5_ zFGBgzPCt0I@6zR=GVjoT|L3{CEXcP=9s>L7%JW%~UsGf#+$br}XG4C$@y5;!u z&n;$0-Zy$Eyr`_|H;O;cJ0X9m`%rjrU!Ko_yj%XEaG;}j{OR+L>DNCuniKgA;X}ac zyqIVG#;!Yv`Y#vqcaIE)E3J!KtY5tUxsi{4G6)8)l;`sxKXrEi+&(GKJ0riT?Le53 z-E#fs?azz+nyv#NTRD}N>HmDlPe0WUnh%xNpC9=L%lpE;>GJvuAb;g;Z>Y3RUVlO4 zy+`+gjf>^^LdZ9n*aMOp%kzbiA2_o+T=VwBAukteaTLt;1cbmh!^p@*4pa0&-mn+&F7G)Ik zM)k`F`IENIpmGDt^`F;I3#-z95rIu%>R@@^jQkY0CSW^4Y(GE#^z{>vzq+Ln_?;K? zM*h|H$jFiu}_n^K;smwpskzbIlE>sM)te>qPS^TL~_!`J(%~l7lPWYk!7QNp^`z;=2 zivA+VQ>pMZk1@X7K%|&mYFK`ptM&ziT0% zxu`$9%IA`@fBsecYM_2975%l5xA(6LV|uAP)6aNK>hq81{gJ=Yu0E_y`oUWv&!nEO zfcmLa^w&YYdG*Fn&!k>IqW;D+PA601&+~PWpK-JWq^m8@*F*l*!FDj84KL2?8n<1ZA@((!NSUq>B%R4O(Q~ICR-yHcAx1pFM8S$-sM%#9UAH9^QR^9MfZ1rO$F3*hru|0G)db_v7hn!{B5QAKc^j(${{{? z$n&gz(RLL3TO)rwxi#!_vV3lkx4#YY;g4E?Rg%hUc571Ke>~q7dAl#oz-NPc?vUE6 z^_wPt@?UR%JLJ#5YzDXeEkC!<>u-Z{IK}3@zVkMaZ_4BtAX}IikK7aK2*9rMgLz~0CS*eR3 zdv2D+k3Bcr8TnYR77#yAte?043Fa@A<}S!L&DH{}BgFc7`}KTRs@D`|Im`Rs1No<|n!?5b^7i*ce#iPIuz9^a-wS!yT8&|{ zujO+ey#KwCAF{L|Y;zT#n=tCXKFFtcZ3yo!RUou(v+Jx{-B2XUANG4Di_!SA{G(FI zzrM(iYupH~x34J8_e1`5Kw}v5SmlGc`t6JQndJ5NM}EtTCg9<1`P@WB%pWS1=hg=x zZ&jMszhNp*{nY$cB(=vx*JE)^^88=OKib$F?gUsqcfs=mk>SS{?o|5 z5ZpyvfAsNV^+!K{k3v3E{yvbwM$GHu$9VnxIU4ynxBEiv$EmBIdOiqwuRQ%>MHBh? zI~e&pjsu`@h}iyM?0+Vi{cQYDsf?d7$VWR2fito4{8;1@zXrmrhT{G=(mxLQ$gZOx z%UqSGpO0tzM@{nmr;p!wo2pP)n6w0@jn^)jAsL3!2&U_k3Zw} z^=At5%P$Ov$r;sibM*5{|7nu;qoSWlUjJ0&&4mLY)5ag?_Gr9QuHWeOyP$q5mHIag z`2*(zA=1yyHy!!#jUym7>c_dcLU{cGWlH>NAy1{k&p4mEQfWuPM6>wZn_fTT znSRDI{h`PoTsRV@NBrP_Wq)ntsZ{tdb?@tj~7^{2_=`mY4l z&(<$gD(jcI$S3RzhW9q&b9cVD{$Y}RUp?cgRQP$wC#@R;Sr3TM-RbRT{1a+F5TE3$AKW zKg&NBKbAi%eo@HJi5LqvvQ!iD`u<})>p#Y`{#%Uvq+VlT>j;&n{biWHdi~MJmp?ED z+H4W)*Y`hf{}SZ?%@+(CD^-`ae<|{Ha*u+Z$5md&{$eg850S^u&4 zv2!Ca$Zx$e6sEX|c|QKh7=J3w%aNZ`V=%b)6!S*cp;9uNNI)Bz9pMCQ{xHnkL^YK5f8~+=S zzy8la=yy@f^Zl>S-;KzxZxa9m3)T|aZ=`<{@|!LM!0Y}hPd}gP`mq`L*e-*h@dB}a zzW?;~YYXxtiVXs{vtr)J{;kNHy9L14^0kHj8|mMs@%aKEqNB>o_`ewU+rJm`jL%)wti&u*FNL}UyOo{SGWFWJnKKkv;IGVJS2~Wkxn&* z_A~#P{Y<(cPo={DjeL)G<6wE!n#5NS{{(6`{@&D%^2yYHDwT7eN0GmKV;ub1U)=w^ z|7`we_OtcJG32xSH6C6qw4A@pe|GMT@l=|RBVXdsco<`6dHgY6um6O`J4}GO$*O*8 zuhM^-Wd38nD*dPDPa^M8eFA)MDz@Lq|5M0suQmaOR}{xjpTE5Sr;$IBYXbe=E6e%M z^JkE6^tX*>sr3JO7YMmNSU%ozsH?*7RC1iXI7q<;M5L;X}L z`mZ6sz;7@VOvU<@`Ooa9QsMta{*uFB2)t`~{ls{E{H`P4dr$x@99>6Qf3mpIdZEOR z$pl^f;Pu}?zK7F52pVVkeUChU6Zuvv20%h>%kO*S?Z1WmC;tK9wO5|Mjl8)>e|UY` z^7|fn`|lth`*%OE%_{HzT}^+ceh~XgKK}QR@7Aj?9Pcg9-$&m2dmlKq!r$WlgOC3M z0q1N+{I*RTBeW%D0xN2xy#k-z@2H`KuOH=lnzug~8{I=*}x@%(ATCn0}sWN!#5 zXnFqQ`~NZWcgFXIEVsnWKeUH@jpFaOzBmcR1H@HzioIia3>-jgxAH3BC?v4L3 z|6twL>bNrhu{>n`cT6{bzeRp<#V*jzYFD)KFeEiw^o8>Q+=J&{7 z{pSw|-6yu+i2s1R@6is>>VV2qKQ+G<$;VHx|0D8Ix7)+JUwrSAk^WErBmbH5*7T3| zy#d6~fpFbUF<1Oi*RUPlAXL_DS)!X-BSirvIYc&!E zrfEdduwNSdFrTcf*!>9ghxr$r>qmR+djpt`F0H1+rP!5bny+!c^SuGT%WHP&`Bj)V zI;o5s`fn3^ZuTP0TPjUdnwftr2IY4k3cn8ZYcd-3Gs)~fkNT-J+aTX7c{+4`I#tN?`Y$6- zr8yn)!v@ZPYk?D`d6rbn|I62Az@4m>w+{g(3Y67p1<9gq*nISW?2n;_KB=Z~IuMBcaYEXbW8&u2!y zWZ*0qIZeL*vLOFr(=71w3Q3jy`uxv|{IR#x{#L28U(aVl{z2h$Z^UnP()du9^!xFpuk z=bwK3l|+91gh|jKDRuhw^|KW65&0*PWHEHC38RXM9ng}zt{;1#VdM6vlC{xzI*{FVIKb0mnf4C#x zH~U1mF>|)!zou7{`u=CYX~5fX}td42qu{nwGF(p(<- z-nAyd*?Qq-8t*twuO=DKe$Ql9aA5Vl$F_z~~cJ7(Qk4h7ZUq$5aJP(1L zMdm5}r`0`8>iy?=wtr>o|3_IuAbFEo|1?gMdjA=J6ZKPRu7rH;<{>b#f#v$i>#vM_ zy#o`#b+9`BQhh(=4{twPe=+~5G*>}>QJo3kS-|rA!Rz-%zEkXY2pX!+pPJvAOZC=dMwB`njL_kLQ{HjA!}li+r0> zVlOb+Jgp}R&&Ds~+4yICHRQcv3|zdw zQD{GngQB0w>gYd}ivQJ-Z#^s+uJzg?)X)59`k7?)pZQOv;(ra~54H$~g&Q^td8U`~ zOfsIupYbgIHIZ)~90bQ}Y)|2DVf|-PpTF$fF!P_C8)p9dA-_Fu5dGesozi?QN1uD{vnPe8{wh4mU&hZL`DstafL;0og{S)B z8K+4;e){;=LEiWDIB1gNuuwnG>*HS+d2%uY%GVb2djDDfG5=ZrG5_l!zoPtPh(B{u z(NFa$_G^;o_4e0Cet6_m7!`b8Xg|;E^*2C%L-iT(;14lxmCv{f$)^&91X zBjo)DOoJP_uL^l1`x_&lz3Eiwa`>h&e!PBt|20AWV$Z3NeCLjk=k@F3-xPVrr<0*k zzNgZBGvvSRm;~u-zY+3${O@A^P-$+C{OCrL!2Rt(K$Y2L;R6 zOWWTD`4t!FxreWrf!53a%zw;(_IoB-{bc^L`bnj^?f=NPqddEYtlf9e?lWlj9q4~4 zKid5W?Y;wBcm03=LzA<0b|7^`Dq`-^@%^6IS&b{9E5woIo#DYVEQ6 z4opYOZqe{|`yWcb{my-d-{qN4>_^XQ^;VO7-s`XXYxfgJ*CADTr{~$2VSlW< zN5c*OHbR~sH*DX*<_)%Q(C$0D3yOxkMd^252*#}upK{+JAsYM_G!gPf{%iLg@|%}H zu6d25dF{T#xk*c)(xS!+PxTqj+xqxv_Z==xTLK?*tGw24I%&eVDC;JD{IvTH>pm=j zeH|J~+ppbscuKz~{mjz((!6%xVcEB(5R+U_$S2^sk4d&}xR3o$rCGc05MsRyqV9-! zqyE?KJM2BN6c#U5?U#wacHiO2vZb&;K#iXauibYTdvz(~Ci1*?-(hp|Qi!xt9QT(*~4wa`Yg;jIK_1j2)%6$h~evB{%H3dM!k!q_bue> zhj!oL?u1C#`9Yr7?mLty774yvRG#Lml7Bj>)DM=&tbXX%588c)rAy{R{TA~6Yxf+r;(HX#8mR9VXn0fQSbwFVlb8eTP2lBVa{O`TkG2?@;Uac7;p(HB{BF zi@Vkjzl^_j-{I=YdGP#&JYN>aALFl#mye%z-+}R0k>~BF{h`>;BtQRX_Z?y%&4cm9 z<>Rm2clbLw0%H1#^T$ZPcHiN5d3N7H+qXv0i-@`RRb)$Yt0#10^qKvI{!D)IjMjx< zc8Qq#N&WBGKI@CKHF@(rh+K7zioMu*F}r18jmy8pZx`cA7c1(sgZ{2fo=fajfYpbv zij|AzzZ9E9f5-kk^<5Por>bsM^0*hIm->SV^Lbc_^dyk}f4*5kan;XuiDjP)IvV8j z?OPCW95sf1&dREC;ve1}=8uURg6(|vT<$aZX}I^G7L$~A*#65s(VA4G|DU$h+_)vx zla+RIhR*d#_!>kOdE8Ojan1M8JI|myaV==utlcqRKlyBb+SB`wQwNlG*govT%=d7f z{{PM~8{&K~RfuDs>(FGQPunj+?ge5`1gSRk{>N$P+a@?g?^t>JY*>>(9pX`)rd8~xe&du$6eJ=DV z8Q&S(37Xi~^sZ}-DvQVFRN7(tGgG!l5KDbHS>t`&z9*NIcF4$&KJz{W5!cxzm3Gp# zzTnfpbE$YIY-d2TX{ODgHNE}cx-0FlecIJWA7MWI|FBIN;!B*diD&kdtzv6x@G*#x zLuRF&Hr{DX3D+S$fc}pCfA>d=O=%vF@^&g#OKFGg*Pd4X09I6Y#g19xS5zvYv=cum zo9Wg2AX3++snSl17Otkz!Oi0H)8DanE@vWFW5|Jr$xW4rg^j-)95xzJEJ_Cm1wSK8@Y;xE&rZ0@Gp2?p?Xdlw&D3we{Pt>GD1QF5F-kix=M*(fr8agc-#}?6b4ai$B%x9K zqE~7=|N7@Q*9x_bJzHji(hl3_eY)@+-q8Q=JFHZ^`-rJZJC%=@F>R&oeC$(AX=i7^ z6jMa2n(=pEs_l$k?Pm60SuOUoY`<6V^lKRMB8b>z@QyEKj!@c}wc2d@N_|~9 zU2VrP|2$KPjDGQ1=;tV66>8&cKJ3vm_U2$UK5XCDq0S4ic}n~1LWB4Nw^l0cTzT2V zw3EiPTW>YaN9L_C)!0}!z7zc%YsdA5zd7skJhA;80~LGN{%`%@SMX0#5Sj6yP5j)g zJCt^=*>*IYrtKtds6;vs^;ggC5ZeFFGbk+%`2#3P)7ayzbyk6GFJos6{!H;}sNKxIb8kkO<9j8= z4p~-QX@~6#WBjjx)7>Bvzx>bmhf6Li?aW!!#pFWs=f$IIwBFGg_0J`f%Rdj}&OKDy z84y0joH6oKY|Aivr5(0E>=%0;l5Yi(TkU(rkL__&X{XiAJ|<7v&Z4l*N;`%2-7t;q zu{UlFwVSnjsP7zevwSekFTQ2KBc+|HaRW@!vCf5u^AfwZ`0>WJN@Pi zGZm-p^eAY)YReRTK)0QV~V&7vsgA4v`&Tnn!v#Ovk zoyUU-+ecQ}a~alL4kF*fro|79`J}XCJ!hJ!4ILMO(+2Kl?X+0-$rR!gxx4Xg)t>Er zFPp~=5Ap6h-zJW=!}gOQ4^P3J^Ficn?3{Sp`f2tsZr$`bCI_0&vqq0n=GSkn)0khC zJXYl-?GN_<`EK4fCrn=LU7_DZrJaKGcmA7BK>Kq+#Ix@F__I}Ply)9niZBhKwWLE; zrq9Z1a9bNQblUB`WX^U}X{QkVOtzILpvCDRvg2NK{E);9N;}6p zMw@EUn&mq-o6^pKry0y|_MG-UcTH_4DZm=8-FNcwJCl~iA(*gz=DhebQ0`<988CfK ze6D{pD(!sEw#F1kYfW4QTcw@SX>83~{C0ZRz;?*ajL@@EL!X5OU6gj%e)HC}b1?O2 z5IJ6SeSD>Tj!HZ2udOq+rtOr@xqSSib=IQZMXsp!#Ma9K1uFLNiHxnSw8QqD z2@4*=Hrmb^tL5=;|H-1X<9|QKw2jutRWYEnbL@5&bH+c0Rr-2KZ6_>aF0k6W!{@Vo zPo*8U|4jGr0{AA#h&&v%GX7`-XQdsNFDp%DXge+MMA3YuYqrwP=F;D- zN*m$Dmw6b};PtiE~ zuzl;<3QOVq+8{FK(wzA6Q>rTMoSQV)bc_0R+5#qFVXGkZ4IY6Z?+ z3YivVWc4$cu>GrFxh>E$CW!PpJ1@RtY#pT?FTV&AoAWEScURgO8dJx-e);LxH5=7- zHm&>?9PR|;miWMFGySv?=`2H(oS6Ig{GXeonyDz{(tY5#qt zQpa54+M9i|lGwY8)ppvK9}F8SdzdCC*(>d^eQoCOm0&$3h-6EMiQh1|yV6d($uXvV zG!O5-35jL)^a$#1ZhGq0E|{mb6YwSo-o%?s-~RkR_TB`prtOXYPb!&bG9P2d6f%Xg z*ONJf5HcnWic~5pDw*Tr;ucUe3~jar#DU@lRkFT*_PCB4jbpbs;?*c{6<6ki5+p(t2gz>;u}7r|LJErtvq)n9kRw=w6i@$c^mdx?{FG;DO;9{1+& zC7d%a?{?h_%GogCZ_atVdx>Ovb?2`Bc7l^!c?mIp*jsnc8#srJgI^rqNv4*j*OJr5 zxcIp%IcHYD2A!7H^N3Xi`2Bgv%9YZ=i6tH!8hXUeA z+rp!vV(wLOJD0EFoWbTRbrb1%-yUzpIa9Z-kv2QmY`Unt;P}5=N6yX|tm{9q8|Sc` zYVUq~$rp2ay|e&-t!Y=bW#{HcH2HO=_A{NN{2%Y$c6zj@Cit z{+vS}&L(?8Pm$v(k?^GKe=70OA60BugSw#k^H>teRh$# zbHa50M6h-n1?=LnZh3^%Nsff#&jRAY%o8}LNXk&%b=q%98CRRf6J0DpTAy=u(;_zo zC-(SW;_+gvZizK(w^7iPaw?tJOUfLHgb5q^#Wj0(h;u%g^wvG1W40+RT5!%Z^TX0# zC9X70Iw3gwryVA?o%_yhzroCk6wn*4_r+M7wDJMARMVzE-PsfM{N;q;3 zS#Uz?J@!k}9I=99lk+6mUi5d}Y|{yxqobTd7ZXT@zan9Mo!W7mFP`I^Rui?l+H}l% z{(eu+Iezb)r0-d{*|6n;v+vq@a!)%|_xs){oFh?A#gedis zZVlxunmmScZ2Mo4o~*KOR(^`$lw5U%Of4LvJ0CNXbLd2iN%FLK;t?1LmAjOVYdQ25 z=eU^_)or4j(f#Id&h@BU(w;EyX3K&FXWZ7?WZd#)y7nIPIES6YuJbMtul|vcTA^^< zopKL2r;BSY-3H28eb}J-p_f;IqT>A)9fVW*nBz8Inu_b((ltZH2ct2aK@B-K?-QM>&on3%{k2}Ctty% zq-d>3@D9lxm%RB6=gf5cx7lIJxgnk8oNh?C-#SVb-j9I9ZV&c!IA+Q@x3}(Z)|_(kZz{|=2a-+6ANkF6 zf87(D@WSTM_HLqX*V@CJ)0%Q(TAe0&6C%Sq0mQ+Os_U9ONn))X`g zoag&;lYN^sx?*bt=X|4l&@}OmuGGB?oYR(a7Hxb8LBfIXCjQX?Brv z{w!?EIcM4wAnQj|*By@%oHzFhf|c`qU6AHF=QvQ#$7lD*!(I_Ey+z+WVRwpf&iXw! znhv3y`3He>w2zCB7RQ?C;=2n@bi<<1CN_uE^86jnX-7FT%f2NqN<_e-d1ia&ye-8! z$pbq#(Na!%>$aRzKD87{^lGK6T|{s`&nW?tlZ6y8>=-An2HuukRSoHM&g4bpa7ux^jH;B@pZ2Y2@8m2CV|ImeN5?sh8! zJ)e()R}n{cmrZKOIc?ib-~E|#4u16GoYzSW$$V6SOfr4}IL1oaS z7LdLyH{+a6)MlueIh?;W5_De*H`{f*1Lq`p?%H#ij=w^uMsrTet`1~+p5Jxbl1B1) zEKXE|zKsh?ciQFQoX(WvFwq1iIFE$W#~hj!cI?49SC(JdGn;a%Moi+I{Ph3R(fQf$ zx^*1{XM2wt@HTHD>HJaF-lD*XazcjvOLA*QLOqYk%^nr$%{kpGna6FR{jr3qGdQQ% zyIv%Z*+LyDAvnXw)`s3u#igJIMLDMn<$OrW4Ks_6gas|mHM2P=IEP|t#=W7>_w~-R zI7hRfHyP1(sSff9PL062kjJf*ba-J&&gn`yU&~s8^T#kaQJ}1@n7%KMXN~E=xP#9} z!>U4aIVXHbUsC7JT3z{9VZ453x2g|2qAE&*-<0N@Zj^KGb4iGg4TH8`ZFJ@HyK&BA zO?2EuI!CkPlbBb!uy+7yT6LT5^%lW7f1wdXUDHU9N>tz+XUef3SpoiDLOBH{>7pYB za*jjDrnq->?x19Yg9rCF z=;Hf$aL&WkNpT&n(d(j=;FLP)PB!E{t!o!0IGq!9pu1d6%2}Z*=dg8%kp*kQNeF`; z*G}tBX}vio_uEf#V=jz_1rbYmJi5q1WQXRG&ci`)!kp~sTwWDv!+0&{^rW2F^A#a3 zPZ(U>@jzF&?-0(}R3>kHr{lCwG~BH60`EjN8gNhi>?iPG{fhf?kI5^Od7+8?cS3DwQf% zmveei&X-GdAmDH)Y|U3tT7TbWzwJLvqh znl#|=2AtEI)lX=BaNijU9V|*qm4o~_XTZ${@h>-yhA6U!b4=R!ku&z@QqV=gv1scE zO>E0a#J36O^r4&f*~d>=IT{A87V~#GbNZ2l_jx4eOM-Lb zO($4eubkvk8aSsf zZ3Stq@H*x8a=rl+*T_ISl+90?R{dNYkc`&g8c3;v;Ff zytlvP@jS2`Lmu|CmI{m)oUhCKLXlIoq}VatILD20oJ;40_B})3afn8$JZ3ECEC^{6 zUx>!Da`Fex3E4D;Os-i&8sIB91I%2(V|fkfQw0~!8Av(TJLiME5CVV3SxFuGjpLjt zI*8vhpN>zzh*8DXjm$HIWBitRPc-ctJLtHt>gL3lyTL`*c90A>y z6qcS%pU638Wtzs1T{s%XM(3cv0^nKMozQmZ(&}-v+ z&N;hbDk)pEffRRFaN_0#!KXUTlA9B2w^86rIW0DqhGj9s;pn9HQXMj#$MesM;qk-h z+(G3-uQ(^H_B0aJ*iLdiB{;X94Tsb1T%^Peti46SP|9i8p%nb-HXOF)?JrGl^*iUZ z`ZzxRV6V|o^uu$`X>K*0EPJJs-slA<&+ZTy*kPaqci8!j0zb;x^PvnR=Nk^DI|J#y z%9)(wQt|ir!)@sJ>;7%dDY@@=l3GWSUJVwUIc{O#2VT;i5O!Xoz@Ks+CzpkwoxxCf z*jTAX!Ys~Nxhy7rYrWB6IrBQ_l=YrTE_pVWx>XmP`^85=`Q5{$8v9v2L_q-MO!ChM z@2!KOpWAQJn4houPITONX^6CbBl8;t z!zd?lpCt@>9R!UZ{Vtj3n#Va-f3J+MQ-bEZHyz}h*GuM*k0Bu0Mhnj4ilgC$Yp`Uy z?hnohq?`*m@9JDtVzW6Xh;jy3%>{=B1wmQcnbH971)KwU_3_;(r)vnCuQV|^{U(M?(YK=eYX#@| zBAT0iK0$grS8#%<&D+_zVP}aTxLkLJWC&cuIp+?nj&DFYmkyoaoRriBWX#^SlI8j! zUO$$_$3Tv!QzWN;f-{_Qy5#vlHYEhY;X%`+O&k8?oGDLN#zzzx4GZA{=X|NNm_&{2 zAQkE)I2C4$fh5}*Qso7renwDE{q8xSv3npaI5b6ilY1%W%t%-s|FGm}7*ziv=bW0c zgcNzzL7MP5kjJy-)EIb0_YJq7EzVa6<(MBT4hFM8IBz*g`Ym8N=d`N$SNw8%PEIX8 z$2sn1%SgFn?WBR@1?LIn1X|9LY*(;$8wH`1b3Cprgf1Qi18BXizP^%k`e>HK=dU^% zYBxT`IToQSNUp&S(%CYCGdssvcw1ERrjMuYc;8-|XXtq?V@o$_HPC2?Z4-9&Xd#?FDm^fVs%wYA=|pGvblhl$D5t;@--Pjw`45*&vCV?pCQ zL-O%v{fa0UO>OqA&IK=K41>R)&y`NVl8v?CSajMPZ%OASyZ0W+Irp9{C!3DelCC(2 zcx;A`g?kUDN*nu(;G8j(lcRkO_&j$ zN-uf}&Xv%yP{(JARK|<-x1(Sz0+cfU(W6K#wT5igrTM_IcL3Y z70H>mrj+NtIA0h3918^sOpz+B^yHjzl+$OJ8JLa^fNCB8mO|#Nq3@fRoSbnuei@yc zv>8^Db53;Blg=k=O7Eiu$7%IgxYTUCH1b4$&KXZN_C+2ObEg1!KVz4)xz$?E3GqB0 zUw2m|9PU+;a~6NrlXE9(NFN6aPM&>Zp-sYQY1Pu6oHK!PuI@91!X*M=wpY9~sO>t= z34e4dK4@bk%o$_BIr&Z3l9#E~r3;ealua57wekc?VLO~SXCmcv>Gy`zHw%EXQ3+Cm zV8QWUcQ*dw%1DUq{D#ku-LAWqOnRx692*Hv#E za6r1VNz_m0gbVTU3nSs|;K!Vkcd(x1pQx33O%$ApO~%2v90Q~;6iW>`Yljj{R*dB^(u;^9w1bY+uQ<4dI;0l(Wp= z0(`dwK+W~XCCxE$ebp#`H9loxBuMMlbI!isSCYB;D@*k(Mf)*5HV#a0I!X7IigD8v z%IOsGFB!2X03L2WD~+)doEKMa#a9T5gd>&2{OZ%oD@fxZm8H~bf>XZPcqkOARf=T{wv7-JC&tb%>-x8)$!0c zcWbHnO);*VN;%_?-y`Gy41k7kQtKwQcs$c6r)KyA5)v2yBg#CKcBTqWuQBi9yI4oU{110{9%SYE6~yU6RVi0( z!C8_r0YX06Ny|2garbn}*X>OlZJ= z^35YS_t#E@#l`HTqN!DQJik-Urvjfy!%6`#FXELn@S5P5kNFz^@7D-3^=H7cJEinjAs@Bvn_-O=e>9L#V z;}ZL?Bwl=zSUM`FVeIV) z$TjQ<=Patbifp}GTPh~sH=f^)hLXi9NE`bJ&MeA#X<`aNGyI`!%T%dCq_{3_U(IRg zeL@_ZC2)!W`$JeoH>+}^uPjU z_V2Z}D?Ah)-_J>o|FxZST8z$bX!BbHgie^j<0*Y+8*zQ_C>`u2IJOZp zz-(|H$!}6~9?yKr+0(TY{M+6ac8#(itE%tfocytc3^n~CU`^y=&e1m6NebQTF4?U2 zq&oU`hFQNsnN2w33NlXE6F-A#`D z*;o2fNN^Tw{(!$;7nddmcIELbq@02C%fiiELm+5KJ~H0Nz&R8DC~2^;iGc1o+i=eF z7ICC>HxH@f@}WGQQem^9YL&9m)+S;eU=ih9tfhg)GY3PXodrny<_VlLEwr@ZYhl`+ z_blX`9;xx9W|*&}Yb7|5W^*C<@5<8MJRUrr#gy}+NIf{$a4@6{D?}cz-^V$%2bMK7 z{TdG4^7iJOr#<(Qrt$ug!zW)JkHxfkkn~k6^>ASGa#8RnG=IXw8ps&h~&xhUxplVMgL_{6256IY=yZ6Qw!VhwyT39lr>C!uv{7dQRl=ETtT) z={h*N*c%?*C`#_mP2`-m4=Wj><7h5o*ecE`r$0odTTPZ~Mhnh_l7B+fh{4kDL88C9 zjB-rx*Mf$@-cUG4adNKWQO>bARmIRw9}b4o=Q!uI#bMGmaGLblM{tr4E`efoqNHaR zMSp%d;5yP?&fT~76mIQXGiyXkaBbo^tCQVR(C(aIjNJX8M^%u4(m?XaZb*IiDbZ~ z`I2^r;I#d)0v;_`B+XsG##vFYigK2nDFlXkxH;q|j)=^A*lX1jEyG`oLB!5Yfh7*HO97JGsFhT`O9 zr?Z@MAhd>IjaN8qUox0;96FpN%TBD68Y~c;=+A3mn_Zl=_Yk}9MZsFi$v>?mtd+cA zr%ee`_S!kl>Aj_-^N%ep`74Y zrfdeMTbHG#f3kKP1)Hc%>vyGK@+o&XRIn)7@%MGkS=gtxp#g-$w&&|P$Nph5v0oS` zz1r-><5~M?3)t?zE~QRA!#SHNXT!|W;N9CDPM0Z4W=^}wIR(MSVACKR9=+JcIbD`q zAq&bTNZ$0kviJ&J-wK=E??`d3?7T$57W&>F{Yt{o=L5m%ZV@uE{cX;9dc($Wxn?;0 zyG`UBs!7+#g@^-Ex6_`Sb2@PwG~e<-TKtNgmnhguIWBI6;o10s;P$F8DOLI|=M;;# zF&v?sNyo)JK;HM)iBq@3Qg9!^dA#{=m=XV2S{cLYGYYm*&Vg>`;AcG${Q49jo5SyM z4jEU+U|%^LVtfV1vBOQ$|MU@QXimYY7rPxwBs`NY^k?-D1%Fdc7Cc)2Fe-vM_Xyp}fayu&%$S^b26B_$`g z!6wgQWXUaS1YJ7n?JQ__RHf-`egEIe)euT=jovyXzE zl+$OkDTFQ?0NaWbBbO>Y=A6F$>Kkm|kAg}U#XQ@t`S-}*`_D+N|8VE!GDPo!C$=V} zliO3yVV&%`Cti~v`vKq-Uz9vr^@MYh!s;9TdOHf9bven~&-J1Y$hKPNq#ZVb^XH`9 z&~?5kF?;xeb6Dqi%%G2?SKa~ec6m`UH<Et58nKUpC1}?N9Rz=@)4tvPm8kqyy5LcMBy$Gqah{Z{B^2_TR?!FoYR-4Xp&e<1_ z$jHkVrD|0K=S;tNc+fsKvCjXIbC^-_up8w1y#DaEK@oDKB#YC;gap(#lzcY|a#a@f z6CCiAw0F29Z5`#t%T>wW03-V3A-Qb-k{IW+1m=dAFxHT?5+ z6cnp}hQ~AI{BzQ1a+0*+;sDO6+-omPADfRfKJtZgnCNz)cVt7aeqfQKAjwp0yLdofH?0p*~{7w{l{cNkEi5HLSN|Qm7mn` zXXT}Jwz95aMv-t>TtKX+ACT~dY#Dh)`Y^(k$1||{J}7*v2zk6W2j?VE&6ckp$*Ed> zVbA`&B=5F=IOoszbqph|!eLNpv7WxnyLY7Hr)yG!bNx9d@$)|Lv@S^;-SR~i644Rs@qC%jwS7f4$-B_1yeK5 z*-trxPg_EvI(^_m^}OUnI&gdw2PRhJvH?ssTXifs&JtnkEj0j0}#8l z969z_a1KxoIg}5Y?CZ_O9b|1MR&R7X+N-XiP|0u@vqIGKpp;K!(e&%mw4s7yn0OFg zJ=BnX*Ufo62dO5XMIo5bus3)-%}drbX7xt*D&?Fz4?Y58-_;^1({ppq5o+_fc5axuzy*pMijp3Ea`JeZgPq~-!BLP> zWhLjl4={lzrnjVkb$x(wTQ*9B%a`kr3Pba7P9lA;*w#W&q>Kw({ZN89ycV34<;@Jv ze~tp%VGB9uY^n*QG`%CO?U>Qe^o$b{^?| zy&=T#Az~DK88(}9mMzZ#>lWXW-rw!bV zd%%{V6-c*27MxSzZEM5Cilbohvfnvp?HN-b-p?enyn@py@HkZS){!c03vkW}%IOt$ zmsEe%9U|seB1Ps1&Y}M842?gGgffl9I+-IabHX1VUr3X7_W~C0wALqJNLL^M^$K#% zN&4RH_;=*oxb8InUYQ(e$l4X1Pw3a)@b}}9Q2Xh49?!dLIib*~S5lLnf-|SUNoZcE zCFx(Q5a*ntn&UZ4!BDk3IBlpxT5l8_%gP-LbngjVPh#u-=^i>aGkCb>g*32$;CLNB z3HLX)Ay%IS=QOoRuqy~NuRFu0?$t=;uY$9)R0l)l2P5I?@VcC{?~)ln#m7>$n=ZUu zBgUVC?zh{KqALpXc+ODH`miD}a znQs%EbM~j-=K|$ice8}tRh;Smf*R!7Q4vqxuN@4zZ;S-z zCEYkDBE=jQkGd(%cNd&71J6N)2YpH3jwLwfBIVR@v49B$o#D~%HAzsi;Os8e(Qxzh zNcdnT*1?88H;3J4Z%KW73(jim^KiMv0CJ;dNzS=MIZLNn!tDp$VBCz_QiRKCBu+8s|)HpzJmL^<)D?L4lZ<$h@lT0}StJa2|Wt`z0)FUZf z1gDC7H$&0zk#H}mBade&F$a_352RL`1n2hDi=a8|O|)MG=Q8E&U1LS>!_H9gm@R2g zSa6;V?_pTnWh8t(xS4Z?pE83%m7Ynpk_5-q^%9iL?@Jm~D8u8qLOJ9^Y1r|w8yui( z`n;M8&ZY*v4JXQtgcHZNaL(*oX3%itE9qXW;5;du1dRv#lZ|=Ga?VxCaamplZcXk6 zmq-(Ge6rv)GU;!akrD<~ycTiJNV?ASk!%3UO@|<&>a-Jj< zfU_OD!G>r;dISp2@bg}V-@U?MNS&hmI(3dRgJw%iNtqbI(Ii}kys>KL%#uQ3rH4P~^nQ^OsypN(Z+;h?{%{o*KM5y~Yggi& zTa?qOl_`|E(iJQ{+K_s3x%Qn8HsqZW3bnV2`}3WZIico=LS*XK-cT+g*e7{-Q&f?d~Z{Jc+eFoQ$+a+5V91;=vb zb;#9iEE%U4oO_fLT=pILmvjZ&g^py#DZyz}YPdm~9tzKHF6NxvbIicsG8fSd5S-`= zH^8mNcrt2iH6G7>%CYEV0UOG8h1umC$*TgaA42!%`34(I=ZC^9hu=A;%}p~XJK2In zHx`^TYj41WtrN&02W!rGKs7tx=7Z?`UBR(tNAfwJ;7q(4WC&Xp3I*;Q2JO)KjT+N|l za!&HbRB-nFb`#3c?{GYHUd!W2p`87r%wf*4E^zNld-8FW;Ows&Xwbxm!oAO8UrFiZ z=5W)}jQA$?1S&E4@a!fGbDlzmgjDC8NA$gIFAGEQbzQ*Ry#v{CQg9mO8D@w$6$(Lf z-ZWvl@VDkLsBaE(+aNeSJKX|n`knUIo(j%mYV$sK73jI53yhlQNPPDQPLKV?N!R&;^OSO)@3n#*?YcmG<4&YYdDd^F z>^FXfQ%~sH#-^oo>~D)i3$V0#Ej^kfIANx@VO5nGB&u9Z9?vssBRwbqopoK{^`lPY zeMP}pY3gst|2PyHm#ob>R#z>c7QB>}j~ATxwQqy(!I@;5) zZ*(EOJOrm!+hGRBL!q$SvkQ-BvUM()IQE5P<{~)dpWcSm@8^&u(`)f^y`-Ft4@-di zNheshz8mS?LyqTkpkd+qP`FZueIJ2|NypN;VEl|1Qqci|Q@p?(=(TPhX?II-UQwIW zfU?l#rV}(T+=H|+5uE;0hZ_!z35Al*{Wzz?CJU%r{k1fFp5QF>xC2A(%_lKkYx8(s zQ_lP6i^1hDCunxR2f5Z>a1N~xF|=?Ch3z$4bI$B@764;DNTq!Q$MWbMI9BXW^7>!F zc|$p2rgK3%-3gA==uO%e6P%CYvKSGO^*oU^l?1(bIBM|!eeaDHoZ7fS40 zLc*Sic-~RY&5gyN+7c(I_MtynKU#2_T#GX7GK4^!OHIzXy3!m9Z_Poxp9+po@Lec7 zaVdH5NpRj%&gZigq2Wv?_*`)y$=O11q%&g;lOjUErEq1=$=$*nHl*ex7RAJUk!pPeCzW#gY%d2Tb~}NGtq-}}T5!G$m|&P*DFpl~dveaW{${YGt0`F{_kT7t zxd*FV*O2Qq1m`2=SihSbjrUOEyIJ(-KNXu~@V`F-zFZr_IXUR_Yx~mg zJ5hWOELx|wIL+hHZmypT-(#=QlZ2i66>VmBsAT_q&1d^@WsBHH&55&5=r@U!ykwr~ z?<@xVL5A|x@|gJl@+ICKZN}a&Y^pKo-P=@Y^1t8zgBnPnj8-)1l3uev*0$NWg`Gck z{VER+`Um?FpK_M!T8T2fl|yHuku4a*f_@`0Td!h5TizKOh$a2cp8m;xtV{~ie|vLZ zUFdHmO)93v8b$wR)>bBY_;2agC6+<`Dw{FYU*fvM*YtRqM*OhY)J$`eLNt~f{5!JP zr~XC8HD$ro2_70yhrRK?<9{{qzZ&>|t_CX5dsn{y=Suy*0{^cDjBDWJ2}i)6^k*m9 zM3J2QNiP1jpwCi#)^0F$HCZtKa#~-(jM}kWzM6s01Gz{|^v)tmi-`K9QqeRD6bRqXHPCMJJ17r`ai zV?CZcQI@`MVxr+cIZUExr;GLFbo4a`{gDrQ`fAV4BkIy$(L}r+cvp6xvgC>Nx^YM; zIxT5zDgNr@PX{l*aJ2IDa-(yAzd&HpZ`(jn*S0Nw1^TOc^v(Z2-t-R~m*u9vE9)2S z)84%W~)CT#(AM3 z;{Sv0?I_w0{YXBdfZ2(*_;-ukTt)ZO(SA3(4j4tl|6}H&-_AZ`eRQT{KkP_#9GKR) z+23EkevQJ<*x&3hHF0A9u<+B4T=beSr`EPO^mgtudM8Ok}B(1ouCaHow2{!kGLl!(ChhSbBEg_={=g&ov1JN z+S1e{r)ioO#uN3&e#_3mMr)Pn&xu1}>>dQ{_u^Z}@ZXuAdi3vKJotHJ_dUj8$&(@nVt<^noeW2>Ahes59AGuNT@5=X>E#t+~R~+9iknPxK%A>2NpND6l zqg$9~ph=+egP;8U>(_#5%CDovcS)zck-;y@dJ%1s&W~wJ*oW%H{1d*i@H){lMhb^1aIY;`QeyxbNxI!zNX86*w zxjYle=Ob{4-9q<4s>%L5@Zt)mO&8Tc`Kv1QDROnEB3keZxNSeM-h+9s75?4d@V<9*pKC# zy8QM*pEF-g_$7%X@yhCr^{bG_oA(J=&vQFYA#TYZ_qGZt-Md{AiDQ zt61S5xpsw~p(Mldqdn@QWj%83Ivbb2t*ZQJpQiU0?HRd=D!rpxFWaL&RsI{fF;60l zTEF`Ip*`xo1BCx*nd9wb9Dgm9f3!z^vaCmL%EOjM^{@7i_NaFlCj28;Kk2QJUUr|> ze$XEEv9cbyRxwdVddyhh`A2)yYXgOUUSRsB~`)j!&!K2+8t*QJZ``KzYVqdn?VWIb{dReEcc9_>-@5-j3Ju3cAS|7={s z4y=E)M}4BKM{dlT8yVD}ZA;XnJ?ia-3;)Pr>CvL3ls-Hhu`ef^<5>QiMsa$QzUGm2jhKP`T=N4<0j{h>YTEk_Ff z$hCAfKL1t}5bWa_gnG0`eWYTQ)NAJt!`a3YX5AU%nm$%XpegDND)7B z9eNtqUt=Lp)1y7=lVv?}6IJ@!Dm~hx-eI)xkKE+QE=Kjw#y9N1_|YEqv9cby4lc&= z)A@0JpdRf}AKgyaBR5v1udC9dJ?c|sJ#y`O8T)Uk(xW} zPnPw_wL7%O===+Hx*qLO@6bW`N3LCO_4)5iE@0& z`o@(tVjQgr_Sbm%_Nm{?3t(>Ckl>jD-9oudwOUB{C)g_ zgEU_LfkWMb#kpr1<=9YYYG-l?4U0iJ9^@L6!#S}nD93t&7w8{SPt#NrT2B*JPZMgZ z3A5GM*x0Z@L~I&9`-XbuST9X)o2A~ChQzN0)-O?x^@QFt*j@gd#jYI7iP(kKfqkYJ zX9=y3ji-&qO+$;I8RRpAAdiMzZbRRb*ym<()a{x ze5f&-2J!UZvC-^?iES2VBX9%qF9?kZopC9FTPn1!dA9mkTj^#uQt=*^#Rzi3G zz(CKS0DnIZ8oEDq=HcVzMPu;`76r30Nod##+o5tyr}V+Q5V-hQ7`H zuwRs88D>9J1R}9BXyf4)>}JC??!G<&L4E4><2u&vlw%mC6H|n=TtjX6uk_5=_zxUR zt2C&OwV0l_?k7H?XFdJAE5|atEQ+?J9H)q~IQk6r2~N|q@+!w7%tjmH;}Ps#%iGgu zkauu(9#4?ZNYAwLD#sqo-p`rOZOYY8?S1KK5rwHvKju2-M>*!;x;Fe0PuJNtLHfqy2qb$0(&jt$sn{I<&O6@jdkYUOaNH#G@#YE;{oUGrV91Eb9 z`ww;t4EFSJ<#$3Fh^SIU5VSGb@DJ15qH(N|@^UTM$j zp|V^N!BW+rS{g5@sz)u}M(8iRK7wm`dDUW#rh0YGV~tta&sXz?4i9GS>)X@nLV(53+P<=1uePIQ_VW+cGBR&~*#4A#d9{X>TN_#{jNJw@4%FSB zy5;^`(N|@^J|k9UZ7H;dxanxZYRLDU^d^O6Q}+2YVyCyMGhLX5wJBvkpK0(O!p^m_ z53l597GqZJo%vGs>4h&*FIDJg%Kkd~5`O4KL!Y94tPjI(qqW$tzBFqrw2Z6lt8=cR z@2l*GD}Azlg|d&$K1+Xg((ihA5&104UtvBg^ms1bFULF=l^Gq*E?qt8hL2!PS5MYS z;m;8xgCF<<jX#e^{fb)c5fShA@>$5k@kp%9M~=%|;RpX_^NFtR zzPw$t=L6cK-sOYHqain0rLW5MCVY&-`%$tz>J#O^k?Ziz*uQ!{8SPPTmn!^Y9I+}r z^Un@;9WeiBk9xhVN3Qn0v45sv2kOxt^;RE+f8^>_dRBkzKt0-{K3dizSNp-(KZ`%i z#y*hiT+2_!{?+XV?NJ{i>yaC((yQAK+N0j`v+$4HRFxk0 zuHgAcd(?-@dgO-wV;p}?-ulwpAKIfnMb;xXRi&@2(xW}F!D-u}=Y^{KKRxv?4Q)30B&N4@uF5kGS6j%DOOU61ytPnPw_ zjs1=u?NRUWMfgXq-SMpbqdn?lWj%6ZGt{ToAKIf{`&IZyuHA{O{i8kVV`M#YW51(E zd(>N+H0JkTUfQSXvN#E;xW zm0o@SMSIjI%6jCcnv3(n-O_*5_aC%Jy`8D>k6dpHW4-$Ri}tA3%X;Lds`PAri5>X- zMSIj+(H`~QW+Hy%rmFPv zBJ;HJqdn@AWj%7Ea~u0tmmlp>?_e(cBR5s0SC=2{Q6DSok?Wnu*uT2`XpefWh47Eu zRFz)69suo8A0z9L8=BYHzqs`Rue=C(9 z?NP6n^~gBap|asA8osJF@^{3AEIps|1T_#f?2A1&)K4s9W0y}JBpk9xa@V!i^o zu`0c~{?Q)wdRdQLZDC{oYCYPc-YP}-M{bNtUtd-KXpj16S&v++BF6sJ>#@)t^{KKR zxiKoe+CSQ(-usb=AGuaVv-Xens85#l$c<6yar+gvU$jTP!(-texmLxD{j1|gd(_9u zdgR8a^y>OUd(>;62>-~nDsJpw-Tu%X^)a#@xq6jeJ$^=e)LT9k{*kLKVeDV6M|;$V z%6jDLReJUF3++*#BI}WBSJK$Oy8WX)>Rq0R_>rqu>3JfRUITdk(H`}QvL3lwD`Wra z`!Cv~-tM{Zk6gV*#9^8KiMAjRxgBq>gONYqdr>JV;tJj z#{SjykM^ifmG#JtQR&6=FRBIBKiZ?-`=y8YTE#r=nvL3nG!^ZyA?Fa2qkNHUC#;Ek_{uA1x9_tCY zRuA@@<9o_i7C&1@pv+IQ{AuR^`n7>{ezPfGWaJ+ZWW$yh*|>RlxQZ1ju5Q6Jf9c~s zL|Yx#O0sd7GEbQWC&<^w!&4?vz&LxXM`fNe3%$Fqr(2+FkiYM6wi1vMP_N8WW}&Cb z5uUE@d^0jti}T3lw3K;Drf=ux<=<4(d<3lxx&STEvvxqBKU*=y)*pHX2C@pOXVa)& zT@zXlSeMFNWfn1HT$gezd`?f1bIgLHs!LH8c21Q!%PjO+#=$ts+-0^o0XBTk1dm6N z!^}2Et`{DUA{Y6y99F-|oMslBOxv0=r4inccTe0F98f-%sth(6*hXt_ZK-MiC+c~+mZq?4Yb62qrlEUrVXXab{c}Jea`Yey&08fj$Aj@^#C~q0DdopnvDqF3v{faAF)q zp7UFdda-1sjtv~@+Saezz^0>9gG%z+N46|d+!<_!`_ZM0tj?U;xwLldMmr67pHb#R zGcGH?U#iZ1`h7;34`uqFI`@j4=(lD4v2)MX4k>e^8J8vV^QO#;{$LE>oHx2u$V8bR z{g#v6^XBF6?&j-Cmx&Gv_I3^M3H9`4XVJE9-SqRP$Y*9;W`6!Mz4n#))GYLwo_}RN zmFa)r{5P<%Yruz1tPS!yQ{+_tZ`YYKjZv9{{dIq7*H*`Nj*jg*wsvmam0n=1Z0tH# z=4*f5m$E&uhR`6*k20_O>weP8g!hYZRvvbLQ|5oa_48xbD!WfB^T0pIF}hFlxpGA= zm@zWx>v?$kdIo!nRr6_mBvuw>E;tMQcl#B}oba!3Tok$8>~lm8n3YSJBhEf2{h6%H z75^-U_oWp%<19Ft-lLQ`<1F+U-lN$3q%vpB^gZ1I{piE7sivF%P`Vj|ZamO-v(KrQ#!=>$Sao&9(kr*V||>FjeF zrE!#b>g;nGrg4<{>g;nA?OBm`&OS%co_~p>XwQl~boS#>wC7*qi1uvHu6IRV`rCNE z*YDN(4fpkBTPNDM`38AX96x{Tex}TKGj1l&_)MQ2%6xYg`b?i4%6vD|{|Cm-WTgRVZ`qj4j4yo#@tJf4cE^h-Vnz6UR5~4jw)< zfc1Xp=D%QXx_?;S^6KxWY+K6QdlqHQw62u7_bl|8)|E2%{$JJ=dmbzE@{DcVwtj3} z!|qqg{Cp;5z2(sw(i>8 zwOeP$9<96bO@^$UJFvJEdG~M2$FH3bA3qQO5IULdN2iDbgZfnJ>EqYY&5uqerQM#b z+jMqx?A+7Uxoh*59eC=A@mbu;yngoMHo~UujdY@1WxoI0xbeJvQzta~HvYc8bZ5FV z+bl-Q;78}k=>x|2ZE@dZ@hjH_WIz6l>z%a+<$8gPx#=fT-5!`;xn3ZkqQa zQkT=7#im$Kz<8OKGrgI9_kP3Xca-ZCGLO?}KHq45hcT3E6@G@n`V7kT3g0q*uFs%c z!;o>EWj$xET*JWhKQL!%+sLL-L$=n1-EZ0RO1X~V+j8N3(Wrhi%$F$FGyEXO=sel8 zSQKj#zGeJy9e>mJSFUwn+;7`v)^pp+wGLV6Gwp9E*E%r$f6({OfzM0jIta#YEpo7( zJn1ZyTQL1*2>Klyng*I6I(O+#zuQ3mdKj^@oORUPX(o*Bil^TjOCS!|4y(oQ~f5twi2kwU#f2IGc z-uM19-;l2KlTH@D;lB5n6Ji}oOdaw4jOtg^>B(unUgUfG-jRpvPApFvuXC}iYy3Ts ztc@%8y`w$qLuEa3qg8sgZpPK!ByHb2+M_;2)+0AnrB|=}LVMJ^oD%UP*Snr^{LDW) z*fr1EC)%SvQPv|jS*2$hcAy^ZQEzuz_(!gbt+9Vrf9ya#+M`}C>yewR(zE!L`%cjw z^;Tzuf8;vU&)PrQqdr>JBRBCodbCG-~{tMp>ub^5+1v`2lYtVgbuow0v){AiE*6j_hl7?obV z?j7w>?{ZPZk6gPZ#{Sjk5A9K(DC?1{SLwgG{$+dA+g%d=k*jTL?4OmNjp5R+f7u@O zdiigRL$A`a`e%tb)T2G>t&)U)jKiwgxBe+2?f!%IsE?NQ$c<6yds3~Z`R#4!AMH_} zD(jJJr!)4izW&f2_1?)Me&p&^dUpPt>5?e)kM^ifmi5TBl8pVU&mY>O-r=(FkK7oQ zo|T^+=pXG-A1mvTYe$UzcN6k7J=&vQdqwz1Zn8?>S*1sN)W^trCVs85mg$hB&2>|cHTqCM(eu8H`O8?Dl-pTB62 z`b1feT+0^5{?&T4N4@1=8vZ>U$c_Gv9_>*dD(jK!kUP@odq33v(H`|FvL3mK-_fHz z>RpzK_>t?7$JoF6`bB%xC(3%{#;Ww{^N04Rw_7IHpUlzbHTJJwH;wkF*UNh3#;Ww{ z`a^rvTP+v$AMH_}D(jJ}&2Q{qef^<5>b+Np_>rss zjvnn%pDgQFx%%(u(H`}&vL3nGf?4}Vd(>-J3IE8|e@Bn@sE?8L z$ki6g+CSQ(-g33@k6itC^k|RzP+5;$ZQ-o_qdn?VWIb~A-_fHz>Rt3Ae&lM4WbGgA zQJ*O5k*oiX9_>+Yw?_C!uC{1K{;Q-tKhYlbdRdQLeTMq<=QrA;-fFGzk6dlBjQpqT z(H`~DvL3m5m0rE?3GGpzD(jJJSKQb?yZp#i%sE?KZMy_2+WB=;s589(%yFvKJIP@yLy8LL5 z`WRV{Tq`SM|LXFiJ?bqt3jfH}tMux9gJ_TXP+5;$yHdvf)#XQf)ThXLd5H^$y#Ff8^>_diDJe?NJ{q>yc|$!Pvig{DStV z*ZwX1BR5&4SC=2{Q6D4gk?XB7_Rs2HdH+Rw)LU*B{*jxUfnHgEXpj0(S&v+YipKuc z`?k>@^(nF*xrr)0-+-Vve`t?-mmMO0qH&LZm`$v1!+wBzok?T;| z*uQ$;JKCdOFYA$;sM4$J5A9KJ6)XHBH@d!gFhxVvX zmG#JtQR&s=XS7GX_bw4Xa;+K~`&aAH9`#zS81EuCMx|FjztA4_F|r=H+D69y)%P#7 zN4;fr;UBp%Dm`B$L(c==f6yNFp|T#iR*jAQtM9*PkNOl@kK7oQUR{4^k9wCHB7Wpr z*%|v+-~Z4a^@*|`xq6je{rp3F)Z5h*{*i0d#Mr;O{?Q)wdRdR$Xq8_5{6l-xTh$W& zk!#h|*uQ$;JKCc@TGk_1uhOgQAMH_}D(jJ}ZD#CWtw(#*d)F56BUk?&J=&u_S=J+0 ztINPYP4r>=MSIjc*a-i~)n}wvw12cmeXOiUu2#yxze11psMpGQMda#LdUg9jd(>k- z61i4#9+JA`hr0csJ?ha8xzWoHn&W%QS5|*)J%}1<9|nWxNx zli^-%rdQ@Ev(RU{MpT)n%tD{xnhiFmrOZ<@{SU0I`DWj{GFO>J3>nuY^_kYD6*vMv*2Xf)|5HTEcBVS zHDykd>3^uLsrJ1q^O}tDGwY67yI1Bne~@Fej;jh~D07?{*GK02r%!g)N*6*z0Q{+RL{>RUKXg$1VD|4dXmi5Qh@bUAe$c<)P zmMqSjBCq*_F?@60*dA_We)L;TcF&t~pL53h-j(^(jLV$$+CXJKH4DA!+V|w&lg+L- zWj>YZf8hL!eed$Kme-jgr}}@p&YWqC${g&k`%Bv+p5eZCWxn>;eJR_6@xFIuUia7i zq?HNxz4K=|duA!~zu)@#v1^sJ8)Y8&2RTOfY1YS5=7Jd`lfGW2dwi9-;4Jjt?N=ys z!oR{%=7xWTqs$Ti3P+hM{#gz?Ps*He7M#rcCyJbL7JAh^O7yeX{G>8x%=G`&no)K= zDD%l##P;1bq|7TbPR9M8@9%q8=9jaGC(~;}nP1Ls9Ljy~$~<%SIqCa^mHFoEbJF(- zEA!6T=cMlwR_33x&q?3+uFOMco1@tGuFOYgpOe1tU7458J|}(OyD~qWeNOtmcV(VB z`<(QB@5+32_BrYM-j#Xl>~j?DS&@IvK1b1>e~F`L&x(9>_Tx$4_pZ!qf6Mt^zc+1T z9a$b@6JM>>9a$b?`Hb{>e(UoWTodaexc56X;^7|I7Mf>nfDF zcE%QCv!CDhuFSn>QPxcBN|}4lLa(Z;^1N-cew;G*{$JJ=>&Gec@{DcVwtj3}!^b3w z{CXy3%yQqmGC!ZO{+m7C-`$7mK+B`d+kaa=e(n6yzISC_Kl^cKzVBU`@BcP#JTKqW zNw)XBE7t{NKmN@3y(`xXWXz>ypkK4)mcjQRu=b=}FOXe5TU(=CFOYft{n);D<=TPl zvebL7d2EWc0NLfK_q{9E6=au{VQh+Z0*v=%jE?LEk@Z-@9@h1Y`eK``(r7BeE!Smiyk7Yb3H@ zWV!EMxlZC|8OpU1Kg&?Am-tzRa?QlgFxYckxo#pWMrQlomFp&${y%7oykBibS;{pP zjLr7Fccu$7qUlPD)D~jB$VB=!|BQW}#nHJ%Oa3MNCj8%@+4au-u&}Z`@@Dzz|Mws2 z*VfO)qOj~fkgr!^b@z$>2WCcWcz*&z6l-8 zir8lczJ9u-J^mQmL;?GM_OYKDU#3AqlX|*JOa2dg=K>&CRp0-MqTmauZ57+9`26Dv zN)jINL2^j|K?BAlA{B9%-JRVXc6Vl&$3CK!)LM&*ii(0Sq>74)h*kwc$V{zTs$dnZ zQfn#oNoi}=j+>BUcPz7)b;zOf}ivk`=)FEac1lDzjVGm zXVcrZq@6SVV#TAr@c_=Nt={%@&(75S;Q1R?{>i@|&|d!GFK*GDKe_#Yl}iijR~~T2 z2Q78;bBEoq<#{VVc-<+#dyYN-JL$6a5f}bo>rejYQc~MCtvvPZ=N*&2;)Jc|O>VJN zxBZ{^^%YNf%d3xh$ZdyTr}mnUd*pSKU)-|ds9R39^H2K4zifT>$)8^FhC83s*>*p5 z*TVneoPB(lQ4h$?;&@KSVQX^J%4`4iK*QOMH{7t|KaV=t-sw%BZN)Uz?t|a?jz`nq zgO5#;m#*3;xhu4KKbo2k=iOU>ONH3`d~@;Hn^sGrYl{;}DC$E0If5+!k9*}=VEbF=%u8Vkh)|~5N`>~xrv{sylvoADXRjJ2I zcJjEbdFQ&-L9`V4+tWjTE~~uA_~kD+r@o69>QDVY|KVI8&L74}U32dKuT5XDcB1p* zCpzEylapVYUjK}V&P_`l{^`corr$hZqSH9r;e9^y+H~Kaj(7I?3x_ZL=hvo>`pS5x z@=1q}f8guVf809WdD{COzHY_q(kHxTyz}t@uRHs7>9bB7@BHCc{QO_O?{(>cM~-(M z_hW}&_Knx2-#K`^v+u7Q9^L2l=|BJctj-4>^t-9vbJU&Q{u3T_UV6}B z<<9GVzU%PxndhYsIB~4AGQg|ec3%4I8%8^uuk!Qb*PNGr?rEc) z@1EoEDPKJ={j=$j&bl)ke)IlsNI(0DQs+z0bayKk|n3l@Q+CtlWh>sE(P8hBIsovAZA$y*(sD!(aB8!zqL z_aA}|pD^~4&e3mi_(xAXKYd>Dk2|v$I@~IqpRO1=t@HYD z{+v&qpT2wDi#y9+=jUH@=lSV3)|}ee{7Q%aX6>8PXRmot=a82>yycQNr!&hpbZVmx zzwj4tPG9xN^_|KI4*zoKE$OCjzp%64BOSiw^KVI?e)-zYYaixt@fmMTH*9)A=j~rT z(C{<++P9_`J>itj#*V`e{`p(eS8ZL>`PHW!{_@}j>06dRzjOJA9Dd0i7o;!y_(`3g zyu{%zwBD9J;4vq5o-yw53-5Yc`kl9&(7Eh1hu6LJ?dirlkL%q2REOVx;DzbW8ml|M z{;!AI^Dln)h3N~gI<|AgzdL-xV=qb%OVZB2e$U}UuDU24ec_7EVV666{?YG9@A&X@ zI(NR+;h%l}9qG|Oe^%!`FLQYPbKaSLX4x}4-+8gahu!$j^vIVV-5LCShhO--ccm|V z|B;=)*x%uA{KLD_W4^SkbH#5Cu>PER(!0|Qw=d~D;TDJgr2X!6|A!skdC=7k-*NnV z($^pM^v=vV4u9wR_oS~Y9oqT(35QpoaB;e3(?I88M>%}w$1hF?K7B~%RX={1wg1JV z-kT2o%~Lw*e>?odtKXYm^z|ooF8G$iA6Rus`mJw0q4T+SIQ-;KUy?rHHwSlq_j?Y% z;*h^gU-PKPb+&GC_>61*GX3SzkLkSNH4cAz>HE?(=lo&kfV#sE@4PQP_aWBaArJgO+S%{nombuE@KJC0K>7ygv1NfAKtr z-?Q?==`sI#XZzp3D#~cU+sS_IQ*UOe=i_s;$7{Fk2o(e%R7?d>;z!{K*Mel-2) z)*rV2@FItgefLMxb(7z3zvFcdpLf$o(+~XHciR7Qg2T7}=A-H7PrSAL{ev97>1mgz z7eD8p+Xo%)@MF%uJbm;9H@DyOln2`LUV8TB=__Zy+5Y*v9A0zY<>{fX{(Ae#O@}{t z!R6^EZ~bcfyN5XZicejht~l?@?E%wEljM*8>hkpRcYdk;!)v9d5^wmM%hQ3U{9XI( zKXdqNU%fnC`nE5$w_f1zQIG#vy5i41+y2VUuJ^w3DIZIZNdLP1{@*zKtK}a{2miU< zepkz{Kjx1=mLBltt?jqH-{B8!`dC_d*LCfg-#Gk*Pk$_Z;udR9iM!xs4^y#12 z(tgNC9DdC&KbC&xe%G~s{1u0fdFmDE`yP5-`;|X)_|Y%8B7Mbq*R>zM-0^eg+pb98 zIeT5Z^=60P{EaKpQ=hc8{e~|({GvyEJbn5(?RMueK7RlHl8>i9duOM8=sJf-KK=3Z zgiHRq{qs*beBkd~nZD+GpKZVCP^X7mUVdfz(^a2q|6|4B>wkD<`h+iizWr}sboh~_ zPox(-@o(E}PIG#E^51_VU3=m6?O%>LeB;VbrZ?UGckQb#ba>>iKACPg^-Jwr0({W_ z`>XVh7v0bvxzW#m>n*^A8{3b&$>BFX=u_!;{^`c{C6Dm=@IND;O85QXm)mzG4*%&b zpGvp<@0Z(0Kg8kNH+(vM#7Dl|zVlFr-}`r;PM`A4FSmca%Hd}|>oe(P@BVUo@??kq z?&{B^cl_qY_G4e=aPje1rC)gYjqNu)!{O(==Bo6aBR90qJiy_zzJFEv^k;slT@C&F z>WNpU=U(}D?SFZP_jkiZSEoPw*x$CFc(B7ix%KKaUGn*M@+rsH$YZWaKk{#%ZNK*{ zhadWaYtomU+ipMhPRIYNo7bctT(_nD%6B{bymwraKIcbQx7UREw)Ugfq!--vsrG&s z`uL7qe@%MJLq5^I`Y4D0;FfFB%YS`&`)xNlz5MS3Hm6s-;j;GUW*q+7z~*%3k1lP$ zd0&U8R%}iO4t{U@KW=yWylegD^s(P~NBg^59e&|UH>aB~yP$pl3mraqVsrX~&%LSr zgVP=U@5bizTW7tl{i>HZeCZ~h_g}AWKlucQk9h0m^c9Dm(?0MQK404J+?@W$W18)Y z|Ht7Ue{gep{b6UduX>-uZ~MUJ^m{Kov;D8{aroxH+MI5fI<@_@S37+EHJj5buRpnc z<_jHu<<(q&_3`ccfewHBip}Zek2$8j{Ok9(`TfmHH>WQ>_{jF#FL(G`JpWgP!`j!* zIy`;;=Ct-ZPibGd#NnG>zd8N(;N#l0f4`sI|E)jWoZj}sgW7-lX@?JZ#pd+Tt&eCQ z{bvrplJ~#*!iTosdXmFeO>a)O?DxR-^}pE1?*C|Qb9&&TlJ=T^cKE_`Hm5f~^uM?M z{4)+;aqi}H)AxV4_3f8BJpNkXiGSKUQg`@~^yiK@etGNrPja~arp@V(Z~vRE2M##= z8Q$lR^;d0u@|}r2@3Y|ZvSU8F^{qd0_{_hifB$~*)?Z)haOrEC)59Ne!Pb9#tHTF> zAAH_+?$()&4xjh4&FQV5dd1fFeZk@9{SWwg^yt=G?;rZ}fNRrBKC^CX<4}hm^tfx& z&Y>%}{`kcX-@N47^zeNS-FoD!9RB2S*QRT)eE8Ns{jS5GfBv;;`kMc~?u3IJU+;R^ zwdt*Y{-x{wGQj`Tyf!`as1IFt@iBgWWE0Q3`qkGR{BnmkzKQ2mkGgK@mQYMa!S_r8^z|pMT=|5C8l*e{htKcjb2a^T}h6 zdGoZx54_)&H2I@HJ!b2t9sc-3x1Sj+2KF@^DXI_KO0+dTaZuRe&d$({OA73ieoSJ^Syo-{4^is`d?qL z;?~dj`Ex$DC0+jQi&rfDvBR$cp1JL^6=SzJ{2za_CB6D9pICA9Z4N*D3!MMW<`vbS zIsC)VZAlNh_-|I+@&kwe^TsXd9S^u+#m(P!_@`gnl8(LTYb#zp;QZw9?`=uXeZ|cy z9=N~5fA$aD|K5LD@u259d?fJofBl0McfH)TU3vV`&QCAfxFx;dya%rQ?i(E*s%=SMeb)Xf|MII2Kjvjy(qBFIp(_h7bN>9A z=Wa<~`VS9VdCC@t+t1|snFCio>ImoW4}Uo4U;KM3U-bl+4+lMLOZv0d{{G6FU+eHq zOE~|!N3J~o0*62Ov@PkoZ-3Ovn;z`?&7$aSIcMVa52dW<9?U=e9c;h)*(W(Ld3bWj)YJpI zRof`2Jud9IPVM#o`WWbAppSt*2KpH2W1x?LJ_h<2=wqOdfj$QM80cf*-j9J*>&Tti z4}ZuTJ&*4LI0fVvIOy#T&xe6k>y8~BPR4dE0WvhobE2zezQ?HEaf&+5mcI!B#HJxvsIlV?Bwvn;|At)FIWIfmwVa7w(qh2 zpVsc%2N^FDqUO@Y_TavK(2K7;u69)3Hc|F#`xxkB;J%Il(_VsokV#)*WqbAkr-MvR zlHbWtxI_Ek_pbQc75RUGr_E~{aDH{P53UUUzCEqaZVK<)EBM8O^_SMnz<*(V@ za_=()ZLbeH7x8)9g?;;=7gxJB7STS4`rWqdgUm+IGvXNa9_QKzx88M5`{{+dHtSd~ z-nIF*&VAE9i0?h0eeliq*8)z{mDxJ!i08~ci1t9V4^F%+(EmJf1lb3zdP4j_J0WATGd@b~rYgFL?%?d}Ym*#~#Lw{IWx;x3QJg_om!5cRul*#{YiQM>xP`*E&) zFgJd1{fB(K{QkxMJ0E_t_Yz(eKZx%=pM9{<_(8M>qJ41CqhDnCJkf5*p6n&;gL{k3B;oRNX=OfkpmN|_3yL4y8vT8=q-X98ezxr0#h3M$=g+P-1CyKNGclkwQpWJ)wgA5Oghp+7^d64wiA7tdxFZD6d z$H2V^13mdgJ)0dZG`}c!)AsBGvjuj?KDaXY`}*;NyzVMe+!;8FAKdl_t{?4bd@gqR z8tsFq-)+l2$dXL*`c@n}KkmprxZ|(xoAyC`@7=WzqCF7pgXK>R^dI<&Mj`*__QApH zoAq+7k?h(k1nk1zG{pP^vaDdR)Qu;eCP9lByaYy#S{-3#T+6VEych^3M_CT}`PF&*jAMFN> zLjF(oLA6ratpEb{L1r4}8}BWfeQ<6V-#w-0ZVG)8t!_Ks6?vI1jOD$Duk9(kEq4D# z820|5kAXf0`WTpl0X_)O%`fUbwLSY_*|KFO({zWvpb-A%wGTKSbBWAOh&T9g{=JKk zL*4bsUy1%cZj$`kQ}SSwcX}_$H&tgcS?yih9-PGw_J3O6KIp|=9&ZaTNBbb^ciXZL z0?CB25~TKfk8|yVx$6%Oy86CpAH?^b&puf2`h#E(MEhXu*-rn_Zt(HQez6bgrD9{Z z41}GDADs3~@6X=A*D@^R=`_xXNVg8}EqRlB3U7V;AfuLksgHp^2JTH5$i)vH=o(6V zyY1Nr=r`#5{%0137k6kM>`s2stwFx`;|Ebr?^t&Gu;j1L?1O`r_3eY-rhO3gySes( zY}ssP<;P5;lfiTCgYOkTzIExJ)mDD%zt3qu_^S78x$Rj#UOuLa{kNAUvvJ7YOLmvm zC&%}m&pzOiU~6fA(y9hd$4iyu@T2CQS}@Gm zFF1a1$B(=}drHsU6yB=q?J+o`&)zZ0#;xJx!J*?8@!E)0DC(8oX@1APqi zVBoi~f02Ea+8W)VeUS02d?ywbKS-Xlcj&X5Lf03o9F6%!%a7SR@VVIiZ!vxl^}D(D zL9c?C*SADS89diMm>WMh_s6b32J&0vhxv4t?6snO5Z`+~`(UB*gJ=&#`{0l}9iP!| zNPcghOYY(?_5k~!UYyqcrn~+D1b9U6@W;k`k7nN-^oza6K9Ei8e;IxD^6qT>`u2fi zs&5}en&}_=80cf*-hqKX(reiMMajNNZmIE()*nQWE~^Hu9kC{Ij0o*f5$RxZ}GE5eBSY^zJ0LkGBuOE!e@#i81=ht*$0^u zIZr1dqzvAXeQ^E0u0ICyTjYlff4yUny_WE5-#-ZNy}R~7v85{G`s&&t;7YBFVCdjw5GxovEqx$wi#><4oo#ShJ zD(DhPl9-V7yLMzB#F#;MZL{Atf9wDm z(cQl&IdJdLXEy~5E%x}q^55Az@VVIKYm6U6{qCN!5B7ibebYXO@4dVBL9_>=eQ?{$ z+&+kQLzvdx!>V;BRYr&)lt?kM<1UyAJ7XW*{8I1Fp3-v{J73#Vcw6lJt4r|xLLUQt z4D>P3gMr_Q6G`?j87C z?D93*2T{Mfr|g5VpwIS9-$e`LeZ%>3_ChhgD8BdZ+6U1di1xw$WvBmWH)K!t(yDc9 zinFEqE?5OwOFLs9+%eL(53-nna5$GPwg>m~i+b^u$JLI?8NK#PeGK$5(8oZAf!((c zvh9nK9oPri_tCQFtF*BA!KT9Aq0ep#onP$s!PRH(9r(Pr*auO+yQl1fbH{wV0{JcS z!+bhR_FB>`A6gs(B`P!bs+hXTmVc7eJJ_h<2=wo0G27U|sn`Q|{JG2inA4k3$3$qU{ z3I4u*{2;Ge36DDiXX_7cKC5pZ^x`g$$Ay<;{2=Og+p-TbYFE4ZyZdqO`sBI$n_gDG zZ`ud(z2~zJ7P`M_v3@mw-0t6XTsfO>+Vf_Wmjft|DHYu`WV$3Pk+~+j#_SGEc{U`lvIfAwm{C#`cK3ME>G~)A)X5T&t^atJUnrzj5(LRX! z-L~ul$T$4m-7bi8W3GLm{Y?)o+_hQ9M-}hdeElo#O>%rbd`CPbiSTOs7lrqp&pue_ z{-)6$i1xwE*WEsdc0=}LFJT{)XOgkG)jI_uG0?|A4+eHEez0uWvfu~Zx$hrjJS^Xd`E3KP&(+2M(vW-`n&sau6-~!esJ?E@0<2PeDC?} zgN4QqqCF7pgNtr)`j2*lk4yH8ebAa{mTMEUS>4W-cE&z9_uJl|J>>`A6kcwz^0hsM zx5duCc9y35*Y`2d$H09B1G{D)P3i-Fx=pZt)l!5!HL(MB-) zA-ip1_QB!*vUljSn?lDIyL~Wr>)wISdy9P#^}B7^2U(JdWVQb8ew-UWnEU(P=u+aRXXb(jD;Eu1Ywe<(lZpfbOrB&|r~TB&%gAie|K#UMzMQ>Sv=8EY@2-6i?SW_??Eh`I52D@h>)-Dj zoIO2Bun(#e<;K`983v)Dov{yY4&%G0@?@ zFS`C8_6~e5cKIqjHf82S{qCN!55|6W-?R_nd+)A&5bc3z9~|^Or~ha-WSq}StJbX_ zsuydeXRIw1#~Zt5CG3oSa9bGPJ*DSv3JB=i2fdWA&;5EaayK8)@qWFo$^@v%Lu%&d z&G(GIDF3{LmV4i~5A`w7$3Pzgj)5Ngpa&@nwGVV%_%j>fp0W=v3I4vmeURt-!u-y_ znSF5cKlkl}UfkvJxbSkc52Ai|PuT}EKfiC<2l2gk*FK2$K(r5*|H$b-+6|Z8cvFue zDEpu_QEMJoFHT1Wx3fpMYfqc=+;6^?L;l12)3*;a_w<*agFAxz`9;0>%HwYP<^5m! z&QCn{97A~jr;mX?2KpGtVPN;|gUn}=%xfQ9GJOi?c5i>vD}%qUZy)6Oy@qmU;LJX_ z?fZTEpci*}JTAN(?SrV_ZOcB$lti@~$E^3bqxA<@|EG_a-@n*@=fiLIUNOHYzW46h z2hkpg_Q7QXgSP%4+6~#0y@Y)*St{=K_mhpm&TV@RY&3D=&-WhtAmizIdW~bI-pBGL z;>Byida|r8e}31>z0Yub<=dZozHcAw8lHvI{$C#heGK$5uq_N6sLJsDgWmJoiyve% zK{3^?2o$f`VSbVGvHY_ZmS6Oh;P2a;?1RN9N2PaZJ;(k(?%M~uE>kmICE5p3zuT65 zkWqV-$9F%@wGZyLzv=(pH|>L)!+XzXA1ri#(`XMw`{3%OZXZOuAsZtv$v&u7oBwC) z4^F#d@39XuT;%CA(!9>ba^F5!?D>(|SoceP4D>P3$3Pwf`S?M;KC#b$J)f$PkrCrcn{Z%1$zKbSdm@4)9` zm#@)2i2B{O?1OBMiDj$J}^F&g^u!#_m*uQkNvW5A1s`Y34xL4`EgIlgT>CjdP%Vl z^)b-LKpz7U18yJ44w(D5z4!sw2HiAC9+usxy6wde;+o_TkB&Dk%syDVZ12!#H-&EZ z3jVy_7v+{NjOD$@&lckc=N_?l;B&Fd*JvL^{qCN!5AL}0zG)xC_ugImAld`bKDc?6 z(|?R3glXM9U>{URnx#r|_>ykj&KB@vWTxT#HybaV`PJTIA1ubWXx~1_WKCY~?6^EX zVfN4TG0?}reHjD4jr^jnG})1T!1>6-@;G0ZeQ@Tp_YQq_Q|P+vgYKK#d+9`cKOKAF zEGH{}&F+?apE38DcZak1!9~y6JMejLu@9ntw=Mg?$03f@wvTh;2Xpg__W#X&(>{pr zJ)eEB(EOrk4@CRmjx|pI(Qe4b$V=Dg&-=5d^xRG1wHB-2 zV^862vGcEmQ*-~yJ_h<2xNl+LxA6Vs%tLmM+6T4OEWP+}$4VbD93Xx7i1m z9k+MjbFs_U7(a;m-92R=%mjTlqq)Ug%I3x0ZEAln;q`Ee@x6D~K8W@}v=1)2W1X!} zj&{RbY_3|jp)|8Qn-|d_tg%giXKD#L(X|c-D zm|t}LDSHP#7rT6o_CeI|wq+k=N@CuQ6d`5s-1x!V^#=z9eKwHaB0ntLK8Wun=udBl zGy2TzI9-^H-`?W)*i(30?EEVXd;ieKKpz8r49vkmw*J8NlkD{N>;taq+6NYa@Y{A| zAMDopgTsH}{P4Zzk{B z`sDk&{OsEYd44bC?+l#T2j}j)ci{8hVjo2P?w+y_PJ5`2S2o=ib16@=`EvG7(LRXp zy{q=YbB{}si)eQL7Y$mxU^85?u9>xaY1dRfftFJ+(Ur?2{aPw;Qg%*1vNX zkB^*lh2FbET|9ryJpH|Si?=iPC_A$^2H<wqVpYyo?Gf?k!2v3Xsy?UPa zn%kjQgo-umljLCTS^kzO8^@<0x&U|hw`TpCa;3DsIXh9>;kEN!u#o5Yy`tqb4cD)f zbX8gZd`zxi<=2JZ^p8&Hf#(1Ve{Oc;xsTpp_=!j1eT>r)K4>1ituId2Cd!r3tfieR z*+Y><8SNc>tXeqklw+67EZHZS`O$yu7hBYOt>?rk$DVxrH&7r3Dy5lbGEl3Rrjmi- zVzZbGjFjsb=K~W(erJ-|WMeWjS+4L?1X5{MrGZ+tTxmkoqxEX5mP{2V^lxd>oUN6T z2J44(9GNJNCY9o3>GY$HI3sBkr%J<#J!FF22b$GpaY6<9FkK$ziRHm?@lj_awc>En zY9!^MYNfzQz@_SDwN|P(%Oy^5LwR^`qB=CLE>D!KU3=D&!!W>ZPHk6-H~VCMavwO9oa4 z6YGP$ZgIFiR2?q)ODtKsocjiA{3~s2Cg7~jf+}8GhpA%S?f{(Pg_3fun$Rj=jZc6E z%gxDRV?1e0l!r?Np*)np`%tScTn`M_%iL*TNxw;BtU5hjnoTC@pPH*x8^YR>q+XgR zHn~{OE=`mslNPv}vSIUK(NpT(r_^n9i^HI*UK&x0x~b8upS}!4Sh>8h*B^lt6m#RhJ-#nX;cFYb(grTO541hk2zFf^wCHvI^9V8cYt@{^%|v#3BA@( zLTM-&XjO)*g~8THVgSRp>kWAV`8|q%8R2ol)n=_!G(SQ!>&{}P*m<&yn zYmBNLOO@e-1{z7V-W;nI8bd{BVwjI|h88M~YP~Q+Q&!;B#>ykKXouP4k54EJS4W2B z$QqzffD*!$Bju(rfBMmke`Bb`tB=%q+e+P!Ja1&AQEDa)sv*--p*%^4W``yc_UoH$ zO*G4ea%H$QlT4V@&>JLW-o23wWYm`o6f5OP#;C4w;_`aqbO_Fig~mj+$?c71Az#s` zg3yxHTaS`vtvFh;Ny_LA^3Y_aUaBRt`e{xJPt9pzNvDjmc~s4=GmcR%OO{5PV3L*!;HU{(Y$P^x zg-J~<=H5`1$y95G-%4rJC~DZ69;gnU#Y{~GxGrf;by*LL<1A=_-&yC50v5RHy?@W#E?J?n~|I+4`;iGI){E28C^^)s0sD-Vqos;wrhAsMW<8e;{{d4J)L z$zTF0mPQIpdcEFAaY*xD2U^hqBC6>)U98)Yi$LFyswT^IyTnl7*RriGC*lRA$#PTh zSg}5=W4#EE_IqF_m4-d8I60_uv>Pv{$n3V06zxh~F$}Hi$XsZ`+^xZIndX*YX3S`F zOr@cT)}-}!7%r)b@p5I{ZmG6L?Fwc=XmGS%oGLeGt%350H6)Y^hBa9~mKCWF)o5EJc0_L&c#nNL++Y&w4-?t%YX21k<$J3ohKMN35sUnK#5 zYR+VTEnouXTL{b@Atr{=n5-gX{j~b-rGikvodsiZ=sXCpMzcIIQE+zTNaLzZYU^h4 zN<-JMUsfF|6)Vh3lU`xk+3Oi<5Y2hhPO&hni?E4J$h5rgF51SQhs$6ep`K6pKnjEWoL0s#2I< zlIVA-{VucLBlJ62nn7EF?{Vv-3Yvb>mFx|2BbrtEP}+GbE)`Wfhe97R1HaJ zrsg#$4B}??hDmWmqFo%mgcuf+*AX&AA*!1os}u((iV0NAzzkI2d`^R<3d&&(g=>m` z%sI{%bQYOi9SU4ihitB)O?btO4n|2fZ}qlSG>J2O8W+HSvsw>;y|DzRnlfgO!XkM) zJT3KRczV=+k+YOVN{H6_=&X$bR9*E+s)9WWmI$pSFtR235klJ1#VIZ7j@o zOB=f-pB?C@#RC0;7QCqEbW5{Yabr>(MgSHrmv6B8p;e9tJcdK(Yk#G8Eb2R6!5Lv^0k15j6qcDATgNq6E^X5 zt(Zimp;=UHP8KvV%fk^WSHc|#;YbF$3IS)|VJuyz@`(Z#O9e(9`^Y&Y6S-6`7bn8A(M6bm z{4xRg9W<>(Kco5?Oi(ZC`mxfeNDa}AjMu=iq2n^n8X$JdyM zm|$T-RuTgZK@>5EWF?{HF>9pr+4QsX&Xrn&SjvECF;Xu(7Z@3fJRunwGeJ5tYbTT8 zSxgX#vIex|3ZmGApujOyEZMYB$<+sy${Gs4%$OWSFdB~cUV#et&GYWjxM(|&*mQ;{< zU;(#?V;d5$$qfLiMZ`Mo*znR|X$tcdq;pl>OGu?^#Z_-LW8MiH=%zAgf=O&eG;Vzo ztTBm#GlXRtm3ee&IZ0?6yc&L)%tsg5MG{L@{=O>m4fQ86K&j)P?gu_ly@a%d%?&pHe=ja0=gnIVu1=7^q#fmD@8$&R3d zskB6B;fQKDsVn6;n5R#;#f3MiLknWCg6MQ$k{hwlCS`qd42MZ`=M7Aj zaD3qx3Xt8vR7Aa$T4`@v7;G9aWwxEWFGs8_Z%Q$luwUNIn&N2B;TU>K$-2nV`pD}` zJ2Dk!sWBO&2u2-m+^|o2{IbL4DY<7kz+Vs-aDCJIG%1a;1|}I8a}41?flQ?;(SH%F z#6bhkkbI}D%Cx+dQ+%O z8LZbKQ5XFWB_WdvjSJR`8Vd*bv8*@ zAI1%mtlqIT{yqbx$<^{MK%9Pr`ps!0FH~_xZUGn&&Jo8t=*6J}FT=$$DRwLU2Rm=D zP^{x%w2SahFbkMUUNDX%kLQ59GF9}Fy{{apDokRYl}vX>Aq%EPxWQ=7QEokI;+mod zHls{SG=C~C0_^L`DD;NYyJh|dl>)-i?LsLI0rMG6(eL18N9(l=i+E`#WwZ~BOd#P! z6BCd!Ug%*&jtg?=#|cc428{)-Na6>uB7_(dx`IiOosq+mYs_)U5tUspj=`z}e#R2c zR!9k9R|oU1h7R!2)s^PqTOq+GGd&Lq;+D%0}aN27SP8Gqp|F6E3;0LTGNhP0e7BZX7O8{fW*RND|lTO%1(&k`osnE zK4&R-jouO8vLCF`!KpF#S8&_#WHN-xm?&Q4HjQp)a9|{vt85f`ZOX=goZ8)bdMemS zH2_15{}8z2eifauqu!|r9yeRb-wo)!CEA206fUzTQ63_;5ga4|a+#=SqNs@HO8N@Lf%z zHD;HobgVd15Ji!LVT_J4RT*iyhivMIsR!nvIg=F&Q}W^~qEZ+#^TIhWS{d%4BmlVP zGN4Z2L>eK!|9C8@&Ul{nMz(igs+dj!8ZSk&ESqbP6}sD%jt6FJ(E~U{5oI z1vpZ5NWKKq&4?)$rg10Y?4K&3dY4Blgoc_9W}L{*x-~E~R;@)R<4CnQ3FCmc#Eu5} z%9HbOm89rccXIwyU2npqD@*JO1!ho1a5ID`1?H9X1ZPCds!*6s?15(c1@44vg2 zTvl$C%;tiLVPd!V2VfPtF(*(RvRDj~)mzd{QGUkj3sJsyk;JSml$YoQq68@vjaTMt z24hX`B@4wlZ(WeHgh$E-R6&-RS|3^>0Sx)iXdZ-N$UsM+q)<4IG!D}a&fy{zXRa62 zUSkPdvsjtJkvU)?s9-b+p-x6)it#pa+_olhjzhU)1-BWb&PT6Pp(t&fSu{9|25N`G zpxH)=#B`zMhba>hrMl*1B!vdfiNR`x07ZSsFcVJbK+(7TQ!1Z%w{4;J`QJyx_0#S=eh;2BX47ZZusRV^~fDXAfZ*9sfU2bM6abIyz zhT7x&9G3`Ks-I>05yK;XtXgs>`-tQLjZiv(S7+G2?=2WkSk#Y#e|8t zPBHG2n)r%%(6C(Jt9@cL5_k0qd&Cc*!=QbN!!_Wqq!@@iWs8$}fGcjuEb-ys+!rsF zK46m43sJ!vMrK$|^aTKmom*Y5tfFagy1`4;!A#Uymoo)K4g*=CK@ch~*BFrvV!bmX z#Iza^C5dHaL!p%j7|OR)neY$^@j-)`1o1dkZdeg7U?{X|;B}Z^{G}WqDjmd7;SusQ z$(J-r=t{{a_!^~GIWg7axk)4;5=)a(7K&!69mUDe|C?*;$O~M_mC+4dPFIBlibE5n zb@HtvWeP#dJBzrgJWc3$;;x|x0s>X2B<7`PwGG`Mwu=YArPY?@ux8rEI#M}s#(_S}PBo5L{?#EhAi|gb=fZK*Ffv#jp6xoyYu+35eDY7wPuIsh0;a37W`>V5Hlo>U;0fi5GHPI>7V13?>-%J3 zcZe85by8-yW1GPu%b{FBzfb?gg4EpJs^p|1l6{1IKRjwv`Q3dj( zQy3q0qskQu%BT*gtDsn^JDP)<2UsvsKSUP~MzoEqC0)=z3}6K_K@)M-^00D3l=@`Y zD+Kg0Xy)uNecrTm*F8j8T9 z5XVTrD>1 z+*hFpxrq;{mBXh#w*XUV7^X!TAa%H0begV@yK|s6Hrpr#e%*e7j!Z7SHkE zT@>Z#7w<7oaWoCc8*Rq0;lUFBFpn#^f33q{l_@|L20u0-RbbXaB#pr#*Efndxy@GP zoy-TQm+}H8&p3W4dtl+D;}Y~lO?mttY90EWsKP){vas!kaC*xJ?X8z9HS({d8ZkVP zW-Zc9Qckp{iC;`=PEH^{Ia<+_|H;R1=&G7zC%9yQ>S@c=(kJLa$LtH8z)D;Q1?~Vj)8Jy3zj%1Azk_UqP2e9Vlyp(HG6j zQ8<&tkS>w!LXmnwRz&HvK0{e{3@QMbG@ZU-`&ir6#gTz=5I7poyNs7THq7ICp^T5_>!nK(dY-9+0;MyN8C zbJ;Xq*qE>>3#zKgDhq+y3?5=|Q0^pDsg%AW5QV|=lBgncDhHuqF73HcI=TWBTq*67 zgQXONL>|CV=2@v8Gkd5A9kHxtR0dwD#sw%MMY8D$Wy75;JexFd9b-&R)J{;QDw1lV z#x%lBJ2V(-h6cT2WN66dBF7Vn0if+;+CINDdxC`j@vwZtj?)Zg=xoPYq$)7@FeSvf$LESWvekE z3|>`k`m+t{8ru$Kos8FJH)0afFxt^@iJbN_3?()>2ZBy>=ZJO6&jq!pb51Z;3fk5v zZbF+)bp$Ntr`@VDCTT2t#+qL?*_xpda{n-A#482cb@8zlE%9kUemlvTHuGvAp{{u$ z&#We%#GpxZbHU+Ng=BDwLz9*XmcerNY&5%7C8D7dEv}+0odQ@%4B@ze zP{Lt`6Q$MF%19YAe9{;fVib)=X$Z!dqlODltOpDesV*sxOwETfx!NE*03}C* zmBit*YD@ik72-JI_{DGMx#+yHd9At?ia~`b7Af9z_JKg%2843=rjZeA+m-v)pvh+P zf;nQo>DS^-di5gSN_kl|85IZ}WPOEroHVC(_WNA>U4?rJ6$>vl7tN@P$*ld#wy}bw z6ka21$(-8oUs#9p#$n_h8E^QGy6Gc$9*r*GOh+X%4fL#8{mj&m#tj;`gJQu7!YJT{ zSO`NCkYrq!+mFTtSu%j+E6Go?&7#^AE3hqFxENq%Ro+38eE0~@6tf#)-SiyQn2DoT zm-5{x66u=7x2W6=%PkT26+s1ug^(~Qgc(~EbDSY$m(1!XG)DdmX5478g`3CNNnvu- z{nuJR({!RxX^iNjj^q*ZDC5fXA!G?k$113cRtU*wR<_Q2t*FpSwst^X9T4F)&@e7s zMLQj4%9=>C%O%1xC{7AHC82>AB`k4bDq^zQFC=N^e}Gydw9}713ZrslRL%=lHDRa@ z=E{xI*~%Q63SJZ-X{Q+!<|tXPipeV+R2~VbL|sUF0o0kDR!&!SI(E5xok+*LIoXv6 zGL3*u*!&#LPtk0K1{&2I4XJ!!Vj21X5obnOM?<^{C`EXMRZ`|oyaq;y!L3THY|Bd_ z0uh`FZl1K{=TX8+c7lXs=|#58z@(a1M8%gW;I+U)aTJK@%BM2SbNuzK1_AB~0M-?{ zYTeMX59a2%th(ky9eAkU+-%v|)~Td~0_&6I6L*;Ip&DQhGkTRed4%LKE-J=}pP zk_%hWFpJ!u=m|%|B~y6qItu`3AkiyTokf};4ceMpi}M3AV(CLoPILvVa4|8=8GvB0 zd>EVsD1EH@>GBu53Kfhf9m*I+e3WgB|HQlIM|n;pGv1cW%EmMju?{CB6IYEv#xRYHdZ?E%t#qXjoN3@~vBx%N?H6Kq`074K5U4Xb! z)N2Q({LRH1k^$20g$4uUige?-RY5zJmlKy!pgnUv)nSWzM_&_#vF+n#9a8{`(1R9> zdBOY8h2&;cM_F9autw}IO?+4ktT+^cuf-jg;Yz6(iUVf%*2*)ag@mq2b6TQqNl`(k z8g(CM7lM?tQ<}#)#=xl@)N?M#%C&Wq9^e47z(m-E-lwftu!=6v3J@ z-*Y-@YJRa)ASQcwivU6LEV9M)G&DFWEePdHE3MWrO)4KQ5FB@oFDxdj zLf&Je5?6RyNxojc+(2mCc(DOSXjbw8>Y-f&{9=XPx+LvUBh=u0rP)rRU!o5f^%HKj zv0m6GhYuS}upV-Hq>PYnpd<;+HV;X6OPNiRRW+-mwgPI+IQ%m#D6$(FWU>CP3BxQo zG9(IxQ)o;ClTc*UFMrycGusdp+q}*f5ybZ9JQyNv;tG{;1WP(t5Y9okfNGGZzTjOR zJ`b{OCntwMPa z%6(A=Df)u$ZBEBjy5=zcyT-R00o2_?wqWy-Wts6NI9gv0Mp6{IpeqvS>ibaBPf*|tphj%(tu zkhHDSz-dA{25D7NK0HrOHN8-lNq`h1=_+0+C_5MKs}6>C!nIvk{U=99c9M#U?kJez zxp}H#NyLCvYE@*NymWWxXVfu!s-r=>s{FR~a8 zd4Aj!pEcp_SRGM?@~}>FkI5v_D{~{H)mka!c(^5D)4;4*S5Wmx&pEQKF`No5qB)2Q ziP>kb63Xh8-KMEvdZoR~vT}ajg_L-7uy6tuw ziJH7k6vI}L1xEO^EQM3%0ofLciV!!d6}0h)oss1Lohwt+v*%SbJT|@Kj33+|WLc$Y zf8e_~BHdgnxJ}qvt^%hXfrRdPf#I5svIp(75`P#Ig(bQMjeN7<&`b(;U z*b5I8bJ3w(F)9JHBeZA2&kluFnF$PSvXECtyFvwJL%O=g{F>1uBi~?R*Z@D`PsYh? z+9g~-MTDjuVR{KhEV?Y6nOds6nKI!C`xWZ~ut`j=kv~EsZ6t=O1Y4GnHxpPtIoK%z zOAKbMA49R688$ovWaTLPmYb|~C!F4<6bTuj8d^ybyV{x# z=T&B!swLLg5l&RtZ*&aZXSD>2E2t9bf!h5jN_7k6kS?t zNy!i^)o^&3o7i17V+sTX3CwWoW>_e{VxbkCk*iVxZS4+&R>asN;E8Yu;BBOXLa!K* zK^8)f=npJ(5sNiefYsFE>CrPY59MLc zMcC~$3Eb9XC3e0rTtjY&utKQ3=1F1M}wp?p^?8o+F@(N58@1KJATtEf|?i1DmTkMtxO3g528|(KJQ`4@kDNC1R z%KOR-bRqbbc!TAo2(l{jp1N17(q&7R{Ia zLYGTe^|}iC9)%WZt|V_4Z9KjXfqm*PT-_q{|s*z4XJGH*i#IOt#}Qz zojn_%_pEK{rL5P`n#1uLa$KNWofTQ?Xn81J?Pa4^jF(}pfI48dpH&MD;R0^0deP15cUObIfLO3?%HU0ETWr!xWJyjK!n*aoYB>X8 ze4!C_0(;hP)N)R{$fsjytzI3K^Uon=TNbk0WiTo0L+b(50b5B2nXu4&ctKx@v3IqH|q-6X0Hjm z54LM32(aGSDFHc5BJnX?xz7r@ zzH2=kJ27&m8&LP&ORws!w(iDiElw}Aq^;;8gQgdJ4{2M!i0|+ zbn}q#M9JC@puAkUvt*AsLo<(t+Yq_a<`c8UUrr985j}WLyQ-Sgwso(!eY;9avvSXf zclshTf6g%5IPfgEjV=VjM9fvdQ1BfS8MdwAbV;nSs8MePS-80iEU=cZ2uf}45;_!m zjm>EjIgpN-8A0Y1oYQGQAzQb+D`cC|D_WeA+;?@<-oT5-`MfCSNVvdo;kCBb+KWTk z1xB7;Yhr4$iq5RlRxo#p0Ca0rT7rY!jCyXDnVU;BzFb8m;|jKVQ4sD(n=8_e<=4v* zeHieJar9K=CV`pfv^D3vc~Z^6rooETtr_4VS9G31B83dXCdxt5?Q&rBc*N;z>fWH% zAJ{t^Xs!UgpmR)ortE*FKGIqFUV^P`LR0k-#&p42k!alyeH6n?4U8E~rp>qD5`BvkF!O`k> zGP9i{H*u&m5!AS5rH1m82P&hJ~)f0vGa%2#hyn z<0S0lK$<0iJWMP`c_bl0&R7Tqxl^$+CQo0=dUQtx@vRbT;Iv1W7In24JTs8wJ3f@1iV`AdwZj}I0?mZtVCjkYt zQ;k~<<31vX$I6yEXQhx1X5}Ca=na-O>I$is96sk!h7mleq zo<0ZB;Ibo~1p^(1swhwJWLF2}83Kc3L?p;U>jcNJb)@^AaD!P^t!11SLwKP@QsJh_}dZrs8ywhTH}wzDSvg5Ld|Q z`Sj6(cuS5VTQsh4w$U#TTwpe6U)n?)7BDi#^0e2gSCBNW^=fmgZ5XPf$T96V9CH_Z zP72pC_Q$F-<;^?yVSF$dwb!sP`AoE#!D2VioDUL4cP2RTs28j{1mophKmo&Zefn}3 znX)!nnok;+W|HG=P8}|ck)am;xWM$>1z{;2hIj@Sj~MhPiDv~dL=O*uevgZhX~J7I zocxq235k&`hjW|e*;-m>b%cHx+Ob$wASueihT#&AX9g!xtP?>djcJBJj&7P%78nQb zFOFg4nFw1R%i!kLmgiHjDt5MJ2b}@7&>1k2F;gw`UEwyA${ynxT>w}8jG{YuW#C14 zX!xClap6;u7r)L51-w^&zqP zz%H!}_hmC48Q+%ag8?LxV9mUfYhh3upLx$ijZs`Es~g@s?VRDe+YU@E0})5yF4pKs zo+>}mu;K=^6+Pk#b7~v|_y=G?Tf)l{vnG zu#yifca}b4)Y&#D;9Lp4+A75f84TL;R!n(YW;nvTh;`wgHH@3{SIb3%=5NK295`6T zRW?b&k9NjoPcE`}^+P77Em5@mO3hd8ZL4Efa5r%aw#pM8+P8sY8L(9}-3_U1Bcjjd z21Qq70AUkeu)Vi@ORE9oE&hI!eiD+J585o5#bL@j;f&|6LZftx7Ic^-l7g)EwiSQS z2|Fqk7xrbkym128AEYL*`8!A_4bNB68k0l2j*B(L&I0{$8I_p6v}o^LAzrLP;o|25@J>C9?h;|)$<_z2k={yc^2kH|@cXkh3$(L5pEa=HkaRUW6;(3V zu*9luTN5kzo;j*=0ijX|x{ABLSUW*#`MdUNU~1KTevX{Xq)J9sTOP*9D%*E*_&BK% z!!Hck`GcoaSHtR)^-8~(If=`yG^>(&rN-WGvX4pX37c&(*Mq~U zpuPB$0gK*+vUY2+KKdz!$o6>2Rmp(?rTcjcDd34CdsI!y$)~WMw7Ij8{*0q&Txl!H zcQfA*Mjlaa{bIt{_UEWb5!9AX8Wrq7X00A&(}D1>_%cyrs&q!LCPt*|b!1{qnAPq% z64JV)NbusiQvDz}X3M*@?%Wh@F7X+mf@ox^cEg8EeD!Gop=Lh5F89yC!jxMls6)p4 z)O+G+ytTgcQDTQIt?ZXy2$qJ1X?myzc1qDzj3#ch)gJbPa%|~tr$jN+tjZ_d1-Yr^ z@&`0z08fFl567**V>rEgn-;4&KbH~JeG9JZmgNby*&)YU^!7+#%2tE7LB0N>iZQ*w zSO3G@l^<*M+7-YGzHvR?ada274opK*nFvY2`SryNj_d?Uo@dxSQqM(EwsdyugAopV zAGKZoM&uY6a#27(PWL5OlPvq4W=1g=Xb(L+J|Pr94cUBhn?vdZ@5Mgo4Om?Z0=&ae z5oQa`vni<<5g>|^j4^RfOayusid?G1Dzo9DY6uhd?a~4dXQ_$S40y|+_6}B;ZqcRL>A!V0YKus)f8Ow;Zx$_cM^THxPLsX_cIVxXd#&tQ_-vRmMsr_hDA-x1`+x zV2{9|b!uY?4aT2BUALqx%rHEREF1$aBBmi6vdqU5Rv|^a1EYl{VyRYQXH?cs$J(sS zbgF8=yAy#-v_QL}*A3!NQa!q}Kr673T3t9iAZwmS#xD{KK>jiJ5tkMVNSON&ve8Y% z48n=^4q?r`eugDS8@OEsfC8yzpY7VM|(4 z^Wr7=YuLBRFH>1pdD@yFYi-6ov>W}P_yaq$^2^q&SgUHt3Tj1UCi>L_tvhfZGHYb} z5C9(pDH8BH>m}7$PN1dMvYc9c8gYO$MX~WYYV6mGP?Yx5fgM|_3wnkfO_o^6q?G(h zSrr@e_{DG^o$v#mD?x+WvAK!$=xiMZ1ffdvHz6%9;w5XL5SwCWdT+D9{eFrTykI>D zmn$37i_VRCl1qC%6K4>ott6X0yF%-xGAQ&{kF;w;kFhV3^0-}A)DB>-MH+v%N_S$0 zW`++}F3y0X+DL_aEf=8?j%e@X5J=s%V*w9BspU(3pyC`+SSTl>5d$MB84zj7d=D@S zk)M}6trV4eWCXLv60ghSumVeHDUUO>A*;L0W)qcAw*8&$<5x~Zl4h3h1S!nSV%q7e zbY*8pzPp2uo@#$PFiiZ`j66VxQuj@@RFvZI0;Gn7u>Pdd^mFC*6O~XT;=n zMv?YUBPnG`QiVYexnjJ%_0Uh)ki#bsk0<&5JlJv47cBBkt|#{yOI(I;gB$@*MS$qN zP{JRqEi^TzHlZ1cup*2B3MK8Yh){rwD+DS%&2Q$47uZTi&MWB7ffNfq4Mm5I;bHjm zE=GqS#oXymlq}`a;s6ppaAieSY;UC+3rlK;A#C747wD#Ohfv0whlNxT<2TYNXEvJp zezKg_(gcui_N6f|EtMRj3qDtxEvypr(HXT8AF+D!z}P&Gd zTv*ptD^H!KpFh^mOW1(!H2(cD|6ZcUtdSQ^6OiY1%NBG!VIv}FDw|D~^5dV4Qb)9P z0*X!*rtI^`%RY~6FMiM1W>rL{6KaPvh7~EUM>hZb;-++B4}JKdeB^; zSiPqNYiHX)sJ@aAuakU|nG)q?so{LigLz_HQw0fl4z|37#G$!OU|Qal7Xo0+@UPn8VeN?(^+XQY_$xFVe4XlA*Dvy z+B@@wLd@!hxw0(uk;}tEnIYw^%7-14#%fz8npQ56fE;!X>t*W%RE1N^$bxwk&ND22 zq3^(NT{2afukV;9V4tNyvf(Fp<4z;(ugV4Th1gzSC@c16%B@4qWem#RxzBOes z&IaX!2Jx)f8#`lJ0#6Y~UmA|f!tn_9jV81u_dD2=cTbLL9P?V&i1JMyV~d|!oz1sV zHzb(~p4c5BHUJ{HFyP-cY@&aP9g|e1FM^;qqMQ5m;X2W*MUGI{{HPkoOS9@nds!5& z;9b>a^7-h+d2jPz2dpyirfn%iq04L_6m3;Hxh=AH?{60z8f(#vdaPH;deg1Y6o+{IZWOc+6?#`ci1(-?gec0u8n@`{4|F7Y4PKR z9%JqW=Aswe*I~oxu?Cl69-7t$c9@rDILH?!_W|@_c`;-=LLS3l7o>GVmO+u}o?u>f z%WyO#k!6+(k9+xqUmWVV@6_!tY9|?RMZqZAD{4JT(o8OS=H$B z$-qjrVA=IN86PAF*1iDApa+sr{?JA7>{$}4efdfaiv4P@7~B8W#H4x3=v*Q{jo3d% z5qwvRvc+j^13Z&*kWpb`)b`CZ>H=A|QxnRX-i+8ABY>L}*q2JQ43;}Y^+Y4>$WA%T zE`5Yj2Nne9wy(7zLpX)a;Q7drxFwE$zPyCX4_<*0q|Ok)2p?XO3WU~OoM5REA44$b ztB5l(HDS!J{j}pKLWyBOntS3)|1wN@&qC zLudkxI0A@e6QA6Oc?|Np zux~gpTvn=S=7bpG>uB11r)x&Win!&v?JNPOvpqSquQo0+=>XZ@dYWJ^%uTh?Qjq-V zLAKJd$hDZf3)EO8-+LGY!y3sHjI>=t4ySg6hcytr!6OPSdqLqjUk9QRQcu1QMGjaB zr-d8xp3+_U_6(pbACBk|C$UAz5x{sMxP^_g!3@8a&uX|5DH*0z7@VdV6+CpP5*lZ= zR8|bWK&pAsb1MxDndw#zS>RS4%v}?%XKTx)_T`C?+;1_VT%x}O3%x9&PMA?I(;DLM z0?t(8Df{eX1OiLMC2H#|LdIto45z^^c;&T(Lt9nQ^&a3&$;!k5tYJB*ml3}Tt$IgP ziPT5!sk&ll0v{sq1$;i@Ha^{H46(^K5#phCg-<{AgN^smkM-Fyi73*HR6_F0@rj_c zjqfarm0cn5D_c=c8=1Btp(5-@5cGW3Mj6`RW)gUQC}>YjRy?DLGf~wU$s|Ochrr?7 zh@3dVdMn|@D1`VcxS4N18GVGfu&MSw3;c!R3QL6$9uJudgIt7G!-DoRi$m_8k_rxKV zJrjnnC9yKyAz?4b@oS1@O~^$B3z|J@h>6`P6JMrP^DvhEDb<`g&5TBlxujMsLc6xW zW7wHiZzGpI9Me=5S)^Q{IBLzZ^rqGDh5|9V}J2ncyYohpj*^`cF zqcH6094IJb;WK%tz-1yQZfXhAY)j%1F{pXP{d>7{>)G|4~Q!v@J*T7s5xO{AtD4uuvvwOrVAMlwbZ_> zPR!M^eB_U@>_F5DWQ16Xxk|*}U=PYK#qSICDTU0s&emJeorQbVtI_v8T+8$ipLkWn zPVH8bH;3z)-b0toC{wkfiz;!enL9?r?E z8Rau;esJQnGR|t9S(>l%gdaa)%cATOm6Rlkp8;NCCO|lb>y6F$H$e@xn(0X6tPGii z?-!Wz?(+nD*2paQeib&gqV!jY1-9%T8)8nN>i90R=Hqus$Q%__xaZRL71zg&pi>=c z?Aj=shS_Sa4{1>o*E+(0z|E8_B}2^9X5?rNZuIc|n*iDKNd&;15BG1e+)@E~igv;Zw#jq1%KI7~ z7e6dx__9sO+)e-`;p>m6M)Gxee3xLOisZMAvh5R!5VVL0k$PvCMU~ao@y-b0B4Uyj zj$}G%llD+yYw&ujY!R-;035;d7*3XIQW#2Bqbnt=r?kDOZyiUNc#y}^v;<#4Wh?l3 zFXDM+&rf<97&Rp5{##2f5Dl1zHheu#Fv&O&teuAan3h~n5?hR0g|BGHno_zXnG<18 zdtG7so2x@&$l5jY1Pgs22QBtPH@zR~hWohPTnfAX*eirG(w<#2FQYzcWiRg-yC^80(KlbPt;|6kZ5~>t(r?nF39~3y zj6I?ui6M2uHfZW@lVnaN@k@;pnq$byl)j*FmC3P$>{LXT$pWbjavpm8T05kXcj0`c z3z)_+5I}5bdway0Z!aUKB$^567ad9@=2yVO}n*>VbjWlK0o zD288S{?MEnjZ)lw1K{ZkSZP)QBn0HsY zt`}i0>~u?|^^*%t$K~On-xlSfmol{ny?K0IAv4TU94$%AYr0+#)JyzCRgwh53!2_F zS;gmv#Fu6inu4#f&yz2FrB{}|%bE>zG}B6gzNQP*hXEI@LS&YZJ3XTCq^%^jId4s3 zS0bdq6zWREam=U0-%vBxoM_n?Nw)^FmJ^QD-wFId&7|4@hr(mzzszKom?1z0@TzHu z)mdKzD6D!(YXTVq^f!a)gq-x<)ISR2lVvTB#S6*Im4|V_dL1s8>#K`O2u05)8zY49 zoUyU?S#c`QU2{sad^Pq*8mQKwZ_i6)D#A!mLs5<~T(wPrNnoBk%V(FBWQNs^e^uL| znhxMuxm0n=D}n;;C<_2CM__m!b2jWgWJ^ihrVG__bTa4sL;%c>Z0&|`!QiA+z+98i zXBrA?aKF~@i?GF%@|LRFUoQg zF+TVXuyTBrsU+2qt!MBl3N1m)cb$;YP+kmMwOb|&>%r{EC}8Qy9>t}Kr&Z(6z>p%0 zpCi;7m-e`bwIX{57p)o`z@M7i_=YJ(=+X$#N_Gun%@d5tNOVI+S}MS5b$f{;ig%hs{*qmiaN_X z;6>^KEEF*oO6o$y(6^Wc6U&rRSn$S~F zQM81^pF}6@iFShB#oP?xs)D{LphXn=UKCbhw+SqL$>1Ot?SjE#MN4(qsnXp2G?>Vy zL#;y&OG7aTncWMa{dUj54XuphyWyL@S zmd<#7V;5u=O=&kDoiYyDEfhvn#BGXREx)sY=DJ51>lB9=E^&+aHAyonjeBxm_~?W}${M5Tl5qbLG4H6!oau}jKM19iPzUhtbr?aAzUR>oPEwr;>i29D-Xe3(ffz!c1f{@K>v!UdwF*y^R zT|Gb)D6UY(mg1#0%fnN6q43!Tv%@0mFnhfVbTj(IJ6MvYEJeAX5n#Cr%i;5i(70dX z)`FYXa}v!N4b0O*$TK%qqxaD0Ba8H1UB1Q=OW+xw2Adb4OzjmyfR^G8kU+SNwBaA+%@fUho0w%d_~^uuE(MHtiIM|C5~nC)CLJ zl4N{oGQLdupJ2q8JbvIu`-f^prfS1(N3h{M1b6T|jAz86*Ls&5+Wtm7KjI@)Ggh|0 zmmbQ*;-NmIxm}ffOxTvp5(Z+o2r6pZ9X`#Jf>T!Ct+V(#BAK)RvbCjy0nXLC`C-^E4Cgf zSTphKs__nr3sF8K`BQ2y-5TdK1Tuy}?I zzgU%u?%;bRyJCS#3uiQU2YLfsq~_|EhxZlPksk;z9p;5bgoVhFp`pqtxx)pI-=!Eg zMy^(bB7E#G7w~R4@XsS_Iz;CcLA@61 zdSryVFIKYA##x4}6~zI%WoQ<|FVd5U(_Rf40$W|sizx*p_Up`@ljngEx5Xa!Hs2@iT5=r`QOF zx!ye;oZ#`Rp60k?n+4C@r?*{FMw#lCRo}pZgA>?iM740Cw*m>T`5R;~Z$`MfI=B>{ zx$l>do1`X$l>=9pK`GI<8}l`-8j5?ahJ4^T*J$tB-fK4A?V61}*QmF>&+?jlJF4k@ zme-8yHpZ)zPAmhUdt0pN-V`e~Nm0RmzscS*(o`$o7*+(QL<0ZrevdgT+~`NY~qUwIa}>Z%n~%?6VTX!Nzp?XxkD~Y=_Uzu}E|*J=5V}VRy-4p!PeMo_fslkyM1fF4m)->xr3wNf zf+%1EREh|qSdgNqfQX{lu}~CjSSX^t&v)kbk_i0XKYX4{|4y$vyBB(`Qx8w(#EPYq zxrrw^md9T5b#3fII_#Ln`m#u6hS0l8R`oJug`NJ39=CsjcU*4M#m$<$jl%m z8kNX#5nqVaQFZ4T0q@MpH@;2O`jLDlJ$}&GOm6jaP@X6?l-_?72^*;O`p7%WIgv?6 zrpQ%^2|6zAC4pX|I*gi_&Jk+r$OLW;>BJ_5P8M_qaFgLs<&5T6G<49e1K1jfC|>Iw z$j>$M-Azo6zfd|%pfp*n{Af~-L!95*dLUB2;< zjxFP;O3&aRUPxdHdWpR@oDvFzZ;~f7z%rv6DDswIzK?W4P;%dv^hau%m9Dw$f> z6NwHRHW{&@QNm=|G#{y?^n&(T=BJVh*`=8$+=c8+8!Q+yL5_q9`H{30vS=@l6AIa+ z=Zzgp_b4bwQl2GaZXw$Q$$lZ5EIIwV)+R~+v}w2@YhTpkq{24T!HBSpRF8a?w~(;z zIn=Fe4hz{P@h&fuVqveu!8f%E`AcNFE@aVzsj`qo`_OM66tYa=SwSHS`MqFy)w7Ug z;)rXa6C0)NvkLsQy0$2kRXvU*$`u0{n0Q9ZdZm!;gq##Ta%7p)%R+8R=9k%Z?+N)! z=1Gt-bA^rJr;vZ?eKas$`IhfUh$)eybcTv?LruRdZTDJE!LrvP=&B5dC#6!)+sLDBXOxTp2Fpk5XpNxK1vzik_H~G2&Xx(OqTF5m?z7Uf) zzzi(~#T9f&>_2K^|8e0WD(I9T_g%v-new5m!W~0KsX{R_`?8FZUk@u>XKDSVPvUl+ z-qk(lnsSgvrHiPLa48iTy;NujQ@N(f%&eBBZ^349Rwb+U-1cVmo}0lJ1XOOvjDfOj z$(2<=PTtgTo^sRm;a>*F5GsL>;tU!ueKdhSs@o;<_4F0C%;fDRX2^k4y5_2|K9TtJ z2x@AzYp!&BmBe?N^Fr&C%q|^OhtN-Co2neAGP1Sz4)XC*$B@n>?AVi8m6afq9g6^o zGPJ}&m!)@FxMqcZom;nl<25JrtH`Q{{t*?uNNYbaFOgm}K+hH3VYLobrd!YEDOf(_42l!g3$s9rxM>ytAbfZ-{;Zpz_lKsb(q4rb(@ z5_U5Y=>a;~TE@u?d z9<&h0Mp|9in`vaK`^1nY$B4~l@1uV(hNVJyZ_?fTR!`x0q-AHZdCB2oRW_q+ShD=Y zH~TsQ<;Rv`eyl$1N0K60)x~f8^D8nGv)oNemv4b4$|nrN4KvgPI?C^Ngq`&&H&cIA zNos;`HkiWID?Fp^V18ajoRiEite9?V{AbDCA2n&D6z*6RlA%{idXFF$4U<%Uh=xff zg!ZCi(YgfrT87qjm2WgAq^0sYCvU;Bu9G=ShtaE26OQ$KZW6nREPaNn?Yi*2N3D^R zn7$V_8iy=irvdXzI9cX5A7mY4M9Pv@uefB>VHT=Xy8NtycGp`G`6HVh^4pcIjK0aM z?aYrS7(sfU5)z++XWqE$KQfdw*<{d76)!%jK8v#yA5lGcO;Ym+VzE!-I8kv`QepP4fjp;ldJf-IPr z!Vdc4P9dw53Dk=IY4t+Z3G94^Ql-Sy|38b~a7U6pQz(#`+L%DuGoaT~r=!ZfT_x*f zu?Tl;YCm)|!2XtJyjg69d33>aJYgJN(HOEvb8_Jr=oPu6`6QNOcEUSm=6k+LGCC|N zNxnklI8rcXb?jJVat9;qHB%pB4b_YMs(Wsy(JXkGU>!FW zu#C>KBoSX^TYtRO=$$0%9${7r1+4V?C2ZF1hq2l;q_B0aObP!Ds;7s1FHTA2+x#~G zhb8%r=0v1`SwH-g-D$p^UUB6cO#$YcL*=0Zk8_HA zI|gHhmwdAxjPi|6?d02JjUU9OX4H_djZSB14VEA;cI7&O^cjY+%3lKNaYnBgIr7lY zB6Cwa>nTCyrtN2$AloJAD;W&iDQN!ctLX_HdtW<8kbGCVJBEMmTf~nlj zjPvYH^9JO5ruy|mmekG#?HD-*4A17{Z%&jdH&fnyW~LZUC(pM{<1WLswprZu_^;0_ zD$JZH6%4P3sQ-FRXA97OazSsVNDA5z@o=5Wf|f}fTU}$BOivv>$xIFT31>8wkF5MB zkIq`Wlbrn(l&rs!SJ-o+yn)ema6w->H}Z71pk;;}Ko_(i>1p!pub>^JdySnb#s7F@ zMSC5e;Z0~knI_}cl!xh!%mxz&jVZP1!r6v(qfiY@}BiX8JK&xg^7wB;CP%(6mnx%XehRgnKFPbrmX9LJp~W@!IUM`Q-0~kGnH>{CsVNYf6ch_= z@hba@L0YFbGqQ6u$G@RzlVL#b6U48cc=PRbs00qQhMIF^@xs}tUTccJ1GCYXaqLVu z?Gv;1Wj0dUE3eImMJFW`G$rU4sK@pnQOK6LJc}y|VNtS<$v5fqk{ei=tZToCLplBF zueA)uJ$sFFw7Rs7spBAaT~gH&mDz8Sb#0QZIA840dRAMkca!ATs>EYQKF(&+lg$_` zH;KhIjagp$hc*;kx#U~uSJAaGN$0!6Si)&@xac@h)>~YWh(3$o84GFiiyr$#`2`{7 z=a3t#9M)hV14r|DWBIXm<{HP!S=u`0E^?#LG31QK_vk#wm>zlw-!aQt$I++vmv7BW zJe(x)6rnv&-{iw_#)Gkw<{2J}6loRjUCpOsM9ad5CP|U97!J1zV;MH;VS|&7f)=C3 z$tg_OCW9p^j}e$Dq^8E2XCe71GgVd~soC-XF;pTZpMK=#`bpOn&#@SS9s4An-D@|;0vBhKYxYCoc_bNK z-;O*P3+;f#m^@*WSq$Y{C#LtMH*o?r#xy(~%&}40lxSX-(0a2NHuic#9cT2WyJ;^h z>A3$eP?_g`p-MIe_CfM!O4ezir-I3*K_=@Ksh{|fd(L0RI(oTD!Ks0n4$8Y;yg_+9htY;dNLPsOj*e9_3ZR0b3MWN z!%tx$;f_{FG}$h2<*$%afn>=!Zy~qPO23eulps&*202F3R{@=+`3+n{R~NI) zCC3}cPz4XnL(f?ll<4dsgB}ZHzG8ro0adhS6|Y-s_a6VXDPY!GJ%Z{d5&6daM}u-2 zBuzGa0;?_b*-qGs-bzCajTvG0aOV!&=vmmY?%Q6j2GCXHT7K9|d%2SEzrAETw-o-j zx5AOhNb-Dkp2%T_^;3Zor3@RE}Vk!WBMD!d#(Gm zv0dxOS+j*}gT0+>B8TKx>NQ@tN5Ok>W*7}8<{DpFd7~!C5{`j!0B3)+?f>C-3_IEW zBh1KtV{aLJ4JB`s_SHb{h|spBDPI$H0e_q|-`HOQ>m9knL^GBRBm?h_{buKl;SrZ~ z`v2ict}hIcm!q8f$TybPk+-fXX7MoYe@J8{KS-YE{IAk$nAFvL-Q&iwHDnbMdI*sp z*|qH>ky{;k98Ys&l50XLo4LeNma_Tp4*ic*@?WV~RT|vrqfuj3yqcvZtCcv#s^+*a zQF9~4s4D2!s$J@&>ZfX`qv{}kRbWSTdgIkxhvN0 ziJZBvm1>Dw+=i-4DucKr9;Gf>{87y#Ox*I0&&blS9W7G*`#p>MFw}z72q1IgTG6o-$`M*aku~xb%NvkJv4&r+y zxhRdxT6MzehcEtFC;5{>YPO=rg8ZY*?HZ(PCAmq#Z5L^}M5uPEew5@=>R=aT9f6NzctaRcTjq zwWRVT>}wDUVkiOmw-z!m*LO!+v81cEignL*^|Ov5Cz=$9oYIuxT55Q!#jQYXHH(xT{pQcj^1xTUR@MpAM9(pQMTETs^wR77M%d_-++H;bH0sYn?|QUb;K z8>tSuPP&x)pzDO|lIy7JAejGBO6~YxpOjJSD#M+kl91S3$D`b((KSbg_^N@#gSf`K zq^_NR(${LxdTB|NjI;pxw+rGaVWrDd%1_cOe~a@U>2?i^`lm(9NFcr7ge7I(oYInZ zlfvIwgceDWv_-}PU566aWL)bbX(ge@5DR*b_@f-?A2oC-$6N8_UF1rekX|UvMK30) z7o#(JF^j)hkd>X8SlyOhWs5|xRE%0eN{qMBcunv z)u9GqYeFsbHzTb!(mY72gI!&y2T}r(uKHSfd35DTM+Mb@7#fn=M$ou`|0d|0LNjO% zanK@M7H)M5`j*fNS`%LzQfbl~P;HUb4*wE&dq{vFIVhrYQHglHDp7|s=}N-A14vCI zLr2Ppibjf}MR`>!bRzdfba_-!ospAZT{98PKwo>V>&C+=@*f{N4t)W9|$62-6=m7Y2~VfwYi8)CC<_4Td2) z-PNgesW(ZdX%j<3>Bu83!(cd!fRQi?M#C7m1IEHQotJWIJmDw6L~1xd4NoGD$uI?` z!Zh5b!wi@S(vI$gSuk72DQ&41xs&ur`w6JK@O3w>tb_INIPLZcTI`d!KLt;Nj9nXH6XBnMXW=>gZiX$e6}G|iupNIdz(oA)fSvFn z?1Gm-+VIP;8(x7|;Wc<2_P`sk7xuw^H~??LTW}EGhIimyI0T2`2)qYJ;e9v;AHauj z96o}N;RJjFpTcMGIeYMOjk+jJNoUrlZCnBY?gL%w#l@5%LM@Hx_eI2+~&ChWi_%IsS`5aVP;Lp%j#c zGH?@=M}82sER+*7RDgJ>2$i5RRDr5cjkHyV8c-8z!Oc(`>VV|KDf7DcuLt#^0qJW9 zjquYLntC%+$iRa5*ogCzQTbE~;(Vaa$Vbt~o9P~BqPq?S=vEh)!VRx{O_ zvS|YoY0)v{r!8UI!L!JfalUZBk@bmJwZ}aH5-H<4jNm?GCt=PnD+%jW9k5F#-5nvt zYROpZjAtgFGES$G59xcI@LRCmN<*LLLl*;n&x3Mq| z#=``d2$NtkOo6E|4W`2km`S)hiFcN+pSo%`=DR@Z;%;3>Qg^L%Io^Z+IdCuB2XkQ_ z%!dWA5Ec>kepn1k-~sHG!ZKJ64_d7$ZK)TxT0wn01WC-cvkTP8O2SFK6|9Gc3A+kb z!y~W;9)-tXEv$p}@HjjHPr_61G;Dy4unC@lXUWfVq+>JsEwB}~!Sk>kUVt5>VJEx@ zyC{p7;AQN0!z6@GcyJ!*B%NgQM_1 z9D@&t>qFGz@DY5BtP|LM0;AwlXoI}ZKP0<+0l_H#l><%%rj|ETg=30&9>2Mu7y@I*BS0 z|1v(wIORhhWfxrkGS*^_h8PGy5r~DNP?B`Up%$}~SdTg5KtL5I{t{5qmT{_$Dn&A7 z+$oLxG9Ytvkgzf?$$Twi(@n?;LRr#R&W>jmVeG|R0pdaCoo2|Wh^$Ib8LB{4sAgBd zw^vmU`?qnov6pbjWd&IR6j;cS{MOL!Cf_yD*Mgg&Hq?Q-P!H-OqX9G|4znJ%RU_;h zQ|?XdWIg{j#ax4QNFJr#lvf?;k@@A=jPT9v6zl@3g`KKyA#6+hx3W7?15UX~T?ABX zU3Mv|ja^Q)g?7+hmt$p>U`tsREH{%EDbGaGkc3+YNJf4~%qdU?z4ZT7>^nhc?3{e2 zp-;!Xi|tok(U(L{ACUza`0WOnkOkS$9de)t^n_l}n|$1AcUFDuG<6&L+wFF$FZ6@{ zkc<2Q_>*<^K=gy`j%qOK5Ex4N<-suAhrH=5@i*PGr-=^*-Es?a~#mHHL zya#ZTFiUZlxp5ila?$l+41Dl zg?SBOAB8x*YhfJ6-`Y@|t0@OJaeoCnU?;rDj!0y$Bg~vooTlx{4#}<7WB)ki>|u?u zI3%ZF+Jkxr#oVCd%+m7nWlLOLv>X@ivFxs-Z!WQ~FKfBomp;iHWA{UKtEcS#gk_Dw zpAB}dc3WZ((CQQRKzz8>M&xcH|IeU4YY)Q4OPmGgxWV`zM7a;q`Fsw4n?w1K^4(&~ zuFI{qYWqC)>3PJMN0=dMn>|=PkNbAqqYkEN`{-K?RD;rkHbTiN6OV{fa&*dMXShwPbisf(k;@je{0CxrcffIk`aB&~6* zMq@(qKO~Oh@DY4W*c0%Hmcjl98K1%DAT9R`ds0Xq^D*g_vFt0towO%Yj*?#HX6<(h z^=QoBVEz_lEba~85$+V6#_t)@bk?34DyM1cdwaV2!JeVc;dY)dvFs%LTF&*#P|C!u ze$+CU*L56sa@u6d?PuEfFW5=Ce?{H}_zixCKM3R0MUY*%iGz8bbX~;l63Co*S<5!_ zl9byORo4FH#KI{@x2l3&kP{5)qg9a+Z!gn&IajIX zTF!}^Ahidp~01crLG=?TF zziR4wFjTKAR5P7cH&0aDss-E1yW%GUeJbnZFNtr9{b;D}9}Cs3lqq{F^3V;xnUDq2HnUN? zLk{I2dF?@*JzZ<{*eK&xFYJ56t#A<;eeipk@-XAZI$EdH+j@1I>v45Ee)>W`{PYKD z-??y(cm|*jgh4PEhJcI>L-C(S+K0h#7y%5AcozK6aO`7oU!>E_ zUe>iCG>&ali(Q-45@g6+7Ubm4v_-Fa0RKy28EHC4{-tcCtpwRAIAh>)+{FGt)GhXN zp*AXQLS${GbfmnzY6Ws0f+YMpXRVni%(&G8aBX2*o1u*P9j~LL_R~l&HDd&((9~u zIX|MU%0A>-%1he!bEunP3&^SbR%C30=ixka!*=Ap06SnOya>DCC07OYvddXJ%UW3G z;caTSYdd8qr=Z*EbLI?P@-&eZzdZMNg>;!REXRoKr0WIsD)Gyn={4M6hduBHY1m6y zRi#($L){Mt;7uK`>}7VSw_H1ThP6|@&6vjSU%lhnrQUVDqz*BbABH3F9vnrU%ysX( z%wF*rX4$uVKwe}W{vqmdkiFtZs2_vu8Bd_f{`3>nPvJB89KL`rLFSvUK+Zl-BJ*qX z-;ft6+iy|7gHv!C&cIpt9)2Ki=cJ4Y^CSEOKf^DC{}nF4Z}2<(0djWxC+bDG1ef6o z`~_FxZ)E-h{{l@^kyWV2;oAba|R4I2`p5H1}25v%DOUi4my;=p`i&a@DhrIIc zC{+RC(N}~@gs%)$psM>-Rn7gHs!kj=+^?&e?meu4_mJ{Ev>~Z~Q_gaJXy$flSI+$I zR<(#z+Rn{{FXDQGux}9d4IQ=){%RASjO`M>4u0yw6XaL=Sv}HRANL0C6{;cmsfmB7 zyGF=t3~tJ^32IYl2F;-b;ctPK&W)5#bRJ_4>fzqUoGWKM?2)nWMVchdy>&kK)BpC9v;E}XjD5Gd zrEeTy4m*JT0d3z0zqi5d5XWfM7eD=|i~jBfJmFh_zXjT#^wnJa41j?!2nNFt7z%P` zE^?&(2pEanQSLX@XyO>-ehayBj`A|&jl|6yMjpn(IOL3n2`~{R zVK*73z*Lw9(_se8ggapt%!a$*Zny{Lz`bxE%!PT#nhy)mFN8l`ujntKkv+ufgx5sE=V@3+phiNA@)G_c-bk zxIGC^k@u%DZ-7kly%E2g;2C%p_vc_UY=Nz?4W5VX@PhjtwF7@U;YI3b7iC)9wNJf- z`DNG*uORnT_q)1$UvsY}kE_({*zEy%#wmT|4P@&cpLpY@Gcx8 z++jEZ?}3~d9z}g0w`1@DeCSSB$KfOL{4wSe@QGXI1zUZJ-DmJQc3%+gOVqF6B>JyG z>i!$d-@?O^(!nlZeDolgvFe8+YJ>+2~vhRdhFdOc|?QXaS=D@vhjy`%H z;pU>B2lJsH?S3%!3(zmbZ4um$elaXT{{SpSKNN<*GRTAF@E~q0K-O6gVO|L`?mUdT z3Rc4-um&EDD5f5RwGnY@T|_{w$L?`>g0wyfPr=i$0eKryH^DRTEIfz5&9DWw!Zvsw zw&V5!>_ER0UZhNS5&k9gFT;5%b2sjaNA{DSVgGqZ<`)s4(Z5)4B2(5ZNg(~}y!AQzKE_o1orJI98~7H!gHv!C z&cIpH^*!nja8Ac9>-{fO6>b8Y$NVE)+cww-V*fMz0ulD7>Q~eYFb_GuMSQM)M>XT7 z8A~Mnf8g$noqwXg2!+Q`TV2BLGGVVsc(@9GLwRl^cz~U|9;f;+f5=)dj&O&m<}ySM+~w8Py}KPcKzM%RfW-Gi2yYXuM%=AbgM;kuv7VKED+4%d^q=PnjCgjUcRw>Hog+F@=F36Ka$&;iO* z2g#@%JzuL7&$lWSzn!2nq+y>9T}W?N$Uxr>`%K7!Z0HU-&;xoxFX#=o;S8iXfvGSJ zztdp``kAEXPMGC6t7cO_cX`gyc6mO8+dVJ`?uGkcE|_No=kdW>7TNP*0kYz_JtKAt z@gwW>MW`*kS)RkJU+$WGV z!%ymA+QBN%&uX>j1kZMksYj5r1|Fr|J_c)H9ju4PJ-?_Y2>&EVYM;X2(;gXLzEB%H z=ha4!?9YExn>@d&XFReOj8e~foH?(Kdd_n}ZT9>|Km3gr`x|{h?w`ng6!HJN+Co~L zXM)lvwi3^_P|a}wXlC4f7{^&*a17?Mc4%|!ONaRwOgm<5A}-YPxY$jqI%79 zNxe=U_INI=R3~KOaFJ&Jxe}@B>Jmmf?O5&clz$ z`3Zi8U*K1`Ks>*}@9+oaKVd0D`$g0Y%I=bJM^>1#6k}haRj8{By>MyuTJb%MK z@Go#tKv`ge3)~O^l12}z7b3w2QE-MZelPd3AjbPosGhDerr)R>|D|8u$cQP`IcXmB3-4SjJKq^$?I1^uVuylPuT%g)@xhk zkWt?2vML}?@*a;`5h@|0ve#_|{-=xxtBRL16#UEFTaEZ-KTsX@jK^d7Zx~kmN_;ZU zhz!ZA*W!$hRT2qDMh$PI<-2Zp@ym@+;;5zL^I65N>rdLUmK*A~rYvtJ-r7(nl-9ba z+i0`(yfQvSS@pf<_FV(Yr6Dwe#@-mpQmH2Bn?f^a4lUpo!ncH0&>Fe2&y{j)gT5_n zr(D|Mue~>Lo%&!Og6u?Z5i5y2b%11VtkuzbMWuL)TB(HZ1f3xb%5%dncuiiV%;mY9 zj8#oky0;j4C~kGp`Qcp0n?G*VMV|rPNROO3XChP9Dp{!6*mZ{-=mBRueygXqgcW~H ze9kygP4yzrz2R2E%X7#+sJ9XJcIbdh9TZKH5Br29|pq-GXh59 zJ_<&oZ^d)lG2W6^l%7-k>JHlESQrQ6VFKY~zcmrRlVGy96n?MQ=So^rkZICr)?-t> zax1blrBIsoCi6`hYZ~(8tZq88W_WMnrr`BtIqj;Xnn_=i8wFC|vL?Bce91Y5Gfzl) zcco5e@rFwa=Cs+!y^A>RhV!(Gdq~q9kTcFz>_hI=br!rq9wc59*AL8>L4DpVw>Zm^ zhqB~>IUBhpX{R~p=c140hUbm@FMCh?$o=toq;WoJTL25OTLkxeTc20rI{S>Uw`y%e*p&#?vmPt(vhy`rLBd9~6I_Azx-~DP_L`^F#PsNx3`> za!z*!zpGfEccpLk^j0KY6-h-!^31&v{H%sYU=2L#tz<qp|L0&cY=Nz?4W5VX@B-|BAU9{D zNY_r{eGzuSOYk!6#{Cs|6<&kay;ZG9{O-Z+4cH6&U_Trn&aKQjL2ls6cH>R#-XhFF zc$@MGax0hZiFyb7cQGG=^4!vu_z!!lSV!PJI12B>G57#JgyZlLd<-Yx6ZjN9gU{g$ z()Fdcn)MZFI7xh8gPgT|gZW$H`wmXQX>U#5DU)y2SKu$W3V*{t@Gmg2GBz-IqT1jBH$;F3ybuXKhyp)E zLkt9<2*g5Bh=XEK97;e*C4X6pV;AW@| zb)YWPgZj__8bTvz3{9XZG=t{Q0&anp&A&hVGC9J)kG_g5Gc|^nu&pcIXTJpg-io02l~^U@#1Up^yi|U^t9` zkuVBI!x*>&#zxlC?Ry-0sb?$FjB!D3nU@AiPxr}>B5GLUBWqd{U?NO{$uI?`!Zer; zGhim%3A11}+y!^TJurv(?u}%u1l|^+57j1)+B%N8ktNi;$U3B_4t904-F(tz)>w71 zH+vl!rygJ(yC9Oaj$O|hg#AL~Edp87+>g4La7*9;SPIKvIXnm};2~IvzlX{1Dp(DV zz#4cI9>Z-dtb_HKABQK692rnsU@L5c=V3d%06U0# zCw^XpUGNgT47=eKcoklYtZTiFx(D8Xy|54V!vS~`-XiXU@HYB);9WQbhv5jk2S?$3 zI0hfUhj1J|f{)<@d;*`sXO!pX@C7oz#QYVU#QZg?*?ZgS8}#2sHc;PTe+vC+kh8Tj zggFb}WB&u3i>z?Z|BMLkMI+Gtj|qqs-N-u3&a;SyYi zEASTtdE?`1q+k6V*}(GfmIJ+*cGAH5C$fn87k8Q87TFD%qZ;DYP`fD~etgVDoI9B{ zZzHQXZ${Abap&y_UlZ1PjAK5=F^KTFl?S{K2|mI`fvnX;z8`%w#NZb2HL{BM{3_Ph z)GET86pSFqY=%t6H{9a{+GH`*;!pxg;#LZ^G?ekl*>rR3CSMEoA}t8tqClD(SV7WW z)>q#u=ZjN~8G28!-zrbs&i<$ZdMPhSS3LS4Z)@1TfT{=|vsbHxTG`ib4 zeP3(VJ=6?-8$u&!3{61Jikp(3X1v;iw7UCxR4!IM$$d|@GHI1~V>3WniQ<*QMKJLd~ka}9|i?){d(rH&|)?T~4 z^#C%K`nn)n%uUoXU)KWqjF3O)-K1{F6@O9WrIA|hYos2874Q(Ogok~ZxMh-tO#J5W zL03@*EqLQ75}4($<7VD*n8q7Pb%0gCHGa+@Zw+Uxt4Z@Cum(KrKOQA-ndDLKf<1=a zT383`;c<8ZT&(Nmy{;$GKLs*xK8?BoHj=hY@C-Z)&%tKc0$X7l$omw}qn1G3PQAYX zI|zGeZClF5;4L>?NPy$HNDlK)luNQK}-kjOJLixO^>%TYc((x<%MA_5aikf_rEiZXK@H%PO1NwP6`P~cqe77On^lcfV<{>E*J(6&%*4L0j_XarzZJ?$ zkf&-4**eTY?A`_!_e$ivraW(vIcdI3Jzk=oCI4UAxyY3;Qor1<_6^WundI#f34e#U z-$jndNW#w{-$0$8!`L4o&+@+AH})W8lvD3vcNE_D4Q7uun4%jTuB&6AG=6~kAsh!& zJ`%Uw8yRAK=w1bcF6XXpyd7E6yLC$4PU}w_JT7vjLh0ow~_yWH4<>@;6 z$~TO3%DDyi0h#;Fz3m~SYY6EYf}bJQNn|-^IA5ceG)X$Y0eLqG8R2FZIJ-nuKo$@OXc7@1BVGHE}9{aN@PW+CGT)N>$XJ zp7g`&uagJQ^e$0u)5vbQ8(B`_bQ3`!Et)RFXw zsk+Zgnxqdq@sz@E>8NS6N102e>;Bs+Tu-dokbhH@wBs4N-)+H7)*PJoP!=;uq3GS5 zdEZI-aO;A!JN+`AG6@o1+Na!cE*mvV_oZ^gDd{LL`JhZ>Osastc&Lb7CGsHtD@P5d zeumQvhLgVGh5C!saTVm4{vm1UU=`JCaQ4WoQmWCXt45(l$=brS&+5pRwSv>eYY>;r ztwH?OjPk2maC6jb%3wBe&L&Qg>sPfY$MfXvh}{<7W}RP$u(Oa`H|j2{EN?q<+J=AG z)7@oNrI*&zY2*E5;%op7p%GzZz1bLj6KD#}K=LnT)g1j%)E20>Kuc%^twG*5mVPVG z8QVnN%^FwIA>TgWI}lL;)ehQ|mV~H#tVHsWq~mh)T!cF(=w&_cr7g<2eX>qFcTmVz z3Zz0O=!|_Dq(c|z3K`HXY7X@*??OrXU*Z|=94ixhS(9X;W6z&>wPPK-9ff4c_AACUvMR>sgc-^qU@aa&qkw{JFarS^>gI#f~W42W3ayiB^J(gB9p$k;)W07`|3uXNjHUMz_I|>a zQ%~Yo-j#WZa(r5srIEEEYB6OfW193=Q!X1RhfRz-Cd?A%Qqi+!4263Z^*JrCoZ5`K zh4{9D^xJKy&*N^!ed*5+FosBYp4nr+9bN!wD?6f=hTPn0CuRI1m@!Dwx{NVa!kIMf z)bTC9j@^UTv0I_XVi{k?xgSFBbyYYGr>WQ7I{fNFcCvnqay=3*3-ca|TfIWO=AQVPa9O-c zo?jzrvL*lJ0V97;Z98yn)+Z*a!RJ0K5rr!9jRCRK_yanS4E_*M&}bmbTZ@ z=JLx|=HqvCTL-pX0X<* zar>4ue+Q@NyGLEmv9^#iQm3t&vEwwd&%jyu9)5sxu*KeNmElVZ3M@DuC1U~44v;5n zil6Xf)~ehKL;p+E7VB5sE|7-b;CIIJKd}E3E>eb5Qkkc zC{DQYJW(#;FGITB?6F>;O_Z@@&sY-oAYY=0;ENQckX;&c8MuisLH(t{t>kyB&To+P zmi2G8%0YSDWey7R475sk{jxJu7B5;A{PJ8}o{0ujJo&1Ke_2yhLaiJM>m{BlAm>-| zysj$xYET{b8l=BwxSV!bwMhHT*a!JaMs4z02kK(3hgu&RKtpH*jr}jvb68WuH;j1^ z)T1YAcgRlmm`=NruWayqia#mVt6}#hQr@%+PtM>*%Gk`E zVDxz~42I)A0!G3p80~+ba&yY`m~Jai5#Jd92eb?6?;o<}<9QVEj)me>$2jCjnT{v? z1egeuK*l+#ugU)7$nmQww9~2nk64qLd)BfCmU5H#oJH1P%v(tJG{Q^=dH-()>P#); zV?D3DPWj0^EbZz^{N9Nw@B7c9Tw?i}i<|t-COvn--4NvKF8b^ee<$!i2Q~lvnX^pH z_xV4i?D?Jp{^wzy4+~%+Eb`0OU|4E1?@Z*2Fw&;(C$7c*FVMG8OZ>N}2mD{scE7Ne zFyAaC%raOG5Bk4CuGq_c6Yg9S?jh_~q6XDT%2V9F4u^dh`&GD0{#N_HA;f>feoH$t z@jRksd>4{&Dr~<-+n)}bAJyhFVe@0!d^T*BGwvW?sxfu@196%$Yc2lPX}{+}Zs)bS z-v1-@&$%V(d;*@t&r_&R!v@%hc@sPX&%$%C+5eL+!}Zkh7XQ!0&FG501L_g`m$2J5 z|F4vVbJis9Nb-Io{?1oq1Reuv&rWx1Up}s~OuQLwsfj5w|7ytWUKOBHJ{l#g&)Ia0v zTbK{R+wcy&3x`0)37Ngk845j}c6``hjI%TIO|>J$@gDw;qP~xM3_d{rA?k6|k5E4* zo)f5_z^CvTe2&`}5adg7au3zaMclxqjK0EM-j!)deooTQ>bXAVzM@iJ`|D`67+(?M z78rM*m<#axG-ESukTs3$wf?leCERX*UG*KD@}E?v{f*Qazr2&eJq7%KPv4MxoIjwK zyUp?)Ls_ezBR%KgN9czAPq_aKzre5XG_hVl{f#vK4u8O(a1pypa2c+El+jVL&8+N&(E!3FNew6q}%N(Zy!>7(Tc>) z2T|aM=xD!+iN0h7qA%V&<6l55(jUTxWZ`!)N&(}g(b}`af(S5}#OFqg)U*XLEFRMK9Ws(-jkB9QDfLYQJ zUm*U$xL3qZ&HyS!8<~}(ZM!J;zd#lI7K5r#4XQ&8s0p>;W~dEype}NxP1Zw>?EO~##hjkS1>NQ>_yR*eLsCKHO9Z(Oz(&+otvgpNXIXsBW z71191Ayhe|+@$w9@{G&N`&P`Wr0HSOBhO)0p-NlS<&XXmSObre206!j40SE6V==QH z^>KIto@6|DD%yE(lY8;ee_I;}w-Gi)d+leUi;Qu}9?q~Yo zQ5{zHCsDSnt)2C?e7os=!koALTqR>d01H2v>>cHO!V8q^F~Y_%JADuxO;`*d=X@U$ z&vA(3>v2BdhMBgXg8N6>-h}-a`6sB8PoiIBy>HF|*Yi%4jEA2h?lbD=^XP!>LFN~P z`x3s=;bjcFqE1E^VJwtzvG&)|vGzB#p>J{jjuM8hu4wK!(WT=^5$utKX2N@4g@_$k#jnh^}w_NqR40z66)Sxr=cH{aObI)V(TrPnq(S!Zau0<) zF~#Tu8AIi{S`>OeL_-V&K+3HMYCI}u?sjZUDSAgKWR*fz3A?Dsjw#LU;nLWZ#*Q;< z;w;W0{Q~213Br~P$tgt|OOwVjF-2*~Me$!WlpgN>5$1W$B7^veeVtnfJ*^ECPF2(lK4rA?%S@=>0zG&4FA^B;IUh>#Ermh{u*B-ffs%52-w+niX z;XWw(E@6K>TZ*Yi9oEBdJ^VUy63OiH=px<|;MMngl;X7`Jjs zbE?&hFH<%njm>m94Ip0wVGw2X5o2|{?qBQ?BuqGs<{75j<+e-VE@>EwdmhNze;BGf z+mv{QgY=oBto`M^{}Gr+!YCLGW8e-L3*%rsOn`}`VN%RAZi-A*lVh5**5u3~rmdO^ zbD7(w#k8=e#{~IKM^Mc`oe6gmZWhdjyWnoP2j;-Nr13t~xiAl8o$)2l3g%&>5$R2AM=H>7p$h^IR@_PtYVtyDu@(sCFsH-tQ0&8Lxs7J}iV=-o( zycV~0upYO^QJ+A467?x~8aBX2*aXkSOy_+r$-8{hOuiRZPd$tMbA%~N8E;0v1-62G zbC{R3)Hd`NxC8n;>UMYmzb%=Acc9;iUi!!ZTIY+TS>_pee{UD|z10lnXD2Qv4&#S= zjf^c$dzL#DtZR_>GVF#|K%Qm4iuxM74(9%a>4#R-?|g$uzG2T;%e=5BrX_7v?)c^3 z3w(q0?2Y-AKJLUL=V{zUgZZ!zndUq4a-XmjYcn~UZEf#oY&?LxH_3yHt8)KOo&moV zBliX4d2VLDZ+{T?x8WUlH>Qn!D5jA*3`dar9&sOq_i>xdms$6@+Stdi{~)FveMjtg zZi2bJ)t>Rkua2Yt2tEdRW^;nDpFk4&PqF(9K8G)eN9L<9(SHRe;cFd-q_wSG8W?f) zcq3!yH@JTr_9y##);ah;g`CsapMeiCOFqw{eves}Z9fqApA3-aP|sukBlbVVNckk_ zIpSyRCPqPob7qNu*KC++RWVZ^-=}^$&>; zF2W_a3|HVUu<0{b3HvvG|3Up1J3cOqEP3|B_lyI~y1W4B0yp~eRtM5#;*7xT!QLBa zYe%B`APW50Zzt?bWGr_Vgl{#K%gUIeMche7|NURvy{23NPyK#AlWX8 zUz4^J?I$jf%Gx!RFsYcO-cA3I=fTDBTO3M2$v`LSu@n9};g8i8cFsKm?nW}QN!qx} zKtAJ`8_N)%oG0CczaU@zjiDTaf%bM;?DNyo!7fKW%Lfwe3fRZvw<1&uq}Z!Ho$bnj zG`pcnBhED9ly9n~(`(zRDghZsoc#>X8@TK%YpGjl2hyLbk%sC}18PDoxEZ-JRvjUK zwb9ps{PeTW57bljkW(M~1|Z{DL(07oG=?V76q-SEXaToCOK1hHp$)W!c7&I2Bpe{+ z?U9)PiGhvO)&`Xnka3K6{YXKNF>cNZOZ8Ry!tnl@=pL1w}4o68uSid`q@ z3~7M|Djm8YuPZ!8Ib@(pzwCy4CS*Z&Aeu9EXKV?m?xZsZdVq5_FYP|a7n7wvdtx7p ze_6ZrA`iWhaVzu*bk%+8HuTL%V;o;oj$nqo9shFX(iiuBfi8Bb=x(&FZj?ed>QCAQ z?~EWP7k>i+8SJsdPli1(AYWn5#9t=yvH0>tj|6h4+Z@8?5LWgD+y^F1iuEBo zV&28auk1@6L+wo-))MDBSWo>t9*{3-_aJPKaJ;gvm-V}}`>mdy^yeP-Ub}&MBG8ML zBzifsHSR&azU?Vw$JsoxpCYaxU*$IbB`oz18v=c<@o((K|81-v3(9xG6qI>8c@;nM zoW7vkzB(Vq-btSmUS#*9ojc+F>t0ZP{{m??dE6Mty(Zrq0|Tzfhm-G(fr0criHr4- zE{8#3v&@S@zCLd9z}ks2k$qx4Z9gPzFLtu7dsf%k&`{o3?}YrzyO`o8XHH3c!CdN4 z;=8{4uyFjFb$W(}&0Dm2MA&T7H!^IVN*f6B#d9M+)Fw!S$k_(Z!}h@FaJrrSlsUT@ z6Do6_p%7*V>;!p!`6B8rcuB{9M>zb;*zJZ_w0(EGN_Z^1c6>d?naHd7eGR`dCccik z2exAO2JD4>upbW4AKrww;2^vW@4&k{9`3E6KMY6UJva*QP{my1TnWLb{Pqx&)*VkdTt@4waHdK)OL%kZz;}>5@*7?h=G=U&ej= zocf;g{qvpkzR%jup5Lrlvu0+^?Ad$GTzETuy98j#OUp?E5C{a21ux)snQL9j-SQ~_ z$jRLSkN^Nc1u!8n00M|&!GHx~3^0BJ1{?@100CoYAc4UDi1R^A`U{tVnCX`c42ZeF zvUp%z0|sFbL(4%47v`rPsLY$dzxkHIa6e=|g8W`e0J#6e*3S0lok~hYor;g+0kp|K zWPZn79GqN29Na=&{8XIWLL3}I+&lm!kR154bq~NQ(tcq@5YvSGtQii}!uSjKf*6QK z1fV<)E^ZFk=%1~A1j@tx!WJNg#Qc)0x`-j`PZO~cPt`sMhXC_APxdC5@@1W3a~k`FaRtl%f|r#F@NCLKQNH_tIeDo z9FWYPbwMo*^9v7xI$?j|B`^a%^QU!-K+9re|7>$Ih%tZRY!G8*|I`B(1t7UUF$e*e zKQQbc7~u~Lm4nuA3I?2C_&*w*|A+@&`QYFJGax@6 ztXCSuSZDx{0AlD&&;)TJv|g~iPeJ_VS6xrR%p{O056akrI2puXvw#F_uwqaK+OHxI z7l9aRw{8$uf%tcOhW}{8637R$fl=@V5r+jNK}9DZMglQ(hPji0Hu;5pL5wB-(>^ai zj4h4`T!S*XAjbK{&m;%!0P>wdejA7h#NmFlfd`zmgdm2_97PZlff%a)5r~OFc`yQu zz#A3FhxWx6$^gmuM+vCpZ~EN}X!_Rg)(`fF1PpL{%MApBGYbONO$8PDLASTioWD~) zF<9;gff~R(T%em~OYyhN0}!-<8qgr)KUmPZk-#hax4>U9RN^Q10@U+cBQ*QR%JkQo zByH(v|lN~xC{$Hr5$VS0N;USO>9n{|h4k#qMLB-q{z=izm z7j%drjg8=n4JB|L{YTRHne_j~g)~Ae0JMPtsPu2G4}a&~{$)4dA#`Q_%?D#>&hIkN za=**|T>=0C{*e2V56<5olK=p|Z9!WL09R)}BJc*Ge+Y1c!xkLl(jbQQ(}>V6{MP?l z?sp8$69?Poj}8Fj$N*pt&K3la`5p|zU|9O2;@|1t@oyb}rlI1$i~Np%%R%EGJP7zg z1YrKk{yBbp_nEk!G6R#)SKoh4kzlszuK<;l1s`}QL3w7sV(7y5XZWi!kpG|2CIo;3 z;4+{l`KRfBW10WR7QcCa&XfI?(gkRM8skr+{K<#T#ozQN|2GdB|1*4Oz5kiqpSphI zKim162aW$b`~dI?3joXf<6`rtwts`c+41B0H|&3x{2wBBRPUf-1P#rc;7{$+vxOD(_zt~Ai)AG+Y^g8}q{pxVG6;00rtw!v#agf0QDDiT?4)ISo??pNyD6V^kBFHrfC3va5e}6Y~a2HHF!bunZX=Rki!n{V{iacz&(H$OmTuG7{H4K z43S0;Kc&guL@!nu-#H%fB3*UpzY=cYvKm`6AT0a zFF<*vAMJzIFALVH1U|1)zqQ2%4F#s}aoT@*OiwLs1z zFz+FFJp)^(1=gnqYLWS|=OYGc;ssm64DNhTffk_x$U#0OXl;DJ25jw9KmxQc6F5SY z;D|7Rtzrgk3caX+6tMTEV7?f*a4%$Wl5Ctu&59mNzfHL4UIEvyxF1XSM135rA1PhZB@fj*5<^=XC z9~<5rwm1?kY$*f}mIYizwg45#9;z6E4w^iM2}UL309GVgE9?ol8$$xY1~Rze;GQE4 zi+T{)Qe@KflNTzl;Lc%dBd)`gK^ozGe|O&>1V5i(6lAOo;tI^eTMxhv>me2<5ON!b z34R%at2|sY3edfc0ti*Y1JCz=$p7u1fC_FY0SGkwPzv)7rWLXY$$)tcKGi=sKWkVlcN5(7XbEF1h5ycr@13LxGf;U_sM z*({kY35dTCs}>UyZxufhhstch(;%fGlc2PVeZRLQdMxrrBueB@{?7`ar)p68`Fi{r zLoos@Ecj&tJOdB4{vhlEo&>Z_{WTYrNF~>6(AJ)z0t%2sKY?FzQMx^@KXgm z#S|0((ckC5P-7tgu)ogWp-X)9Jp|_GIVc0jhxvtTfB9dspbqGW z{*G_|@izoU;D--zI}3iEA|W6kBETadA|fIqBcY(-p`)Rqq7mcZV&ajLP*RYSkdaZ* zu`^Q9u+ox|G4V6Aa&YqS@K7=eiVARvuygZpL6ty|k&)3*(TLE|iMXiAsJZ^zblV1C zBY_@*KP-d>fWd~qVnc2_q5cR29{j}vNMKKX5O|0W2akY=gp7g;3RGi(`wg(LFmSN& z@Nl4AAwJMUemHD+9BNJp1YFf8h%^p(TmdmzNVJj_?f7aV2Xx%Vj)BN11cXGyB=ii7 zOw4z9c=`AR1cmNDkdl^>m6KP0q@k&$t)pvVYWCFJ!qUpg*~Qh(-NWCp=-BwgF> zUpKc7kB(1H&(1F{zd`#29*Y0$)?YpQH~qo}`vn6B2MdP??H2^b4Ggf@aPZWe2sjd| zh)*1FX}AKA@FZihD%z20xz!HvjU7i&2BN)unFmnf6@A9=m~ zB#g3puG*0Ei8C*PyLrN%%h4e~`jx|e1>e@=iG-Oi>DV*E@kxmn)R)uWfg7JYX&a%t zyT@X2^sO@if8bbJs$x^y3@1X6W)R9wAL9?)hSzi zdWkoz#%F??}zE&4==clN=oY>!Ej9wG0xL*xfi+A1X5xDn! zDs@zE(Ml-vg^o^%=I7Zj^)tX#-GT}L@y~hp)tdcSYh(u%RY`0Y2f=PpxvLU+m3D7~ zV!m6DIRCz1p_R-)BiHM0Y#Cy5Ps;LJpcucuczkoj!sXqToR#jvq{$us0S%{W?VEyB zOar0hPg7r7VxJ|%8Ol9zCDKUH9G@RK)RJX?jpo9ngW zTEtlTS^BG-z1Du3E(w9BTWt{n0E&qupJgBUA&u(KXjAv}v&BTjsb1zvKMNTMh8I^) zm?_S9DD4tC6TQ$tDM`C8Wt-wJu=-8?eJrqL75}Mue2-*dJ%{DFe?5Ss8PeWll%ecl)r05J~h(clsW!fJJ0H)rogvnOt0e}jODO3I^8+w-~~Kk$0&Vc9y7 z6s0EEBeO&qVB!y08HfbUeIbAQ0w&)KWzJCoZF?LGLJXvPt)`CK+St-ZPTWj6zY2zA z-hsf162nlI9Y*;|J(Vi794WDcbGXkj|51rV>L^k|+T)$ff&fwb202TlduVgy+u^{u z>E=V1FWI9q=%XnLFT17BG~oQjIg4(*24zHCCP0Q##>>1OFN?A@ioQ3QL~k!Q^rov` z^zxfq32EF!3SB}7-E-|L+LU$n;(m^nIeRWyYRQ0bqi`HS#N^GYp3toNW7~dx78BR? z9)YXUK}S9ED5AD6@7VWg6B(pJ>|p{qxDbGzu}du_QZir?$cU>E+JwPOuc#XJ_ zOT2MIJ;A;-&QMnus;NpV0VkKiCU}`rK^KsE_032VX?);C5UvV)(Q&Kg41hIxQa9IWT7R z>kecEIA*%t0yI@PUx;;7b=n2n=Kz88V(be$NjU?)DFzelj-nac_C2mjlB!_~Aus98 z@;CF8_H4#^t%n=k0-}w>0f{_bq|CPR^Lu8fQE#GQVS9%tH+VkDs8!Xsa%z`uf3gb2 zmR;6*n0eh~R4dr+Ui5A|x*~G(Y@RlTGKIb>3xgxmJ4`efKgx$9(W7uq0akB_89udp zCk$zoviXjCPR!!Njj{XpAHP!~ZBI5RG(KnXV(T*xyB`?-^24$?oGHqB?)cu?u~Mh& zs7J8>8gZDnF`5mm|TKbi;*O7u~!9XQ_6v)i3F zHcs}<^Sa72zJ4=Qc}D}5}%%Y*B~R1Dy& zuqO8f<4}Wn;-ff|v?IpXbpm9msjIao#kJ{l@87q?E^yNJ_54nKveQ>Ly?L!n3BWlhz+2dgj#XhbSi|AF=gXW3C_K+Zv z?6_VciSV_J!?*0$VkXPeYYky5D>9#}JdSbjD17%7*I+M6ck&^SvgEFLQEo z_tqC@w=E+^g&EO(fT(EiYa~t=Ekx$Fuk-$EL%7bMx33<(7>ZmM+ z_ewEDbJECT=2M=m!=T(iq>SM$@YwLVcCw8q1#wgBe6;E^-;SZcoaEA~fWVfFC%Fo> z*SŬM&&ZnMC>-77NtPApG*#IeyvC3dOwHla3}B<>gnqMJ0|`aMx)LDJAN^Z{-; zC;kkKrAlH~$-adi;dqDNakh^#4)OE4Lt5B!q_n4b^4=FWey?3M zg^-{xtXSn#Yxuo_Tb{7d0-wxv^^`^5<-_wMgrSRQwskug7injZhm?OV>-;SezsF3HFi`a!!Y1zzz18+&T z%EI^fB)-G+aFmy;A||yA#jivuP>bbuTs-o_dt>Pola9ryD;n!AJ(s?%B$RmJv$IL3 z&ZH;W_ESZ)j65rHBos8I3?RP+Is}i{GvMdiV`SZXHPmAt1rlyYLrPzaX5UPvwwF#5 zyY3na^eR9CA&8MckKsnQqq~eo`t@vHO9of2JdRsKhX6#HkM2ddkFeL|!YCWPk77NE z%?Wi(M0^$2jP%E+tOK*PFFst?69bVd>a$s!>I++AX>!IZbM>=*fi7RFF z6UD1i3ttNHDf^O@-8cC05F=S~ZL*VI(a<(xvMEN2!~z*NQgR{UG51GN8%k|&skL7@ zz1(=)M%>=bGP39FBeYN9Qbb0!?ihTmulaZ=uuA9L#=ocW%U8-T8|cR{PD5pgR-5Sr zHVa=Kc1p2DGF*S9vBZ(htX8?pl9EJdwZ`>*+bKL20+(ufAX~bRM$YUzJ;Ix#MAz7> z7r?+}Z|_~jlCG6S=9OA{3p{7XVS*FNkz%N&5z8SBelM}N=-Y4= zb6=XX7FQWzaUrNsa_q}6=`Y+&BzWZ9)0H84D;1tv6mH`0`~39m!<+r3+t6L09NV{8lou_01`Fmxd`}zE?{cU|vi0LmqVK-Pehk7tP%y$TMLWJNCe3 z4u7}f;~6ztRaL5aN)@wvvS|y8nS>-L{g7kMcF=Q`Hhy(7H95a-RJK5-E@A#%>(gXJ zQ++3Y46mh)ao4wQ%3TbvDlQTgA~BhHE@F^owE7LSh+rx2N9AePkhlyV8(W;5#3*oe z*I{@(#6V(+YCej_^qy2~ogP^fXc_+W;;6{*$RgO{k8W8s`GmL^L~8vN|}VxAMB8t>doy66uh zcHseWabw}D;fK5F*C@N(kE&TL%9dsGv8$dbFMSH4+*{3}71^k5b~0vK;IAK%tWGQO zm@Kwon-4!58YF6WaX-p*WY-xXI?g%3A)oY4WzcGza#U#o{ zF!li?#uc_wYN=LK4zWzOXbRH__sz`8jFf)3VrRwDi81#`vwK@*w-YtuJmB(U

OsyFLhI*Mp}h>)qN1WVXHFH5o_#Dd z8KMv96QC{EeW|fC*_P$>j?sW5T7%?KY!@yipHz%=ACZ5i>2b)Bk3f&&IAO%wCUckS zVnwo0dBu;&fC;hs>@6@cH{3X!qBc>M->}G#&ex=hNWYDuNhRoF2HKW3SY zR&9)zE?I}Du^1tWDq>d8b~VG>)RD`bcawr=>{Rw{UgOxV&1jnr9GCEekk~|#>zzz{ z@j(oyaPye%R~OE2Xc9JdZA9BFIgvy8qBCQ$o)4)Z60aTil024u_;XFl*)m3Ts zGXNzJ*x?+_|AePiPUxP~pV8U%ma!&sDS+DX1y*0LLnugj7VGuKvl-_BkPU#s9Szu^WD;0g%Wi5iR!s=@#jj^mQkZ9- z(H?HH>Yyr$hl3rvwoaaKMnzxFiTdc_R>9KSJ0pl#D_S9i|AN$7T`t#wf~s1HWQQj9 zs6rsdSMiC{SbD2&;5=ip47&Yn{d&+|@FI_@rktH*)77IXS8nM%x@tE#fG@f{k~0zm z>88mzEuwea`w^{_g_=OpYdc0bZvG0gjL|R_W)}V2p$Fr;6E;--Mhxq{JsLo&Z@lYt z%-iWqF~-y!@(aQ33lyd@XBW|=idBzTOav=6Im$O#cs7V+i4TzkM4k^V8<_H9)?Ua> z3R}?DzYqUlo2SA%&11tZZ4bGWUt7EG41XHNk{#Bv!6rS{Aa?ut#}*YV%rAn4g9Ql= zN(e~E2=E99NN6bFwiPl83Nk7NDhe7VCI&h-Ix-3tHWn5RE)E(dE*3~Xwy2;5Vd0SA z;E=FTkx`-S{~rC=qJk{J48lTi{dx)WZe!zTcm-@( zF!E?4s=+2hRc=c8>)I*_16#IAEYO^00!T-gxRaE>>y|vAf1GS91qeIjKTif+SHXtY zjXs3g<4M8;a@Q!hyLiWigvgd(M+zNpj>f@?=^ru#FSkFPnV)kFb>i;Al}pz~i|MlW z<*kp?9nT;6oSSrVB_4|vRzY_ZUW{POoeF#2ND{PmgDY6i7D0*Y{q!IsxazFAS}#H| zIKp){2fia+`5bVV^0!{U8-5GmF^+Y|bdBnG_arNjHVD4M;eqPu^Y+HQ@w}^E*+el8+%~GH5 zVb1xXve5=OC}4yQ52u(&>Cw@l$$C-DH=g(17jZG2^rCCo#{9#WdyXcfOigWSJ5xPe zVKnYhxAbKQ2q2o~4@Evjyq6Q! zU3Evp_ax%$AWx1(yJ7vrtUIjS*vflU-?-w2Tt_)v^6%2p$ou~8C*=a;*IK+~8Lqac zI&QEyEYhZ&4{`(iiQqe&1ym!mQ!-b|-HamK7_IL%o%onb>mkv_^UkvPMOU)M#P{1Q zJL)s_t=5-wRit-Hm=!%X(CI>N8{nFodl1SIjm78GM;_VU?ZJ>Wreymu!rZHoq(M5K z;sqV$L9EfoVzKCV@1r=oH`;qQQ|&MArA~>J8(3H|)Za{m5iKllu-L$rv^MDrek`%B z+Ia8K%PUeua(AHq(}efYHTLxEMM&cNmnN}WdZF^v%D6MxA2tCd( zd^^)$!<@`(DnmwA&$xF&df!LNosM8-!+kF1{xIi$WXEKllKPZFvZK8Gl9DhU_R#6@;=&@0iB+;(zY2%+2=AM?;^3no;)9|rNw}aj%^#pP}AoM)e-m16CQEZ zkyj$a9+#xKH20rres#D7FxCzVKIkFY?(USG3VL^i;j+`p*%IL%b3!6VdI8^i%~7we zsh7&JFH)46gVo2&ZJgZ=gxR=ds=v>f-CQ-5AhFNO5uNO6%a;^cTGQH@5fv9c{w6j; zM8SMfzN&EL!O-0J7+1+?cU{jrqnh1crm__c%ofNMOqZe7=sb6BBSX77-hE)^ z_Yzj?BB`{@{k{6+-5ezmeJesOc5H^aev!x?|5rn6EQup7n;FuF`B_<)iQl4LPTXaW z$IE(wh=P)ifgiGlQYIfOucx2KB&p1)Wo>wTjnUekj33!3`e`WgRJhSvd+u#*O|bJQ zb~~&qHs^508_)_}GPzbaOs_hHPz^Q%=kA-?xE0S`rs~cOro7;U5%b_!y(8ol3ot|# zAA9S@iAcr1cGf$Y-4oTF!F*AkC%3GG*fCi#GuXIisFwUh^s@os`H1Wb%rnWIA&nw+ zcVXp2^8Dv-zs9N%6uZ$?C=|r^59DGI^+jV>I%O!Xl3SH**2G>z9=T8t5uZ-)c{7_V z-2#|;G8l2opP#|Je8Q077`s-CK&*9?dL$}a&f7F9a(`K`*oI$&%}k({yFTK)s7!h; zT7?crMO0eglYH^u8M0)qbIUC-m9%9pdw{>!oaY{Uxtpjl=E!F2LTX8yOdXNQa@}{X zfVOc_$J=8`5*1=IV7^OXiqdHox`ZKv$e2+o73-PZT&k@6Xug4>Io~qTQLm3Yb=W|L zefUPN=Z+v1jJ{bN*~aA*d4Ux_cbt=*4UB$QECUlPgUsWOf)ypJIbmW(p0V%fjo)!U zcn&_Ni1ITtamZ7kkf<>W;(dCj@)_q68dnYlat?WV~6)laDHGp0fsr*p2ZHAQOZe4XKC zq8@Gc3cfJbm%~h!l#G5`Sy|;CqCV!Y@9W#{>t=~`NOpZ4v6B6LoBV0vVXMLTa>Lj) z%hQHuXzqz6Wd)6#XX8#$p?sCx1) zN1kAAhc#cWDR-n)@-le+shal2Fxr&Y760tQ18<49Te3CLcckF_tUfndt@Q$G9CZ$T zLz6WdshatkQNqC{VYLTQp)PFFOchssYn<7GSF%R-ZFf~`=TNFwhF*Ph^u9mNaIo8` zk~f1GNVGarF~n;9u3j}f@H3TpOxT-lL-KQ;QdP;1EcfdxFYadR%C{aQSeI6-eqOFM z4Z#xSxAjdDVOqk}4em)+JrE1>CR`D?R?XZ!6s=qkmV&EPg1b*Tvi5K(TARiDt5Y{; zoL+-QLy~%_vh|Gmdl}5bZwsHi37zcB5^EIDZ3T#M6r^hoqa8hl`cI3*@XKZ&AKY1( zmX4mz&+s_&8Hsn}*6Hnhv1+ya=+5f+@$6V0yX@QEwQ$>Y+gQUZPeICXT$QEAnChi@AM`Nw~YXqu`nzqZXb0jt+~|?PZsfbFi|#zw1Ub+S}`rU_Dusf zwFZKFg9u}d2t&HtT;Dn>7qRpDpucueyT1-}$}wVshY* z-R&4Y=)VP!+%vQfrC$-gDz_0K8kuIBbDg^Ji06!GrQ_^lb|r(n(<-v`L*xC9`&dDV zU)pw44D{3QtqxY^-p@y~G72-PmMD~(}q;dcE5XOuzY!w zt(v;It3(TI#jV>1mlRsdhM_VV zBTs#dt=YuX(z|!sZ6STp)YIzpq15j%B$lSe#ZY{4JF?t!dX!c+MyrHb7^=c}t{y!M zV69+TLVEDbF&r7G(NR|9wENL!dm#(y@+5oiYv%mDxJ$A7>lv`Vy@uGnRJlUA4KLGP zHjkF9cqN+9h3(h6j!Sw7(#CZ89OrBr5FgwELEdsD7A;gYhsYzwIQsVs)~c)QgyL~7 zgFRm&Hk{y>^Au3JsUu6~q3oqud_Hq)JgztbO9gsO>uO6m6}f+~G&e`l{Mc(l<}wg# zdL!8~RMSw?QWdl{ocJQ~!8wxb5T!B;-u@wNW#khL>BIP20C&6{q27nGvteAtiSiZC z)VmPnigxEPMO&2TN#b*~8v(&CyNv?)=UOuD0s>v+vb&o~T62vR{vP0aW~g>UdM(m? zhRbP)?2)=qR>a~U1oVN{Mok~W{0yo_1SyT9uYme4YPvD- zxH{Pe5T;31W`fKXro1G8T;jEXj*$m#HJ?9TtmTVusz&5WeFa8j?)jjjhGAKyjX1`g z?ql%|Q$!tf$PjsESYbm?@@)%@$m100l38JoEI|j&JXIZZ-ev$-k1jrca-~c}XmTJ7 z@ZlC&@uzG&$%h4fEztLRJU$l&0$V8<@`jWcaeY@APkBgWZ~ibH`<6UH&(jnM+QRxC z9*kA6Lp<<3YPOl|Yz$j4E2FlV_ur?w=I>>9G!HU%H%LX~=U|4QH|#Y%s;Tp7OmSpB z>f4@W8Fnqp(HmvGmdG>wIurO_Z(ge6tU_};HIPFZGfydbI`^_F=4hxh>P0%y)QJk# zc3$rUeVtb^@0(l&;>A|0EC6dRP#^b`4>e)OK9U|Pr&)o7-I<%)9QNbf1(Xt-3li9M0+ESo}`v1ieQb@tC4-@~`j*>i?_ zQN*85z3_#2-#dtWUuxx`Cpz~nD9h>XgUaZ4vpf;?2~1;FOBB*ei$Tm!-o?BSb8lW= zxpS;Cm)PKF2zNuaSQ|{(nSqc& ziJw~Xz3ui)O<#-@E%q}}CizT!W!a2tez(Z|Zbw6N={Vm*y;+}}P*ZKV0aYyk;Ta_A z%>7<|ZM7fX*BP1My(Sq4k7sN&wH|76^baB>5mCtN)(%zGr@IN`G}+_jN8@w6(p4P} z48Gk0^2c8$;OOxOVw$K;9vCi3Y56n@qPL3Lb8F88@2W31>+E^6tUCw&{4C_)KDpX@b? zQguV8{5tO+Vc)%B1W*Ej01 zL}6V7=^0{bhm@Emt%Xe}>(C5+%xl~wGfz)-E_2J)-;i{TbN=>y(MgCBSI2r0%f$;5 z<3hX7$7=Ko5rF9`2Yc6n3YIRz#ZU_Wq^Er`n824{Y?oI8h}_byEb)w)f90}~IrMCj z*MY3z!3f8^!Rh`+M2(a1M1Sh?5GnVh>{K~&N+7dHykHKA`hn$lLu!QB z(xP=@5l=5t&Yrinr0f__YM-pQWB7RqQY?ND*lzze>3fp9PituTu`2XyCClec!NYrv z^ra01@Cv0>bbj?jiicl2r-s~;^A^fozeUzMu{&dKvqrAmx zRryF7z5@d5n@)=4)?*M z)@Z(1Zfy$4h0S3>zfO~3S$>A?7iRQ#k%DEY)E@~QUck9t=C~H$8I7G@ea)LJuiEb4E>@bXZJqX2O-8PbZtGw=Mo?K`f|$fw*Cc-!l1|vxK7>2e zo-^QX}z=cSM>;B-hpIR^ZpXSl0bONIK7Qsh`CV?Xkj> zk}X1-FDuqfRW+O&Xt_qQM%%=@^6WKX zZY3xqU&X}CGQTu3IZ`p3rm+_>AJI?0Vs$F->9$6~41S*yoBGoSewf~FUeuABY*md9 zKayA%j);T5AksJ{r912`5hK2KpG@g`|7l6UU{>)cQ`OuzVC60$+L9}pwCf(-YN_N# zVIyxMD^7Ccm$Sr!{Rbn-XIoc25A_XcdSg1wP0K1i3Yl^yNIv>@=LUa+AaPZ_Ua!$* zJbuk*ifi*wR@+W+a60mg@f|&6m96VhVQw|jMA}~Bl4C>LVMIc)oB1*uji`)G2Oa;g zo?OjR)>r=Qr32*cu#E0jJYIp*I5QuHYI93#TY?#eW2t_YqruC*fh5|v)6G7lS>vMq zqy^b8`=u?sTW&I{O_=8NQz;COq)1v;+&Jc>l^va)e{$yYrE4B5O?Y(Bwz&QTAfQK*RgZ$?B?%pYJ?1fS_r4E$q%->?oo}Gv#m8XC)t>Jr8E^uYlMVE zmnV^3cVYxQO3%S(IMfPr@dLJIo|Z3PI6LcIdCf1?bJN0vJZw=$q`f06c-H6GD0hO7 z-!CZ0=IL8NnT7p?Y>H&#_1aRwYyH)!%B3612q88JwRu|XJ)$sEUQbJ5RvQA-No5M z++X{q^G>V)+_?zaN|lD0QXzZt_s%OJ7yR@@QQ^*!Ekmpm?HuW_g?-JI7ztMIy5lGI zqTCgQ50e_lJ50+FSQn68d#)p0Lq0##$J;Mr7kaD2C=ax(NkMrie=S znR_0qaFxm}#}-I5GV@HHpX;eScAoGxFTG~_o+^TSaPPPieR=!URb!egTvOu11gu&F z4q46@4>pGo-H2D4-C#RsYC~N@<2pQT^IY)u?kCwy!iRCxF>-S))fO}LenskX67x9P zv%Q?l5iAR4%)O9lGq^i`%BJa#kUfmW7`gE&9##=qEtK<44lD|wah69S7ExjxdxJ1~ z5@IrxhCctLgTYsWb>soQY~Sp$(-?2O6@DJx<~>6_(m`bxHo5I@C)_T(=503!u}=@z zT!q|%s+i5vnI-8Q)~F<4iehN%RGZKX7zJ&uSB7S|wmba@UHaK%Bqnw;|2qPIu_mq`uR*Ha!>u)YK7gcoTmyKXCquXcA$4-%gj zgzIh|5yYa-%S$a}O9{@C-Tz|xwexK|+>{jW?)OV;r}V0LLFpII=G11Dg!I3NC^=oJ zUZ}LS5M4~Il<&-v>b==zuom^-8ns*lYSpEs+aftMl!?O013b#TF2=6-E(%t9x`fNI zw-&L}jK*!)vx245M-qre0@~vfq=}=CI4LCkAw*q|D!+EKjYT%^n|!s{xF~X74k}ia zM>QR-y!6Xh@P@430ukS8LwRXt9+c-NxJIsgnR<5D4Xb;EtD~A|gYLRc#5_i`$>$(N z=0c^|iiDxUjP0!OiSxn7M7j`hN|&HXwfh*4HV#EriPX+8^%e(~KXJNLRFf6G%^Q)@ z@s4S>yHdV>kRmt65&r)Qw{7UCkD91NQ_aA=GkIcT}~e zY6tsAmS@LR7&@;B5Up{ff%QS|a2O@m61A`@KRWN@4uRqiVi8f(#l_nS&M=2akx!3; zwCtnbeRYWIJ%y>CSJ1S%a|`Uc4jU{qaegd`7T`$eo#9J(#<4+!;xLG*ddfyYX1rcB z-ap<#Z87tpvMhjnVoo!rYE0q@i2}BidYy;W>=c|4p6apDGrGy(m-yH9Um5}zx>vrL zh;|}vo!=QPJD_8V38?m%LGVhTi*|H~o8b19Rntl@FDvTo=yFZoi!yVjk5bTk6T3ve zOqwPcG?R-}09?;1*nEBDq~X#ZLGZz2D0Hu^TEKR#M!`$ZOOV*+&2?q~!5*orejRvL zq8L`4A7q7{(xlN;GRtZi*LwEia)M`wYlbMNIT8+TptO$R{A1em<}{A|8(Pwu%GvpD z+p5L)`VYEtjFH;S1U6741bf?iYV)+BbHDi+(hSXJOUu$ZFG!|F+N)4zEboUY2tTd$ zm*GZUn_FuczIRB+1YqD{A$YV=oK$gJyen$2<*pF8BO&5)0$WO@Vb}m%GfzKw{gD-R zGj{~)JZ87COYyw|c0Yh;fUe6*pf9P+T#r`*6PIjBE20ju%#9Pr7!=GOhOGs?#LktZ z40)(asN(sFzm~*y8Eng{5+hy-A$i@H zT$eCBRN})cU_}lp0eYFs;wS>Sb4-xVA199>M&v1httA1^EQ3zL^Gjix6seaEpYi5K zo`C-9$P;~6DZco?)k@|n9*$UxC7A?s?GXf>H2;U9eJf4pU3ZJ!lk9l<%lSTZ48$VT zuw3;?o|}wiD8AbawC?SE`Y!jKAo)`VQSoL~qK}pC9ZcpqQlvQhQ}2Mm$qfVLSBj4O)8`?b>$oUgiW(V#!^;XE^?F zLmD)~rYCENqh#mAyWXjF&UU7!LkuyYnsJnS$alR_NM+8*vJw@=lM!?eCxKx0>G>XY zWpzx{Ou6>Eg}Fct@vFh58hgIyI#)v`dfnu$G>cJ9hB?=F4^9(GR}@l^=#xLe=SLLG zWG2XktvwTLliC|1?#XvAkGy`o;-k{_ZDOIZxHiebjmc7$5v6_^LYI!H80&M%o1LFi z5}u|59@B(+OROxuGN9M{ZhW~O^C~2V?(*RS!C4|vU_YR5qg-h*cmbCrD3g~ND+E6z z!V?e`>&~e5dSLL0&8%?2okgzVKsoAODIAPzjej5OSS+?brHjO6q^Ik);zeG(qYR7-qESpV(^Wm*6jVV<_V*^ST7}hgnO!c zL{DVwUVGleZxDQ&KOMKE7-IId4W_(n+jJxTsIaWyz7lP|9rk7eo^4G?j2yUe8OUY9 zJI)n{)McW$ua;sc#pd8?w>qaWn0nmrMRrP;I~UzV&)v(EZh688k+|wSqd0l3cQ;8C zQ7*5?D>rZVb^G3~tR;bT+atpDF?v_g zOk5dVs(v%Y5w)hes^CvO>pL&JS;_+a-)5$z(?`F1**8G7Fya5{B{ zO!=N=F2uL4-xbwRXFCJ?nlM|$;j;{TqXW##i2M(Foro5z`b?C{>GAS7UxT)!at1`m zuQ)a-92I=&Cv;Q>-`PcuAPdrZ%#xaN0qjJ8ca5;Nj8M4M&QV>D_0iw!S!$irEU5EKA0aL2u*ddo6z<}rrr;)ex}L%*<7auY># z^px^=tJ&8c(GR-3KL{f}i|Mv^n$yxa*zdA)C>`t#oJ4JnMY8AX4&eyNiG&IF#V=}l z;%qJ`lO%P*&jbF<7C+DsSA|xg7I9~XgYXcMGI+8XMXq0ZfINleMGxSa@u7ZQO{gtZG_1;Z!0Zpa#XH(x)|I)6HpOS z^a_4lZ*-8Pit|j)%jM=eG&V8=RbI9D=v!ztc;c(NcdVF&x zIpG^~rW>*3s}JYCcw;5YdbIrev4hy8bN-(n?}Ri4`P|g)H~Jj*FF%m6jbBEZC!{uT zZC}lIT}$b&1oG$5i zG^=+RqVIU$1s{9le){cO;MtZnUZSl8%zQe%V^}8S1tZy7dVO2hgRS<~rwLtS1&o-_ z7Baqgz}G~S$k%a}Fd;zL!lw$Z#V_t33M-C0iBml2op*4-Q{}-J5@!D}o8~;w~d&Of9eOsz>p1nGKuj;Jl;Qx(X?x*iu=`mhf5S{A#2< z#$KvJSnOcG;X&l9B^&;(w=o7fR>^pA9~oor09i?iFwrMue_Hnud;kEKT{SrQhs_Kw7fDC)|B<<(whv2YKTYGzED z3Eodh(6wxE)4Cce&-anyVM&>`+sm3*Pg8WY7ayoBR86?7Jq}-jL`jKg4KUuI&@Q)P z7%b>t__cj<+IYw1XJr_0E=_2mb^&-o41CDQW##4bH1{t&{A9NZBl35a<(^gfiETT5 zZhE}*NpFSXO~a$w+8SRq*7L~&5s9+M6+G|adiR^lr}K>gZRKxx%4da!I$MdHRfw#G z@*DFdxZm2)c68-xxT=ZNt@dH~FRf>rjQe|Pj((8NUbCs_AyyaoKd5PSB4 zo%r`D^wa`r7XCwJ+$ zrvCsl=}&;3Jor`nHh5oD_+jBaeE6eN)ucLU_~hp`)rMbI__aryh^NmtUN%yCHoC5#ar!Os3*(ln;Hyde zcdBR_wbh(cBh7IWTmJ7P5tTCT+ny`)>hDyupTT+z8m_B6wy@q`BE!Byj^l4c2ON6h zx}}M7(mD|cDW@q0}8!{XgL#JVnEhf`Ug`v~oh9r4fRvUSDZ@k5U z$vN(7dt19(>u9d*=8obCR5WtLL041UFvvfJ4^pK$J=x88i%Hd`wvtO&x5I8yXzVT7 zhuUNZICjiuYX1NLQoQq)18sF#6znL<&gVCw_;`}xJw-8#NP18vEjN)xgojcdF-3|No4CKG~M2m>>*DS!rru45beU5x}AZs;O3dSivaRzg}rF74$lJ=%=+}A z!ExE`P0wm}3ywTfXs}+wgPKYOamR{n79GXiNkxH+x{`u!E_f7_Sa%n7B^DLM-APO? zF6v4G;_jrR7Z-IU77L5Il8XxV7j-2T9mU;AMT9z=MTRd7WyDQ)vBF$5~FByrQf zek;w!W8sB%vv2S_aM(FwHNBDQ>vIH)<|K&8jP6zhW7fV{wbZBhpQ?>QN1o5Y);2L( zL1%}IT*?@ibpf-nMietC$jBAuEb>q6ekY*vbiUu4qcy`?>w2e&{{Yfumf|fF0f~^6Ys`NWEx;%yx4RQ{ zhMM@KX-nf|*QAy&2H8mVV&OO6uvCeZ#vk`#$}wP02?GO;GtGHtk3K2d_yfaM`qsx` zbn_TKPG)921YGXgqX4nO3~{*PvUrKq(ODXM7}D15oBse3zAWh93H&`CrK#GimnB&= z`#(4dWS75|5nLh+<%uNvlE)SCuC?NgQ^&fzy3dJjzST6$O33Gkld`JdVMky9rF9)- zMzhfi;-3*~zY{gv&l&ih3QG4PG-pxSpFI3X@e*oYE5Eyd?hyfR5{^os0A)w1uT0RtWPgb_KfTrNbiFm) zmSZ&K-`wE?jDNuE%#`IPd0ywI8cLc;HTR>#MVOo;PJoF1WCyN$l7F3jJ*0lio)25q zverCZE}?Q0ds}Gs;9w4+q;kN1AX4R%*$v7GYb1QW&fjWv#sVPVSJ_%`!S90_8)Hh) zm&6zGk>)JYwZkR>`{WdX0PmdQwf0h744qni&yH-g9}#$x?JWE^r`+ln2Y|NGmn)xA z1_$CreT%7h_dxLK{{UyL#1`m{v}t}Ei5Z5`8PZ)jlKZjTO{7YTI~r+nh-g7rd2EQ1d=q`;4ge ztraPCGIf&K9lnd;e}>-+kln*)X`#!v{yr}cpQ=a)_eOIbeT-l3*M(|cE7M>tI+wha zbG}&^;CIP2uO&6R)XmDYy$@m4J~78=@-Kq4=V><`*Y~76q@LW+x0;(Z&xo}-C%9pjhBKGXzfeC)`J+(r z-Nv=0UD?_@*<4SN60Yx`{saa{G@PZ-Ar!jY^=)tB4V9d&9lpzAMhM7xe;&i}CcH+{ z(#{LRqu;cXNg@d%W^yv5bmNY{Q;JG5?q4$6$D`bMwrjo9qwN{NmD_W3$Ixfmu)H;; zU9X3(Otz_IEzR7k8H}-cV~>D9ImS<^qEynf=|@w0W;*kL4~d6*l9jRmdEBnrSYe z=PTYUrK)(3#vUNoZagzIgH1%a@(gj2#(fCr2x5^B*~KA_6MrjTH<+;U3b zZ5SYRW6o>OXS2SU^jS4!4Rdg_UCdPEDRu!@{sN#6u6=8Uy(Z+jj;u9B3U13@=TG7J zU{yB>M5*QT3;p^BtUQv0QVn( zt|Q@gsUn?APo0R0Fta1KK;+<$$FJdBm8iHoqiQu%_h0-uvGFHYywSWfcF-Z;Fxk5} zAx|GD?Nufxp-hYMY~Z``7l3U;1w$NXy;**#9U+DQEH_?xZVuZ(9~AW3NB z7(AWFf%@0hUJCecq5KimH7_6hL(xX3;>qt}k4{+1NpGavB4^Aja~Zmul8QGnAjvD7 zp2}5Y2-z#M3e@E%tI-|_;lJ6xdS|ofJN2+U=e>n&FED3W{Ay?&PU;?TlBq$Kr|fpNF0o@s71@v1*rW zjcpvDh8|mQQp$M>8xPN*Ty>~;s*l~W62nGObBobv&5w+lo|U7?;Y7T*S?v>1SW52w z?28x~AOW}L1Jj-dL0%{E3-*N6j;@zp6ow;lX!mMnyaAQW*ck{qa5&3%HG+hj=4V5x z6-$!e@D+`3AN*DLt>dGlT0^G|8&0;>%TP^4b70=s#()t5L#tSQ?k?=$b9AQ)ejk~jseT7WpDw{^bqdIh??Wv6~ ziM9U#8h8g*zVRwtN2tT%nQW$xTkMGxU&|K& zeb9SWR;2bZYg(CNcMVQnJsq2YNw%cIr^NpNuBQ|ulIK(L1Sw_qwv;v)mL5pS`G6nR zs$E*%U+Qe%ca1Jq$q*sc=cdx45Y1$B!LvaGz%poUiqafw8z`^O$A4=%M*HpS0x^26o=s$=* z5;T1?!+QRU;feI^J_+q^QaJ2(g3>oES%)N*$mi)?mxO*5={ohJLt`Wpg}-QIX_*u& z02zsx;Y@3tpr|J!p~$PPkAzn%YeTyOmEtjyN|vqkJU07Mn(9_*@=j4!+^Z=fx|gX50dNS9fF<0m73Nr>FBm+4`&XEf2-JA-)aoz=H@7x zTw!Alz-NKlt=s9BvC0}#eGYN=E!7z3rVC(wD@|{9&I$84wHIUbhxSLhvYSQM^lMiQ zbEmD^8OQbsW;qGZMJ8`C# z^rFBnX}L52>TXRI0o2NN3y#R9(O@08Q%@9F2Nv|EZlb_A6W*J;ivZ%o6y4NV1(Y{#bq}Q!4TTgFaH4?)CV8L*q$jNw0coVsU>72q4|*&E>7@3j zU>72rMT2ql%$h6%>4SL36+yl1~DYX>P}6$txP? z#hx0pV;tJ0pkRLL$QXm^g)Dzc##o9m_@My+3I4n%IgZqw;BDou%80vc&;M1bFP;g|uxB)@*!Yh7zu~<(y z!AE)h*EU&RDqm;vI_<)|%UAf99-fjt=ZQ3nG6(@6K<%GQv%eqk0a(jD!Y!`;MzP89 z4|{$80OWdTIUo+bxUUqS;?IQSZ5}J%6I~OkPc^-xPa{PX(nOU0hI>%65QqTP^))|&GnHm28e4B#c5^_#J&H*6T&bD6>JPb7JeQQv;@Xnhh z#1P6si_Df~KQ|dHSFb`24{r5^O!pG>j8gM9hEIoI6z}r?0D^nX_r*U8TTO2S5=n5+ zbLC6rfTA(a&AEsS0po&xyjROmd|~j!LN(K)d-;*eH<1LVC5h@(0fF`Ws~_!*W9q)+ zca>p#Gw3fFe$ZYQ@OX@0Ld3|qP#bX^bzq?J)4A)?zCZDW_Os(XV*db9HrFtv%%#yL z8&)6oQ~iO|XPO>qi)-Qt<#=@V{LiXx{x10MRI|31N43)IT6h|DmRSsuJY_)+7zY>x zobDu%jHs`jG<_!KFAm#yUfSwlCW<^H4Iw3)zW}JgEycy`(|HjbF=+~- zsOLO(1FlU;Cxn)JDK0!osb0Ym@}4_Ybwdx$lx8TP`HXT(jDf%ak(yVy)KctHO+Q6# zR@Lx>L#XPONpAAUlG(wX+J*Fp zF}dVoT~`?n#O}etIU!0>l-|R0j8>BVzpo%=ixBAum8lB|!@(Udz$@fPj zq+n$9V86u2fsPlEpOy8!Tg09_*WT{g#POLikeOFM8RZ1jaA`Z9=#~+B?ewCc7^kw@MyWHVE8hjc8B(k1PGNURzh(GxCb2(q)W~oVRj+*bpdPb3J z`^&B42N*k7pLW3K*qY(B-G9Jd3v_*D<4M%+Xu^pu9|NX2Bk?Qsq@MDp-c%&e=p(tN#E1PQUOi$KJks*8Ed-HN*_1r4oslyoWg3 zj*HNKB-Fa;Y>W0^%zD!|EyVIn2;4~r)6i9N_Y!v4-M{e` zwW~YDtIp1Yl!-90r_n|@`seFersf#Xy~zMB4o{_0vL;NliV{RDK*}CElf^PtxoskS zV@tHSx{4=A_r`##GxX!Bs!_2#*VL^o=&-)GmJk{3m=y%@N%pOMBf$Ed;rmvw(dqCg z5*8#gj1Gq!1Nq~nUdvJ)nQK7Tt~_0;MWaDv%PM9^kyLDq4yQeT3hH$K0J2)yKA+*} zKF<-4%6WhTcpXa~?0=Os;X!kt2%Whke{H)~eijB%3>}E@|ypQCGg`*SDtjI=gIX9A5ah|SAd8g{WBGO+-($&qVxDIZvCBYE|10;n9KZoUCMR-r(B=JPIz9`is3~+py zl@*7!20-WCkG*3oT_pE3SZT{+$}FxWyfIu{NL-Xvjid!jAnsR=rz8sccS!JmgLE=y zveK>Ee=i?sx*lYi9_`cc0=VkpVL4qLROmP>Hh6ZIq3fEC*z~(8m#SqJ`N+c`G+2_!v0yTttyV}sJOvd7Cs^TDbsv^e=Wu4v43Z6ERM}@ z4h|X4SSztCs(XM3*R^?urSZSTT9=(3kpy~j7bkeb$_LbqqwrdBO&)Ks&Ukd8+EtJ?^b>HQc$*>0Gh=&-AOj(%c$^ z^=DV{C*mBQFuBwGJK*bM9-C)kkXo$dq8B|&v1Vo^vQAGYl1Vkm*ds*n?m!iYY>w5A zsokrZ**GMQYgf^3F5$L|$hVg`OtT&w@NlD#rhhuu@iWOB?R9LVZ75aT{HlG2y>+*< zXEv(#F)U%w^o!`Mbv@$YBMxB-pfZqo8+RVQrn1?^#-ML5m`yt%UFZP$SN{O7R<<&p z=U4v#2?mE2(Pv!I1v|`l{m9nG=h89`E6OTx(woyjO5w z5SweE5IFgY{i4m-WOgJ2_*PHDsVDycg+=iTdW8_nD~+e9Q3L+~PipI558wJ6w63d8 zFRWkwkuUN-U-2fNaK0(=8lY7JSCxmjS3l!kseSOKT}R^=iF^}ts4O=T-p?%4BzZ+2 zD;>LtB!GCxQS_*kWZP*QRGd>yzlzO#)zR~%<+LYMxbxy^K$Y;ZkPj!hAlKaX-?Asc zdp%D_({4OzsOvX6rIHOnqlsEp62zLT>Q}AyQJ}~OU$bC2M^N0dZNmxyc<+e?PGZk{jXe47Ha(;%pFxZ%{cbA*bLe%9>9@>_U zP2KNx(OXS=-1#r!ufTDk_}^Xdzl3#r?-*)YOtCJhBoW2?$tCJ-!aFfV{{Uz%I&e6w z>+jkp#k!8Y9mT1OL$Tg7Z=_mVF4YPb3aq#}$MLfat;8 zvEj`g3k33X`|E8=>`a&PY;;npIs>~rcKqwmd?)dnSMcVC{{RaU#2RI$w>#_N(boFT z*D}D+?oLcaK~fLhUcS^e;ZVkiyEQn?%bYnn(@0Y+iT+lUMAJNP2oQX zX_hBg)9hn)g2LiR=Sxk>B_B3PC64CF&$UF~G@X^g6uq3GDBY(Qzec69?zP9-AP4;DKy-QVz}aIC(Ya?q?gRNQL8n0#j|rcu2%cTw-IYrwpKb!_j+?dGu+=6R9K%lMOAz=2JU-t*14sb z;b8e()&BFM7z|9+)L-TKomT4de;NEx8a?)fdvoGlFT=K$_Y#|{If~6K=*BjJSptFA z<;lqWD+%XVNV`S1@-~K5h?3UJ=D*;cu3bSH<0KB<{@F($#3#_t`k?){4blW9_j7wTtsGQUQ_41c-#W9V#gqG1B{c?8LnEq zM%uL~Yv#_HSq8rR^g7tSA$WRCD@oLu=2z5hVYrIOM#klQ#oe{z10k289>;3`B za>%&ZhGtANGqLV-#~H3^XBf(lS^db_Wmsgr*k9G2;jZ}c^xJt2&x$nNK4|BYaq^;X zkaS&!MkM>^pH3_1eIMXwi{iD4@5K83n!(f?I9@_=)DYWo`5Ml7mL^Z*X0gk#>v*O3 zp1nWDFAbpr@5MTvq~AFUXBxx~dmV_KJAUx}YlqT)40v8C?Hcy~08zVllXHe-OfEUv z6nEpRe}!|@#$siooWAyGuvmDj*?r6Wi<*bV{{RiZ8|*p^*Q7E1?x8ts{X-cIPCNtP zndEw*G%J=qndeq_=JS*{8Fm9T(`1V)x_sh%VAgT_(>@)8%H$ z7^2+i*?<`XpJlGrEk{Jsqtltqm5fms44g)+%aBPR9Ob#lBLHGW4QsQd}>BVAT|{{Y=d7QpR$a9bV6-7IiFI?=rNKC$0b@m-RMHC5xvtsjy+siTK zn~uC3)uz;~E>`m5(VpVe!z;*L)BvMYLj?_P_WX*qovtdT3gDGb1WnYSYz&{Nyp$%BPN^T--6yb@pM{6+}OBP-}!o|gT8LzlJEqtrDo?A;?&iuUeJ&E-Zx zD5Du1sOUcN99N`xH{s`oz8hLg6}8mT-rjECdv~dfThZ+CNV z!aftx^xM0ek2FuHO0hibSdkY$DxkpUx%bJa?lqkg!a6n})t=u=)@U_;aLbaBhrypkz(n(Js zKfgE}C?}fWJ}dlX(S8xxu9szQw;m(Cg{6iGMsk{m zQ)}WUjx_H9X|i~OR0*nTBbMF>-V^Sd*0ob*b_(AWG!ulz*u4c?`wJo4%{F0tY9 zwFmH`0l)*(1CDyvW8n`9!J+BUYd6I=5>#gZAnr*y1N0`8>dIP2V2wD#SGnlF20j_- zR(E<`i<5M1vvG1W`?hT7<|C;mip%iV$GsE7seNUo>C$SqlJKt@vfIX>@s{MA`vLW= zs#Ma^G=y&TKA(nNKEyDEN=VVVgBtV-dz}9OO8Gxu@!yVoSDCeY!Kc`ee{&Hj7CwOF z{w#i#%~E)Cl>D0(c&PbNq+BIND-uolozsm9B5*+N^grK9M`?aC8Tad z5vcOiWGb%|`T2Gso^#<#L8V!(rJ7#dN`Zlzb#2U8a#Se5^zZerSc?5bN>uII7aUZ| zP4yZ{BaE={?Zv@KCerS%10F=OvajS%^seRZLha{q^1G(-W54e=QQD0nSG@E(+j%XmGvunO?Z?Uhu3kMx zQMd*Kk6L`fEP+??tPc)&mfKI&qPo7D5ylDW$UfB-Dm53&xZ@2^ zb@1(;o8ikMu$4CwFYm4ncM>~s+PtGv_`T+4(@3?Af#fvAmVTV!Nc~CrSDxcmqrA?< z;RR@(&o;al<}TosJ3#}1j-+JZSI+vLy{+qKb^Xk;DZtpIENlM&0T>*8DwPG*kDa}b zV%0t*cz;f34|XS!WF(|RdB@?v$>WkM!J}f#6?b5D8RL%Q>rGLO#N^LO*8Vp5hTzE$ zhpnKpPx%b*<9^Y zj>GQr>;-6e2I2{PY2jOI_~M$=`$pB|SvXf!ZP;!P9CODstoj6+g63x%BX6EKt(06G z6S6V6h+a<%&jYP{hNIzGJQ=9?r{YEI_P4r4+C8qGEeb(%b#XhAP?b_uBVEUEIsOm_ z%~MXNyYFbroh8haHC<08(EKs4c%AR0(X{r0-qU;BUEP5dya02TbDn*GIj)M|;&!K| z+}P>X_7>LqGT!~B;?z$g{i;BvSI%cHSS~UF;~*SW>m);$CcO?T?D0aouJ82!057Ka zrgq34iX#W<^{-Nk)Kb^R#&l_G$0{XZK^UzIKlSoRlYV~+xV--{xR0APn?(Y3B-WqPUKU^ zLF>(LPgwiGTHMJ+^k03oIB9Qw$u67rMc*XTKpc_L9dboyX}W7#iydO*sEkO2f_cLo zqa)I{ovd;#?9RI5#2;gYBZxx_^d-S(KljZt!L%7QtuIZwEB38L+B-BOaF$Gfv4hyL z;AWIlmc>iC=)VoMEkjlKQ}H-YBJ7IR_W@Uy&92~bdH`3N(eN|r?ciUFdS#W=GfQn@ zd?$_~8_I97Pr<=B&ePW&KN{}#bEg&0-~5hBNlO;t-COTf7wU4q5cQYv-|Zpd4Mp~t zZgmS7?n{DK$he9zAmD?_=bZ7@s(gC2RQRu{-On76yxL}!a3*&GGLLM7AQc1H@_Ef` z6?sU?X;#9~ZR+6<{U*n!cyq_6$3L{DjjH%^GZv9x_qLi$3kKy&b%sD2$z1*NcMv*v z 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

gv_5Gkpi7f(Rh~LM2Z+LWK)xkKU9!) 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�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%0D^A+0Bps!IiAscr-@x% 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 K-uB(>kN??8*#t@e literal 0 HcmV?d00001 diff --git a/modules/sfm/samples/data/images/resized_IMG_2891.jpg b/modules/sfm/samples/data/images/resized_IMG_2891.jpg new file mode 100644 index 0000000000000000000000000000000000000000..330af2f5e5d31d7c3214c03b3d8062efd030d7d1 GIT binary patch literal 170198 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

FGkd_^eJxjpDf!#k?7GE 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�@7N>59W=+sK-6tw>U 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

1#sKiVOunpnIguE`LQ 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%0AsFefbj>3C)9Lb4{Fx3$ziD7 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 CA@9HZ=;$}u1_E?3wMxvZN%i!nh2c9&>&9vDoS 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 I#Xjf%*~e6hqW}N^ literal 0 HcmV?d00001 diff --git a/modules/sfm/samples/data/images/resized_IMG_2892.jpg b/modules/sfm/samples/data/images/resized_IMG_2892.jpg new file mode 100644 index 0000000000000000000000000000000000000000..45e5787ef49afd2fff088217da3faef1bf26d470 GIT binary patch literal 210762 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�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 +#include +#include + +#include +#include +#include + +using namespace std; +using namespace cv; +using namespace cv::sfm; + +static void help() { + cout + << "\n------------------------------------------------------------------\n" + << " This program shows the two view reconstruction capabilities in the \n" + << " OpenCV Structure From Motion (SFM) module.\n" + << " It uses the following data from the VGG datasets at ...\n" + << " Usage:\n" + << " reconv2_pts.txt \n " + << " where the first line has the number of points and each subsequent \n" + << " line has entries for matched points as: \n" + << " x1 y1 x2 y2 \n" + << "------------------------------------------------------------------\n\n" + << endl; +} + +int main(int argc, char** argv) +{ + // Do projective reconstruction + bool is_projective = true; + + // Read 2D points from text file + + Mat_ x1, x2; + int npts; + + if (argc < 2) { + help(); + exit(0); + } else { + ifstream myfile(argv[1]); + if (!myfile.is_open()) { + cout << "Unable to read file: " << argv[1] << endl; + exit(0); + + } else { + string line; + + // Read number of points + getline(myfile, line); + npts = (int) atof(line.c_str()); + + x1 = Mat_(2, npts); + x2 = Mat_(2, npts); + + // Read the point coordinates + for (int i = 0; i < npts; ++i) { + getline(myfile, line); + stringstream s(line); + string cord; + + s >> cord; + x1(0, i) = atof(cord.c_str()); + s >> cord; + x1(1, i) = atof(cord.c_str()); + + s >> cord; + x2(0, i) = atof(cord.c_str()); + s >> cord; + x2(1, i) = atof(cord.c_str()); + + } + + myfile.close(); + + } + } + + // Call the reconstruction function + + std::vector < Mat_ > points2d; + points2d.push_back(x1); + points2d.push_back(x2); + Matx33d K_estimated; + Mat_ points3d_estimated; + std::vector < cv::Mat > Ps_estimated; + + reconstruct(points2d, Ps_estimated, points3d_estimated, K_estimated, is_projective); + + + // Print output + + cout << endl; + cout << "Projection Matrix of View 1: " << endl; + cout << "============================ " << endl; + cout << Ps_estimated[0] << endl << endl; + cout << "Projection Matrix of View 2: " << endl; + cout << "============================ " << endl; + cout << Ps_estimated[1] << endl << endl; + + + // Display 3D points using VIZ module + + // Create the pointcloud + std::vector point_cloud; + for (int i = 0; i < npts; ++i) { + cv::Vec3f point3d((float) points3d_estimated(0, i), + (float) points3d_estimated(1, i), + (float) points3d_estimated(2, i)); + point_cloud.push_back(point3d); + } + + // Create a 3D window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); + + viz::WCloud cloud_widget(point_cloud, viz::Color::green()); + + myWindow.showWidget("cloud", cloud_widget); + myWindow.spin(); + + return 0; +} \ No newline at end of file diff --git a/modules/sfm/samples/scene_reconstruction.cpp b/modules/sfm/samples/scene_reconstruction.cpp new file mode 100644 index 0000000000..3f95667497 --- /dev/null +++ b/modules/sfm/samples/scene_reconstruction.cpp @@ -0,0 +1,160 @@ +#include +#include +#include +#include + +#include +#include +#include + +using namespace std; +using namespace cv; +using namespace cv::sfm; + +static void help() { + cout + << "\n------------------------------------------------------------------------------------\n" + << " This program shows the multiview reconstruction capabilities in the \n" + << " OpenCV Structure From Motion (SFM) module.\n" + << " It reconstruct a scene from a set of 2D images \n" + << " Usage:\n" + << " example_sfm_scene_reconstruction \n" + << " where: path_to_file is the file absolute path into your system which contains\n" + << " the list of images to use for reconstruction. \n" + << " f is the focal lenght in pixels. \n" + << " cx is the image principal point x coordinates in pixels. \n" + << " cy is the image principal point y coordinates in pixels. \n" + << "------------------------------------------------------------------------------------\n\n" + << endl; +} + + +int getdir(const string _filename, vector &files) +{ + ifstream myfile(_filename.c_str()); + if (!myfile.is_open()) { + cout << "Unable to read file: " << _filename << endl; + exit(0); + } else {; + size_t found = _filename.find_last_of("/\\"); + string line_str, path_to_file = _filename.substr(0, found); + while ( getline(myfile, line_str) ) + files.push_back(path_to_file+string("/")+line_str); + } + return 1; +} + + +int main(int argc, char* argv[]) +{ + // Read input parameters + + if ( argc != 5 ) + { + help(); + exit(0); + } + + // Parse the image paths + + vector images_paths; + getdir( argv[1], images_paths ); + + + // Build instrinsics + + float f = atof(argv[2]), + cx = atof(argv[3]), cy = atof(argv[4]); + + Matx33d K = Matx33d( f, 0, cx, + 0, f, cy, + 0, 0, 1); + + + /// Reconstruct the scene using the 2d images + + bool is_projective = true; + vector Rs_est, ts_est, points3d_estimated; + reconstruct(images_paths, Rs_est, ts_est, K, points3d_estimated, is_projective); + + + // Print output + + cout << "\n----------------------------\n" << endl; + cout << "Reconstruction: " << endl; + cout << "============================" << endl; + cout << "Estimated 3D points: " << points3d_estimated.size() << endl; + cout << "Estimated cameras: " << Rs_est.size() << endl; + cout << "Refined intrinsics: " << endl << K << endl << endl; + cout << "3D Visualization: " << endl; + cout << "============================" << endl; + + + /// Create 3D windows + + viz::Viz3d window("Coordinate Frame"); + window.setWindowSize(Size(500,500)); + window.setWindowPosition(Point(150,150)); + window.setBackgroundColor(); // black by default + + // Create the pointcloud + cout << "Recovering points ... "; + + // recover estimated points3d + vector point_cloud_est; + for (int i = 0; i < points3d_estimated.size(); ++i) + point_cloud_est.push_back(Vec3f(points3d_estimated[i])); + + cout << "[DONE]" << endl; + + + /// Recovering cameras + cout << "Recovering cameras ... "; + + vector path; + for (size_t i = 0; i < Rs_est.size(); ++i) + path.push_back(Affine3d(Rs_est[i],ts_est[i])); + + cout << "[DONE]" << endl; + + + /// Add the pointcloud + if ( point_cloud_est.size() > 0 ) + { + cout << "Rendering points ... "; + + viz::WCloud cloud_widget(point_cloud_est, viz::Color::green()); + window.showWidget("point_cloud", cloud_widget); + + cout << "[DONE]" << endl; + } + else + { + cout << "Cannot render points: Empty pointcloud" << endl; + } + + + /// Add cameras + if ( path.size() > 0 ) + { + cout << "Rendering Cameras ... "; + + window.showWidget("cameras_frames_and_lines", viz::WTrajectory(path, viz::WTrajectory::BOTH, 0.1, viz::Color::green())); + window.showWidget("cameras_frustums", viz::WTrajectoryFrustums(path, K, 0.1, viz::Color::yellow())); + + window.setViewerPose(path[0]); + + cout << "[DONE]" << endl; + } + else + { + cout << "Cannot render the cameras: Empty path" << endl; + } + + /// Wait for key 'q' to close the window + cout << endl << "Press 'q' to close each windows ... " << endl; + + window.spin(); + + return 0; +} \ No newline at end of file diff --git a/modules/sfm/samples/trajectory_reconstruccion.cpp b/modules/sfm/samples/trajectory_reconstruccion.cpp new file mode 100644 index 0000000000..5c3dc70922 --- /dev/null +++ b/modules/sfm/samples/trajectory_reconstruccion.cpp @@ -0,0 +1,246 @@ +#include +#include +#include + +#include +#include +#include + +using namespace std; +using namespace cv; +using namespace cv::sfm; + +static void help() { + cout + << "\n------------------------------------------------------------------\n" + << " This program shows the camera trajectory reconstruction capabilities\n" + << " in the OpenCV Structure From Motion (SFM) module.\n" + << " \n" + << " Usage:\n" + << " example_sfm_trajectory_reconstruction \n" + << " where: is the tracks file absolute path into your system. \n" + << " \n" + << " The file must have the following format: \n" + << " row1 : x1 y1 x2 y2 ... x36 y36 for track 1\n" + << " row2 : x1 y1 x2 y2 ... x36 y36 for track 2\n" + << " etc\n" + << " \n" + << " i.e. a row gives the 2D measured position of a point as it is tracked\n" + << " through frames 1 to 36. If there is no match found in a view then x\n" + << " and y are -1.\n" + << " \n" + << " Each row corresponds to a different point.\n" + << " \n" + << " f is the focal lenght in pixels. \n" + << " cx is the image principal point x coordinates in pixels. \n" + << " cy is the image principal point y coordinates in pixels. \n" + << "------------------------------------------------------------------\n\n" + << endl; +} + + +/* Build the following structure data + * + * frame1 frame2 frameN + * track1 | (x11,y11) | -> | (x12,y12) | -> | (x1N,y1N) | + * track2 | (x21,y11) | -> | (x22,y22) | -> | (x2N,y2N) | + * trackN | (xN1,yN1) | -> | (xN2,yN2) | -> | (xNN,yNN) | + * + * + * In case a marker (x,y) does not appear in a frame its + * values will be (-1,-1). + */ + +void +parser_2D_tracks(const string &_filename, std::vector &points2d ) +{ + ifstream myfile(_filename.c_str()); + + if (!myfile.is_open()) + { + cout << "Unable to read file: " << _filename << endl; + exit(0); + + } else { + + double x, y; + string line_str; + int n_frames = 0, n_tracks = 0; + + // extract data from text file + + vector > tracks; + for ( ; getline(myfile,line_str); ++n_tracks) + { + istringstream line(line_str); + + vector track; + for ( n_frames = 0; line >> x >> y; ++n_frames) + { + if ( x > 0 && y > 0) + track.push_back(Vec2d(x,y)); + else + track.push_back(Vec2d(-1)); + } + tracks.push_back(track); + } + + // embed data in reconstruction api format + + for (int i = 0; i < n_frames; ++i) + { + Mat_ frame(2, n_tracks); + + for (int j = 0; j < n_tracks; ++j) + { + frame(0,j) = tracks[j][i][0]; + frame(1,j) = tracks[j][i][1]; + } + points2d.push_back(Mat(frame)); + } + + myfile.close(); + } + +} + + +/* Keyboard callback to control 3D visualization + */ + +bool camera_pov = false; + +void keyboard_callback(const viz::KeyboardEvent &event, void* cookie) +{ + if ( event.action == 0 &&!event.symbol.compare("s") ) + camera_pov = !camera_pov; +} + + +/* Sample main code + */ + +int main(int argc, char** argv) +{ + // Read input parameters + + if ( argc != 5 ) + { + help(); + exit(0); + } + + // Read 2D points from text file + std::vector points2d; + parser_2D_tracks( argv[1], points2d ); + + // Set the camera calibration matrix + const double f = atof(argv[2]), + cx = atof(argv[3]), cy = atof(argv[4]); + + Matx33d K = Matx33d( f, 0, cx, + 0, f, cy, + 0, 0, 1); + + /// Reconstruct the scene using the 2d correspondences + + bool is_projective = true; + vector Rs_est, ts_est, points3d_estimated; + reconstruct(points2d, Rs_est, ts_est, K, points3d_estimated, is_projective); + + // Print output + + cout << "\n----------------------------\n" << endl; + cout << "Reconstruction: " << endl; + cout << "============================" << endl; + cout << "Estimated 3D points: " << points3d_estimated.size() << endl; + cout << "Estimated cameras: " << Rs_est.size() << endl; + cout << "Refined intrinsics: " << endl << K << endl << endl; + + cout << "3D Visualization: " << endl; + cout << "============================" << endl; + + + /// Create 3D windows + viz::Viz3d window_est("Estimation Coordinate Frame"); + window_est.setBackgroundColor(); // black by default + window_est.registerKeyboardCallback(&keyboard_callback); + + // Create the pointcloud + cout << "Recovering points ... "; + + // recover estimated points3d + vector point_cloud_est; + for (int i = 0; i < points3d_estimated.size(); ++i) + point_cloud_est.push_back(Vec3f(points3d_estimated[i])); + + cout << "[DONE]" << endl; + + + /// Recovering cameras + cout << "Recovering cameras ... "; + + vector path_est; + for (size_t i = 0; i < Rs_est.size(); ++i) + path_est.push_back(Affine3d(Rs_est[i],ts_est[i])); + + cout << "[DONE]" << endl; + + /// Add cameras + cout << "Rendering Trajectory ... "; + + /// Wait for key 'q' to close the window + cout << endl << "Press: " << endl; + cout << " 's' to switch the camera pov" << endl; + cout << " 'q' to close the windows " << endl; + + + if ( path_est.size() > 0 ) + { + // animated trajectory + int idx = 0, forw = -1, n = static_cast(path_est.size()); + + while(!window_est.wasStopped()) + { + /// Render points as 3D cubes + for (size_t i = 0; i < point_cloud_est.size(); ++i) + { + Vec3d point = point_cloud_est[i]; + Affine3d point_pose(Mat::eye(3,3,CV_64F), point); + + char buffer[50]; + sprintf (buffer, "%d", static_cast(i)); + + viz::WCube cube_widget(Point3f(0.1,0.1,0.0), Point3f(0.0,0.0,-0.1), true, viz::Color::blue()); + cube_widget.setRenderingProperty(viz::LINE_WIDTH, 2.0); + window_est.showWidget("Cube"+string(buffer), cube_widget, point_pose); + } + + Affine3d cam_pose = path_est[idx]; + + viz::WCameraPosition cpw(0.25); // Coordinate axes + viz::WCameraPosition cpw_frustum(K, 0.3, viz::Color::yellow()); // Camera frustum + + if ( camera_pov ) + window_est.setViewerPose(cam_pose); + else + { + // render complete trajectory + window_est.showWidget("cameras_frames_and_lines_est", viz::WTrajectory(path_est, viz::WTrajectory::PATH, 1.0, viz::Color::green())); + + window_est.showWidget("CPW", cpw, cam_pose); + window_est.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); + } + + // update trajectory index (spring effect) + forw *= (idx==n || idx==0) ? -1: 1; idx += forw; + + // frame rate 1s + window_est.spinOnce(1, true); + window_est.removeAllWidgets(); + } + + } + + return 0; +} diff --git a/modules/sfm/src/conditioning.cpp b/modules/sfm/src/conditioning.cpp new file mode 100644 index 0000000000..7c70a8fcb8 --- /dev/null +++ b/modules/sfm/src/conditioning.cpp @@ -0,0 +1,187 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" + +// Eigen +#include + +// OpenCV +#include +#include + +// libmv headers +#include "libmv/multiview/conditioning.h" + +namespace cv +{ +namespace sfm +{ + +template +void +preconditionerFromPoints( const Mat_ &_points, + Mat_ _Tr ) +{ + libmv::Mat points; + libmv::Mat3 Tr; + + cv2eigen( _points, points ); + + libmv::PreconditionerFromPoints( points, &Tr ); + + eigen2cv( Tr, _Tr ); +} + + +void +preconditionerFromPoints( InputArray _points, + OutputArray _T ) +{ + const Mat points = _points.getMat(); + const int depth = points.depth(); + CV_Assert((points.dims == 2 || points.dims == 3) && (depth == CV_32F || depth == CV_64F)); + + _T.create(3, 3, depth); + + Mat T = _T.getMat(); + + if ( depth == CV_32F ) + { + preconditionerFromPoints(points, T); + } + else + { + preconditionerFromPoints(points, T); + } +} + +template +void +isotropicPreconditionerFromPoints( const Mat_ &_points, + Mat_ _T ) +{ + libmv::Mat points; + libmv::Mat3 Tr; + + cv2eigen( _points, points ); + + libmv::IsotropicPreconditionerFromPoints( points, &Tr ); + + eigen2cv( Tr, _T ); +} + +void +isotropicPreconditionerFromPoints( InputArray _points, + OutputArray _T ) +{ + const Mat points = _points.getMat(); + const int depth = points.depth(); + CV_Assert((points.dims == 2 || points.dims == 3) && (depth == CV_32F || depth == CV_64F)); + + _T.create(3, 3, depth); + + Mat T = _T.getMat(); + + if ( depth == CV_32F ) + { + isotropicPreconditionerFromPoints(points, T); + } + else + { + isotropicPreconditionerFromPoints(points, T); + } +} + +template +void +applyTransformationToPoints( const Mat_ &_points, + const Mat_ &_T, + Mat_ _transformed_points ) +{ + libmv::Mat points, transformed_points; + libmv::Mat3 Tr; + + cv2eigen( _points, points ); + cv2eigen( _T, Tr ); + + libmv::ApplyTransformationToPoints( points, Tr, &transformed_points ); + + eigen2cv( transformed_points, _transformed_points ); +} + +void +applyTransformationToPoints( InputArray _points, + InputArray _T, + OutputArray _transformed_points ) +{ + const Mat points = _points.getMat(), T = _T.getMat(); + const int depth = points.depth(); + CV_Assert((points.dims == 2 || points.dims == 3) && T.size() == Size(3,3) && (depth == CV_32F || depth == CV_64F)); + + _transformed_points.create(points.size(), depth); + + Mat transformed_points = _transformed_points.getMat(); + + if ( depth == CV_32F ) + { + applyTransformationToPoints(points, T, transformed_points); + } + else + { + applyTransformationToPoints(points, T, transformed_points); + } +} + +void +normalizePoints( InputArray points, + OutputArray normalized_points, + OutputArray T ) +{ + preconditionerFromPoints(points, T); + applyTransformationToPoints(points, T, normalized_points); +} + +void +normalizeIsotropicPoints( InputArray points, + OutputArray normalized_points, + OutputArray T ) +{ + isotropicPreconditionerFromPoints(points, T); + applyTransformationToPoints(points, T, normalized_points); +} + +} /* namespace sfm */ +} /* namespace cv */ diff --git a/modules/sfm/src/fundamental.cpp b/modules/sfm/src/fundamental.cpp new file mode 100644 index 0000000000..ca0523ee08 --- /dev/null +++ b/modules/sfm/src/fundamental.cpp @@ -0,0 +1,595 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" + +// Eigen +#include + +// OpenCV +#include +#include +#include +#include +#include +#include + +// libmv headers +#include "libmv/multiview/fundamental.h" + +#include +using namespace std; + +namespace cv +{ +namespace sfm +{ + template + void + projectionsFromFundamental( const Mat_ &F, + Mat_ P1, + Mat_ P2 ) + { + P1 << 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0; + + Vec e2; + cv::SVD::solveZ(F.t(), e2); + + Mat_ P2cols = skew(e2) * F; + for(char j=0;j<3;++j) { + for(char i=0;i<3;++i) + P2(j,i) = P2cols(j,i); + P2(j,3) = e2(j); + } + + } + + void + projectionsFromFundamental( InputArray _F, + OutputArray _P1, + OutputArray _P2 ) + { + const Mat F = _F.getMat(); + const int depth = F.depth(); + CV_Assert(F.cols == 3 && F.rows == 3 && (depth == CV_32F || depth == CV_64F)); + + _P1.create(3, 4, depth); + _P2.create(3, 4, depth); + + Mat P1 = _P1.getMat(), P2 = _P2.getMat(); + + // type + if( depth == CV_32F ) + { + projectionsFromFundamental(F, P1, P2); + } + else + { + projectionsFromFundamental(F, P1, P2); + } + + } + + template + void + fundamentalFromProjections( const Mat_ &P1, + const Mat_ &P2, + Mat_ F ) + { + Mat_ X[3]; + vconcat( P1.row(1), P1.row(2), X[0] ); + vconcat( P1.row(2), P1.row(0), X[1] ); + vconcat( P1.row(0), P1.row(1), X[2] ); + + Mat_ Y[3]; + vconcat( P2.row(1), P2.row(2), Y[0] ); + vconcat( P2.row(2), P2.row(0), Y[1] ); + vconcat( P2.row(0), P2.row(1), Y[2] ); + + Mat_ XY; + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + { + vconcat(X[j], Y[i], XY); + F(i, j) = determinant(XY); + } + } + + void + fundamentalFromProjections( InputArray _P1, + InputArray _P2, + OutputArray _F ) + { + const Mat P1 = _P1.getMat(), P2 = _P2.getMat(); + const int depth = P1.depth(); + CV_Assert((P1.cols == 4 && P1.rows == 3) && P1.rows == P2.rows && P1.cols == P2.cols); + CV_Assert((depth == CV_32F || depth == CV_64F) && depth == P2.depth()); + + _F.create(3, 3, depth); + + Mat F = _F.getMat(); + + // type + if( depth == CV_32F ) + { + fundamentalFromProjections(P1, P2, F); + } + else + { + fundamentalFromProjections(P1, P2, F); + } + + } + + template + void + normalizedEightPointSolver( const Mat_ &_x1, + const Mat_ &_x2, + Mat_ _F ) + { + libmv::Mat x1, x2; + libmv::Mat3 F; + + cv2eigen(_x1, x1); + cv2eigen(_x2, x2); + + libmv::NormalizedEightPointSolver(x1, x2, &F); + + eigen2cv(F, _F); + } + + void + normalizedEightPointSolver( InputArray _x1, InputArray _x2, OutputArray _F ) + { + const Mat x1 = _x1.getMat(), x2 = _x2.getMat(); + const int depth = x1.depth(); + CV_Assert(x1.dims == 2 && x1.dims == x2.dims && (depth == CV_32F || depth == CV_64F)); + + _F.create(3, 3, depth); + + Mat F = _F.getMat(); + + // type + if( depth == CV_32F ) + { + normalizedEightPointSolver(x1, x2, F); + } + else + { + normalizedEightPointSolver(x1, x2, F); + } + + } + + template + void + relativeCameraMotion( const Mat_ &R1, + const Mat_ &t1, + const Mat_ &R2, + const Mat_ &t2, + Mat_ R, + Mat_ t ) + { + R = R2 * R1.t(); + t = t2 - R * t1; + } + + void + relativeCameraMotion( InputArray _R1, InputArray _t1, InputArray _R2, + InputArray _t2, OutputArray _R, OutputArray _t ) + { + const Mat R1 = _R1.getMat(), t1 = _t1.getMat(), R2 = _R2.getMat(), t2 = _t2.getMat(); + const int depth = R1.depth(); + CV_Assert((R1.cols == 3 && R1.rows == 3) && (R1.size() == R2.size())); + CV_Assert((t1.cols == 1 && t1.rows == 3) && (t1.size() == t2.size())); + CV_Assert((depth == CV_32F || depth == CV_64F) && depth == R2.depth() && depth == t1.depth() && depth == t2.depth()); + + _R.create(3, 3, depth); + _t.create(3, 1, depth); + + Mat R = _R.getMat(), t = _t.getMat(); + + // type + if( depth == CV_32F ) + { + relativeCameraMotion(R1, t1, R2, t2, R, t); + } + else + { + relativeCameraMotion(R1, t1, R2, t2, R, t); + } + + } + + template + void + motionFromEssential( const Mat_ &_E, + std::vector &_Rs, + std::vector &_ts ) + { + libmv::Mat3 E; + std::vector < libmv::Mat3 > Rs; + std::vector < libmv::Vec3 > ts; + + cv2eigen(_E, E); + + libmv::MotionFromEssential(E, &Rs, &ts); + + _Rs.clear(); + _ts.clear(); + + int n = Rs.size(); + CV_Assert(ts.size() == n); + + for ( int i = 0; i < n; ++i ) + { + Mat_ R_temp, t_temp; + + eigen2cv(Rs[i], R_temp); + _Rs.push_back(R_temp); + + eigen2cv(ts[i], t_temp); + _ts.push_back(t_temp); + } + + } + + void + motionFromEssential( InputArray _E, OutputArrayOfArrays _Rs, + OutputArrayOfArrays _ts ) + { + const Mat E = _E.getMat(); + const int depth = E.depth(), cn = 4; + CV_Assert(E.cols == 3 && E.rows == 3 && (depth == CV_32F || depth == CV_64F)); + + _Rs.create(cn, 1, depth); + _ts.create(cn, 1, depth); + for (int i = 0; i < cn; ++i) + { + _Rs.create(Size(3,3), depth, i); + _ts.create(Size(3,1), depth, i); + } + + std::vector Rs, ts; + _Rs.getMatVector(Rs); + _ts.getMatVector(ts); + + // type + if( depth == CV_32F ) + { + motionFromEssential(E, Rs, ts); + } + else + { + motionFromEssential(E, Rs, ts); + } + + for (int i = 0; i < cn; ++i) + { + Rs[i].copyTo(_Rs.getMatRef(i)); + ts[i].copyTo(_ts.getMatRef(i)); + } + + } + + template + int motionFromEssentialChooseSolution( const std::vector &Rs, + const std::vector &ts, + const Mat_ &K1, + const Mat_ &x1, + const Mat_ &K2, + const Mat_ &x2 ) + { + Mat_ P1, P2, R1 = Mat_::eye(3,3); + + T val = static_cast(0.0); + Vec t1(val, val, val); + + projectionFromKRt(K1, R1, t1, P1); + + std::vector > points2d; + points2d.push_back(x1); + points2d.push_back(x2); + + for ( int i = 0; i < 4; ++i ) + { + const Mat_ R2 = Rs[i]; + const Vec t2 = ts[i]; + projectionFromKRt(K2, R2, t2, P2); + + std::vector > Ps; + Ps.push_back(P1); + Ps.push_back(P2); + + Vec X; + triangulatePoints(points2d, Ps, X); + + T d1 = depth(R1, t1, X); + T d2 = depth(R2, t2, X); + + // Test if point is front to the two cameras. + if ( d1 > 0 && d2 > 0 ) + { + return i; + } + } + + return -1; + } + + int motionFromEssentialChooseSolution( InputArrayOfArrays _Rs, + InputArrayOfArrays _ts, + InputArray _K1, + InputArray _x1, + InputArray _K2, + InputArray _x2 ) + { + std::vector Rs, ts; + _Rs.getMatVector(Rs); + _ts.getMatVector(ts); + const Mat K1 = _K1.getMat(), x1 = _x1.getMat(), K2 = _K2.getMat(), x2 = _x2.getMat(); + const int depth = K1.depth(); + CV_Assert( Rs.size() == 4 && ts.size() == 4 ); + CV_Assert((K1.cols == 3 && K1.rows == 3) && (K1.size() == K2.size())); + CV_Assert((x1.cols == 1 && x1.rows == 2) && (x1.size() == x2.size())); + CV_Assert((depth == CV_32F || depth == CV_64F) && depth == K2.depth() && depth == x1.depth() && depth == x2.depth()); + + int solution = 0; + + // type + if( depth == CV_32F ) + { + solution = motionFromEssentialChooseSolution(Rs, ts, K1, x1, K2, x2); + } + else + { + solution = motionFromEssentialChooseSolution(Rs, ts, K1, x1, K2, x2); + } + + return solution; + } + + template + void + fundamentalFromEssential( const Mat_ &E, + const Mat_ &K1, + const Mat_ &K2, + Mat_ F ) + { + F = K2.inv().t() * E * K1.inv(); + } + + void + fundamentalFromEssential( InputArray _E, + InputArray _K1, + InputArray _K2, + OutputArray _F ) + { + const Mat E = _E.getMat(), K1 = _K1.getMat(), K2 = _K2.getMat(); + const int depth = E.depth(); + CV_Assert(E.cols == 3 && E.rows == 3 && E.size() == _K1.size() && E.size() == _K2.size() && (depth == CV_32F || depth == CV_64F)); + + _F.create(3, 3, depth); + + Mat F = _F.getMat(); + + // type + if( depth == CV_32F ) + { + fundamentalFromEssential(E, K1, K2, F); + } + else + { + fundamentalFromEssential(E, K1, K2, F); + } + + } + + template + void + essentialFromFundamental( const Mat_ &F, + const Mat_ &K1, + const Mat_ &K2, + Mat_ E ) + { + E = K2.t() * F * K1; + } + + void + essentialFromFundamental( InputArray _F, + InputArray _K1, + InputArray _K2, + OutputArray _E ) + { + const Mat F = _F.getMat(), K1 = _K1.getMat(), K2 = _K2.getMat(); + const int depth = F.depth(); + CV_Assert(F.cols == 3 && F.rows == 3 && F.size() == _K1.size() && F.size() == _K2.size() && (depth == CV_32F || depth == CV_64F)); + + _E.create(3, 3, depth); + + Mat E = _E.getMat(); + + // type + if( depth == CV_32F ) + { + essentialFromFundamental(F, K1, K2, E); + } + else + { + essentialFromFundamental(F, K1, K2, E); + } + } + + template + void + essentialFromRt( const Mat_ &_R1, + const Mat_ &_t1, + const Mat_ &_R2, + const Mat_ &_t2, + Mat_ _E ) + { + libmv::Mat3 E; + libmv::Mat3 R1, R2; + libmv::Vec3 t1, t2; + + cv2eigen( _R1, R1 ); + cv2eigen( _t1, t1 ); + cv2eigen( _R2, R2 ); + cv2eigen( _t2, t2 ); + + libmv::EssentialFromRt( R1, t1, R2, t2, &E ); + + eigen2cv( E, _E ); + } + + void + essentialFromRt( InputArray _R1, + InputArray _t1, + InputArray _R2, + InputArray _t2, + OutputArray _E ) + { + const Mat R1 = _R1.getMat(), t1 = _t1.getMat(), R2 = _R2.getMat(), t2 = _t2.getMat(); + const int depth = R1.depth(); + CV_Assert((R1.cols == 3 && R1.rows == 3) && (R1.size() == R2.size())); + CV_Assert((t1.cols == 1 && t1.rows == 3) && (t1.size() == t2.size())); + CV_Assert((depth == CV_32F || depth == CV_64F) && depth == R2.depth() && depth == t1.depth() && depth == t2.depth()); + + _E.create(3, 3, depth); + + Mat E = _E.getMat(); + + // type + if( depth == CV_32F ) + { + essentialFromRt(R1, t1, R2, t2, E); + } + else + { + essentialFromRt(R1, t1, R2, t2, E); + } + + } + + template + void + normalizeFundamental( const Mat_ &F, Mat_ F_normalized ) + { + F_normalized = F * (1.0/norm(F,NORM_L2)); // Frobenius Norm + + if ( F_normalized(2,2) < 0 ) + { + F_normalized *= -1; + } + } + + void + normalizeFundamental( InputArray _F, + OutputArray _F_normalized ) + { + const Mat F = _F.getMat(); + const int depth = F.depth(); + CV_Assert(F.cols == 3 && F.rows == 3 && (depth == CV_32F || depth == CV_64F)); + + _F_normalized.create(3, 3, depth); + + Mat F_normalized = _F_normalized.getMat(); + + // type + if( depth == CV_32F ) + { + normalizeFundamental(F, F_normalized); + } + else + { + normalizeFundamental(F, F_normalized); + } + } + + template + void + computeOrientation( const Mat_ &x1, + const Mat_ &x2, + Mat_ R, + Mat_ t, + T s ) + { + Mat_ rr, rl, rt, lt; + normalizePoints(x1, rr, rt); + normalizePoints(x2, rl, lt); + + Mat_ rrBar, rlBar, rVar, lVar; + meanAndVarianceAlongRows(rr, rrBar, rVar); + meanAndVarianceAlongRows(rl, rlBar, lVar); + + Mat_ rrp, rlp; + rrp = rr - repeat(rrBar, x1.rows, x1.cols); + rlp = rl - repeat(rlBar, x2.rows, x2.cols); + + // TODO: finish implementation + // https://github.com/vrabaud/sfm_toolbox/blob/master/sfm/computeOrientation.m#L44 + } + + void + computeOrientation( InputArrayOfArrays _x1, + InputArrayOfArrays _x2, + OutputArray _R, + OutputArray _t, + double s ) + { + const Mat x1 = _x1.getMat(), x2 = _x2.getMat(); + const int depth = x1.depth(); + CV_Assert(x1.size() == x2.size() && (depth == CV_32F || depth == CV_64F)); + + _R.create(3, 3, depth); + _t.create(3, 1, depth); + + Mat R = _R.getMat(), t = _t.getMat(); + + // type + if( depth == CV_32F ) + { + computeOrientation(x1, x2, R, t, s); + } + else + { + computeOrientation(x1, x2, R, t, s); + } + } + +} /* namespace sfm */ +} /* namespace cv */ diff --git a/modules/sfm/src/libmv_capi.h b/modules/sfm/src/libmv_capi.h new file mode 100644 index 0000000000..606bed1a22 --- /dev/null +++ b/modules/sfm/src/libmv_capi.h @@ -0,0 +1,435 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// + // + // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + // + // By downloading, copying, installing or using the software you agree to this license. + // If you do not agree to this license, do not download, install, + // copy or use the software. + // + // + // License Agreement + // For Open Source Computer Vision Library + // + // Copyright (C) 2015, OpenCV Foundation, all rights reserved. + // Third party copyrights are property of their respective owners. + // + // Redistribution and use in source and binary forms, with or without modification, + // are permitted provided that the following conditions are met: + // + // * Redistribution's of source code must retain the above copyright notice, + // this list of conditions and the following disclaimer. + // + // * Redistribution's in binary form must reproduce the above copyright notice, + // this list of conditions and the following disclaimer in the documentation + // and/or other materials provided with the distribution. + // + // * The name of the copyright holders may not be used to endorse or promote products + // derived from this software without specific prior written permission. + // + // This software is provided by the copyright holders and contributors "as is" and + // any express or implied warranties, including, but not limited to, the implied + // warranties of merchantability and fitness for a particular purpose are disclaimed. + // In no event shall the Intel Corporation or contributors be liable for any direct, + // indirect, incidental, special, exemplary, or consequential damages + // (including, but not limited to, procurement of substitute goods or services; + // loss of use, data, or profits; or business interruption) however caused + // and on any theory of liability, whether in contract, strict liability, + // or tort (including negligence or otherwise) arising in any way out of + // the use of this software, even if advised of the possibility of such damage. + // + //M*/ + +#ifndef __OPENCV_SFM_LIBMV_CAPI__ +#define __OPENCV_SFM_LIBMV_CAPI__ + +#include "libmv/logging/logging.h" + +#include "libmv/correspondence/feature.h" +#include "libmv/correspondence/feature_matching.h" +#include "libmv/correspondence/matches.h" +#include "libmv/correspondence/nRobustViewMatching.h" + +#include "libmv/simple_pipeline/bundle.h" +#include "libmv/simple_pipeline/camera_intrinsics.h" +#include "libmv/simple_pipeline/keyframe_selection.h" +#include "libmv/simple_pipeline/initialize_reconstruction.h" +#include "libmv/simple_pipeline/pipeline.h" +#include "libmv/simple_pipeline/reconstruction_scale.h" +#include "libmv/simple_pipeline/tracks.h" + +using namespace cv; +using namespace cv::sfm; +using namespace libmv; + + +//////////////////////////////////////// +// Based on 'libmv_capi' (blender API) +/////////////////////////////////////// + +struct libmv_Reconstruction { + EuclideanReconstruction reconstruction; + /* Used for per-track average error calculation after reconstruction */ + Tracks tracks; + CameraIntrinsics *intrinsics; + double error; + bool is_valid; +}; + + +////////////////////////////////////// +// Based on 'libmv_capi' (blender API) +///////////////////////////////////// + +void libmv_initLogging(const char* argv0) { + // Make it so FATAL messages are always print into console. + char severity_fatal[32]; + snprintf(severity_fatal, sizeof(severity_fatal), "%d", + google::GLOG_FATAL); + + google::InitGoogleLogging(argv0); + google::SetCommandLineOption("logtostderr", "1"); + google::SetCommandLineOption("v", "0"); + google::SetCommandLineOption("stderrthreshold", severity_fatal); + google::SetCommandLineOption("minloglevel", severity_fatal); +} + +void libmv_startDebugLogging(void) { + google::SetCommandLineOption("logtostderr", "1"); + google::SetCommandLineOption("v", "2"); + google::SetCommandLineOption("stderrthreshold", "1"); + google::SetCommandLineOption("minloglevel", "0"); +} + +void libmv_setLoggingVerbosity(int verbosity) { + char val[10]; + snprintf(val, sizeof(val), "%d", verbosity); + google::SetCommandLineOption("v", val); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Based on the 'selectTwoKeyframesBasedOnGRICAndVariance()' function from 'libmv_capi' (blender API) +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* Select the two keyframes that give a lower reprojection error + */ + +bool selectTwoKeyframesBasedOnGRICAndVariance( + Tracks& tracks, + Tracks& normalized_tracks, + CameraIntrinsics& camera_intrinsics, + int& keyframe1, + int& keyframe2) { + + libmv::vector keyframes; + + /* Get list of all keyframe candidates first. */ + SelectKeyframesBasedOnGRICAndVariance(normalized_tracks, + camera_intrinsics, + keyframes); + + if (keyframes.size() < 2) { + LG << "Not enough keyframes detected by GRIC"; + return false; + } else if (keyframes.size() == 2) { + keyframe1 = keyframes[0]; + keyframe2 = keyframes[1]; + return true; + } + + /* Now choose two keyframes with minimal reprojection error after initial + * reconstruction choose keyframes with the least reprojection error after + * solving from two candidate keyframes. + * + * In fact, currently libmv returns single pair only, so this code will + * not actually run. But in the future this could change, so let's stay + * prepared. + */ + int previous_keyframe = keyframes[0]; + double best_error = std::numeric_limits::max(); + for (int i = 1; i < keyframes.size(); i++) { + EuclideanReconstruction reconstruction; + int current_keyframe = keyframes[i]; + libmv::vector keyframe_markers = + normalized_tracks.MarkersForTracksInBothImages(previous_keyframe, + current_keyframe); + + Tracks keyframe_tracks(keyframe_markers); + + /* get a solution from two keyframes only */ + EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction); + EuclideanBundle(keyframe_tracks, &reconstruction); + EuclideanCompleteReconstruction(keyframe_tracks, + &reconstruction, + NULL); + + double current_error = EuclideanReprojectionError(tracks, + reconstruction, + camera_intrinsics); + + LG << "Error between " << previous_keyframe + << " and " << current_keyframe + << ": " << current_error; + + if (current_error < best_error) { + best_error = current_error; + keyframe1 = previous_keyframe; + keyframe2 = current_keyframe; + } + + previous_keyframe = current_keyframe; + } + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Based on the 'libmv_cameraIntrinsicsFillFromOptions()' function from 'libmv_capi' (blender API) +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/* Fill the camera intrinsics parameters given the camera instrinsics + * options values. + */ + +static void libmv_cameraIntrinsicsFillFromOptions( + const libmv_CameraIntrinsicsOptions* camera_intrinsics_options, + CameraIntrinsics* camera_intrinsics) { + camera_intrinsics->SetFocalLength(camera_intrinsics_options->focal_length, + camera_intrinsics_options->focal_length); + + camera_intrinsics->SetPrincipalPoint( + camera_intrinsics_options->principal_point_x, + camera_intrinsics_options->principal_point_y); + + camera_intrinsics->SetImageSize(camera_intrinsics_options->image_width, + camera_intrinsics_options->image_height); + + switch (camera_intrinsics_options->distortion_model) { + case SFM_DISTORTION_MODEL_POLYNOMIAL: + { + PolynomialCameraIntrinsics *polynomial_intrinsics = + static_cast(camera_intrinsics); + + polynomial_intrinsics->SetRadialDistortion( + camera_intrinsics_options->polynomial_k1, + camera_intrinsics_options->polynomial_k2, + camera_intrinsics_options->polynomial_k3); + + break; + } + + case SFM_DISTORTION_MODEL_DIVISION: + { + DivisionCameraIntrinsics *division_intrinsics = + static_cast(camera_intrinsics); + + division_intrinsics->SetDistortion( + camera_intrinsics_options->division_k1, + camera_intrinsics_options->division_k2); + break; + } + + default: + assert(!"Unknown distortion model"); + } +} + + +////////////////////////////////////////////////////////////////////////////////////////////////////// +// Based on the 'libmv_cameraIntrinsicsCreateFromOptions()' function from 'libmv_capi' (blender API) +////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* Create the camera intrinsics model given the camera instrinsics + * options values. + */ + +CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions( + const libmv_CameraIntrinsicsOptions* camera_intrinsics_options) { + CameraIntrinsics *camera_intrinsics = NULL; + switch (camera_intrinsics_options->distortion_model) { + case SFM_DISTORTION_MODEL_POLYNOMIAL: + camera_intrinsics = new PolynomialCameraIntrinsics(); + break; + case SFM_DISTORTION_MODEL_DIVISION: + camera_intrinsics = new DivisionCameraIntrinsics(); + break; + default: + assert(!"Unknown distortion model"); + } + libmv_cameraIntrinsicsFillFromOptions(camera_intrinsics_options, + camera_intrinsics); + return camera_intrinsics; +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// Based on the 'libmv_getNormalizedTracks()' function from 'libmv_capi' (blender API) +//////////////////////////////////////////////////////////////////////////////////////// + +/* Normalizes the tracks given the camera intrinsics parameters + */ + +void +libmv_getNormalizedTracks(const libmv::Tracks &tracks, + const libmv::CameraIntrinsics &camera_intrinsics, + libmv::Tracks *normalized_tracks) { + libmv::vector markers = tracks.AllMarkers(); + for (int i = 0; i < markers.size(); ++i) { + libmv::Marker &marker = markers[i]; + camera_intrinsics.InvertIntrinsics(marker.x, marker.y, + &marker.x, &marker.y); + normalized_tracks->Insert(marker.image, + marker.track, + marker.x, marker.y, + marker.weight); + } +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// Based on the 'libmv_solveRefineIntrinsics()' function from 'libmv_capi' (blender API) +////////////////////////////////////////////////////////////////////////////////////////// + +/* Refine the final solution using Bundle Adjustment + */ + +void libmv_solveRefineIntrinsics( + const Tracks &tracks, + const int refine_intrinsics, + const int bundle_constraints, + EuclideanReconstruction* reconstruction, + CameraIntrinsics* intrinsics) { + /* only a few combinations are supported but trust the caller/ */ + int bundle_intrinsics = 0; + + if (refine_intrinsics & SFM_REFINE_FOCAL_LENGTH) { + bundle_intrinsics |= libmv::BUNDLE_FOCAL_LENGTH; + } + if (refine_intrinsics & SFM_REFINE_PRINCIPAL_POINT) { + bundle_intrinsics |= libmv::BUNDLE_PRINCIPAL_POINT; + } + if (refine_intrinsics & SFM_REFINE_RADIAL_DISTORTION_K1) { + bundle_intrinsics |= libmv::BUNDLE_RADIAL_K1; + } + if (refine_intrinsics & SFM_REFINE_RADIAL_DISTORTION_K2) { + bundle_intrinsics |= libmv::BUNDLE_RADIAL_K2; + } + + EuclideanBundleCommonIntrinsics(tracks, + bundle_intrinsics, + bundle_constraints, + reconstruction, + intrinsics); +} + + +/////////////////////////////////////////////////////////////////////////////////// +// Based on the 'finishReconstruction()' function from 'libmv_capi' (blender API) +/////////////////////////////////////////////////////////////////////////////////// + +/* Finish the reconstrunction and computes the final reprojection error + */ + +void finishReconstruction( + const Tracks &tracks, + const CameraIntrinsics &camera_intrinsics, + libmv_Reconstruction *libmv_reconstruction) { + EuclideanReconstruction &reconstruction = + libmv_reconstruction->reconstruction; + + /* Reprojection error calculation. */ + libmv_reconstruction->tracks = tracks; + libmv_reconstruction->error = EuclideanReprojectionError(tracks, + reconstruction, + camera_intrinsics); +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// Based on the 'libmv_solveReconstruction()' function from 'libmv_capi' (blender API) +//////////////////////////////////////////////////////////////////////////////////////// + +/* Perform the complete reconstruction process + */ + +libmv_Reconstruction *libmv_solveReconstruction( + const Tracks &libmv_tracks, + const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options, + libmv_ReconstructionOptions* libmv_reconstruction_options) { + libmv_Reconstruction *libmv_reconstruction = + new libmv_Reconstruction(); + + Tracks tracks = libmv_tracks; + EuclideanReconstruction &reconstruction = + libmv_reconstruction->reconstruction; + + /* Retrieve reconstruction options from C-API to libmv API. */ + CameraIntrinsics *camera_intrinsics; + camera_intrinsics = libmv_reconstruction->intrinsics = + libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options); + + /* Invert the camera intrinsics/ */ + Tracks normalized_tracks; + libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks); + + /* keyframe selection. */ + int keyframe1 = libmv_reconstruction_options->keyframe1, + keyframe2 = libmv_reconstruction_options->keyframe2; + + if (libmv_reconstruction_options->select_keyframes) { + LG << "Using automatic keyframe selection"; + + selectTwoKeyframesBasedOnGRICAndVariance(tracks, + normalized_tracks, + *camera_intrinsics, + keyframe1, + keyframe2); + + /* so keyframes in the interface would be updated */ + libmv_reconstruction_options->keyframe1 = keyframe1; + libmv_reconstruction_options->keyframe2 = keyframe2; + } + + /* Actual reconstruction. */ + LG << "frames to init from: " << keyframe1 << " " << keyframe2; + + libmv::vector keyframe_markers = + normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2); + + LG << "number of markers for init: " << keyframe_markers.size(); + + if (keyframe_markers.size() < 8) { + LG << "No enough markers to initialize from"; + libmv_reconstruction->is_valid = false; + return libmv_reconstruction; + } + + EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction); + EuclideanBundle(normalized_tracks, &reconstruction); + EuclideanCompleteReconstruction(normalized_tracks, + &reconstruction, + NULL); + + /* Refinement/ */ + if (libmv_reconstruction_options->refine_intrinsics) { + libmv_solveRefineIntrinsics( + tracks, + libmv_reconstruction_options->refine_intrinsics, + libmv::BUNDLE_NO_CONSTRAINTS, + &reconstruction, + camera_intrinsics); + } + + /* Set reconstruction scale to unity. */ + EuclideanScaleToUnity(&reconstruction); + + finishReconstruction(tracks, + *camera_intrinsics, + libmv_reconstruction); + + libmv_reconstruction->is_valid = true; + return (libmv_Reconstruction *) libmv_reconstruction; +} + +#endif \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/CMake/Installation.cmake b/modules/sfm/src/libmv_light/CMake/Installation.cmake new file mode 100644 index 0000000000..910df4c1ea --- /dev/null +++ b/modules/sfm/src/libmv_light/CMake/Installation.cmake @@ -0,0 +1,9 @@ +#Install macro for libmv libraries +MACRO (LIBMV_INSTALL_LIB name) + + set_target_properties( ${name} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib + ) + +ENDMACRO (LIBMV_INSTALL_LIB) \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/CMakeLists.txt b/modules/sfm/src/libmv_light/CMakeLists.txt new file mode 100644 index 0000000000..4feead2b53 --- /dev/null +++ b/modules/sfm/src/libmv_light/CMakeLists.txt @@ -0,0 +1,5 @@ +# installation rules +include(CMake/Installation.cmake) + +set(BUILD_SHARED_LIBS OFF) # Force static libs for 3rdparty dependencies +add_subdirectory(libmv) \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/libmv/CMakeLists.txt b/modules/sfm/src/libmv_light/libmv/CMakeLists.txt new file mode 100644 index 0000000000..103b728826 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(correspondence) +add_subdirectory(multiview) +add_subdirectory(numeric) + +if ( Ceres_FOUND ) + add_subdirectory(simple_pipeline) +endif () \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/libmv/base/CMakeLists.txt b/modules/sfm/src/libmv_light/libmv/base/CMakeLists.txt new file mode 100644 index 0000000000..5c54b13649 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/base/CMakeLists.txt @@ -0,0 +1,9 @@ +# define the source files +SET(BASE_SRC ) + +# define the header files (make the headers appear in IDEs.) +FILE(GLOB BASE_HDRS *.h) + +ADD_LIBRARY(base STATIC ${BASE_SRC} ${BASE_HDRS}) + +LIBMV_INSTALL_LIB(base) \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/libmv/base/vector.h b/modules/sfm/src/libmv_light/libmv/base/vector.h new file mode 100644 index 0000000000..1931fb0b1f --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/base/vector.h @@ -0,0 +1,176 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Get an aligned vector implementation. Must be included before . The +// Eigen guys went through some trouble to make a portable override for the +// fixed size vector types. + +#ifndef LIBMV_BASE_VECTOR_H +#define LIBMV_BASE_VECTOR_H + +#include +#include + +#include + +namespace libmv { + +// A simple container class, which guarantees 16 byte alignment needed for most +// vectorization. Don't use this container for classes that cannot be copied +// via memcpy. +// FIXME: this class has some issues: +// - doesn't support iterators. +// - impede compatibility with code using STL. +// - the STL already provide support for custom allocators +// it could be replaced with a simple +// template class vector : std::vector {} declaration +// provided it doesn't break code relying on libmv::vector specific behavior +template > +class vector { + public: + ~vector() { clear(); } + + vector() { init(); } + vector(int size) { init(); resize(size); } + vector(int size, const T & val) { + init(); + resize(size); + std::fill(data_, data_+size_, val); } + + // Copy constructor and assignment. + vector(const vector &rhs) { + init(); + copy(rhs); + } + vector &operator=(const vector &rhs) { + if (&rhs != this) { + copy(rhs); + } + return *this; + } + + /// Swaps the contents of two vectors in constant time. + void swap(vector &other) { + std::swap(allocator_, other.allocator_); + std::swap(size_, other.size_); + std::swap(capacity_, other.capacity_); + std::swap(data_, other.data_); + } + + T *data() const { return data_; } + int size() const { return size_; } + int capacity() const { return capacity_; } + const T& back() const { return data_[size_ - 1]; } + T& back() { return data_[size_ - 1]; } + const T& front() const { return data_[0]; } + T& front() { return data_[0]; } + const T& operator[](int n) const { return data_[n]; } + T& operator[](int n) { return data_[n]; } + const T& at(int n) const { return data_[n]; } + T& at(int n) { return data_[n]; } + const T * begin() const { return data_; } + const T * end() const { return data_+size_; } + T * begin() { return data_; } + T * end() { return data_+size_; } + + void resize(size_t size) { + reserve(size); + if (size > size_) { + construct(size_, size); + } else if (size < size_) { + destruct(size, size_); + } + size_ = size; + } + + void push_back(const T &value) { + if (size_ == capacity_) { + reserve(size_ ? 2 * size_ : 1); + } + new (&data_[size_++]) T(value); + } + + void pop_back() { + resize(size_ - 1); + } + + void clear() { + destruct(0, size_); + deallocate(); + init(); + } + + void reserve(unsigned int size) { + if (size > size_) { + T *data = static_cast(allocate(size)); + memcpy(data, data_, sizeof(*data)*size_); + allocator_.deallocate(data_, capacity_); + data_ = data; + capacity_ = size; + } + } + + bool empty() { + return size_ == 0; + } + + private: + void construct(int start, int end) { + for (int i = start; i < end; ++i) { + new (&data_[i]) T; + } + } + void destruct(int start, int end) { + for (int i = start; i < end; ++i) { + data_[i].~T(); + } + } + void init() { + size_ = 0; + data_ = 0; + capacity_ = 0; + } + + void *allocate(int size) { + return size ? allocator_.allocate(size) : 0; + } + + void deallocate() { + allocator_.deallocate(data_, size_); + data_ = 0; + } + + void copy(const vector &rhs) { + resize(rhs.size()); + for (int i = 0; i < rhs.size(); ++i) { + (*this)[i] = rhs[i]; + } + } + + Allocator allocator_; + size_t size_; + size_t capacity_; + T *data_; +}; + +} // namespace libmv + +#endif // LIBMV_BASE_VECTOR_H diff --git a/modules/sfm/src/libmv_light/libmv/base/vector_utils.h b/modules/sfm/src/libmv_light/libmv/base/vector_utils.h new file mode 100644 index 0000000000..c71e1bea95 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/base/vector_utils.h @@ -0,0 +1,34 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + + +#ifndef LIBMV_BASE_VECTOR_UTILS_H_ +#define LIBMV_BASE_VECTOR_UTILS_H_ + +/// Delete the contents of a container. +template +void DeleteElements(Array *array) { + for (int i = 0; i < array->size(); ++i) { + delete (*array)[i]; + } + array->clear(); +} + +#endif // LIBMV_BASE_VECTOR_UTILS_H_ diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/CMakeLists.txt b/modules/sfm/src/libmv_light/libmv/correspondence/CMakeLists.txt new file mode 100644 index 0000000000..5aac7bab6f --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/CMakeLists.txt @@ -0,0 +1,13 @@ +# define the source files +SET(CORRESPONDENCE_SRC feature_matching.cc + matches.cc + nRobustViewMatching.cc) + +# define the header files (make the headers appear in IDEs.) +FILE(GLOB CORRESPONDENCE_HDRS *.h) + +ADD_LIBRARY(correspondence STATIC ${CORRESPONDENCE_SRC} ${CORRESPONDENCE_HDRS}) + +TARGET_LINK_LIBRARIES(correspondence multiview) + +LIBMV_INSTALL_LIB(correspondence) \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/bipartite_graph.h b/modules/sfm/src/libmv_light/libmv/correspondence/bipartite_graph.h new file mode 100644 index 0000000000..e11fb3e29c --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/bipartite_graph.h @@ -0,0 +1,139 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_CORRESPONDENCE_INT_BIPARTITE_GRAPH_H_ +#define LIBMV_CORRESPONDENCE_INT_BIPARTITE_GRAPH_H_ + +#include +#include +#include +#include + +namespace libmv { + +// A bipartite graph with labelled edges. +template +class BipartiteGraph { + public: + typedef std::map, EdgeT> EdgeMap; + + void Insert(const T &left, const T &right, const EdgeT &edge) { + left_to_right_[std::make_pair(left, right)] = edge; + right_to_left_[std::make_pair(right, left)] = edge; + } + void Remove(const T &left, const T &right) { + typename EdgeMap::iterator iter = + left_to_right_.find(std::make_pair(left, right)); + if (iter != left_to_right_.end()) + left_to_right_.erase(iter); + iter = right_to_left_.find(std::make_pair(right, left)); + if (iter != right_to_left_.end()) + right_to_left_.erase(iter); + } + + int NumLeftLeft(T left) const { + int n = 0; + typename EdgeMap::const_iterator it; + for (it = left_to_right_.begin(); it != left_to_right_.end(); ++it) { + if (it->first.first == left) + n++; + } + return n; + } + + int NumLeftRight(T right) const { + int n = 0; + typename EdgeMap::const_iterator it; + for (it = left_to_right_.begin(); it != left_to_right_.end(); ++it) { + if (it->first.second == right) + n++; + } + return n; + } + + // Erases all the elements. + // Note that this function does not desallocate pointers + void Clear() { + left_to_right_.clear(); + right_to_left_.clear(); + } + class Range { + friend class BipartiteGraph; + public: + T left() const { return reversed_ ? it_->first.second : it_->first.first; } + T right() const { return reversed_ ? it_->first.first : it_->first.second;} + EdgeT edge() const { return it_->second; } + + void operator++() { ++it_; } + EdgeT operator*() { return it_->second; } + operator bool() const { return it_ != end_; } + + private: + Range(typename EdgeMap::const_iterator it, + typename EdgeMap::const_iterator end, + bool reversed) + : reversed_(reversed), it_(it), end_(end) {} + + bool reversed_; + typename EdgeMap::const_iterator it_, end_; + }; + + Range All() const { + return Range(left_to_right_.begin(), left_to_right_.end(), false); + } + + Range AllReversed() const { + return Range(right_to_left_.begin(), right_to_left_.end(), true); + } + + Range ToLeft(T left) const { + return Range(left_to_right_.lower_bound(Lower(left)), + left_to_right_.upper_bound(Upper(left)), false); + } + + Range ToRight(T right) const { + return Range(right_to_left_.lower_bound(Lower(right)), + right_to_left_.upper_bound(Upper(right)), true); + } + + // Find a pointer to the edge, or NULL if not found. + const EdgeT *Edge(T left, T right) const { + typename EdgeMap::const_iterator it = + left_to_right_.find(std::make_pair(left, right)); + if (it != left_to_right_.end()) { + return &(it->second); + } + return NULL; + } + + private: + std::pair Lower(T first) const { + return std::make_pair(first, std::numeric_limits::min()); + } + std::pair Upper(T first) const { + return std::make_pair(first, std::numeric_limits::max()); + } + EdgeMap left_to_right_; + EdgeMap right_to_left_; +}; + +} // namespace libmv + +#endif // LIBMV_CORRESPONDENCE_BIPARTITE_GRAPH_H_ diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/feature.h b/modules/sfm/src/libmv_light/libmv/correspondence/feature.h new file mode 100644 index 0000000000..3ec97bbf4c --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/feature.h @@ -0,0 +1,72 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_CORRESPONDENCE_FEATURE_H_ +#define LIBMV_CORRESPONDENCE_FEATURE_H_ + +#include + +#include "libmv/numeric/numeric.h" + +namespace libmv +{ + class Feature + { + public: + virtual + ~Feature() {}; + }; + +class PointFeature : public Feature { + public: + PointFeature(float xx=0.0f, float yy=0.0f) { + coords[0] = xx; + coords[1] = yy; + scale = 0.0; + orientation = 0.0; + } + + PointFeature &operator=(const PointFeature &other) + { + if (this == &other) + return *this; + scale = other.scale; + orientation = other.orientation; + coords = other.coords; + return *this; + } + + PointFeature(const cv::KeyPoint & keypoint) { + coords[0] = keypoint.pt.x; + coords[1] = keypoint.pt.y; + scale = keypoint.octave; + orientation = keypoint.angle; + } + float x() const { return coords(0); } + float y() const { return coords(1); } + + Vec2f coords; // (x, y), i.e. (column, row). + float scale; // In pixels. + float orientation; // In radians. +}; + +} // namespace libmv + +#endif // LIBMV_CORRESPONDENCE_FEATURE_H_ diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/feature_matching.cc b/modules/sfm/src/libmv_light/libmv/correspondence/feature_matching.cc new file mode 100644 index 0000000000..c59db04dcc --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/feature_matching.cc @@ -0,0 +1,143 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include + +#include "libmv/correspondence/feature_matching.h" + +// Compute candidate matches between 2 sets of features. Two features A and B +// are a candidate match if A is the nearest neighbor of B and B is the nearest +// neighbor of A. +void FindCandidateMatches(const FeatureSet &left, + const FeatureSet &right, + Matches *matches) { + if (left.features.empty() || + right.features.empty() ) { + return; + } + + cv::FlannBasedMatcher matcherA; + cv::FlannBasedMatcher matcherB; + + // Paste the necessary data in contiguous arrays. + cv::Mat arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left); + cv::Mat arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right); + + matcherA.add(std::vector(1, arrayB)); + matcherB.add(std::vector(1, arrayA)); + std::vector matchesA, matchesB; + matcherA.match(arrayA, matchesA); + matcherB.match(arrayB, matchesB); + + // From putative matches get symmetric matches. + int max_track_number = 0; + for (size_t i = 0; i < matchesA.size(); ++i) + { + // Add the match only if we have a symmetric result. + if (i == matchesB[matchesA[i].trainIdx].trainIdx) + { + matches->Insert(0, max_track_number, &left.features[i]); + matches->Insert(1, max_track_number, &right.features[matchesA[i].trainIdx]); + ++max_track_number; + } + } +} + +cv::Mat FeatureSet::FeatureSetDescriptorsToContiguousArray + ( const FeatureSet & featureSet ) { + + if (featureSet.features.empty()) { + return cv::Mat(); + } + int descriptorSize = featureSet.features[0].descriptor.cols; + // Allocate and paste the necessary data. + cv::Mat array(featureSet.features.size(), descriptorSize, CV_32F); + + //-- Paste data in the contiguous array : + for (int i = 0; i < (int)featureSet.features.size(); ++i) { + featureSet.features[i].descriptor.copyTo(array.row(i)); + } + return array; +} + +// Compute candidate matches between 2 sets of features with a ratio. +void FindCandidateMatches_Ratio(const FeatureSet &left, + const FeatureSet &right, + Matches *matches, + float fRatio) { + if (left.features.empty() || right.features.empty()) + return; + + cv::FlannBasedMatcher matcherA; + + // Paste the necessary data in contiguous arrays. + cv::Mat arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left); + cv::Mat arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right); + + matcherA.add(std::vector(1, arrayB)); + std::vector < std::vector > matchesA; + matcherA.knnMatch(arrayA, matchesA, 2); + + // From putative matches get matches that fit the "Ratio" heuristic. + int max_track_number = 0; + for (size_t i = 0; i < matchesA.size(); ++i) + { + float distance0 = matchesA[i][0].distance; + float distance1 = matchesA[i][1].distance; + // Add the match only if we have a symmetric result. + if (distance0 < fRatio * distance1) + { + { + matches->Insert(0, max_track_number, &left.features[i]); + matches->Insert(1, max_track_number, &right.features[matchesA[i][0].trainIdx]); + ++max_track_number; + } + } + } +} + +// Compute correspondences that match between 2 sets of features with a ratio. +void FindCorrespondences(const FeatureSet &left, + const FeatureSet &right, + std::map *correspondences, + float fRatio) { + if (left.features.empty() || right.features.empty()) + return; + + cv::FlannBasedMatcher matcherA; + + // Paste the necessary data in contiguous arrays. + cv::Mat arrayA = FeatureSet::FeatureSetDescriptorsToContiguousArray(left); + cv::Mat arrayB = FeatureSet::FeatureSetDescriptorsToContiguousArray(right); + + matcherA.add(std::vector(1, arrayB)); + std::vector < std::vector > matchesA; + matcherA.knnMatch(arrayA, matchesA, 2); + + // From putative matches get matches that fit the "Ratio" heuristic. + for (size_t i = 0; i < matchesA.size(); ++i) + { + float distance0 = matchesA[i][0].distance; + float distance1 = matchesA[i][1].distance; + // Add the match only if we have a symmetric result. + if (distance0 < fRatio * distance1) + (*correspondences)[i] = matchesA[i][0].trainIdx; + } +} diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/feature_matching.h b/modules/sfm/src/libmv_light/libmv/correspondence/feature_matching.h new file mode 100644 index 0000000000..0552f28506 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/feature_matching.h @@ -0,0 +1,96 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + + +#ifndef LIBMV_CORRESPONDENCE_FEATURE_MATCHING_H_ +#define LIBMV_CORRESPONDENCE_FEATURE_MATCHING_H_ + +#include + +#include + +#include "libmv/base/vector.h" +#include "libmv/correspondence/feature.h" +#include "libmv/correspondence/matches.h" + +using namespace libmv; + +/// Define the description of a feature described by : +/// A PointFeature (x,y,scale,orientation), +/// And a descriptor (a vector of floats). +class KeypointFeature : public ::PointFeature { + public: + virtual ~KeypointFeature(){}; + + void set(const PointFeature &feature,const cv::Mat &descriptor) + { + PointFeature::operator=(feature); + descriptor.copyTo(this->descriptor); + } + + // Match kdtree traits: with this, the Feature can act as a kdtree point. + float operator[](int i) const { + if (descriptor.depth() != CV_32F) + std::cerr << "KeypointFeature does not contain floats" << std::endl; + return descriptor.at(i); + } + + cv::Mat descriptor; +}; + +/// FeatureSet : Store an array of KeypointFeature ( Keypoint and descriptor). +struct FeatureSet { + std::vector features; + + /// return a float * containing the concatenation of descriptor data. + /// Must be deleted with [] + static cv::Mat FeatureSetDescriptorsToContiguousArray + ( const FeatureSet & featureSet ); +}; + +// Compute candidate matches between 2 sets of features. Two features a and b +// are a candidate match if a is the nearest neighbor of b and b is the nearest +// neighbor of a. +void FindCandidateMatches(const FeatureSet &left, + const FeatureSet &right, + Matches *matches); + +// Compute candidate matches between 2 sets of features. +// Keep only strong and distinctive matches by using the Davide Lowe's ratio +// method. +// I.E: A match is considered as strong if the following test is true : +// I.E distance[0] < fRatio * distances[1]. +// From David Lowe “Distinctive Image Features from Scale-Invariant Keypoints”. +// You can use David Lowe's magic ratio (0.6 or 0.8). +// 0.8 allow to remove 90% of the false matches while discarding less than 5% +// of the correct matches. +void FindCandidateMatches_Ratio(const FeatureSet &left, + const FeatureSet &right, + Matches *matches, + float fRatio = 0.8f); +// TODO(pmoulon) Add Lowe's ratio symmetric match method. +// Compute correspondences that match between 2 sets of features with a ratio. + +void FindCorrespondences(const FeatureSet &left, + const FeatureSet &right, + std::map *correspondences, + float fRatio = 0.8f); + +#endif //LIBMV_CORRESPONDENCE_FEATURE_MATCHING_H_ diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/matches.cc b/modules/sfm/src/libmv_light/libmv/correspondence/matches.cc new file mode 100644 index 0000000000..2e1a89e4eb --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/matches.cc @@ -0,0 +1,99 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/correspondence/matches.h" +#include "libmv/correspondence/feature.h" + +namespace libmv { + +Matches::~Matches() {} + +void DeleteMatchFeatures(Matches *matches) { + (void) matches; + // XXX + /* + for (Correspondences::FeatureIterator it = correspondences->ScanAllFeatures(); + !it.Done(); it.Next()) { + delete const_cast(it.feature()); + } + */ +} + +int Matches::GetNumberOfMatches(ImageID id1,ImageID id2) const +{ + Features features1 = InImage(id1); + Features features2 = InImage(id2); + int count = 0; + for(int i1=0;features1;++features1,++i1) + { + Features temp = features2; + for(int i2=0;temp;++temp,++i2) + { + if(features1.track() == temp.track()) + { + ++count; + break; + } + } + } + return count; +} + +void Matches::DrawMatches(ImageID image_id1,const cv::Mat &image1,ImageID image_id2,const cv::Mat &image2, cv::Mat &out)const +{ + std::vector points1; + std::vector points2; + std::vector matches; + KeyPoints(image_id1,points1); + KeyPoints(image_id2,points2); + MatchesTwo(image_id1,image_id2,matches); + cv::drawMatches(image1,points1,image2,points2,matches,out); +} + +void Matches::MatchesTwo(ImageID image1,ImageID image2,std::vector &matches)const +{ + Features features1 = InImage(image1); + Features features2 = InImage(image2); + for(int i1=0;features1;++features1,++i1) + { + Features temp = features2; + for(int i2=0;temp;++temp,++i2) + { + if(features1.track() == temp.track()) + { + matches.push_back(cv::DMatch(i1,i2,std::numeric_limits::max())); + break; + } + } + } +} + +void Matches::KeyPoints(ImageID image,std::vector &keypoints)const +{ + PointFeatures2KeyPoints(InImage(image),keypoints); +} + +void Matches::PointFeatures2KeyPoints(Features features,std::vector &keypoints)const +{ + for(;features;++features) + keypoints.push_back(cv::KeyPoint(features.feature()->x(),features.feature()->y(),1)); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/matches.h b/modules/sfm/src/libmv_light/libmv/correspondence/matches.h new file mode 100644 index 0000000000..23871d1bdc --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/matches.h @@ -0,0 +1,319 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_CORRESPONDENCE_MATCHES_H_ +#define LIBMV_CORRESPONDENCE_MATCHES_H_ + +#include +#include + +#include +#include + +#include "libmv/base/vector.h" +// TODO(julien) use the bipartite_graph_new.h now +#include "libmv/correspondence/bipartite_graph.h" +#include "libmv/logging/logging.h" +#include "libmv/correspondence/feature.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +class Matches { + public: + typedef int ImageID; + typedef int TrackID; + typedef BipartiteGraph Graph; + + ~Matches(); + + // Iterate over features, silently skiping any that are not FeatureT or + // derived from FeatureT. + template + class Features { + public: + ImageID image() const { return r_.left(); } + TrackID track() const { return r_.right(); } + const FeatureT *feature() const { + return static_cast(r_.edge()); + } + operator bool() const { return r_; } + void operator++() { ++r_; Skip(); } + Features(Graph::Range range) : r_(range) { Skip(); } + + private: + void Skip() { + while (r_ && !dynamic_cast (r_.edge())) ++r_; + } + Graph::Range r_; + }; + typedef Features Points; + + template + Features All() const { return Features(graph_.All()); } + + template + Features AllReversed() const { return Features(graph_.AllReversed()); } + + template + Features InImage(ImageID image) const { + return Features(graph_.ToLeft(image)); + } + + template + Features InTrack(TrackID track) const { + return Features(graph_.ToRight(track)); + } + + void PointFeatures2KeyPoints(Features features,std::vector &keypoints)const; + void KeyPoints(ImageID image,std::vector &keypoints)const; + void MatchesTwo(ImageID image1,ImageID image2,std::vector &matches)const; + void DrawMatches(ImageID image_id1,const cv::Mat &image1,ImageID image_id2,const cv::Mat &image2, cv::Mat &out)const; + + // Does not take ownership of feature. + void Insert(ImageID image, TrackID track, const Feature *feature) { + graph_.Insert(image, track, feature); + images_.insert(image); + tracks_.insert(track); + } + + void Remove(ImageID image, TrackID track) { + graph_.Remove(image, track); + } + + // Erases all the elements. + // Note that this function does not desallocate features + void Clear() { + graph_.Clear(); + images_.clear(); + tracks_.clear(); + } + // Insert all elements of matches (images, tracks, feature) as new data + void Insert(const Matches &matches) { + size_t max_images = GetMaxImageID(); + size_t max_tracks = GetMaxTrackID(); + std::map new_image_ids; + std::map new_track_ids; + std::set::const_iterator iter_image; + std::set::const_iterator iter_track; + + ImageID image_id; + iter_image = matches.images_.begin(); + for (; iter_image != matches.images_.end(); ++iter_image) { + image_id = ++max_images; + new_image_ids[*iter_image] = image_id; + images_.insert(image_id); + } + TrackID track_id; + iter_track = matches.tracks_.begin(); + for (; iter_track != matches.tracks_.end(); ++iter_track) { + track_id = ++max_tracks; + new_track_ids[*iter_track] = track_id; + tracks_.insert(track_id); + } + iter_image = matches.images_.begin(); + for (; iter_image != matches.images_.end(); ++iter_image) { + iter_track = matches.tracks_.begin(); + for (; iter_track != matches.tracks_.end(); ++iter_track) { + const Feature * feature = matches.Get(*iter_image, *iter_track); + image_id = new_image_ids[*iter_image]; + track_id = new_track_ids[*iter_track]; + graph_.Insert(image_id, track_id, feature); + } + } + } + // Merge common elements add new data (image, track, feature). + void Merge(const Matches &matches) { + std::map new_track_ids; + std::set::const_iterator iter_image; + std::set::const_iterator iter_track; + //Find non common elements and add them into new_matches + std::set::const_iterator found_image; + std::set::const_iterator found_track; + iter_image = matches.images_.begin(); + for (; iter_image != matches.images_.end(); ++iter_image) { + found_image = images_.find(*iter_image); + if (found_image == images_.end()) { + images_.insert(*iter_image); + } + iter_track = matches.tracks_.begin(); + for (; iter_track != matches.tracks_.end(); ++iter_track) { + found_track = tracks_.find(*iter_track); + if (found_track == tracks_.end() + && new_track_ids.find(*iter_track) == new_track_ids.end()) { + new_track_ids[*iter_track] = *iter_track; + tracks_.insert(*iter_track); + } + const Feature * feature = matches.Get(*iter_image, *iter_track); + graph_.Insert(*iter_image, *iter_track, feature); + } + } + } + + const Feature *Get(ImageID image, TrackID track) const { + const Feature *const *f = graph_.Edge(image, track); + return f ? *f : NULL; + } + + ImageID GetMaxImageID() const { + ImageID max_images = -1; + std::set::const_iterator iter_image = + std::max_element (images_.begin(), images_.end()); + if (iter_image != images_.end()) { + max_images = *iter_image; + } + return max_images; + } + + TrackID GetMaxTrackID() const { + TrackID max_tracks = -1; + std::set::const_iterator iter_track = + std::max_element (tracks_.begin(), tracks_.end()); + if (iter_track != tracks_.end()) { + max_tracks = *iter_track; + } + return max_tracks; + } + + int GetNumberOfMatches(ImageID id1,ImageID id2) const; + + const std::set &get_images() const { + return images_; + } + const std::set &get_tracks() const { + return tracks_; + } + + int NumFeatureImage(ImageID image_id) const { + return graph_.NumLeftLeft(image_id); + } + + int NumFeatureTrack(TrackID track_id) const { + return graph_.NumLeftRight(track_id); + } + + + size_t NumTracks() const { return tracks_.size(); } + size_t NumImages() const { return images_.size(); } + + private: + Graph graph_; + std::set images_; + std::set tracks_; +}; + + +/** + * Intersect sorted lists. Destroys originals; leaves results as the single + * entry in sorted_items. + */ +template +void Intersect(std::vector< std::vector > *sorted_items) { + std::vector tmp; + while (sorted_items->size() > 1) { + int n = sorted_items->size(); + std::vector &s1 = (*sorted_items)[n - 1]; + std::vector &s2 = (*sorted_items)[n - 2]; + tmp.resize(std::min(s1.size(), s2.size())); + typename std::vector::iterator it = std::set_intersection( + s1.begin(), s1.end(), s2.begin(), s2.end(), tmp.begin()); + tmp.resize(int(it - tmp.begin())); + std::swap(tmp, s2); + tmp.resize(0); + sorted_items->pop_back(); + } +} + +/** + * Extract matrices from a set of matches, containing the point locations. Only + * points for tracks which appear in all images are returned in tracks. + * + * \param matches The matches from which to extract the points. + * \param images Which images to extract the points from. + * \param xs The resulting matrices containing the points. The entries will + * match the ordering of images. + */ +inline void TracksInAllImages(const Matches &matches, + const vector &images, + vector *tracks) { + if (!images.size()) { + return; + } + std::vector > all_tracks; + all_tracks.resize(images.size()); + for (int i = 0; i < images.size(); ++i) { + for (Matches::Points r = matches.InImage(images[i]); r; ++r) { + all_tracks[i].push_back(r.track()); + } + } + Intersect(&all_tracks); + CHECK(all_tracks.size() == 1); + for (size_t i = 0; i < all_tracks[0].size(); ++i) { + tracks->push_back(all_tracks[0][i]); + } +} + +/** + * Extract matrices from a set of matches, containing the point locations. Only + * points for tracks which appear in all images are returned in xs. Each output + * matrix is of size 2 x N, where N is the number of tracks that are in all the + * images. + * + * \param matches The matches from which to extract the points. + * \param images Which images to extract the points from. + * \param xs The resulting matrices containing the points. The entries will + * match the ordering of images. + */ +inline void PointMatchMatrices(const Matches &matches, + const vector &images, + vector *tracks, + vector *xs) { + TracksInAllImages(matches, images, tracks); + + xs->resize(images.size()); + for (int i = 0; i < images.size(); ++i) { + (*xs)[i].resize(2, tracks->size()); + for (int j = 0; j < tracks->size(); ++j) { + const PointFeature *f = static_cast( + matches.Get(images[i], (*tracks)[j])); + (*xs)[i](0, j) = f->x(); + (*xs)[i](1, j) = f->y(); + } + } +} + +inline void TwoViewPointMatchMatrices(const Matches &matches, + Matches::ImageID image_id1, + Matches::ImageID image_id2, + vector *xs) { + vector tracks; + vector images; + images.push_back(image_id1); + images.push_back(image_id2); + PointMatchMatrices(matches, images, &tracks, xs); +} + +// Delete the features in a correspondences. Uses const_cast to avoid the +// constness problems. This is more intended for tests than for actual use. +void DeleteMatchFeatures(Matches *matches); + +} // namespace libmv + +#endif // LIBMV_CORRESPONDENCE_MATCHES_H_ diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/nRobustViewMatching.cc b/modules/sfm/src/libmv_light/libmv/correspondence/nRobustViewMatching.cc new file mode 100644 index 0000000000..86673d49ff --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/nRobustViewMatching.cc @@ -0,0 +1,303 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include + +#include "libmv/base/vector_utils.h" +#include "libmv/correspondence/feature.h" +#include "libmv/correspondence/feature_matching.h" +#include "libmv/correspondence/nRobustViewMatching.h" +#include "libmv/multiview/robust_fundamental.h" + +using namespace libmv; +using namespace correspondence; +using namespace std; + +nRobustViewMatching::nRobustViewMatching(){ +#ifdef CV_VERSION_EPOCH + m_pDescriber = NULL; +#endif +} + +nRobustViewMatching::nRobustViewMatching( + cv::Ptr pDetector, + cv::Ptr pDescriber){ + m_pDetector = pDetector; + m_pDescriber = pDescriber; +} + +/** + * Compute the data and store it in the class map + * + * \param[in] filename The file from which the data will be extracted. + * + * \return True if success. + */ +bool nRobustViewMatching::computeData(const string & filename) +{ + cv::Mat im_cv = cv::imread(filename, 0); + if (im_cv.empty()) { + LOG(FATAL) << "Failed loading image: " << filename; + return false; + } + else + { + libmv::vector features; + std::vector features_cv; + m_pDetector->detect( im_cv, features_cv ); + features.resize(features_cv.size()); + for(size_t i=0; icompute(im_cv, features_cv, descriptors); + + // Copy data. + m_ViewData.insert( make_pair(filename,FeatureSet()) ); + FeatureSet & KeypointData = m_ViewData[filename]; + KeypointData.features.resize(descriptors.rows); + for(int i = 0;i < descriptors.rows; ++i) + { + KeypointFeature & feat = KeypointData.features[i]; + descriptors.row(i).copyTo(feat.descriptor); + *(PointFeature*)(&feat) = *(PointFeature*)features[i]; + } + + DeleteElements(&features); + + return true; + } +} + +/** +* Compute the putative match between data computed from element A and B +* Store the match data internally in the class +* map< , MatchObject > +* +* \param[in] The name of the filename A (use computed data for this element) +* \param[in] The name of the filename B (use computed data for this element) +* +* \return True if success. +*/ +bool nRobustViewMatching::MatchData(const string & dataA, const string & dataB) +{ + // Check input data + if ( find(m_vec_InputNames.begin(), m_vec_InputNames.end(), dataA) + == m_vec_InputNames.end() || + find(m_vec_InputNames.begin(), m_vec_InputNames.end(), dataB) + == m_vec_InputNames.end()) + { + LOG(INFO) << "[nViewMatching::MatchData] " + << "Could not identify one of the input name."; + return false; + } + if (m_ViewData.find(dataA) == m_ViewData.end() || + m_ViewData.find(dataB) == m_ViewData.end()) + { + LOG(INFO) << "[nViewMatching::MatchData] " + << "Could not identify data for one of the input name."; + return false; + } + + // Computed data exist for the given name + int iDataA = find(m_vec_InputNames.begin(), m_vec_InputNames.end(), dataA) + - m_vec_InputNames.begin(); + int iDataB = find(m_vec_InputNames.begin(), m_vec_InputNames.end(), dataB) + - m_vec_InputNames.begin(); + + Matches matches; + //TODO(pmoulon) make FindCandidatesMatches a parameter. + FindCandidateMatches_Ratio(m_ViewData[dataA], + m_ViewData[dataB], + &matches); + Matches consistent_matches; + if (computeConstrainMatches(matches,iDataA,iDataB,&consistent_matches)) + { + matches = consistent_matches; + } + if (matches.NumTracks() > 0) + { + m_sharedData.insert( + make_pair( + make_pair(m_vec_InputNames[iDataA],m_vec_InputNames[iDataB]), + matches) + ); + } + + return true; +} + +/** +* From a series of element it computes the cross putative match list. +* +* \param[in] vec_data The data on which we want compute cross matches. +* +* \return True if success (and any matches was found). +*/ +bool nRobustViewMatching::computeCrossMatch( const std::vector & vec_data) +{ + if (m_pDetector == NULL || m_pDescriber == NULL) { + LOG(FATAL) << "Invalid Detector or Describer."; + return false; + } + + m_vec_InputNames = vec_data; + bool bRes = true; + for (int i=0; i < vec_data.size(); ++i) { + bRes &= computeData(vec_data[i]); + } + + bool bRes2 = true; + for (int i=0; i < vec_data.size(); ++i) { + for (int j=0; j < i; ++j) + { + if (m_ViewData.find(vec_data[i]) != m_ViewData.end() && + m_ViewData.find(vec_data[j]) != m_ViewData.end()) + { + bRes2 &= this->MatchData( vec_data[i], vec_data[j]); + } + } + } + return bRes2; +} + +bool nRobustViewMatching::computeRelativeMatch( + const std::vector& vec_data) { + if (m_pDetector == NULL || m_pDescriber == NULL) { + LOG(FATAL) << "Invalid Detector or Describer."; + return false; + } + + m_vec_InputNames = vec_data; + bool bRes = true; + for (int i=0; i < vec_data.size(); ++i) { + bRes &= computeData(vec_data[i]); + } + + bool bRes2 = true; + for (int i=1; i < vec_data.size(); ++i) { + if (m_ViewData.find(vec_data[i-1]) != m_ViewData.end() && + m_ViewData.find(vec_data[i]) != m_ViewData.end()) + { + bRes2 &= this->MatchData(vec_data[i-1], vec_data[i]); + } + } + // Match the first and the last images (in order to detect loop) + bRes2 &= this->MatchData(vec_data[0], vec_data[vec_data.size() - 1]); + return bRes2; +} + +/** +* Give the posibility to constrain the matches list. +* +* \param[in] matchIn The input match data between indexA and indexB. +* \param[in] dataAindex The reference index for element A. +* \param[in] dataBindex The reference index for element B. +* \param[out] matchesOut The output match that satisfy the internal constraint. +* +* \return True if success. +*/ +bool nRobustViewMatching::computeConstrainMatches(const Matches & matchIn, + int dataAindex, + int dataBindex, + Matches * matchesOut) +{ + if (matchesOut == NULL) + { + LOG(INFO) << "[nViewMatching::computeConstrainMatches]" + << " Could not export constrained matches."; + return false; + } + libmv::vector x; + libmv::vector tracks, images; + images.push_back(0); + images.push_back(1); + PointMatchMatrices(matchIn, images, &tracks, &x); + + libmv::vector inliers; + Mat3 H; + // TODO(pmoulon) Make the Correspondence filter a parameter. + //HomographyFromCorrespondences2PointRobust(x[0], x[1], 0.3, &H, &inliers); + //HomographyFromCorrespondences4PointRobust(x[0], x[1], 0.3, &H, &inliers); + //AffineFromCorrespondences2PointRobust(x[0], x[1], 1, &H, &inliers); + FundamentalFromCorrespondences7PointRobust(x[0], x[1], 1.0, &H, &inliers); + + //TODO(pmoulon) insert an optimization phase. + // Rerun Robust correspondance on the inliers. + // it will allow to compute a better model and filter ugly fitting. + + //-- Assert that the output of the model is consistent : + // As much as the minimal points are inliers. + if (inliers.size() > 7 * 2) { //2* [nbPoints required by the estimator] + // If tracks table is empty initialize it + if (m_featureToTrackTable.size() == 0) { + // Build new correspondence graph containing only inliers. + for (int l = 0; l < inliers.size(); ++l) { + const int k = inliers[l]; + m_featureToTrackTable[matchIn.Get(0, tracks[k])] = l; + m_featureToTrackTable[matchIn.Get(1, tracks[k])] = l; + m_tracks.Insert(dataAindex, l, + matchIn.Get(dataBindex, tracks[k])); + m_tracks.Insert(dataBindex, l, + matchIn.Get(dataAindex, tracks[k])); + } + } + else { + // Else update the tracks + for (int l = 0; l < inliers.size(); ++l) { + const int k = inliers[l]; + map::const_iterator iter = + m_featureToTrackTable.find(matchIn.Get(1, tracks[k])); + + if (iter!=m_featureToTrackTable.end()) { + // Add a feature to the existing track + const int trackIndex = iter->second; + m_featureToTrackTable[matchIn.Get(0, tracks[k])] = trackIndex; + m_tracks.Insert(dataAindex, trackIndex, + matchIn.Get(0, tracks[k])); + } + else { + // It's a new track + const int trackIndex = m_tracks.NumTracks(); + m_featureToTrackTable[matchIn.Get(0, tracks[k])] = trackIndex; + m_featureToTrackTable[matchIn.Get(1, tracks[k])] = trackIndex; + m_tracks.Insert(dataAindex, trackIndex, + matchIn.Get(0, tracks[k])); + m_tracks.Insert(dataBindex, trackIndex, + matchIn.Get(1, tracks[k])); + } + } + } + // Export common feature between the two view + if (matchesOut) { + Matches & consistent_matches = *matchesOut; + // Build new correspondence graph containing only inliers. + for (int l = 0; l < inliers.size(); ++l) { + int k = inliers[l]; + for (int i = 0; i < 2; ++i) { + consistent_matches.Insert(images[i], tracks[k], + matchIn.Get(images[i], tracks[k])); + } + } + } + } + return true; +} + diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/nRobustViewMatching.h b/modules/sfm/src/libmv_light/libmv/correspondence/nRobustViewMatching.h new file mode 100644 index 0000000000..faddbc3ed2 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/nRobustViewMatching.h @@ -0,0 +1,138 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_CORRESPONDENCE_N_ROBUST_VIEW_MATCHING_INTERFACE_H_ +#define LIBMV_CORRESPONDENCE_N_ROBUST_VIEW_MATCHING_INTERFACE_H_ + +struct FeatureSet; +#include + +#include "libmv/correspondence/feature.h" +#include "libmv/correspondence/matches.h" +#include "libmv/correspondence/nViewMatchingInterface.h" + +namespace libmv { +namespace correspondence { + +using namespace std; + +class nRobustViewMatching :public nViewMatchingInterface { + + public: + nRobustViewMatching(); + // Constructor (Specify a detector and a describer interface) + // The class do not handle memory management over this two parameter. + nRobustViewMatching(cv::Ptr pDetector, + cv::Ptr pDescriber); + //TODO(pmoulon) Add a constructor with a Detector and a Descriptor + // Add also a Template function to make the match robust.. + ~nRobustViewMatching(){}; + + /** + * Compute the data and store it in the class map + * + * \param[in] filename The file from which the data will be extracted. + * + * \return True if success. + */ + bool computeData(const string & filename); + + /** + * Compute the putative match between data computed from element A and B + * Store the match data internally in the class + * map< , MatchObject > + * + * \param[in] The name of the filename A (use computed data for this element) + * \param[in] The name of the filename B (use computed data for this element) + * + * \return True if success. + */ + bool MatchData(const string & dataA, const string & dataB); + + /** + * From a series of element it computes the cross putative match list. + * + * \param[in] vec_data The data on which we want compute cross matches. + * + * \return True if success (and any matches was found). + */ + bool computeCrossMatch( const std::vector & vec_data); + + + /** + * From a series of element it computes the incremental putative match list. + * (only locally, in the relative neighborhood) + * + * \param[in] vec_data The data on which we want compute matches. + * + * \return True if success (and any matches was found). + */ + bool computeRelativeMatch( const std::vector & vec_data); + + /** + * Give the posibility to constrain the matches list. + * + * \param[in] matchIn The input match data between indexA and indexB. + * \param[in] dataAindex The reference index for element A. + * \param[in] dataBindex The reference index for element B. + * \param[out] matchesOut The output match that satisfy the internal constraint. + * + * \return True if success. + */ + bool computeConstrainMatches(const Matches & matchIn, + int dataAindex, + int dataBindex, + Matches * matchesOut); + + /// Return pairwise correspondence ( geometrically filtered ) + const map< pair, Matches> & getSharedData() const + { return m_sharedData; } + /// Return extracted feature over the given image. + const map & getViewData() const + { return m_ViewData; } + /// Return detected geometrical consistent matches + const Matches & getMatches() const + { return m_tracks; } + +private : + /// Input data names + std::vector m_vec_InputNames; + /// Data that represent each named element. + map m_ViewData; + /// Matches between element named element . + map< pair, Matches> m_sharedData; + + /// LookUpTable to make the crossCorrespondence easier between tracks + /// and feature. + map m_featureToTrackTable; + + /// Matches between all the view. + Matches m_tracks; + + /// Interface to detect Keypoint. + cv::Ptr m_pDetector; + /// Interface to describe Keypoint. + cv::Ptr m_pDescriber; +}; + +} // using namespace correspondence +} // using namespace libmv + +#endif // LIBMV_CORRESPONDENCE_N_ROBUST_VIEW_MATCHING_INTERFACE_H_ diff --git a/modules/sfm/src/libmv_light/libmv/correspondence/nViewMatchingInterface.h b/modules/sfm/src/libmv_light/libmv/correspondence/nViewMatchingInterface.h new file mode 100644 index 0000000000..2810b2f206 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/correspondence/nViewMatchingInterface.h @@ -0,0 +1,70 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_CORRESPONDENCE_N_VIEW_MATCHING_INTERFACE_H_ +#define LIBMV_CORRESPONDENCE_N_VIEW_MATCHING_INTERFACE_H_ + +#include + +namespace libmv { +namespace correspondence { + + using namespace std; + +class nViewMatchingInterface { + + public: + virtual ~nViewMatchingInterface() {}; + + /** + * Compute the data and store it in the class map + * + * \param[in] filename The file from which the data will be extracted. + * + * \return True if success. + */ + virtual bool computeData(const string & filename)=0; + + /** + * Compute the putative match between data computed from element A and B + * Store the match data internally in the class + * map< , MatchObject > + * + * \param[in] The name of the filename A (use computed data for this element) + * \param[in] The name of the filename B (use computed data for this element) + * + * \return True if success. + */ + virtual bool MatchData(const string & dataA, const string & dataB)=0; + + /** + * From a series of element it compute the cross putative match list. + * + * \param[in] vec_data The data on which we want compute cross matches. + * + * \return True if success (and any matches was found). + */ + virtual bool computeCrossMatch( const std::vector & vec_data)=0; +}; + +} // using namespace correspondence +} // using namespace libmv + +#endif // LIBMV_CORRESPONDENCE_N_VIEW_MATCHING_INTERFACE_H_ diff --git a/modules/sfm/src/libmv_light/libmv/logging/logging.h b/modules/sfm/src/libmv_light/libmv/logging/logging.h new file mode 100644 index 0000000000..776d9d52f7 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/logging/logging.h @@ -0,0 +1,31 @@ +// Copyright (c) 2007, 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_LOGGING_LOGGING_H +#define LIBMV_LOGGING_LOGGING_H + +#include + +#define LG LOG(INFO) +#define V0 LOG(INFO) +#define V1 LOG(INFO) +#define V2 LOG(INFO) + +#endif // LIBMV_LOGGING_LOGGING_H diff --git a/modules/sfm/src/libmv_light/libmv/multiview/CMakeLists.txt b/modules/sfm/src/libmv_light/libmv/multiview/CMakeLists.txt new file mode 100644 index 0000000000..3fc7e4b5f1 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/CMakeLists.txt @@ -0,0 +1,22 @@ +# define the source files +SET(MULTIVIEW_SRC conditioning.cc + euclidean_resection.cc + fundamental.cc + fundamental_kernel.cc + homography.cc + panography.cc + panography_kernel.cc + projection.cc + robust_estimation.cc + robust_fundamental.cc + robust_resection.cc + triangulation.cc + twoviewtriangulation.cc) + +# define the header files (make the headers appear in IDEs.) +FILE(GLOB MULTIVIEW_HDRS *.h) + +ADD_LIBRARY(multiview STATIC ${MULTIVIEW_SRC} ${MULTIVIEW_HDRS}) +TARGET_LINK_LIBRARIES(multiview glog numeric) + +LIBMV_INSTALL_LIB(multiview) diff --git a/modules/sfm/src/libmv_light/libmv/multiview/conditioning.cc b/modules/sfm/src/libmv_light/libmv/multiview/conditioning.cc new file mode 100644 index 0000000000..0afbf119ea --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/conditioning.cc @@ -0,0 +1,99 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/conditioning.h" +#include "libmv/multiview/projection.h" + +namespace libmv { + +// HZ 4.4.4 pag.109: Point conditioning (non isotropic) +void PreconditionerFromPoints(const Mat &points, Mat3 *T) { + Vec mean, variance; + MeanAndVarianceAlongRows(points, &mean, &variance); + + double xfactor = sqrt(2.0 / variance(0)); + double yfactor = sqrt(2.0 / variance(1)); + + // If variance is equal to 0.0 set scaling factor to identity. + // -> Else it will provide nan value (because division by 0). + if (variance(0) < 1e-8) + xfactor = mean(0) = 1.0; + if (variance(1) < 1e-8) + yfactor = mean(1) = 1.0; + + *T << xfactor, 0, -xfactor * mean(0), + 0, yfactor, -yfactor * mean(1), + 0, 0, 1; +} +// HZ 4.4.4 pag.107: Point conditioning (isotropic) +void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T) { + Vec mean, variance; + MeanAndVarianceAlongRows(points, &mean, &variance); + + double var_norm = variance.norm(); + double factor = sqrt(2.0 / var_norm); + + // If variance is equal to 0.0 set scaling factor to identity. + // -> Else it will provide nan value (because division by 0). + if (var_norm < 1e-8) { + factor = 1.0; + mean.setOnes(); + } + + *T << factor, 0, -factor * mean(0), + 0, factor, -factor * mean(1), + 0, 0, 1; +} + +void ApplyTransformationToPoints(const Mat &points, + const Mat3 &T, + Mat *transformed_points) { + int n = points.cols(); + transformed_points->resize(2, n); + Mat3X p(3, n); + EuclideanToHomogeneous(points, &p); + p = T * p; + HomogeneousToEuclidean(p, transformed_points); +} + +void NormalizePoints(const Mat &points, + Mat *normalized_points, + Mat3 *T) { + PreconditionerFromPoints(points, T); + ApplyTransformationToPoints(points, *T, normalized_points); +} + +void NormalizeIsotropicPoints(const Mat &points, + Mat *normalized_points, + Mat3 *T) { + IsotropicPreconditionerFromPoints(points, T); + ApplyTransformationToPoints(points, *T, normalized_points); +} + +// Denormalize the results. See HZ page 109. +void UnnormalizerT::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H) { + *H = T2.transpose() * (*H) * T1; +} + +void UnnormalizerI::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H) { + *H = T2.inverse() * (*H) * T1; +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/conditioning.h b/modules/sfm/src/libmv_light/libmv/multiview/conditioning.h new file mode 100644 index 0000000000..8f3e3a7607 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/conditioning.h @@ -0,0 +1,59 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_CONDITIONNING_H_ +#define LIBMV_MULTIVIEW_CONDITIONNING_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +// Point conditioning (non isotropic) +void PreconditionerFromPoints(const Mat &points, Mat3 *T); +// Point conditioning (isotropic) +void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T); + +void ApplyTransformationToPoints(const Mat &points, + const Mat3 &T, + Mat *transformed_points); + +void NormalizePoints(const Mat &points, + Mat *normalized_points, + Mat3 *T); + +void NormalizeIsotropicPoints(const Mat &points, + Mat *normalized_points, + Mat3 *T); + +/// Use inverse for unnormalize +struct UnnormalizerI { + // Denormalize the results. See HZ page 109. + static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H); +}; + +/// Use transpose for unnormalize +struct UnnormalizerT { + // Denormalize the results. See HZ page 109. + static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H); +}; + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_CONDITIONNING_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/euclidean_resection.cc b/modules/sfm/src/libmv_light/libmv/multiview/euclidean_resection.cc new file mode 100644 index 0000000000..03ddf5e96f --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/euclidean_resection.cc @@ -0,0 +1,774 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/euclidean_resection.h" + +#include +#include + +#include +#include + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/projection.h" + +namespace libmv { +namespace euclidean_resection { + +typedef unsigned int uint; + +bool EuclideanResection(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t, + ResectionMethod method) { + switch (method) { + case RESECTION_ANSAR_DANIILIDIS: + EuclideanResectionAnsarDaniilidis(x_camera, X_world, R, t); + break; + case RESECTION_EPNP: + return EuclideanResectionEPnP(x_camera, X_world, R, t); + break; + case RESECTION_PPNP: + return EuclideanResectionPPnP(x_camera, X_world, R, t); + break; + default: + LOG(FATAL) << "Unknown resection method."; + } + return false; +} + +bool EuclideanResection(const Mat &x_image, + const Mat3X &X_world, + const Mat3 &K, + Mat3 *R, Vec3 *t, + ResectionMethod method) { + CHECK(x_image.rows() == 2 || x_image.rows() == 3) + << "Invalid size for x_image: " + << x_image.rows() << "x" << x_image.cols(); + + Mat2X x_camera; + if (x_image.rows() == 2) { + EuclideanToNormalizedCamera(x_image, K, &x_camera); + } else if (x_image.rows() == 3) { + HomogeneousToNormalizedCamera(x_image, K, &x_camera); + } + return EuclideanResection(x_camera, X_world, R, t, method); +} + +void AbsoluteOrientation(const Mat3X &X, + const Mat3X &Xp, + Mat3 *R, + Vec3 *t) { + int num_points = X.cols(); + Vec3 C = X.rowwise().sum() / num_points; // Centroid of X. + Vec3 Cp = Xp.rowwise().sum() / num_points; // Centroid of Xp. + + // Normalize the two point sets. + Mat3X Xn(3, num_points), Xpn(3, num_points); + for (int i = 0; i < num_points; ++i) { + Xn.col(i) = X.col(i) - C; + Xpn.col(i) = Xp.col(i) - Cp; + } + + // Construct the N matrix (pg. 635). + double Sxx = Xn.row(0).dot(Xpn.row(0)); + double Syy = Xn.row(1).dot(Xpn.row(1)); + double Szz = Xn.row(2).dot(Xpn.row(2)); + double Sxy = Xn.row(0).dot(Xpn.row(1)); + double Syx = Xn.row(1).dot(Xpn.row(0)); + double Sxz = Xn.row(0).dot(Xpn.row(2)); + double Szx = Xn.row(2).dot(Xpn.row(0)); + double Syz = Xn.row(1).dot(Xpn.row(2)); + double Szy = Xn.row(2).dot(Xpn.row(1)); + + Mat4 N; + N << Sxx + Syy + Szz, Syz - Szy, Szx - Sxz, Sxy - Syx, + Syz - Szy, Sxx - Syy - Szz, Sxy + Syx, Szx + Sxz, + Szx - Sxz, Sxy + Syx, -Sxx + Syy - Szz, Syz + Szy, + Sxy - Syx, Szx + Sxz, Syz + Szy, -Sxx - Syy + Szz; + + // Find the unit quaternion q that maximizes qNq. It is the eigenvector + // corresponding to the lagest eigenvalue. + Vec4 q = N.jacobiSvd(Eigen::ComputeFullU).matrixU().col(0); + + // Retrieve the 3x3 rotation matrix. + Vec4 qq = q.array() * q.array(); + double q0q1 = q(0) * q(1); + double q0q2 = q(0) * q(2); + double q0q3 = q(0) * q(3); + double q1q2 = q(1) * q(2); + double q1q3 = q(1) * q(3); + double q2q3 = q(2) * q(3); + + (*R) << qq(0) + qq(1) - qq(2) - qq(3), + 2 * (q1q2 - q0q3), + 2 * (q1q3 + q0q2), + 2 * (q1q2+ q0q3), + qq(0) - qq(1) + qq(2) - qq(3), + 2 * (q2q3 - q0q1), + 2 * (q1q3 - q0q2), + 2 * (q2q3 + q0q1), + qq(0) - qq(1) - qq(2) + qq(3); + + // Fix the handedness of the R matrix. + if (R->determinant() < 0) { + R->row(2) = -R->row(2); + } + // Compute the final translation. + *t = Cp - *R * C; +} + +// Convert i and j indices of the original variables into their quadratic +// permutation single index. It follows that t_ij = t_ji. +static int IJToPointIndex(int i, int j, int num_points) { + // Always make sure that j is bigger than i. This handles t_ij = t_ji. + if (j < i) { + std::swap(i, j); + } + int idx; + int num_permutation_rows = num_points * (num_points - 1) / 2; + + // All t_ii's are located at the end of the t vector after all t_ij's. + if (j == i) { + idx = num_permutation_rows + i; + } else { + int offset = (num_points - i - 1) * (num_points - i) / 2; + idx = (num_permutation_rows - offset + j - i - 1); + } + return idx; +}; + +// Convert i and j indexes of the solution for lambda to their linear indexes. +static int IJToIndex(int i, int j, int num_lambda) { + if (j < i) { + std::swap(i, j); + } + int A = num_lambda * (num_lambda + 1) / 2; + int B = num_lambda - i; + int C = B * (B + 1) / 2; + int idx = A - C + j - i; + return idx; +}; + +static int Sign(double value) { + return (value < 0) ? -1 : 1; +}; + +// Organizes a square matrix into a single row constraint on the elements of +// Lambda to create the constraints in equation (5) in "Linear Pose Estimation +// from Points or Lines", by Ansar, A. and Daniilidis, PAMI 2003. vol. 25, no. +// 5. +static Vec MatrixToConstraint(const Mat &A, + int num_k_columns, + int num_lambda) { + Vec C(num_k_columns); + C.setZero(); + int idx = 0; + for (int i = 0; i < num_lambda; ++i) { + for (int j = i; j < num_lambda; ++j) { + C(idx) = A(i, j); + if (i != j) { + C(idx) += A(j, i); + } + ++idx; + } + } + return C; +} + +// Normalizes the columns of vectors. +static void NormalizeColumnVectors(Mat3X *vectors) { + int num_columns = vectors->cols(); + for (int i = 0; i < num_columns; ++i) { + vectors->col(i).normalize(); + } +} + +void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, + Vec3 *t) { + CHECK(x_camera.cols() == X_world.cols()); + CHECK(x_camera.cols() > 3); + + int num_points = x_camera.cols(); + + // Copy the normalized camera coords into 3 vectors and normalize them so + // that they are unit vectors from the camera center. + Mat3X x_camera_unit(3, num_points); + x_camera_unit.block(0, 0, 2, num_points) = x_camera; + x_camera_unit.row(2).setOnes(); + NormalizeColumnVectors(&x_camera_unit); + + int num_m_rows = num_points * (num_points - 1) / 2; + int num_tt_variables = num_points * (num_points + 1) / 2; + int num_m_columns = num_tt_variables + 1; + Mat M(num_m_columns, num_m_columns); + M.setZero(); + Matu ij_index(num_tt_variables, 2); + + // Create the constraint equations for the t_ij variables (7) and arrange + // them into the M matrix (8). Also store the initial (i, j) indices. + int row = 0; + for (int i = 0; i < num_points; ++i) { + for (int j = i+1; j < num_points; ++j) { + M(row, row) = -2 * x_camera_unit.col(i).dot(x_camera_unit.col(j)); + M(row, num_m_rows + i) = x_camera_unit.col(i).dot(x_camera_unit.col(i)); + M(row, num_m_rows + j) = x_camera_unit.col(j).dot(x_camera_unit.col(j)); + Vec3 Xdiff = X_world.col(i) - X_world.col(j); + double center_to_point_distance = Xdiff.norm(); + M(row, num_m_columns - 1) = + - center_to_point_distance * center_to_point_distance; + ij_index(row, 0) = i; + ij_index(row, 1) = j; + ++row; + } + ij_index(i + num_m_rows, 0) = i; + ij_index(i + num_m_rows, 1) = i; + } + + int num_lambda = num_points + 1; // Dimension of the null space of M. + Mat V = M.jacobiSvd(Eigen::ComputeFullV).matrixV().block(0, + num_m_rows, + num_m_columns, + num_lambda); + + // TODO(vess): The number of constraint equations in K (num_k_rows) must be + // (num_points + 1) * (num_points + 2)/2. This creates a performance issue + // for more than 4 points. It is fine for 4 points at the moment with 18 + // instead of 15 equations. + int num_k_rows = num_m_rows + num_points * + (num_points*(num_points-1)/2 - num_points+1); + int num_k_columns = num_lambda * (num_lambda + 1) / 2; + Mat K(num_k_rows, num_k_columns); + K.setZero(); + + // Construct the first part of the K matrix corresponding to (t_ii, t_jk) for + // i != j. + int counter_k_row = 0; + for (int idx1 = num_m_rows; idx1 < num_tt_variables; ++idx1) { + for (int idx2 = 0; idx2 < num_m_rows; ++idx2) { + unsigned int i = ij_index(idx1, 0); + unsigned int j = ij_index(idx2, 0); + unsigned int k = ij_index(idx2, 1); + + if (i != j && i != k) { + int idx3 = IJToPointIndex(i, j, num_points); + int idx4 = IJToPointIndex(i, k, num_points); + + K.row(counter_k_row) = + MatrixToConstraint(V.row(idx1).transpose() * V.row(idx2)- + V.row(idx3).transpose() * V.row(idx4), + num_k_columns, + num_lambda); + ++counter_k_row; + } + } + } + + // Construct the second part of the K matrix corresponding to (t_ii,t_jk) for + // j==k. + for (int idx1 = num_m_rows; idx1 < num_tt_variables; ++idx1) { + for (int idx2 = idx1 + 1; idx2 < num_tt_variables; ++idx2) { + unsigned int i = ij_index(idx1, 0); + unsigned int j = ij_index(idx2, 0); + unsigned int k = ij_index(idx2, 1); + + int idx3 = IJToPointIndex(i, j, num_points); + int idx4 = IJToPointIndex(i, k, num_points); + + K.row(counter_k_row) = + MatrixToConstraint(V.row(idx1).transpose() * V.row(idx2)- + V.row(idx3).transpose() * V.row(idx4), + num_k_columns, + num_lambda); + ++counter_k_row; + } + } + Vec L_sq = K.jacobiSvd(Eigen::ComputeFullV).matrixV().col(num_k_columns - 1); + + // Pivot on the largest element for numerical stability. Afterwards recover + // the sign of the lambda solution. + double max_L_sq_value = fabs(L_sq(IJToIndex(0, 0, num_lambda))); + int max_L_sq_index = 1; + for (int i = 1; i < num_lambda; ++i) { + double abs_sq_value = fabs(L_sq(IJToIndex(i, i, num_lambda))); + if (max_L_sq_value < abs_sq_value) { + max_L_sq_value = abs_sq_value; + max_L_sq_index = i; + } + } + // Ensure positiveness of the largest value corresponding to lambda_ii. + L_sq = L_sq * Sign(L_sq(IJToIndex(max_L_sq_index, + max_L_sq_index, + num_lambda))); + + Vec L(num_lambda); + L(max_L_sq_index) = sqrt(L_sq(IJToIndex(max_L_sq_index, + max_L_sq_index, + num_lambda))); + + for (int i = 0; i < num_lambda; ++i) { + if (i != max_L_sq_index) { + L(i) = L_sq(IJToIndex(max_L_sq_index, i, num_lambda)) / L(max_L_sq_index); + } + } + + // Correct the scale using the fact that the last constraint is equal to 1. + L = L / (V.row(num_m_columns - 1).dot(L)); + Vec X = V * L; + + // Recover the distances from the camera center to the 3D points Q. + Vec d(num_points); + d.setZero(); + for (int c_point = num_m_rows; c_point < num_tt_variables; ++c_point) { + d(c_point - num_m_rows) = sqrt(X(c_point)); + } + + // Create the 3D points in the camera system. + Mat X_cam(3, num_points); + for (int c_point = 0; c_point < num_points; ++c_point) { + X_cam.col(c_point) = d(c_point) * x_camera_unit.col(c_point); + } + // Recover the camera translation and rotation. + AbsoluteOrientation(X_world, X_cam, R, t); +} + +// Selects 4 virtual control points using mean and PCA. +static void SelectControlPoints(const Mat3X &X_world, + Mat *X_centered, + Mat34 *X_control_points) { + size_t num_points = X_world.cols(); + + // The first virtual control point, C0, is the centroid. + Vec mean, variance; + MeanAndVarianceAlongRows(X_world, &mean, &variance); + X_control_points->col(0) = mean; + + // Computes PCA + X_centered->resize(3, num_points); + for (size_t c = 0; c < num_points; c++) { + X_centered->col(c) = X_world.col(c) - mean; + } + Mat3 X_centered_sq = (*X_centered) * X_centered->transpose(); + Eigen::JacobiSVD X_centered_sq_svd(X_centered_sq, Eigen::ComputeFullU); + Vec3 w = X_centered_sq_svd.singularValues(); + Mat3 u = X_centered_sq_svd.matrixU(); + for (size_t c = 0; c < 3; c++) { + double k = sqrt(w(c) / num_points); + X_control_points->col(c + 1) = mean + k * u.col(c); + } +} + +// Computes the barycentric coordinates for all real points +static void ComputeBarycentricCoordinates(const Mat3X &X_world_centered, + const Mat34 &X_control_points, + Mat4X *alphas) { + size_t num_points = X_world_centered.cols(); + Mat3 C2; + for (size_t c = 1; c < 4; c++) { + C2.col(c-1) = X_control_points.col(c) - X_control_points.col(0); + } + + Mat3 C2inv = C2.inverse(); + Mat3X a = C2inv * X_world_centered; + + alphas->resize(4, num_points); + alphas->setZero(); + alphas->block(1, 0, 3, num_points) = a; + for (size_t c = 0; c < num_points; c++) { + (*alphas)(0, c) = 1.0 - alphas->col(c).sum(); + } +} + +// Estimates the coordinates of all real points in the camera coordinate frame +static void ComputePointsCoordinatesInCameraFrame( + const Mat4X &alphas, + const Vec4 &betas, + const Eigen::Matrix &U, + Mat3X *X_camera) { + size_t num_points = alphas.cols(); + + // Estimates the control points in the camera reference frame. + Mat34 C2b; C2b.setZero(); + for (size_t cu = 0; cu < 4; cu++) { + for (size_t c = 0; c < 4; c++) { + C2b.col(c) += betas(cu) * U.block(11 - cu, c * 3, 1, 3).transpose(); + } + } + + // Estimates the 3D points in the camera reference frame + X_camera->resize(3, num_points); + for (size_t c = 0; c < num_points; c++) { + X_camera->col(c) = C2b * alphas.col(c); + } + + // Check the sign of the z coordinate of the points (should be positive) + uint num_z_neg = 0; + for (size_t i = 0; i < X_camera->cols(); ++i) { + if ((*X_camera)(2, i) < 0) { + num_z_neg++; + } + } + + // If more than 50% of z are negative, we change the signs + if (num_z_neg > 0.5 * X_camera->cols()) { + C2b = -C2b; + *X_camera = -(*X_camera); + } +} + +bool EuclideanResectionEPnP(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t) { + CHECK(x_camera.cols() == X_world.cols()); + CHECK(x_camera.cols() > 3); + size_t num_points = X_world.cols(); + + // Select the control points. + Mat34 X_control_points; + Mat X_centered; + SelectControlPoints(X_world, &X_centered, &X_control_points); + + // Compute the barycentric coordinates. + Mat4X alphas(4, num_points); + ComputeBarycentricCoordinates(X_centered, X_control_points, &alphas); + + // Estimates the M matrix with the barycentric coordinates + Mat M(2 * num_points, 12); + Eigen::Matrix sub_M; + for (size_t c = 0; c < num_points; c++) { + double a0 = alphas(0, c); + double a1 = alphas(1, c); + double a2 = alphas(2, c); + double a3 = alphas(3, c); + double ui = x_camera(0, c); + double vi = x_camera(1, c); + M.block(2*c, 0, 2, 12) << a0, 0, + a0*(-ui), a1, 0, + a1*(-ui), a2, 0, + a2*(-ui), a3, 0, + a3*(-ui), 0, + a0, a0*(-vi), 0, + a1, a1*(-vi), 0, + a2, a2*(-vi), 0, + a3, a3*(-vi); + } + + // TODO(julien): Avoid the transpose by rewriting the u2.block() calls. + Eigen::JacobiSVD MtMsvd(M.transpose()*M, Eigen::ComputeFullU); + Eigen::Matrix u2 = MtMsvd.matrixU().transpose(); + + // Estimate the L matrix. + Eigen::Matrix dv1; + Eigen::Matrix dv2; + Eigen::Matrix dv3; + Eigen::Matrix dv4; + + dv1.row(0) = u2.block(11, 0, 1, 3) - u2.block(11, 3, 1, 3); + dv1.row(1) = u2.block(11, 0, 1, 3) - u2.block(11, 6, 1, 3); + dv1.row(2) = u2.block(11, 0, 1, 3) - u2.block(11, 9, 1, 3); + dv1.row(3) = u2.block(11, 3, 1, 3) - u2.block(11, 6, 1, 3); + dv1.row(4) = u2.block(11, 3, 1, 3) - u2.block(11, 9, 1, 3); + dv1.row(5) = u2.block(11, 6, 1, 3) - u2.block(11, 9, 1, 3); + dv2.row(0) = u2.block(10, 0, 1, 3) - u2.block(10, 3, 1, 3); + dv2.row(1) = u2.block(10, 0, 1, 3) - u2.block(10, 6, 1, 3); + dv2.row(2) = u2.block(10, 0, 1, 3) - u2.block(10, 9, 1, 3); + dv2.row(3) = u2.block(10, 3, 1, 3) - u2.block(10, 6, 1, 3); + dv2.row(4) = u2.block(10, 3, 1, 3) - u2.block(10, 9, 1, 3); + dv2.row(5) = u2.block(10, 6, 1, 3) - u2.block(10, 9, 1, 3); + dv3.row(0) = u2.block(9, 0, 1, 3) - u2.block(9, 3, 1, 3); + dv3.row(1) = u2.block(9, 0, 1, 3) - u2.block(9, 6, 1, 3); + dv3.row(2) = u2.block(9, 0, 1, 3) - u2.block(9, 9, 1, 3); + dv3.row(3) = u2.block(9, 3, 1, 3) - u2.block(9, 6, 1, 3); + dv3.row(4) = u2.block(9, 3, 1, 3) - u2.block(9, 9, 1, 3); + dv3.row(5) = u2.block(9, 6, 1, 3) - u2.block(9, 9, 1, 3); + dv4.row(0) = u2.block(8, 0, 1, 3) - u2.block(8, 3, 1, 3); + dv4.row(1) = u2.block(8, 0, 1, 3) - u2.block(8, 6, 1, 3); + dv4.row(2) = u2.block(8, 0, 1, 3) - u2.block(8, 9, 1, 3); + dv4.row(3) = u2.block(8, 3, 1, 3) - u2.block(8, 6, 1, 3); + dv4.row(4) = u2.block(8, 3, 1, 3) - u2.block(8, 9, 1, 3); + dv4.row(5) = u2.block(8, 6, 1, 3) - u2.block(8, 9, 1, 3); + + Eigen::Matrix L; + for (size_t r = 0; r < 6; r++) { + L.row(r) << dv1.row(r).dot(dv1.row(r)), + 2.0 * dv1.row(r).dot(dv2.row(r)), + dv2.row(r).dot(dv2.row(r)), + 2.0 * dv1.row(r).dot(dv3.row(r)), + 2.0 * dv2.row(r).dot(dv3.row(r)), + dv3.row(r).dot(dv3.row(r)), + 2.0 * dv1.row(r).dot(dv4.row(r)), + 2.0 * dv2.row(r).dot(dv4.row(r)), + 2.0 * dv3.row(r).dot(dv4.row(r)), + dv4.row(r).dot(dv4.row(r)); + } + Vec6 rho; + rho << (X_control_points.col(0) - X_control_points.col(1)).squaredNorm(), + (X_control_points.col(0) - X_control_points.col(2)).squaredNorm(), + (X_control_points.col(0) - X_control_points.col(3)).squaredNorm(), + (X_control_points.col(1) - X_control_points.col(2)).squaredNorm(), + (X_control_points.col(1) - X_control_points.col(3)).squaredNorm(), + (X_control_points.col(2) - X_control_points.col(3)).squaredNorm(); + + // There are three possible solutions based on the three approximations of L + // (betas). Below, each one is solved for then the best one is chosen. + Mat3X X_camera; + Mat3 K; K.setIdentity(); + vector Rs(3); + vector ts(3); + Vec rmse(3); + + // At one point this threshold was 1e-3, and caused no end of problems in + // Blender by causing frames to not resect when they would have worked fine. + // When the resect failed, the projective followup is run leading to worse + // results, and often the dreaded "flipping" where objects get flipped + // between frames. Instead, disable the check for now, always succeeding. The + // ultimate check is always reprojection error anyway. + // + // TODO(keir): Decide if setting this to infinity, effectively disabling the + // check, is the right approach. So far this seems the case. + double kSuccessThreshold = std::numeric_limits::max(); + + // Find the first possible solution for R, t corresponding to: + // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33] + // Betas_approx_1 = [b00 b01 b02 b03] + Vec4 betas = Vec4::Zero(); + Eigen::Matrix l_6x4; + for (size_t r = 0; r < 6; r++) { + l_6x4.row(r) << L(r, 0), L(r, 1), L(r, 3), L(r, 6); + } + Eigen::JacobiSVD svd_of_l4(l_6x4, + Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec4 b4 = svd_of_l4.solve(rho); + if ((l_6x4 * b4).isApprox(rho, kSuccessThreshold)) { + if (b4(0) < 0) { + b4 = -b4; + } + b4(0) = std::sqrt(b4(0)); + betas << b4(0), b4(1) / b4(0), b4(2) / b4(0), b4(3) / b4(0); + ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera); + AbsoluteOrientation(X_world, X_camera, &Rs[0], &ts[0]); + rmse(0) = RootMeanSquareError(x_camera, X_world, K, Rs[0], ts[0]); + } else { + LOG(ERROR) << "First approximation of beta not good enough."; + ts[0].setZero(); + rmse(0) = std::numeric_limits::max(); + } + + // Find the second possible solution for R, t corresponding to: + // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33] + // Betas_approx_2 = [b00 b01 b11] + betas.setZero(); + Eigen::Matrix l_6x3; + l_6x3 = L.block(0, 0, 6, 3); + Eigen::JacobiSVD svdOfL3(l_6x3, + Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec3 b3 = svdOfL3.solve(rho); + VLOG(2) << " rho = " << rho; + VLOG(2) << " l_6x3 * b3 = " << l_6x3 * b3; + if ((l_6x3 * b3).isApprox(rho, kSuccessThreshold)) { + if (b3(0) < 0) { + betas(0) = std::sqrt(-b3(0)); + betas(1) = (b3(2) < 0) ? std::sqrt(-b3(2)) : 0; + } else { + betas(0) = std::sqrt(b3(0)); + betas(1) = (b3(2) > 0) ? std::sqrt(b3(2)) : 0; + } + if (b3(1) < 0) { + betas(0) = -betas(0); + } + betas(2) = 0; + betas(3) = 0; + ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera); + AbsoluteOrientation(X_world, X_camera, &Rs[1], &ts[1]); + rmse(1) = RootMeanSquareError(x_camera, X_world, K, Rs[1], ts[1]); + } else { + LOG(ERROR) << "Second approximation of beta not good enough."; + ts[1].setZero(); + rmse(1) = std::numeric_limits::max(); + } + + // Find the third possible solution for R, t corresponding to: + // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33] + // Betas_approx_3 = [b00 b01 b11 b02 b12] + betas.setZero(); + Eigen::Matrix l_6x5; + l_6x5 = L.block(0, 0, 6, 5); + Eigen::JacobiSVD svdOfL5(l_6x5, + Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec5 b5 = svdOfL5.solve(rho); + if ((l_6x5 * b5).isApprox(rho, kSuccessThreshold)) { + if (b5(0) < 0) { + betas(0) = std::sqrt(-b5(0)); + if (b5(2) < 0) { + betas(1) = std::sqrt(-b5(2)); + } else { + b5(2) = 0; + } + } else { + betas(0) = std::sqrt(b5(0)); + if (b5(2) > 0) { + betas(1) = std::sqrt(b5(2)); + } else { + b5(2) = 0; + } + } + if (b5(1) < 0) { + betas(0) = -betas(0); + } + betas(2) = b5(3) / betas(0); + betas(3) = 0; + ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera); + AbsoluteOrientation(X_world, X_camera, &Rs[2], &ts[2]); + rmse(2) = RootMeanSquareError(x_camera, X_world, K, Rs[2], ts[2]); + } else { + LOG(ERROR) << "Third approximation of beta not good enough."; + ts[2].setZero(); + rmse(2) = std::numeric_limits::max(); + } + + // Finally, with all three solutions, select the (R, t) with the best RMSE. + VLOG(2) << "RMSE for solution 0: " << rmse(0); + VLOG(2) << "RMSE for solution 1: " << rmse(1); + VLOG(2) << "RMSE for solution 2: " << rmse(2); + size_t n = 0; + if (rmse(1) < rmse(0)) { + n = 1; + } + if (rmse(2) < rmse(n)) { + n = 2; + } + if (rmse(n) == std::numeric_limits::max()) { + LOG(ERROR) << "All three possibilities failed. Reporting failure."; + return false; + } + + VLOG(1) << "RMSE for best solution #" << n << ": " << rmse(n); + *R = Rs[n]; + *t = ts[n]; + + // TODO(julien): Improve the solutions with non-linear refinement. + return true; +} + +/* + + Straight from the paper: + http://www.diegm.uniud.it/fusiello/papers/3dimpvt12-b.pdf + + function [R T] = ppnp(P,S,tol) + % input + % P : matrix (nx3) image coordinates in camera reference [u v 1] + % S : matrix (nx3) coordinates in world reference [X Y Z] + % tol: exit threshold + % + % output + % R : matrix (3x3) rotation (world-to-camera) + % T : vector (3x1) translation (world-to-camera) + % + n = size(P,1); + Z = zeros(n); + e = ones(n,1); + A = eye(n)-((e*e’)./n); + II = e./n; + err = +Inf; + E_old = 1000*ones(n,3); + while err>tol + [U,˜,V] = svd(P’*Z*A*S); + VT = V’; + R=U*[1 0 0; 0 1 0; 0 0 det(U*VT)]*VT; + PR = P*R; + c = (S-Z*PR)’*II; + Y = S-e*c’; + Zmindiag = diag(PR*Y’)./(sum(P.*P,2)); + Zmindiag(Zmindiag<0)=0; + Z = diag(Zmindiag); + E = Y-Z*PR; + err = norm(E-E_old,’fro’); + E_old = E; + end + T = -R*c; + end + + */ +// TODO(keir): Re-do all the variable names and add comments matching the paper. +// This implementation has too much of the terseness of the original. On the +// other hand, it did work on the first try. +bool EuclideanResectionPPnP(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t) { + int n = x_camera.cols(); + Mat Z = Mat::Zero(n, n); + Vec e = Vec::Ones(n); + Mat A = Mat::Identity(n, n) - (e * e.transpose() / n); + Vec II = e / n; + + Mat P(n, 3); + P.col(0) = x_camera.row(0); + P.col(1) = x_camera.row(1); + P.col(2).setConstant(1.0); + + Mat S = X_world.transpose(); + + double error = std::numeric_limits::infinity(); + Mat E_old = 1000 * Mat::Ones(n, 3); + + Vec3 c; + Mat E(n, 3); + + int iteration = 0; + double tolerance = 1e-5; + // TODO(keir): The limit of 100 can probably be reduced, but this will require + // some investigation. + while (error > tolerance && iteration < 100) { + Mat3 tmp = P.transpose() * Z * A * S; + Eigen::JacobiSVD svd(tmp, Eigen::ComputeFullU | Eigen::ComputeFullV); + Mat3 U = svd.matrixU(); + Mat3 VT = svd.matrixV().transpose(); + Vec3 s; + s << 1, 1, (U * VT).determinant(); + *R = U * s.asDiagonal() * VT; + Mat PR = P * *R; // n x 3 + c = (S - Z*PR).transpose() * II; + Mat Y = S - e*c.transpose(); // n x 3 + Vec Zmindiag = (PR * Y.transpose()).diagonal() + .cwiseQuotient(P.rowwise().squaredNorm()); + for (int i = 0; i < n; ++i) { + Zmindiag[i] = std::max(Zmindiag[i], 0.0); + } + Z = Zmindiag.asDiagonal(); + E = Y - Z*PR; + error = (E - E_old).norm(); + LOG(INFO) << "PPnP error(" << (iteration++) << "): " << error; + E_old = E; + } + *t = -*R*c; + + // TODO(keir): Figure out what the failure cases are. Is it too many + // iterations? Spend some time going through the math figuring out if there + // is some way to detect that the algorithm is going crazy, and return false. + return true; +} + + +} // namespace resection +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/euclidean_resection.h b/modules/sfm/src/libmv_light/libmv/multiview/euclidean_resection.h new file mode 100644 index 0000000000..40eedadd1a --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/euclidean_resection.h @@ -0,0 +1,148 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_ +#define LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_ + +#include "libmv/numeric/numeric.h" +#include "libmv/multiview/projection.h" + +namespace libmv { +namespace euclidean_resection { + +enum ResectionMethod { + RESECTION_ANSAR_DANIILIDIS, + + // The "EPnP" algorithm by Lepetit et al. + // http://cvlab.epfl.ch/~lepetit/papers/lepetit_ijcv08.pdf + RESECTION_EPNP, + + // The Procrustes PNP algorithm ("PPnP") + // http://www.diegm.uniud.it/fusiello/papers/3dimpvt12-b.pdf + RESECTION_PPNP +}; + +/** + * Computes the extrinsic parameters, R and t for a calibrated camera + * from 4 or more 3D points and their normalized images. + * + * \param x_camera Image points in normalized camera coordinates e.g. x_camera + * = inv(K) * x_image. + * \param X_world 3D points in the world coordinate system + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * \param method The resection method to use. + */ +bool EuclideanResection(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t, + ResectionMethod method = RESECTION_EPNP); + +/** + * Computes the extrinsic parameters, R and t for a calibrated camera + * from 4 or more 3D points and their images. + * + * \param x_image Image points in non-normalized image coordinates. The + * coordates are laid out one per row. The matrix can be Nx2 + * or Nx3 for euclidean or homogenous 2D coordinates. + * \param X_world 3D points in the world coordinate system + * \param K Intrinsic parameters camera matrix + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * \param method Resection method + */ +bool EuclideanResection(const Mat &x_image, + const Mat3X &X_world, + const Mat3 &K, + Mat3 *R, Vec3 *t, + ResectionMethod method = RESECTION_EPNP); + +/** + * The absolute orientation algorithm recovers the transformation between a set + * of 3D points, X and Xp such that: + * + * Xp = R*X + t + * + * The recovery of the absolute orientation is implemented after this article: + * Horn, Hilden, "Closed-form solution of absolute orientation using + * orthonormal matrices" + */ +void AbsoluteOrientation(const Mat3X &X, + const Mat3X &Xp, + Mat3 *R, + Vec3 *t); + +/** + * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or + * more 3D points and their images. + * + * \param x_camera Image points in normalized camera coordinates, e.g. + * x_camera=inv(K)*x_image + * \param X_world 3D points in the world coordinate system + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * + * This is the algorithm described in: "Linear Pose Estimation from Points or + * Lines", by Ansar, A. and Daniilidis, PAMI 2003. vol. 25, no. 5. + */ +void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t); +/** + * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or + * more 3D points and their images. + * + * \param x_camera Image points in normalized camera coordinates, + * e.g. x_camera = inv(K) * x_image + * \param X_world 3D points in the world coordinate system + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * + * This is the algorithm described in: + * "{EP$n$P: An Accurate $O(n)$ Solution to the P$n$P Problem", by V. Lepetit + * and F. Moreno-Noguer and P. Fua, IJCV 2009. vol. 81, no. 2 + * \note: the non-linear optimization is not implemented here. + */ +bool EuclideanResectionEPnP(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t); + +/** + * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or + * more 3D points and their images. + * + * \param x_camera Image points in normalized camera coordinates, + * e.g. x_camera = inv(K) * x_image + * \param X_world 3D points in the world coordinate system + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * + * Straight from the paper: + * http://www.diegm.uniud.it/fusiello/papers/3dimpvt12-b.pdf + */ +bool EuclideanResectionPPnP(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t); + +} // namespace euclidean_resection +} // namespace libmv + + +#endif /* LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_ */ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/fundamental.cc b/modules/sfm/src/libmv_light/libmv/multiview/fundamental.cc new file mode 100644 index 0000000000..a18dab0ffd --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/fundamental.cc @@ -0,0 +1,551 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/fundamental.h" + +#if CERES_FOUND +#include "ceres/ceres.h" +#endif +#include "libmv/logging/logging.h" +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/poly.h" +#include "libmv/multiview/conditioning.h" +#include "libmv/multiview/projection.h" +#include "libmv/multiview/triangulation.h" + +namespace libmv { + +static void EliminateRow(const Mat34 &P, int row, Mat *X) { + X->resize(2, 4); + + int first_row = (row + 1) % 3; + int second_row = (row + 2) % 3; + + for (int i = 0; i < 4; ++i) { + (*X)(0, i) = P(first_row, i); + (*X)(1, i) = P(second_row, i); + } +} + +void ProjectionsFromFundamental(const Mat3 &F, Mat34 *P1, Mat34 *P2) { + *P1 << Mat3::Identity(), Vec3::Zero(); + Vec3 e2; + Mat3 Ft = F.transpose(); + Nullspace(&Ft, &e2); + *P2 << CrossProductMatrix(e2) * F, e2; +} + +// Addapted from vgg_F_from_P. +void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F) { + Mat X[3]; + Mat Y[3]; + Mat XY; + + for (int i = 0; i < 3; ++i) { + EliminateRow(P1, i, X + i); + EliminateRow(P2, i, Y + i); + } + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + VerticalStack(X[j], Y[i], &XY); + (*F)(i, j) = XY.determinant(); + } + } +} + +// HZ 11.1 pag.279 (x1 = x, x2 = x') +// http://www.cs.unc.edu/~marc/tutorial/node54.html +static double EightPointSolver(const Mat &x1, const Mat &x2, Mat3 *F) { + DCHECK_EQ(x1.rows(), 2); + DCHECK_GE(x1.cols(), 8); + DCHECK_EQ(x1.rows(), x2.rows()); + DCHECK_EQ(x1.cols(), x2.cols()); + + int n = x1.cols(); + Mat A(n, 9); + for (int i = 0; i < n; ++i) { + A(i, 0) = x2(0, i) * x1(0, i); + A(i, 1) = x2(0, i) * x1(1, i); + A(i, 2) = x2(0, i); + A(i, 3) = x2(1, i) * x1(0, i); + A(i, 4) = x2(1, i) * x1(1, i); + A(i, 5) = x2(1, i); + A(i, 6) = x1(0, i); + A(i, 7) = x1(1, i); + A(i, 8) = 1; + } + + Vec9 f; + double smaller_singular_value = Nullspace(&A, &f); + *F = Map(f.data()); + return smaller_singular_value; +} + +// HZ 11.1.1 pag.280 +void EnforceFundamentalRank2Constraint(Mat3 *F) { + Eigen::JacobiSVD USV(*F, Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec3 d = USV.singularValues(); + d(2) = 0.0; + *F = USV.matrixU() * d.asDiagonal() * USV.matrixV().transpose(); +} + +// HZ 11.2 pag.281 (x1 = x, x2 = x') +double NormalizedEightPointSolver(const Mat &x1, + const Mat &x2, + Mat3 *F) { + DCHECK_EQ(x1.rows(), 2); + DCHECK_GE(x1.cols(), 8); + DCHECK_EQ(x1.rows(), x2.rows()); + DCHECK_EQ(x1.cols(), x2.cols()); + + // Normalize the data. + Mat3 T1, T2; + PreconditionerFromPoints(x1, &T1); + PreconditionerFromPoints(x2, &T2); + Mat x1_normalized, x2_normalized; + ApplyTransformationToPoints(x1, T1, &x1_normalized); + ApplyTransformationToPoints(x2, T2, &x2_normalized); + + // Estimate the fundamental matrix. + double smaller_singular_value = + EightPointSolver(x1_normalized, x2_normalized, F); + EnforceFundamentalRank2Constraint(F); + + // Denormalize the fundamental matrix. + *F = T2.transpose() * (*F) * T1; + + return smaller_singular_value; +} + +// Seven-point algorithm. +// http://www.cs.unc.edu/~marc/tutorial/node55.html +double FundamentalFrom7CorrespondencesLinear(const Mat &x1, + const Mat &x2, + std::vector *F) { + DCHECK_EQ(x1.rows(), 2); + DCHECK_EQ(x1.cols(), 7); + DCHECK_EQ(x1.rows(), x2.rows()); + DCHECK_EQ(x2.cols(), x2.cols()); + + // Build a 9 x n matrix from point matches, where each row is equivalent to + // the equation x'T*F*x = 0 for a single correspondence pair (x', x). The + // domain of the matrix is a 9 element vector corresponding to F. The + // nullspace should be rank two; the two dimensions correspond to the set of + // F matrices satisfying the epipolar geometry. + Matrix A; + for (int ii = 0; ii < 7; ++ii) { + A(ii, 0) = x1(0, ii) * x2(0, ii); // 0 represents x coords, + A(ii, 1) = x1(1, ii) * x2(0, ii); // 1 represents y coords. + A(ii, 2) = x2(0, ii); + A(ii, 3) = x1(0, ii) * x2(1, ii); + A(ii, 4) = x1(1, ii) * x2(1, ii); + A(ii, 5) = x2(1, ii); + A(ii, 6) = x1(0, ii); + A(ii, 7) = x1(1, ii); + A(ii, 8) = 1.0; + } + + // Find the two F matrices in the nullspace of A. + Vec9 f1, f2; + double s = Nullspace2(&A, &f1, &f2); + Mat3 F1 = Map(f1.data()); + Mat3 F2 = Map(f2.data()); + + // Then, use the condition det(F) = 0 to determine F. In other words, solve + // det(F1 + a*F2) = 0 for a. + double a = F1(0, 0), j = F2(0, 0), + b = F1(0, 1), k = F2(0, 1), + c = F1(0, 2), l = F2(0, 2), + d = F1(1, 0), m = F2(1, 0), + e = F1(1, 1), n = F2(1, 1), + f = F1(1, 2), o = F2(1, 2), + g = F1(2, 0), p = F2(2, 0), + h = F1(2, 1), q = F2(2, 1), + i = F1(2, 2), r = F2(2, 2); + + // Run fundamental_7point_coeffs.py to get the below coefficients. + // The coefficients are in ascending powers of alpha, i.e. P[N]*x^N. + double P[4] = { + a*e*i + b*f*g + c*d*h - a*f*h - b*d*i - c*e*g, + a*e*r + a*i*n + b*f*p + b*g*o + c*d*q + c*h*m + d*h*l + e*i*j + f*g*k - + a*f*q - a*h*o - b*d*r - b*i*m - c*e*p - c*g*n - d*i*k - e*g*l - f*h*j, + a*n*r + b*o*p + c*m*q + d*l*q + e*j*r + f*k*p + g*k*o + h*l*m + i*j*n - + a*o*q - b*m*r - c*n*p - d*k*r - e*l*p - f*j*q - g*l*n - h*j*o - i*k*m, + j*n*r + k*o*p + l*m*q - j*o*q - k*m*r - l*n*p, + }; + + // Solve for the roots of P[3]*x^3 + P[2]*x^2 + P[1]*x + P[0] = 0. + double roots[3]; + int num_roots = SolveCubicPolynomial(P, roots); + + // Build the fundamental matrix for each solution. + for (int kk = 0; kk < num_roots; ++kk) { + F->push_back(F1 + roots[kk] * F2); + } + return s; +} + +double FundamentalFromCorrespondences7Point(const Mat &x1, + const Mat &x2, + std::vector *F) { + DCHECK_EQ(x1.rows(), 2); + DCHECK_GE(x1.cols(), 7); + DCHECK_EQ(x1.rows(), x2.rows()); + DCHECK_EQ(x1.cols(), x2.cols()); + + // Normalize the data. + Mat3 T1, T2; + PreconditionerFromPoints(x1, &T1); + PreconditionerFromPoints(x2, &T2); + Mat x1_normalized, x2_normalized; + ApplyTransformationToPoints(x1, T1, &x1_normalized); + ApplyTransformationToPoints(x2, T2, &x2_normalized); + + // Estimate the fundamental matrix. + double smaller_singular_value = + FundamentalFrom7CorrespondencesLinear(x1_normalized, x2_normalized, &(*F)); + + for (int k = 0; k < F->size(); ++k) { + Mat3 & Fmat = (*F)[k]; + // Denormalize the fundamental matrix. + Fmat = T2.transpose() * Fmat * T1; + } + return smaller_singular_value; +} + +void NormalizeFundamental(const Mat3 &F, Mat3 *F_normalized) { + *F_normalized = F / FrobeniusNorm(F); + if ((*F_normalized)(2, 2) < 0) { + *F_normalized *= -1; + } +} + +double SampsonDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) { + Vec3 x(x1(0), x1(1), 1.0); + Vec3 y(x2(0), x2(1), 1.0); + + Vec3 F_x = F * x; + Vec3 Ft_y = F.transpose() * y; + double y_F_x = y.dot(F_x); + + return Square(y_F_x) / ( F_x.head<2>().squaredNorm() + + Ft_y.head<2>().squaredNorm()); +} + +double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) { + Vec3 x(x1(0), x1(1), 1.0); + Vec3 y(x2(0), x2(1), 1.0); + + Vec3 F_x = F * x; + Vec3 Ft_y = F.transpose() * y; + double y_F_x = y.dot(F_x); + + return Square(y_F_x) * ( 1 / F_x.head<2>().squaredNorm() + + 1 / Ft_y.head<2>().squaredNorm()); +} + +// HZ 9.6 pag 257 (formula 9.12) +void EssentialFromFundamental(const Mat3 &F, + const Mat3 &K1, + const Mat3 &K2, + Mat3 *E) { + *E = K2.transpose() * F * K1; +} + +// HZ 9.6 pag 257 (formula 9.12) +// Or http://ai.stanford.edu/~birch/projective/node20.html +void FundamentalFromEssential(const Mat3 &E, + const Mat3 &K1, + const Mat3 &K2, + Mat3 *F) { + *F = K2.inverse().transpose() * E * K1.inverse(); +} + +void RelativeCameraMotion(const Mat3 &R1, + const Vec3 &t1, + const Mat3 &R2, + const Vec3 &t2, + Mat3 *R, + Vec3 *t) { + *R = R2 * R1.transpose(); + *t = t2 - (*R) * t1; +} + +// HZ 9.6 pag 257 +void EssentialFromRt(const Mat3 &R1, + const Vec3 &t1, + const Mat3 &R2, + const Vec3 &t2, + Mat3 *E) { + Mat3 R; + Vec3 t; + RelativeCameraMotion(R1, t1, R2, t2, &R, &t); + Mat3 Tx = CrossProductMatrix(t); + *E = Tx * R; +} + +// HZ 9.6 pag 259 (Result 9.19) +void MotionFromEssential(const Mat3 &E, + std::vector *Rs, + std::vector *ts) { + Eigen::JacobiSVD USV(E, Eigen::ComputeFullU | Eigen::ComputeFullV); + Mat3 U = USV.matrixU(); + Mat3 Vt = USV.matrixV().transpose(); + + // Last column of U is undetermined since d = (a a 0). + if (U.determinant() < 0) { + U.col(2) *= -1; + } + // Last row of Vt is undetermined since d = (a a 0). + if (Vt.determinant() < 0) { + Vt.row(2) *= -1; + } + + Mat3 W; + W << 0, -1, 0, + 1, 0, 0, + 0, 0, 1; + + Mat3 U_W_Vt = U * W * Vt; + Mat3 U_Wt_Vt = U * W.transpose() * Vt; + + Rs->resize(4); + (*Rs)[0] = U_W_Vt; + (*Rs)[1] = U_W_Vt; + (*Rs)[2] = U_Wt_Vt; + (*Rs)[3] = U_Wt_Vt; + + ts->resize(4); + (*ts)[0] = U.col(2); + (*ts)[1] = -U.col(2); + (*ts)[2] = U.col(2); + (*ts)[3] = -U.col(2); +} + +int MotionFromEssentialChooseSolution(const std::vector &Rs, + const std::vector &ts, + const Mat3 &K1, + const Vec2 &x1, + const Mat3 &K2, + const Vec2 &x2) { + DCHECK_EQ(4, Rs.size()); + DCHECK_EQ(4, ts.size()); + + Mat34 P1, P2; + Mat3 R1; + Vec3 t1; + R1.setIdentity(); + t1.setZero(); + P_From_KRt(K1, R1, t1, &P1); + for (int i = 0; i < 4; ++i) { + const Mat3 &R2 = Rs[i]; + const Vec3 &t2 = ts[i]; + P_From_KRt(K2, R2, t2, &P2); + Vec3 X; + TriangulateDLT(P1, x1, P2, x2, &X); + double d1 = Depth(R1, t1, X); + double d2 = Depth(R2, t2, X); + // Test if point is front to the two cameras. + if (d1 > 0 && d2 > 0) { + return i; + } + } + return -1; +} + +bool MotionFromEssentialAndCorrespondence(const Mat3 &E, + const Mat3 &K1, + const Vec2 &x1, + const Mat3 &K2, + const Vec2 &x2, + Mat3 *R, + Vec3 *t) { + std::vector Rs; + std::vector ts; + MotionFromEssential(E, &Rs, &ts); + int solution = MotionFromEssentialChooseSolution(Rs, ts, K1, x1, K2, x2); + if (solution >= 0) { + *R = Rs[solution]; + *t = ts[solution]; + return true; + } else { + return false; + } +} + +void FundamentalToEssential(const Mat3 &F, Mat3 *E) { + Eigen::JacobiSVD svd(F, Eigen::ComputeFullU | Eigen::ComputeFullV); + + // See Hartley & Zisserman page 294, result 11.1, which shows how to get the + // closest essential matrix to a matrix that is "almost" an essential matrix. + double a = svd.singularValues()(0); + double b = svd.singularValues()(1); + double s = (a + b) / 2.0; + + LG << "Initial reconstruction's rotation is non-euclidean by " + << (((a - b) / std::max(a, b)) * 100) << "%; singular values:" + << svd.singularValues().transpose(); + + Vec3 diag; + diag << s, s, 0; + + *E = svd.matrixU() * diag.asDiagonal() * svd.matrixV().transpose(); +} + +// Default settings for fundamental estimation which should be suitable +// for a wide range of use cases. +EstimateFundamentalOptions::EstimateFundamentalOptions(void) : + max_num_iterations(50), + expected_average_symmetric_distance(1e-16) { +} + +namespace { +// Cost functor which computes symmetric epipolar distance +// used for fundamental matrix refinement. +class FundamentalSymmetricEpipolarCostFunctor { + public: + FundamentalSymmetricEpipolarCostFunctor(const Vec2 &x, + const Vec2 &y) + : x_(x), y_(y) {} + + template + bool operator()(const T *fundamental_parameters, T *residuals) const { + typedef Eigen::Matrix Mat3; + typedef Eigen::Matrix Vec3; + + Mat3 F(fundamental_parameters); + + Vec3 x(T(x_(0)), T(x_(1)), T(1.0)); + Vec3 y(T(y_(0)), T(y_(1)), T(1.0)); + + Vec3 F_x = F * x; + Vec3 Ft_y = F.transpose() * y; + T y_F_x = y.dot(F_x); + + residuals[0] = y_F_x * T(1) / F_x.head(2).norm(); + residuals[1] = y_F_x * T(1) / Ft_y.head(2).norm(); + + return true; + } + + const Mat x_; + const Mat y_; +}; + +#if CERES_FOUND +// Termination checking callback used for fundamental estimation. +// It finished the minimization as soon as actual average of +// symmetric epipolar distance is less or equal to the expected +// average value. +class TerminationCheckingCallback : public ceres::IterationCallback { + public: + TerminationCheckingCallback(const Mat &x1, const Mat &x2, + const EstimateFundamentalOptions &options, + Mat3 *F) + : options_(options), x1_(x1), x2_(x2), F_(F) {} + + virtual ceres::CallbackReturnType operator()( + const ceres::IterationSummary& summary) { + // If the step wasn't successful, there's nothing to do. + if (!summary.step_is_successful) { + return ceres::SOLVER_CONTINUE; + } + + // Calculate average of symmetric epipolar distance. + double average_distance = 0.0; + for (int i = 0; i < x1_.cols(); i++) { + average_distance = SymmetricEpipolarDistance(*F_, + x1_.col(i), + x2_.col(i)); + } + average_distance /= x1_.cols(); + + if (average_distance <= options_.expected_average_symmetric_distance) { + return ceres::SOLVER_TERMINATE_SUCCESSFULLY; + } + + return ceres::SOLVER_CONTINUE; + } + + private: + const EstimateFundamentalOptions &options_; + const Mat &x1_; + const Mat &x2_; + Mat3 *F_; +}; +#endif // CERES_FOUND +} // namespace + +/* Fundamental transformation estimation. */ +bool EstimateFundamentalFromCorrespondences( + const Mat &x1, + const Mat &x2, + const EstimateFundamentalOptions &options, + Mat3 *F) { + // Step 1: Algebraic fundamental estimation. + + // Assume algebraic estiation always succeeds, + NormalizedEightPointSolver(x1, x2, F); + +#if CERES_FOUND + LG << "Estimated matrix after algebraic estimation:\n" << *F; + + // Step 2: Refine matrix using Ceres minimizer. + ceres::Problem problem; + for (int i = 0; i < x1.cols(); i++) { + FundamentalSymmetricEpipolarCostFunctor + *fundamental_symmetric_epipolar_cost_function = + new FundamentalSymmetricEpipolarCostFunctor(x1.col(i), + x2.col(i)); + + problem.AddResidualBlock( + new ceres::AutoDiffCostFunction< + FundamentalSymmetricEpipolarCostFunctor, + 2, // num_residuals + 9>(fundamental_symmetric_epipolar_cost_function), + NULL, + F->data()); + } + + // Configure the solve. + ceres::Solver::Options solver_options; + solver_options.linear_solver_type = ceres::DENSE_QR; + solver_options.max_num_iterations = options.max_num_iterations; + solver_options.update_state_every_iteration = true; + + // Terminate if the average symmetric distance is good enough. + TerminationCheckingCallback callback(x1, x2, options, F); + solver_options.callbacks.push_back(&callback); + + // Run the solve. + ceres::Solver::Summary summary; + ceres::Solve(solver_options, &problem, &summary); + + VLOG(1) << "Summary:\n" << summary.FullReport(); + + LG << "Final refined matrix:\n" << *F; + + return summary.IsSolutionUsable(); +#endif // CERES_FOUND + return true; +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/fundamental.h b/modules/sfm/src/libmv_light/libmv/multiview/fundamental.h new file mode 100644 index 0000000000..51067aefc2 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/fundamental.h @@ -0,0 +1,187 @@ +// Copyright (c) 2007, 2008, 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_FUNDAMENTAL_H_ +#define LIBMV_MULTIVIEW_FUNDAMENTAL_H_ + +#include + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +void ProjectionsFromFundamental(const Mat3 &F, Mat34 *P1, Mat34 *P2); +void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F); + +/** + * The normalized 8-point fundamental matrix solver. + */ +double NormalizedEightPointSolver(const Mat &x1, + const Mat &x2, + Mat3 *F); + +/** + * 7 points (minimal case, points coordinates must be normalized before): + */ +double FundamentalFrom7CorrespondencesLinear(const Mat &x1, + const Mat &x2, + std::vector *F); + +/** + * 7 points (points coordinates must be in image space): + */ +double FundamentalFromCorrespondences7Point(const Mat &x1, + const Mat &x2, + std::vector *F); + +/** + * 8 points (points coordinates must be in image space): + */ +double NormalizedEightPointSolver(const Mat &x1, + const Mat &x2, + Mat3 *F); + +/** + * Fundamental matrix utility function: + */ +void EnforceFundamentalRank2Constraint(Mat3 *F); + +void NormalizeFundamental(const Mat3 &F, Mat3 *F_normalized); + +/** + * Approximate squared reprojection errror. + * + * See page 287 of HZ equation 11.9. This avoids triangulating the point, + * relying only on the entries in F. + */ +double SampsonDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2); + +/** + * Calculates the sum of the distances from the points to the epipolar lines. + * + * See page 288 of HZ equation 11.10. + */ +double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2); + +/** + * Compute the relative camera motion between two cameras. + * + * Given the motion parameters of two cameras, computes the motion parameters + * of the second one assuming the first one to be at the origin. + * If T1 and T2 are the camera motions, the computed relative motion is + * T = T2 T1^{-1} + */ +void RelativeCameraMotion(const Mat3 &R1, + const Vec3 &t1, + const Mat3 &R2, + const Vec3 &t2, + Mat3 *R, + Vec3 *t); + +void EssentialFromFundamental(const Mat3 &F, + const Mat3 &K1, + const Mat3 &K2, + Mat3 *E); + +void FundamentalFromEssential(const Mat3 &E, + const Mat3 &K1, + const Mat3 &K2, + Mat3 *F); + +void EssentialFromRt(const Mat3 &R1, + const Vec3 &t1, + const Mat3 &R2, + const Vec3 &t2, + Mat3 *E); + +void MotionFromEssential(const Mat3 &E, + std::vector *Rs, + std::vector *ts); + +/** + * Choose one of the four possible motion solutions from an essential matrix. + * + * Decides the right solution by checking that the triangulation of a match + * x1--x2 lies in front of the cameras. See HZ 9.6 pag 259 (9.6.3 Geometrical + * interpretation of the 4 solutions) + * + * \return index of the right solution or -1 if no solution. + */ +int MotionFromEssentialChooseSolution(const std::vector &Rs, + const std::vector &ts, + const Mat3 &K1, + const Vec2 &x1, + const Mat3 &K2, + const Vec2 &x2); + +bool MotionFromEssentialAndCorrespondence(const Mat3 &E, + const Mat3 &K1, + const Vec2 &x1, + const Mat3 &K2, + const Vec2 &x2, + Mat3 *R, + Vec3 *t); + +/** + * Find closest essential matrix E to fundamental F + */ +void FundamentalToEssential(const Mat3 &F, Mat3 *E); + +/** + * This structure contains options that controls how the fundamental + * estimation operates. + * + * Defaults should be suitable for a wide range of use cases, but + * better performance and accuracy might require tweaking/ + */ +struct EstimateFundamentalOptions { + // Default constructor which sets up a options for generic usage. + EstimateFundamentalOptions(void); + + // Maximal number of iterations for refinement step. + int max_num_iterations; + + // Expected average of symmetric epipolar distance between + // actual destination points and original ones transformed by + // estimated fundamental matrix. + // + // Refinement will finish as soon as average of symmetric + // epipolar distance is less or equal to this value. + // + // This distance is measured in the same units as input points are. + double expected_average_symmetric_distance; +}; + +/** + * Fundamental transformation estimation. + * + * This function estimates the fundamental transformation from a list of 2D + * correspondences by doing algebraic estimation first followed with result + * refinement. + */ +bool EstimateFundamentalFromCorrespondences( + const Mat &x1, + const Mat &x2, + const EstimateFundamentalOptions &options, + Mat3 *F); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_FUNDAMENTAL_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/fundamental_kernel.cc b/modules/sfm/src/libmv_light/libmv/multiview/fundamental_kernel.cc new file mode 100644 index 0000000000..df130b5064 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/fundamental_kernel.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include + +// TODO(keir): This code is plain unfinished! Doesn't even compile! + +#include "libmv/base/vector.h" +#include "libmv/multiview/fundamental_kernel.h" +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/poly.h" +#include "libmv/logging/logging.h" + +namespace libmv { +namespace fundamental { +namespace kernel { + +void SevenPointSolver::Solve(const Mat &x1, const Mat &x2, vector *F) { + assert(2 == x1.rows()); + assert(7 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + // Set up the homogeneous system Af = 0 from the equations x'T*F*x = 0. + MatX9 A(x1.cols(), 9); + EncodeEpipolarEquation(x1, x2, &A); + + // Find the two F matrices in the nullspace of A. + Vec9 f1, f2; + Nullspace2(&A, &f1, &f2); + Mat3 F1 = Map(f1.data()); + Mat3 F2 = Map(f2.data()); + + // Then, use the condition det(F) = 0 to determine F. In other words, solve + // det(F1 + a*F2) = 0 for a. + double a = F1(0, 0), j = F2(0, 0), + b = F1(0, 1), k = F2(0, 1), + c = F1(0, 2), l = F2(0, 2), + d = F1(1, 0), m = F2(1, 0), + e = F1(1, 1), n = F2(1, 1), + f = F1(1, 2), o = F2(1, 2), + g = F1(2, 0), p = F2(2, 0), + h = F1(2, 1), q = F2(2, 1), + i = F1(2, 2), r = F2(2, 2); + + // Run fundamental_7point_coeffs.py to get the below coefficients. + // The coefficients are in ascending powers of alpha, i.e. P[N]*x^N. + double P[4] = { + a*e*i + b*f*g + c*d*h - a*f*h - b*d*i - c*e*g, + a*e*r + a*i*n + b*f*p + b*g*o + c*d*q + c*h*m + d*h*l + e*i*j + f*g*k - + a*f*q - a*h*o - b*d*r - b*i*m - c*e*p - c*g*n - d*i*k - e*g*l - f*h*j, + a*n*r + b*o*p + c*m*q + d*l*q + e*j*r + f*k*p + g*k*o + h*l*m + i*j*n - + a*o*q - b*m*r - c*n*p - d*k*r - e*l*p - f*j*q - g*l*n - h*j*o - i*k*m, + j*n*r + k*o*p + l*m*q - j*o*q - k*m*r - l*n*p, + }; + + // Solve for the roots of P[3]*x^3 + P[2]*x^2 + P[1]*x + P[0] = 0. + double roots[3]; + int num_roots = SolveCubicPolynomial(P, roots); + + // Build the fundamental matrix for each solution. + for (int kk = 0; kk < num_roots; ++kk) { + F->push_back(F1 + roots[kk] * F2); + } +} + +//template +void EightPointSolver::Solve(const Mat &x1, const Mat &x2, vector *Fs) { + assert(2 == x1.rows()); + assert(8 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + MatX9 A(x1.cols(), 9); + EncodeEpipolarEquation(x1, x2, &A); + + Vec9 f; + Nullspace(&A, &f); + Mat3 F = Map(f.data()); + + // Force the fundamental property if the A matrix has full rank. + if (x1.cols() > 8) { + Eigen::JacobiSVD USV(F, Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec3 d = USV.singularValues(); + d[2] = 0.0; + F = USV.matrixU() * d.asDiagonal() * USV.matrixV().transpose(); + } + Fs->push_back(F); +} + +} // namespace kernel +} // namespace fundamental +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/fundamental_kernel.h b/modules/sfm/src/libmv_light/libmv/multiview/fundamental_kernel.h new file mode 100644 index 0000000000..5fd4051611 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/fundamental_kernel.h @@ -0,0 +1,148 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +// TODO(keir): This code is plain unfinished! Doesn't even compile! + +#ifndef LIBMV_MULTIVIEW_FUNDAMENTAL_KERNEL_H_ +#define LIBMV_MULTIVIEW_FUNDAMENTAL_KERNEL_H_ + +#include "libmv/base/vector.h" +#include "libmv/multiview/conditioning.h" +#include "libmv/multiview/two_view_kernel.h" +#include "libmv/numeric/numeric.h" +#include "libmv/logging/logging.h" + +namespace libmv { +namespace fundamental { +namespace kernel { + +// TODO(keir): Templatize error functions to work with autodiff (only F). +struct SampsonError { + static double Error(const Mat3 &F, const Vec2 &x1, const Vec2 &x2) { + Vec3 x(x1(0), x1(1), 1.0); + Vec3 y(x2(0), x2(1), 1.0); + // See page 287 equation (11.9) of HZ. + Vec3 F_x = F * x; + Vec3 Ft_y = F.transpose() * y; + return Square(y.dot(F_x)) / ( F_x.head<2>().squaredNorm() + + Ft_y.head<2>().squaredNorm()); + } +}; + +struct SymmetricEpipolarDistanceError { + static double Error(const Mat3 &F, const Vec2 &x1, const Vec2 &x2) { + Vec3 x(x1(0), x1(1), 1.0); + Vec3 y(x2(0), x2(1), 1.0); + // See page 288 equation (11.10) of HZ. + Vec3 F_x = F * x; + Vec3 Ft_y = F.transpose() * y; + return Square(y.dot(F_x)) * ( 1 / F_x.head<2>().squaredNorm() + + 1 / Ft_y.head<2>().squaredNorm()) + / 4.0; // The divide by 4 is to make this match the sampson distance. + } +}; + +/** + * Seven-point algorithm for solving for the fundamental matrix from point + * correspondences. See page 281 in HZ, though oddly they use a different + * equation: \f$det(\alpha F_1 + (1-\alpha)F_2) = 0\f$. Since \f$F_1\f$ and + * \f$F2\f$ are projective, there's no need to balance the relative scale. + * Instead, here, the simpler equation is solved: \f$det(F_1 + \alpha F_2) = + * 0\f$. + * + * \see http://www.cs.unc.edu/~marc/tutorial/node55.html + */ +struct SevenPointSolver { + enum { MINIMUM_SAMPLES = 7 }; + static void Solve(const Mat &x1, const Mat &x2, vector *F); +}; + +struct EightPointSolver { + enum { MINIMUM_SAMPLES = 8 }; + static void Solve(const Mat &x1, const Mat &x2, vector *Fs); +}; + +typedef two_view::kernel::Kernel + SevenPointKernel; + +typedef two_view::kernel::Kernel + EightPointKernel; + +typedef two_view::kernel::Kernel< + two_view::kernel::NormalizedSolver, + SampsonError, + Mat3> + NormalizedSevenPointKernel; + +typedef two_view::kernel::Kernel< + two_view::kernel::NormalizedSolver, + SampsonError, + Mat3> + NormalizedEightPointKernel; + +// Set the default kernel to normalized 7 point, because it is the fastest (in +// a robust estimation context) and most robust of the above kernels. +typedef NormalizedSevenPointKernel Kernel; + +// TODO(keir): Convert this to a solver that enforces the essential +// constraints; in particular det(F) = 0 and the two nonzero singular values +// are equal. +typedef two_view::kernel::Kernel + EssentialKernel; + +/** + * Build a 9 x n matrix from point matches, where each row is equivalent to the + * equation x'T*F*x = 0 for a single correspondence pair (x', x). The domain of + * the matrix is a 9 element vector corresponding to F. In other words, set up + * the linear system + * + * Af = 0, + * + * where f is the F matrix as a 9-vector rather than a 3x3 matrix (row + * major). If the points are well conditioned and there are 8 or more, then + * the nullspace should be rank one. If the nullspace is two dimensional, + * then the rank 2 constraint must be enforced to identify the appropriate F + * matrix. + * + * Note that this does not resize the matrix A; it is expected to have the + * appropriate size already. + */ +template +inline void EncodeEpipolarEquation(const TMatX &x1, const TMatX &x2, TMatA *A) { + for (int i = 0; i < x1.cols(); ++i) { + (*A)(i, 0) = x2(0, i) * x1(0, i); // 0 represents x coords, + (*A)(i, 1) = x2(0, i) * x1(1, i); // 1 represents y coords. + (*A)(i, 2) = x2(0, i); + (*A)(i, 3) = x2(1, i) * x1(0, i); + (*A)(i, 4) = x2(1, i) * x1(1, i); + (*A)(i, 5) = x2(1, i); + (*A)(i, 6) = x1(0, i); + (*A)(i, 7) = x1(1, i); + (*A)(i, 8) = 1.0; + } +} + +} // namespace kernel +} // namespace fundamental +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_FUNDAMENTAL_KERNEL_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/homography.cc b/modules/sfm/src/libmv_light/libmv/multiview/homography.cc new file mode 100644 index 0000000000..9a9d22b43d --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/homography.cc @@ -0,0 +1,477 @@ +// Copyright (c) 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/homography.h" + +#if CERES_FOUND +#include "ceres/ceres.h" +#endif +#include "libmv/logging/logging.h" +#include "libmv/multiview/conditioning.h" +#include "libmv/multiview/homography_parameterization.h" + +namespace libmv { +/** 2D Homography transformation estimation in the case that points are in + * euclidean coordinates. + * + * x = H y + * x and y vector must have the same direction, we could write + * crossproduct(|x|, * H * |y| ) = |0| + * + * | 0 -1 x2| |a b c| |y1| |0| + * | 1 0 -x1| * |d e f| * |y2| = |0| + * |-x2 x1 0| |g h 1| |1 | |0| + * + * That gives : + * + * (-d+x2*g)*y1 + (-e+x2*h)*y2 + -f+x2 |0| + * (a-x1*g)*y1 + (b-x1*h)*y2 + c-x1 = |0| + * (-x2*a+x1*d)*y1 + (-x2*b+x1*e)*y2 + -x2*c+x1*f |0| + */ +static bool Homography2DFromCorrespondencesLinearEuc( + const Mat &x1, + const Mat &x2, + Mat3 *H, + double expected_precision) { + assert(2 == x1.rows()); + assert(4 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + int n = x1.cols(); + MatX8 L = Mat::Zero(n * 3, 8); + Mat b = Mat::Zero(n * 3, 1); + for (int i = 0; i < n; ++i) { + int j = 3 * i; + L(j, 0) = x1(0, i); // a + L(j, 1) = x1(1, i); // b + L(j, 2) = 1.0; // c + L(j, 6) = -x2(0, i) * x1(0, i); // g + L(j, 7) = -x2(0, i) * x1(1, i); // h + b(j, 0) = x2(0, i); // i + + ++j; + L(j, 3) = x1(0, i); // d + L(j, 4) = x1(1, i); // e + L(j, 5) = 1.0; // f + L(j, 6) = -x2(1, i) * x1(0, i); // g + L(j, 7) = -x2(1, i) * x1(1, i); // h + b(j, 0) = x2(1, i); // i + + // This ensures better stability + // TODO(julien) make a lite version without this 3rd set + ++j; + L(j, 0) = x2(1, i) * x1(0, i); // a + L(j, 1) = x2(1, i) * x1(1, i); // b + L(j, 2) = x2(1, i); // c + L(j, 3) = -x2(0, i) * x1(0, i); // d + L(j, 4) = -x2(0, i) * x1(1, i); // e + L(j, 5) = -x2(0, i); // f + } + // Solve Lx=B + Vec h = L.fullPivLu().solve(b); + Homography2DNormalizedParameterization::To(h, H); + if ((L * h).isApprox(b, expected_precision)) { + return true; + } else { + return false; + } +} + +/** 2D Homography transformation estimation in the case that points are in + * homogeneous coordinates. + * + * | 0 -x3 x2| |a b c| |y1| -x3*d+x2*g -x3*e+x2*h -x3*f+x2*1 |y1| (-x3*d+x2*g)*y1 (-x3*e+x2*h)*y2 (-x3*f+x2*1)*y3 |0| + * | x3 0 -x1| * |d e f| * |y2| = x3*a-x1*g x3*b-x1*h x3*c-x1*1 * |y2| = (x3*a-x1*g)*y1 (x3*b-x1*h)*y2 (x3*c-x1*1)*y3 = |0| + * |-x2 x1 0| |g h 1| |y3| -x2*a+x1*d -x2*b+x1*e -x2*c+x1*f |y3| (-x2*a+x1*d)*y1 (-x2*b+x1*e)*y2 (-x2*c+x1*f)*y3 |0| + * X = |a b c d e f g h|^t + */ +bool Homography2DFromCorrespondencesLinear(const Mat &x1, + const Mat &x2, + Mat3 *H, + double expected_precision) { + if (x1.rows() == 2) { + return Homography2DFromCorrespondencesLinearEuc(x1, x2, H, + expected_precision); + } + assert(3 == x1.rows()); + assert(4 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + const int x = 0; + const int y = 1; + const int w = 2; + int n = x1.cols(); + MatX8 L = Mat::Zero(n * 3, 8); + Mat b = Mat::Zero(n * 3, 1); + for (int i = 0; i < n; ++i) { + int j = 3 * i; + L(j, 0) = x2(w, i) * x1(x, i); // a + L(j, 1) = x2(w, i) * x1(y, i); // b + L(j, 2) = x2(w, i) * x1(w, i); // c + L(j, 6) = -x2(x, i) * x1(x, i); // g + L(j, 7) = -x2(x, i) * x1(y, i); // h + b(j, 0) = x2(x, i) * x1(w, i); + + ++j; + L(j, 3) = x2(w, i) * x1(x, i); // d + L(j, 4) = x2(w, i) * x1(y, i); // e + L(j, 5) = x2(w, i) * x1(w, i); // f + L(j, 6) = -x2(y, i) * x1(x, i); // g + L(j, 7) = -x2(y, i) * x1(y, i); // h + b(j, 0) = x2(y, i) * x1(w, i); + + // This ensures better stability + ++j; + L(j, 0) = x2(y, i) * x1(x, i); // a + L(j, 1) = x2(y, i) * x1(y, i); // b + L(j, 2) = x2(y, i) * x1(w, i); // c + L(j, 3) = -x2(x, i) * x1(x, i); // d + L(j, 4) = -x2(x, i) * x1(y, i); // e + L(j, 5) = -x2(x, i) * x1(w, i); // f + } + // Solve Lx=B + Vec h = L.fullPivLu().solve(b); + if ((L * h).isApprox(b, expected_precision)) { + Homography2DNormalizedParameterization::To(h, H); + return true; + } else { + return false; + } +} + +// Default settings for homography estimation which should be suitable +// for a wide range of use cases. +EstimateHomographyOptions::EstimateHomographyOptions(void) : + use_normalization(true), + max_num_iterations(50), + expected_average_symmetric_distance(1e-16) { +} + +namespace { +void GetNormalizedPoints(const Mat &original_points, + Mat *normalized_points, + Mat3 *normalization_matrix) { + IsotropicPreconditionerFromPoints(original_points, normalization_matrix); + ApplyTransformationToPoints(original_points, + *normalization_matrix, + normalized_points); +} + +// Cost functor which computes symmetric geometric distance +// used for homography matrix refinement. +class HomographySymmetricGeometricCostFunctor { + public: + HomographySymmetricGeometricCostFunctor(const Vec2 &x, + const Vec2 &y) { + xx_ = x(0); + xy_ = x(1); + yx_ = y(0); + yy_ = y(1); + } + + template + bool operator()(const T *homography_parameters, T *residuals) const { + typedef Eigen::Matrix Mat3; + typedef Eigen::Matrix Vec3; + + Mat3 H(homography_parameters); + + Vec3 x(T(xx_), T(xy_), T(1.0)); + Vec3 y(T(yx_), T(yy_), T(1.0)); + + Vec3 H_x = H * x; + Vec3 Hinv_y = H.inverse() * y; + + H_x /= H_x(2); + Hinv_y /= Hinv_y(2); + + // This is a forward error. + residuals[0] = H_x(0) - T(yx_); + residuals[1] = H_x(1) - T(yy_); + + // This is a backward error. + residuals[2] = Hinv_y(0) - T(xx_); + residuals[3] = Hinv_y(1) - T(xy_); + + return true; + } + + // TODO(sergey): Think of better naming. + double xx_, xy_; + double yx_, yy_; +}; + +#if CERES_FOUND +// Termination checking callback used for homography estimation. +// It finished the minimization as soon as actual average of +// symmetric geometric distance is less or equal to the expected +// average value. +class TerminationCheckingCallback : public ceres::IterationCallback { + public: + TerminationCheckingCallback(const Mat &x1, const Mat &x2, + const EstimateHomographyOptions &options, + Mat3 *H) + : options_(options), x1_(x1), x2_(x2), H_(H) {} + + virtual ceres::CallbackReturnType operator()( + const ceres::IterationSummary& summary) { + // If the step wasn't successful, there's nothing to do. + if (!summary.step_is_successful) { + return ceres::SOLVER_CONTINUE; + } + + // Calculate average of symmetric geometric distance. + double average_distance = 0.0; + for (int i = 0; i < x1_.cols(); i++) { + average_distance = SymmetricGeometricDistance(*H_, + x1_.col(i), + x2_.col(i)); + } + average_distance /= x1_.cols(); + + if (average_distance <= options_.expected_average_symmetric_distance) { + return ceres::SOLVER_TERMINATE_SUCCESSFULLY; + } + + return ceres::SOLVER_CONTINUE; + } + + private: + const EstimateHomographyOptions &options_; + const Mat &x1_; + const Mat &x2_; + Mat3 *H_; +}; +#endif // CERES_FOUND +} // namespace + +/** 2D Homography transformation estimation in the case that points are in + * euclidean coordinates. + */ +bool EstimateHomography2DFromCorrespondences( + const Mat &x1, + const Mat &x2, + const EstimateHomographyOptions &options, + Mat3 *H) { + // TODO(sergey): Support homogenous coordinates, not just euclidean. + + assert(2 == x1.rows()); + assert(4 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + Mat3 T1 = Mat3::Identity(), + T2 = Mat3::Identity(); + + // Step 1: Algebraic homography estimation. + Mat x1_normalized, x2_normalized; + + if (options.use_normalization) { + LG << "Estimating homography using normalization."; + GetNormalizedPoints(x1, &x1_normalized, &T1); + GetNormalizedPoints(x2, &x2_normalized, &T2); + } else { + x1_normalized = x1; + x2_normalized = x2; + } + + // Assume algebraic estiation always suceeds, + Homography2DFromCorrespondencesLinear(x1_normalized, x2_normalized, H); + + // Denormalize the homography matrix. + if (options.use_normalization) { + *H = T2.inverse() * (*H) * T1; + } + + LG << "Estimated matrix after algebraic estimation:\n" << *H; + +#if CERES_FOUND + // Step 2: Refine matrix using Ceres minimizer. + ceres::Problem problem; + for (int i = 0; i < x1.cols(); i++) { + HomographySymmetricGeometricCostFunctor + *homography_symmetric_geometric_cost_function = + new HomographySymmetricGeometricCostFunctor(x1.col(i), + x2.col(i)); + + problem.AddResidualBlock( + new ceres::AutoDiffCostFunction< + HomographySymmetricGeometricCostFunctor, + 4, // num_residuals + 9>(homography_symmetric_geometric_cost_function), + NULL, + H->data()); + } + + // Configure the solve. + ceres::Solver::Options solver_options; + solver_options.linear_solver_type = ceres::DENSE_QR; + solver_options.max_num_iterations = options.max_num_iterations; + solver_options.update_state_every_iteration = true; + + // Terminate if the average symmetric distance is good enough. + TerminationCheckingCallback callback(x1, x2, options, H); + solver_options.callbacks.push_back(&callback); + + // Run the solve. + ceres::Solver::Summary summary; + ceres::Solve(solver_options, &problem, &summary); + + VLOG(1) << "Summary:\n" << summary.FullReport(); + + LG << "Final refined matrix:\n" << *H; + + return summary.IsSolutionUsable(); +#endif // CERES_FOUND + return true; +} + +/** + * x2 ~ A * x1 + * x2^t * Hi * A *x1 = 0 + * H1 = H2 = H3 = + * | 0 0 0 1| |-x2w| |0 0 0 0| | 0 | | 0 0 1 0| |-x2z| + * | 0 0 0 0| -> | 0 | |0 0 1 0| -> |-x2z| | 0 0 0 0| -> | 0 | + * | 0 0 0 0| | 0 | |0-1 0 0| | x2y| |-1 0 0 0| | x2x| + * |-1 0 0 0| | x2x| |0 0 0 0| | 0 | | 0 0 0 0| | 0 | + * H4 = H5 = H6 = + * |0 0 0 0| | 0 | | 0 1 0 0| |-x2y| |0 0 0 0| | 0 | + * |0 0 0 1| -> |-x2w| |-1 0 0 0| -> | x2x| |0 0 0 0| -> | 0 | + * |0 0 0 0| | 0 | | 0 0 0 0| | 0 | |0 0 0 1| |-x2w| + * |0-1 0 0| | x2y| | 0 0 0 0| | 0 | |0 0-1 0| | x2z| + * |a b c d| + * A = |e f g h| + * |i j k l| + * |m n o 1| + * + * x2^t * H1 * A *x1 = (-x2w*a +x2x*m )*x1x + (-x2w*b +x2x*n )*x1y + (-x2w*c +x2x*o )*x1z + (-x2w*d +x2x*1 )*x1w = 0 + * x2^t * H2 * A *x1 = (-x2z*e +x2y*i )*x1x + (-x2z*f +x2y*j )*x1y + (-x2z*g +x2y*k )*x1z + (-x2z*h +x2y*l )*x1w = 0 + * x2^t * H3 * A *x1 = (-x2z*a +x2x*i )*x1x + (-x2z*b +x2x*j )*x1y + (-x2z*c +x2x*k )*x1z + (-x2z*d +x2x*l )*x1w = 0 + * x2^t * H4 * A *x1 = (-x2w*e +x2y*m )*x1x + (-x2w*f +x2y*n )*x1y + (-x2w*g +x2y*o )*x1z + (-x2w*h +x2y*1 )*x1w = 0 + * x2^t * H5 * A *x1 = (-x2y*a +x2x*e )*x1x + (-x2y*b +x2x*f )*x1y + (-x2y*c +x2x*g )*x1z + (-x2y*d +x2x*h )*x1w = 0 + * x2^t * H6 * A *x1 = (-x2w*i +x2z*m )*x1x + (-x2w*j +x2z*n )*x1y + (-x2w*k +x2z*o )*x1z + (-x2w*l +x2z*1 )*x1w = 0 + * + * X = |a b c d e f g h i j k l m n o|^t +*/ +bool Homography3DFromCorrespondencesLinear(const Mat &x1, + const Mat &x2, + Mat4 *H, + double expected_precision) { + assert(4 == x1.rows()); + assert(5 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + const int x = 0; + const int y = 1; + const int z = 2; + const int w = 3; + int n = x1.cols(); + MatX15 L = Mat::Zero(n * 6, 15); + Mat b = Mat::Zero(n * 6, 1); + for (int i = 0; i < n; ++i) { + int j = 6 * i; + L(j, 0) = -x2(w, i) * x1(x, i); // a + L(j, 1) = -x2(w, i) * x1(y, i); // b + L(j, 2) = -x2(w, i) * x1(z, i); // c + L(j, 3) = -x2(w, i) * x1(w, i); // d + L(j, 12) = x2(x, i) * x1(x, i); // m + L(j, 13) = x2(x, i) * x1(y, i); // n + L(j, 14) = x2(x, i) * x1(z, i); // o + b(j, 0) = -x2(x, i) * x1(w, i); + + ++j; + L(j, 4) = -x2(z, i) * x1(x, i); // e + L(j, 5) = -x2(z, i) * x1(y, i); // f + L(j, 6) = -x2(z, i) * x1(z, i); // g + L(j, 7) = -x2(z, i) * x1(w, i); // h + L(j, 8) = x2(y, i) * x1(x, i); // i + L(j, 9) = x2(y, i) * x1(y, i); // j + L(j, 10) = x2(y, i) * x1(z, i); // k + L(j, 11) = x2(y, i) * x1(w, i); // l + + ++j; + L(j, 0) = -x2(z, i) * x1(x, i); // a + L(j, 1) = -x2(z, i) * x1(y, i); // b + L(j, 2) = -x2(z, i) * x1(z, i); // c + L(j, 3) = -x2(z, i) * x1(w, i); // d + L(j, 8) = x2(x, i) * x1(x, i); // i + L(j, 9) = x2(x, i) * x1(y, i); // j + L(j, 10) = x2(x, i) * x1(z, i); // k + L(j, 11) = x2(x, i) * x1(w, i); // l + + ++j; + L(j, 4) = -x2(w, i) * x1(x, i); // e + L(j, 5) = -x2(w, i) * x1(y, i); // f + L(j, 6) = -x2(w, i) * x1(z, i); // g + L(j, 7) = -x2(w, i) * x1(w, i); // h + L(j, 12) = x2(y, i) * x1(x, i); // m + L(j, 13) = x2(y, i) * x1(y, i); // n + L(j, 14) = x2(y, i) * x1(z, i); // o + b(j, 0) = -x2(y, i) * x1(w, i); + + ++j; + L(j, 0) = -x2(y, i) * x1(x, i); // a + L(j, 1) = -x2(y, i) * x1(y, i); // b + L(j, 2) = -x2(y, i) * x1(z, i); // c + L(j, 3) = -x2(y, i) * x1(w, i); // d + L(j, 4) = x2(x, i) * x1(x, i); // e + L(j, 5) = x2(x, i) * x1(y, i); // f + L(j, 6) = x2(x, i) * x1(z, i); // g + L(j, 7) = x2(x, i) * x1(w, i); // h + + ++j; + L(j, 8) = -x2(w, i) * x1(x, i); // i + L(j, 9) = -x2(w, i) * x1(y, i); // j + L(j, 10) = -x2(w, i) * x1(z, i); // k + L(j, 11) = -x2(w, i) * x1(w, i); // l + L(j, 12) = x2(z, i) * x1(x, i); // m + L(j, 13) = x2(z, i) * x1(y, i); // n + L(j, 14) = x2(z, i) * x1(z, i); // o + b(j, 0) = -x2(z, i) * x1(w, i); + } + // Solve Lx=B + Vec h = L.fullPivLu().solve(b); + if ((L * h).isApprox(b, expected_precision)) { + Homography3DNormalizedParameterization::To(h, H); + return true; + } else { + return false; + } +} + +double SymmetricGeometricDistance(const Mat3 &H, + const Vec2 &x1, + const Vec2 &x2) { + Vec3 x(x1(0), x1(1), 1.0); + Vec3 y(x2(0), x2(1), 1.0); + + Vec3 H_x = H * x; + Vec3 Hinv_y = H.inverse() * y; + + H_x /= H_x(2); + Hinv_y /= Hinv_y(2); + + return (H_x.head<2>() - y.head<2>()).squaredNorm() + + (Hinv_y.head<2>() - x.head<2>()).squaredNorm(); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/homography.h b/modules/sfm/src/libmv_light/libmv/multiview/homography.h new file mode 100644 index 0000000000..7d64b086dd --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/homography.h @@ -0,0 +1,145 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_HOMOGRAPHY_H_ +#define LIBMV_MULTIVIEW_HOMOGRAPHY_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +/** + * 2D homography transformation estimation. + * + * This function estimates the homography transformation from a list of 2D + * correspondences which represents either: + * + * - 3D points on a plane, with a general moving camera. + * - 3D points with a rotating camera (pure rotation). + * - 3D points + different planar projections + * + * \param x1 The first 2xN or 3xN matrix of euclidean or homogeneous points. + * \param x2 The second 2xN or 3xN matrix of euclidean or homogeneous points. + * \param H The 3x3 homography transformation matrix (8 dof) such that + * x2 = H * x1 with |a b c| + * H = |d e f| + * |g h 1| + * \param expected_precision The expected precision in order for instance + * to accept almost homography matrices. + * + * \return True if the transformation estimation has succeeded. + * \note There must be at least 4 non-colinear points. + */ +bool Homography2DFromCorrespondencesLinear(const Mat &x1, + const Mat &x2, + Mat3 *H, + double expected_precision = + EigenDouble::dummy_precision()); + +/** + * This structure contains options that controls how the homography + * estimation operates. + * + * Defaults should be suitable for a wide range of use cases, but + * better performance and accuracy might require tweaking/ + */ +struct EstimateHomographyOptions { + // Default constructor which sets up a options for generic usage. + EstimateHomographyOptions(void); + + // Normalize correspondencies before estimating the homography + // in order to increase estimation stability. + // + // Normaliztion will make it so centroid od correspondences + // is the coordinate origin and their average distance from + // the origin is sqrt(2). + // + // See: + // - R. Hartley and A. Zisserman. Multiple View Geometry in Computer + // Vision. Cambridge University Press, second edition, 2003. + // - https://www.cs.ubc.ca/grads/resources/thesis/May09/Dubrofsky_Elan.pdf + bool use_normalization; + + // Maximal number of iterations for the refinement step. + int max_num_iterations; + + // Expected average of symmetric geometric distance between + // actual destination points and original ones transformed by + // estimated homography matrix. + // + // Refinement will finish as soon as average of symmetric + // geometric distance is less or equal to this value. + // + // This distance is measured in the same units as input points are. + double expected_average_symmetric_distance; +}; + +/** + * 2D homography transformation estimation. + * + * This function estimates the homography transformation from a list of 2D + * correspondences by doing algebraic estimation first followed with result + * refinement. + */ +bool EstimateHomography2DFromCorrespondences( + const Mat &x1, + const Mat &x2, + const EstimateHomographyOptions &options, + Mat3 *H); + +/** + * 3D Homography transformation estimation. + * + * This function can be used in order to estimate the homography transformation + * from a list of 3D correspondences. + * + * \param[in] x1 The first 4xN matrix of homogeneous points + * \param[in] x2 The second 4xN matrix of homogeneous points + * \param[out] H The 4x4 homography transformation matrix (15 dof) such that + * x2 = H * x1 with |a b c d| + * H = |e f g h| + * |i j k l| + * |m n o 1| + * \param[in] expected_precision The expected precision in order for instance + * to accept almost homography matrices. + * + * \return true if the transformation estimation has succeeded + * + * \note Need at least 5 non coplanar points + * \note Points coordinates must be in homogeneous coordinates + */ +bool Homography3DFromCorrespondencesLinear(const Mat &x1, + const Mat &x2, + Mat4 *H, + double expected_precision = + EigenDouble::dummy_precision()); + +/** + * Calculate symmetric geometric cost: + * + * D(H * x1, x2)^2 + D(H^-1 * x2, x1) + */ +double SymmetricGeometricDistance(const Mat3 &H, + const Vec2 &x1, + const Vec2 &x2); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_HOMOGRAPHY_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/homography_error.h b/modules/sfm/src/libmv_light/libmv/multiview/homography_error.h new file mode 100644 index 0000000000..0bcf5b70c9 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/homography_error.h @@ -0,0 +1,248 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_HOMOGRAPHY_ERRORS_H_ +#define LIBMV_MULTIVIEW_HOMOGRAPHY_ERRORS_H_ + +#include "libmv/multiview/projection.h" + +namespace libmv { +namespace homography { +namespace homography2D { + + /** + * Structure for estimating the asymmetric error between a vector x2 and the + * transformed x1 such that + * Error = ||x2 - Psi(H * x1)||^2 + * where Psi is the function that transforms homogeneous to euclidean coords. + * \note It should be distributed as Chi-squared with k = 2. + */ +struct AsymmetricError { + /** + * Computes the asymmetric residuals between a set of 2D points x2 and the + * transformed 2D point set x1 such that + * Residuals_i = x2_i - Psi(H * x1_i) + * where Psi is the function that transforms homogeneous to euclidean coords. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A set of 2D points (2xN or 3xN matrix of column vectors). + * \param[in] x2 A set of 2D points (2xN or 3xN matrix of column vectors). + * \param[out] dx A 2xN matrix of column vectors of residuals errors + */ + static void Residuals(const Mat &H, const Mat &x1, + const Mat &x2, Mat2X *dx) { + dx->resize(2, x1.cols()); + Mat3X x2h_est; + if (x1.rows() == 2) + x2h_est = H * EuclideanToHomogeneous(static_cast(x1)); + else + x2h_est = H * x1; + dx->row(0) = x2h_est.row(0).array() / x2h_est.row(2).array(); + dx->row(1) = x2h_est.row(1).array() / x2h_est.row(2).array(); + if (x2.rows() == 2) + *dx = x2 - *dx; + else + *dx = HomogeneousToEuclidean(static_cast(x2)) - *dx; + } + /** + * Computes the asymmetric residuals between a 2D point x2 and the transformed + * 2D point x1 such that + * Residuals = x2 - Psi(H * x1) + * where Psi is the function that transforms homogeneous to euclidean coords. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \param[in] x2 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \param[out] dx A vector of size 2 of the residual error + */ + static void Residuals(const Mat &H, const Vec &x1, + const Vec &x2, Vec2 *dx) { + Vec3 x2h_est; + if (x1.rows() == 2) + x2h_est = H * EuclideanToHomogeneous(static_cast(x1)); + else + x2h_est = H * x1; + if (x2.rows() == 2) + *dx = x2 - x2h_est.head<2>() / x2h_est[2]; + else + *dx = HomogeneousToEuclidean(static_cast(x2)) - + x2h_est.head<2>() / x2h_est[2]; + } + /** + * Computes the squared norm of the residuals between a set of 2D points x2 + * and the transformed 2D point set x1 such that + * Error = || x2 - Psi(H * x1) ||^2 + * where Psi is the function that transforms homogeneous to euclidean coords. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A set of 2D points (2xN or 3xN matrix of column vectors). + * \param[in] x2 A set of 2D points (2xN or 3xN matrix of column vectors). + * \return The squared norm of the asymmetric residuals errors + */ + static double Error(const Mat &H, const Mat &x1, const Mat &x2) { + Mat2X dx; + Residuals(H, x1, x2, &dx); + return dx.squaredNorm(); + } + /** + * Computes the squared norm of the residuals between a 2D point x2 and the + * transformed 2D point x1 such that rms = || x2 - Psi(H * x1) ||^2 + * where Psi is the function that transforms homogeneous to euclidean coords. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \param[in] x2 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \return The squared norm of the asymmetric residual error + */ + static double Error(const Mat &H, const Vec &x1, const Vec &x2) { + Vec2 dx; + Residuals(H, x1, x2, &dx); + return dx.squaredNorm(); + } +}; + + /** + * Structure for estimating the symmetric error + * between a vector x2 and the transformed x1 such that + * Error = ||x2 - Psi(H * x1)||^2 + ||x1 - Psi(H^-1 * x2)||^2 + * where Psi is the function that transforms homogeneous to euclidean coords. + * \note It should be distributed as Chi-squared with k = 4. + */ +struct SymmetricError { + /** + * Computes the squared norm of the residuals between x2 and the + * transformed x1 such that + * Error = ||x2 - Psi(H * x1)||^2 + ||x1 - Psi(H^-1 * x2)||^2 + * where Psi is the function that transforms homogeneous to euclidean coords. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \param[in] x2 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \return The squared norm of the symmetric residuals errors + */ + static double Error(const Mat &H, const Vec &x1, const Vec &x2) { + // TODO(keir): This is awesomely inefficient because it does a 3x3 + // inversion for each evaluation. + Mat3 Hinv = H.inverse(); + return AsymmetricError::Error(H, x1, x2) + + AsymmetricError::Error(Hinv, x2, x1); + } + // TODO(julien) Add residuals function \see AsymmetricError +}; + /** + * Structure for estimating the algebraic error (cross product) + * between a vector x2 and the transformed x1 such that + * Error = ||[x2] * H * x1||^^2 + * where [x2] is the skew matrix of x2. + */ +struct AlgebraicError { + // TODO(julien) Make an AlgebraicError2Rows and AlgebraicError3Rows + + /** + * Computes the algebraic residuals (cross product) between a set of 2D + * points x2 and the transformed 2D point set x1 such that + * [x2] * H * x1 where [x2] is the skew matrix of x2. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A set of 2D points (2xN or 3xN matrix of column vectors). + * \param[in] x2 A set of 2D points (2xN or 3xN matrix of column vectors). + * \param[out] dx A 3xN matrix of column vectors of residuals errors + */ + static void Residuals(const Mat &H, const Mat &x1, + const Mat &x2, Mat3X *dx) { + dx->resize(3, x1.cols()); + Vec3 col; + for (int i = 0; i < x1.cols(); ++i) { + Residuals(H, x1.col(i), x2.col(i), &col); + dx->col(i) = col; + } + } + /** + * Computes the algebraic residuals (cross product) between a 2D point x2 + * and the transformed 2D point x1 such that + * [x2] * H * x1 where [x2] is the skew matrix of x2. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \param[in] x2 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \param[out] dx A vector of size 3 of the residual error + */ + static void Residuals(const Mat &H, const Vec &x1, + const Vec &x2, Vec3 *dx) { + Vec3 x2h_est; + if (x1.rows() == 2) + x2h_est = H * EuclideanToHomogeneous(static_cast(x1)); + else + x2h_est = H * x1; + if (x2.rows() == 2) + *dx = SkewMat(EuclideanToHomogeneous(static_cast(x2))) * x2h_est; + else + *dx = SkewMat(x2) * x2h_est; + // TODO(julien) This is inefficient since it creates an + // identical 3x3 skew matrix for each evaluation. + } + /** + * Computes the squared norm of the algebraic residuals between a set of 2D + * points x2 and the transformed 2D point set x1 such that + * [x2] * H * x1 where [x2] is the skew matrix of x2. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A set of 2D points (2xN or 3xN matrix of column vectors). + * \param[in] x2 A set of 2D points (2xN or 3xN matrix of column vectors). + * \return The squared norm of the asymmetric residuals errors + */ + static double Error(const Mat &H, const Mat &x1, const Mat &x2) { + Mat3X dx; + Residuals(H, x1, x2, &dx); + return dx.squaredNorm(); + } + /** + * Computes the squared norm of the algebraic residuals between a 2D point x2 + * and the transformed 2D point x1 such that + * [x2] * H * x1 where [x2] is the skew matrix of x2. + * + * \param[in] H The 3x3 homography matrix. + * The estimated homography should approximatelly hold the condition y = H x. + * \param[in] x1 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \param[in] x2 A 2D point (vector of size 2 or 3 (euclidean/homogeneous)) + * \return The squared norm of the asymmetric residual error + */ + static double Error(const Mat &H, const Vec &x1, const Vec &x2) { + Vec3 dx; + Residuals(H, x1, x2, &dx); + return dx.squaredNorm(); + } +}; +// TODO(keir): Add error based on ideal points. + +} // namespace homography2D +// TODO(julien) add homography3D errors +} // namespace homography +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_HOMOGRAPHY_ERRORS_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/homography_parameterization.h b/modules/sfm/src/libmv_light/libmv/multiview/homography_parameterization.h new file mode 100644 index 0000000000..5a42a20b06 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/homography_parameterization.h @@ -0,0 +1,91 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_ +#define LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +/** A parameterization of the 2D homography matrix that uses 8 parameters so + * that the matrix is normalized (H(2,2) == 1). + * The homography matrix H is built from a list of 8 parameters (a, b,...g, h) + * as follows + * |a b c| + * H = |d e f| + * |g h 1| + */ +template +class Homography2DNormalizedParameterization { + public: + typedef Eigen::Matrix Parameters; // a, b, ... g, h + typedef Eigen::Matrix Parameterized; // H + + /// Convert from the 8 parameters to a H matrix. + static void To(const Parameters &p, Parameterized *h) { + *h << p(0), p(1), p(2), + p(3), p(4), p(5), + p(6), p(7), 1.0; + } + + /// Convert from a H matrix to the 8 parameters. + static void From(const Parameterized &h, Parameters *p) { + *p << h(0, 0), h(0, 1), h(0, 2), + h(1, 0), h(1, 1), h(1, 2), + h(2, 0), h(2, 1); + } +}; + +/** A parameterization of the 2D homography matrix that uses 15 parameters so + * that the matrix is normalized (H(3,3) == 1). + * The homography matrix H is built from a list of 15 parameters (a, b,...n, o) + * as follows + * |a b c d| + * H = |e f g h| + * |i j k l| + * |m n o 1| + */ +template +class Homography3DNormalizedParameterization { + public: + typedef Eigen::Matrix Parameters; // a, b, ... n, o + typedef Eigen::Matrix Parameterized; // H + + /// Convert from the 15 parameters to a H matrix. + static void To(const Parameters &p, Parameterized *h) { + *h << p(0), p(1), p(2), p(3), + p(4), p(5), p(6), p(7), + p(8), p(9), p(10), p(11), + p(12), p(13), p(14), 1.0; + } + + /// Convert from a H matrix to the 15 parameters. + static void From(const Parameterized &h, Parameters *p) { + *p << h(0, 0), h(0, 1), h(0, 2), h(0, 3), + h(1, 0), h(1, 1), h(1, 2), h(1, 3), + h(2, 0), h(2, 1), h(2, 2), h(2, 3), + h(3, 0), h(3, 1), h(3, 2); + } +}; + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/nviewtriangulation.h b/modules/sfm/src/libmv_light/libmv/multiview/nviewtriangulation.h new file mode 100644 index 0000000000..f4614ab1a5 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/nviewtriangulation.h @@ -0,0 +1,80 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Compute a 3D position of a point from several images of it. In particular, +// compute the projective point X in R^4 such that x = PX. +// +// Algorithm is the standard DLT; for derivation see appendix of Keir's thesis. + +#ifndef LIBMV_MULTIVIEW_NVIEWTRIANGULATION_H +#define LIBMV_MULTIVIEW_NVIEWTRIANGULATION_H + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +// x's are 2D coordinates (x,y,1) in each image; Ps are projective cameras. The +// output, X, is a homogeneous four vectors. +template +void NViewTriangulate(const Matrix &x, + const vector > &Ps, + Matrix *X) { + int nviews = x.cols(); + assert(nviews == Ps.size()); + + Matrix design(3*nviews, 4 + nviews); + design.setConstant(0.0); + for (int i = 0; i < nviews; i++) { + design.template block<3, 4>(3*i, 0) = -Ps[i]; + design(3*i + 0, 4 + i) = x(0, i); + design(3*i + 1, 4 + i) = x(1, i); + design(3*i + 2, 4 + i) = 1.0; + } + Matrix X_and_alphas; + Nullspace(&design, &X_and_alphas); + X->resize(4); + *X = X_and_alphas.head(4); +} + +// x's are 2D coordinates (x,y,1) in each image; Ps are projective cameras. The +// output, X, is a homogeneous four vectors. +// This method uses the algebraic distance approximation. +// Note that this method works better when the 2D points are normalized +// with an isotopic normalization. +template +void NViewTriangulateAlgebraic(const Matrix &x, + const vector > &Ps, + Matrix *X) { + int nviews = x.cols(); + assert(nviews == Ps.size()); + + Matrix design(2*nviews, 4); + for (int i = 0; i < nviews; i++) { + design.template block<2, 4>(2*i, 0) = SkewMatMinimal(x.col(i)) * Ps[i]; + } + X->resize(4); + Nullspace(&design, X); +} + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_RESECTION_H diff --git a/modules/sfm/src/libmv_light/libmv/multiview/panography.cc b/modules/sfm/src/libmv_light/libmv/multiview/panography.cc new file mode 100644 index 0000000000..b62802948c --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/panography.cc @@ -0,0 +1,125 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#include "libmv/multiview/panography.h" + +namespace libmv { + +static bool Build_Minimal2Point_PolynomialFactor( + const Mat & x1, const Mat & x2, + double * P) { // P must be a double[4] + assert(2 == x1.rows()); + assert(2 == x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + // Setup the variable of the input problem: + Vec xx1 = (x1.col(0)).transpose(); + Vec yx1 = (x1.col(1)).transpose(); + + double a12 = xx1.dot(yx1); + Vec xx2 = (x2.col(0)).transpose(); + Vec yx2 = (x2.col(1)).transpose(); + double b12 = xx2.dot(yx2); + + double a1 = xx1.squaredNorm(); + double a2 = yx1.squaredNorm(); + + double b1 = xx2.squaredNorm(); + double b2 = yx2.squaredNorm(); + + // Build the 3rd degre polynomial in F^2. + // + // f^6 * p + f^4 * q + f^2* r + s = 0; + // + // Coefficients in ascending powers of alpha, i.e. P[N]*x^N. + // Run panography_coeffs.py to get the below coefficients. + P[0] = b1*b2*a12*a12-a1*a2*b12*b12; + P[1] = -2*a1*a2*b12+2*a12*b1*b2+b1*a12*a12+b2*a12*a12-a1*b12*b12-a2*b12*b12; + P[2] = b1*b2-a1*a2-2*a1*b12-2*a2*b12+2*a12*b1+2*a12*b2+a12*a12-b12*b12; + P[3] = b1+b2-2*b12-a1-a2+2*a12; + + // If P[3] equal to 0 we get ill conditionned data + return (P[3] != 0.0); +} + +// This implements a minimal solution (2 points) for panoramic stitching: +// +// http://www.cs.ubc.ca/~mbrown/minimal/minimal.html +// +// [1] M. Brown and R. Hartley and D. Nister. Minimal Solutions for Panoramic +// Stitching. CVPR07. +void F_FromCorrespondance_2points(const Mat &x1, const Mat &x2, + vector *fs) { + // Build Polynomial factor to get squared focal value. + double P[4]; + Build_Minimal2Point_PolynomialFactor(x1, x2, &P[0]); + + // Solve it by using F = f^2 and a Cubic polynomial solver + // + // F^3 * p + F^2 * q + F^1 * r + s = 0 + // + double roots[3]; + int num_roots = SolveCubicPolynomial(P, roots); + for (int i = 0; i < num_roots; ++i) { + if (roots[i] > 0.0) { + fs->push_back(sqrt(roots[i])); + } + } +} + +// Compute the 3x3 rotation matrix that fits two 3D point clouds in the least +// square sense. The method is from: +// +// K. Arun,T. Huand and D. Blostein. Least-squares fitting of 2 3-D point +// sets. IEEE Transactions on Pattern Analysis and Machine Intelligence, +// 9:698-700, 1987. +void GetR_FixedCameraCenter(const Mat &x1, const Mat &x2, + const double focal, + Mat3 *R) { + assert(3 == x1.rows()); + assert(2 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + // Build simplified K matrix + Mat3 K(Mat3::Identity() * 1.0/focal); + K(2, 2)= 1.0; + + // Build the correlation matrix; equation (22) in [1]. + Mat3 C = Mat3::Zero(); + for (int i = 0; i < x1.cols(); ++i) { + Mat r1i = (K * x1.col(i)).normalized(); + Mat r2i = (K * x2.col(i)).normalized(); + C += r2i * r1i.transpose(); + } + + // Solve for rotation. Equations (24) and (25) in [1]. + Eigen::JacobiSVD svd(C, Eigen::ComputeThinU | Eigen::ComputeThinV); + Mat3 scale = Mat3::Identity(); + scale(2, 2) = ((svd.matrixU() * svd.matrixV().transpose()).determinant() > 0.0) + ? 1.0 + : -1.0; + + (*R) = svd.matrixU() * scale * svd.matrixV().transpose(); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/panography.h b/modules/sfm/src/libmv_light/libmv/multiview/panography.h new file mode 100644 index 0000000000..6e87bd7130 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/panography.h @@ -0,0 +1,99 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#ifndef LIBMV_MULTIVIEW_PANOGRAPHY_H +#define LIBMV_MULTIVIEW_PANOGRAPHY_H + +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/poly.h" +#include "libmv/base/vector.h" + +namespace libmv { + +// This implements a minimal solution (2 points) for panoramic stitching: +// +// http://www.cs.ubc.ca/~mbrown/minimal/minimal.html +// +// [1] M. Brown and R. Hartley and D. Nister. Minimal Solutions for Panoramic +// Stitching. CVPR07. +// +// The 2-point algorithm solves for the rotation of the camera with a single +// focal length (4 degrees of freedom). +// +// Compute from 1 to 3 possible focal lenght for 2 point correspondences. +// Suppose that the cameras share the same optical center and focal lengths: +// +// Image 1 => H*x = x' => Image 2 +// x (u1j) x' (u2j) +// a (u11) a' (u21) +// b (u12) b' (u22) +// +// The return values are 1 to 3 possible values for the focal lengths such +// that: +// +// [f 0 0] +// K = [0 f 0] +// [0 0 1] +// +void F_FromCorrespondance_2points(const Mat &x1, const Mat &x2, + vector *fs); + +// Compute the 3x3 rotation matrix that fits two 3D point clouds in the least +// square sense. The method is from: +// +// K. Arun,T. Huand and D. Blostein. Least-squares fitting of 2 3-D point +// sets. IEEE Transactions on Pattern Analysis and Machine Intelligence, +// 9:698-700, 1987. +// +// Given the calibration matrices K1, K2 solve for the rotation from +// corresponding image rays. +// +// R = min || X2 - R * x1 ||. +// +// In case of panography, which is for a camera that shares the same camera +// center, +// +// H = K2 * R * K1.inverse(); +// +// For the full explanation, see Section 8, Solving for Rotation from [1]. +// +// Parameters: +// +// x1 : Point cloud A (3D coords) +// x2 : Point cloud B (3D coords) +// +// [f 0 0] +// K1 = [0 f 0] +// [0 0 1] +// +// K2 (the same form as K1, but may have different f) +// +// Returns: A rotation matrix that minimizes +// +// R = arg min || X2 - R * x1 || +// +void GetR_FixedCameraCenter(const Mat &x1, const Mat &x2, + const double focal, + Mat3 *R); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_PANOGRAPHY_H diff --git a/modules/sfm/src/libmv_light/libmv/multiview/panography_kernel.cc b/modules/sfm/src/libmv_light/libmv/multiview/panography_kernel.cc new file mode 100644 index 0000000000..8fdc9e79ae --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/panography_kernel.cc @@ -0,0 +1,51 @@ +// Copyright (c) 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/panography_kernel.h" +#include "libmv/multiview/panography.h" + +namespace libmv { +namespace panography { +namespace kernel { + +void TwoPointSolver::Solve(const Mat &x1, const Mat &x2, vector *Hs) { + // Solve for the focal lengths. + vector fs; + F_FromCorrespondance_2points(x1, x2, &fs); + + // Then solve for the rotations and homographies. + Mat x1h, x2h; + EuclideanToHomogeneous(x1, &x1h); + EuclideanToHomogeneous(x2, &x2h); + for (int i = 0; i < fs.size(); ++i) { + Mat3 K1 = Mat3::Identity() * fs[i]; + K1(2, 2) = 1.0; + + Mat3 R; + GetR_FixedCameraCenter(x1h, x2h, fs[i], &R); + R /= R(2, 2); + + (*Hs).push_back(K1 * R * K1.inverse()); + } +} + +} // namespace kernel +} // namespace panography +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/panography_kernel.h b/modules/sfm/src/libmv_light/libmv/multiview/panography_kernel.h new file mode 100644 index 0000000000..a6adbd54b2 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/panography_kernel.h @@ -0,0 +1,54 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_PANOGRAPHY_KERNEL_H +#define LIBMV_MULTIVIEW_PANOGRAPHY_KERNEL_H + +#include "libmv/base/vector.h" +#include "libmv/multiview/conditioning.h" +#include "libmv/multiview/projection.h" +#include "libmv/multiview/two_view_kernel.h" +#include "libmv/multiview/homography_error.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { +namespace panography { +namespace kernel { + +struct TwoPointSolver { + enum { MINIMUM_SAMPLES = 2 }; + static void Solve(const Mat &x1, const Mat &x2, vector *Hs); +}; + +typedef two_view::kernel::Kernel< + TwoPointSolver, homography::homography2D::AsymmetricError, Mat3> + UnnormalizedKernel; + +typedef two_view::kernel::Kernel< + two_view::kernel::NormalizedSolver, + homography::homography2D::AsymmetricError, + Mat3> + Kernel; + +} // namespace kernel +} // namespace panography +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_PANOGRAPHY_KERNEL_H diff --git a/modules/sfm/src/libmv_light/libmv/multiview/projection.cc b/modules/sfm/src/libmv_light/libmv/multiview/projection.cc new file mode 100644 index 0000000000..f8bece3de6 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/projection.cc @@ -0,0 +1,224 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/projection.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +void P_From_KRt(const Mat3 &K, const Mat3 &R, const Vec3 &t, Mat34 *P) { + P->block<3, 3>(0, 0) = R; + P->col(3) = t; + (*P) = K * (*P); +} + +void KRt_From_P(const Mat34 &P, Mat3 *Kp, Mat3 *Rp, Vec3 *tp) { + // Decompose using the RQ decomposition HZ A4.1.1 pag.579. + Mat3 K = P.block(0, 0, 3, 3); + + Mat3 Q; + Q.setIdentity(); + + // Set K(2,1) to zero. + if (K(2, 1) != 0) { + double c = -K(2, 2); + double s = K(2, 1); + double l = sqrt(c * c + s * s); + c /= l; + s /= l; + Mat3 Qx; + Qx << 1, 0, 0, + 0, c, -s, + 0, s, c; + K = K * Qx; + Q = Qx.transpose() * Q; + } + // Set K(2,0) to zero. + if (K(2, 0) != 0) { + double c = K(2, 2); + double s = K(2, 0); + double l = sqrt(c * c + s * s); + c /= l; + s /= l; + Mat3 Qy; + Qy << c, 0, s, + 0, 1, 0, + -s, 0, c; + K = K * Qy; + Q = Qy.transpose() * Q; + } + // Set K(1,0) to zero. + if (K(1, 0) != 0) { + double c = -K(1, 1); + double s = K(1, 0); + double l = sqrt(c * c + s * s); + c /= l; + s /= l; + Mat3 Qz; + Qz << c, -s, 0, + s, c, 0, + 0, 0, 1; + K = K * Qz; + Q = Qz.transpose() * Q; + } + + Mat3 R = Q; + + // Ensure that the diagonal is positive. + // TODO(pau) Change this to ensure that: + // - K(0,0) > 0 + // - K(2,2) = 1 + // - det(R) = 1 + if (K(2, 2) < 0) { + K = -K; + R = -R; + } + if (K(1, 1) < 0) { + Mat3 S; + S << 1, 0, 0, + 0, -1, 0, + 0, 0, 1; + K = K * S; + R = S * R; + } + if (K(0, 0) < 0) { + Mat3 S; + S << -1, 0, 0, + 0, 1, 0, + 0, 0, 1; + K = K * S; + R = S * R; + } + + // Compute translation. + Vec p(3); + p << P(0, 3), P(1, 3), P(2, 3); + // TODO(pau) This sould be done by a SolveLinearSystem(A, b, &x) call. + // TODO(keir) use the eigen LU solver syntax... + Vec3 t = K.inverse() * p; + + // scale K so that K(2,2) = 1 + K = K / K(2, 2); + + *Kp = K; + *Rp = R; + *tp = t; +} + +void ProjectionShiftPrincipalPoint(const Mat34 &P, + const Vec2 &principal_point, + const Vec2 &principal_point_new, + Mat34 *P_new) { + Mat3 T; + T << 1, 0, principal_point_new(0) - principal_point(0), + 0, 1, principal_point_new(1) - principal_point(1), + 0, 0, 1; + *P_new = T * P; +} + +void ProjectionChangeAspectRatio(const Mat34 &P, + const Vec2 &principal_point, + double aspect_ratio, + double aspect_ratio_new, + Mat34 *P_new) { + Mat3 T; + T << 1, 0, 0, + 0, aspect_ratio_new / aspect_ratio, 0, + 0, 0, 1; + Mat34 P_temp; + + ProjectionShiftPrincipalPoint(P, principal_point, Vec2(0, 0), &P_temp); + P_temp = T * P_temp; + ProjectionShiftPrincipalPoint(P_temp, Vec2(0, 0), principal_point, P_new); +} + +void HomogeneousToEuclidean(const Mat &H, Mat *X) { + int d = H.rows() - 1; + int n = H.cols(); + X->resize(d, n); + for (size_t i = 0; i < n; ++i) { + double h = H(d, i); + for (int j = 0; j < d; ++j) { + (*X)(j, i) = H(j, i) / h; + } + } +} + +void HomogeneousToEuclidean(const Mat3X &h, Mat2X *e) { + e->resize(2, h.cols()); + e->row(0) = h.row(0).array() / h.row(2).array(); + e->row(1) = h.row(1).array() / h.row(2).array(); +} +void HomogeneousToEuclidean(const Mat4X &h, Mat3X *e) { + e->resize(3, h.cols()); + e->row(0) = h.row(0).array() / h.row(3).array(); + e->row(1) = h.row(1).array() / h.row(3).array(); + e->row(2) = h.row(2).array() / h.row(3).array(); +} + +void HomogeneousToEuclidean(const Vec3 &H, Vec2 *X) { + double w = H(2); + *X << H(0) / w, H(1) / w; +} + +void HomogeneousToEuclidean(const Vec4 &H, Vec3 *X) { + double w = H(3); + *X << H(0) / w, H(1) / w, H(2) / w; +} + +void EuclideanToHomogeneous(const Mat &X, Mat *H) { + int d = X.rows(); + int n = X.cols(); + H->resize(d + 1, n); + H->block(0, 0, d, n) = X; + H->row(d).setOnes(); +} + +void EuclideanToHomogeneous(const Vec2 &X, Vec3 *H) { + *H << X(0), X(1), 1; +} + +void EuclideanToHomogeneous(const Vec3 &X, Vec4 *H) { + *H << X(0), X(1), X(2), 1; +} + +// TODO(julien) Call conditioning.h/ApplyTransformationToPoints ? +void EuclideanToNormalizedCamera(const Mat2X &x, const Mat3 &K, Mat2X *n) { + Mat3X x_image_h; + EuclideanToHomogeneous(x, &x_image_h); + Mat3X x_camera_h = K.inverse() * x_image_h; + HomogeneousToEuclidean(x_camera_h, n); +} + +void HomogeneousToNormalizedCamera(const Mat3X &x, const Mat3 &K, Mat2X *n) { + Mat3X x_camera_h = K.inverse() * x; + HomogeneousToEuclidean(x_camera_h, n); +} + +double Depth(const Mat3 &R, const Vec3 &t, const Vec3 &X) { + return (R*X)(2) + t(2); +} + +double Depth(const Mat3 &R, const Vec3 &t, const Vec4 &X) { + Vec3 Xe = X.head<3>() / X(3); + return Depth(R, t, Xe); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/projection.h b/modules/sfm/src/libmv_light/libmv/multiview/projection.h new file mode 100644 index 0000000000..3220bc2dbb --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/projection.h @@ -0,0 +1,231 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_PROJECTION_H_ +#define LIBMV_MULTIVIEW_PROJECTION_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +void P_From_KRt(const Mat3 &K, const Mat3 &R, const Vec3 &t, Mat34 *P); +void KRt_From_P(const Mat34 &P, Mat3 *K, Mat3 *R, Vec3 *t); + +// Applies a change of basis to the image coordinates of the projection matrix +// so that the principal point becomes principal_point_new. +void ProjectionShiftPrincipalPoint(const Mat34 &P, + const Vec2 &principal_point, + const Vec2 &principal_point_new, + Mat34 *P_new); + +// Applies a change of basis to the image coordinates of the projection matrix +// so that the aspect ratio becomes aspect_ratio_new. This is done by +// stretching the y axis. The aspect ratio is defined as the quotient between +// the focal length of the y and the x axis. +void ProjectionChangeAspectRatio(const Mat34 &P, + const Vec2 &principal_point, + double aspect_ratio, + double aspect_ratio_new, + Mat34 *P_new); + +void HomogeneousToEuclidean(const Mat &H, Mat *X); +void HomogeneousToEuclidean(const Mat3X &h, Mat2X *e); +void HomogeneousToEuclidean(const Mat4X &h, Mat3X *e); +void HomogeneousToEuclidean(const Vec3 &H, Vec2 *X); +void HomogeneousToEuclidean(const Vec4 &H, Vec3 *X); +inline Vec2 HomogeneousToEuclidean(const Vec3 &h) { + return h.head<2>() / h(2); +} +inline Vec3 HomogeneousToEuclidean(const Vec4 &h) { + return h.head<3>() / h(3); +} +inline Mat2X HomogeneousToEuclidean(const Mat3X &h) { + Mat2X e(2, h.cols()); + e.row(0) = h.row(0).array() / h.row(2).array(); + e.row(1) = h.row(1).array() / h.row(2).array(); + return e; +} + +void EuclideanToHomogeneous(const Mat &X, Mat *H); +inline Mat3X EuclideanToHomogeneous(const Mat2X &x) { + Mat3X h(3, x.cols()); + h.block(0, 0, 2, x.cols()) = x; + h.row(2).setOnes(); + return h; +} +inline void EuclideanToHomogeneous(const Mat2X &x, Mat3X *h) { + h->resize(3, x.cols()); + h->block(0, 0, 2, x.cols()) = x; + h->row(2).setOnes(); +} +inline Mat4X EuclideanToHomogeneous(const Mat3X &x) { + Mat4X h(4, x.cols()); + h.block(0, 0, 3, x.cols()) = x; + h.row(3).setOnes(); + return h; +} +inline void EuclideanToHomogeneous(const Mat3X &x, Mat4X *h) { + h->resize(4, x.cols()); + h->block(0, 0, 3, x.cols()) = x; + h->row(3).setOnes(); +} +void EuclideanToHomogeneous(const Vec2 &X, Vec3 *H); +void EuclideanToHomogeneous(const Vec3 &X, Vec4 *H); +inline Vec3 EuclideanToHomogeneous(const Vec2 &x) { + return Vec3(x(0), x(1), 1); +} +inline Vec4 EuclideanToHomogeneous(const Vec3 &x) { + return Vec4(x(0), x(1), x(2), 1); +} +// Conversion from image coordinates to normalized camera coordinates +void EuclideanToNormalizedCamera(const Mat2X &x, const Mat3 &K, Mat2X *n); +void HomogeneousToNormalizedCamera(const Mat3X &x, const Mat3 &K, Mat2X *n); + +inline Vec2 Project(const Mat34 &P, const Vec3 &X) { + Vec4 HX; + HX << X, 1.0; + Vec3 hx = P * HX; + return hx.head<2>() / hx(2); +} + +inline void Project(const Mat34 &P, const Vec4 &X, Vec3 *x) { + *x = P * X; +} + +inline void Project(const Mat34 &P, const Vec4 &X, Vec2 *x) { + Vec3 hx = P * X; + *x = hx.head<2>() / hx(2); +} + +inline void Project(const Mat34 &P, const Vec3 &X, Vec3 *x) { + Vec4 HX; + HX << X, 1.0; + Project(P, HX, x); +} + +inline void Project(const Mat34 &P, const Vec3 &X, Vec2 *x) { + Vec3 hx; + Project(P, X, x); + *x = hx.head<2>() / hx(2); +} + +inline void Project(const Mat34 &P, const Mat4X &X, Mat2X *x) { + x->resize(2, X.cols()); + for (int c = 0; c < X.cols(); ++c) { + Vec3 hx = P * X.col(c); + x->col(c) = hx.head<2>() / hx(2); + } +} + +inline Mat2X Project(const Mat34 &P, const Mat4X &X) { + Mat2X x; + Project(P, X, &x); + return x; +} + +inline void Project(const Mat34 &P, const Mat3X &X, Mat2X *x) { + x->resize(2, X.cols()); + for (int c = 0; c < X.cols(); ++c) { + Vec4 HX; + HX << X.col(c), 1.0; + Vec3 hx = P * HX; + x->col(c) = hx.head<2>() / hx(2); + } +} + +inline void Project(const Mat34 &P, const Mat3X &X, const Vecu &ids, Mat2X *x) { + x->resize(2, ids.size()); + Vec4 HX; + Vec3 hx; + for (int c = 0; c < ids.size(); ++c) { + HX << X.col(ids[c]), 1.0; + hx = P * HX; + x->col(c) = hx.head<2>() / hx(2); + } +} + +inline Mat2X Project(const Mat34 &P, const Mat3X &X) { + Mat2X x(2, X.cols()); + Project(P, X, &x); + return x; +} + +inline Mat2X Project(const Mat34 &P, const Mat3X &X, const Vecu &ids) { + Mat2X x(2, ids.size()); + Project(P, X, ids, &x); + return x; +} + +double Depth(const Mat3 &R, const Vec3 &t, const Vec3 &X); +double Depth(const Mat3 &R, const Vec3 &t, const Vec4 &X); + +/** +* Returns true if the homogenious 3D point X is in front of +* the camera P. +*/ +inline bool isInFrontOfCamera(const Mat34 &P, const Vec4 &X) { + double condition_1 = P.row(2).dot(X) * X[3]; + double condition_2 = X[2] * X[3]; + if (condition_1 > 0 && condition_2 > 0) + return true; + else + return false; +} + +inline bool isInFrontOfCamera(const Mat34 &P, const Vec3 &X) { + Vec4 X_homo; + X_homo.segment<3>(0) = X; + X_homo(3) = 1; + return isInFrontOfCamera( P, X_homo); +} + +/** +* Transforms a 2D point from pixel image coordinates to a 2D point in +* normalized image coordinates. +*/ +inline Vec2 ImageToNormImageCoordinates(Mat3 &Kinverse, Vec2 &x) { + Vec3 x_h = Kinverse*EuclideanToHomogeneous(x); + return HomogeneousToEuclidean( x_h ); +} + +/// Estimates the root mean square error (2D) +inline double RootMeanSquareError(const Mat2X &x_image, + const Mat4X &X_world, + const Mat34 &P) { + size_t num_points = x_image.cols(); + Mat2X dx = Project(P, X_world) - x_image; + return dx.norm() / num_points; +} + +/// Estimates the root mean square error (2D) +inline double RootMeanSquareError(const Mat2X &x_image, + const Mat3X &X_world, + const Mat3 &K, + const Mat3 &R, + const Vec3 &t) { + Mat34 P; + P_From_KRt(K, R, t, &P); + size_t num_points = x_image.cols(); + Mat2X dx = Project(P, X_world) - x_image; + return dx.norm() / num_points; +} +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_PROJECTION_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/random_sample.h b/modules/sfm/src/libmv_light/libmv/multiview/random_sample.h new file mode 100644 index 0000000000..198173c57b --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/random_sample.h @@ -0,0 +1,63 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_RANDOM_SAMPLE_H_ +#define LIBMV_MULTIVIEW_RANDOM_SAMPLE_H_ + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +/*! + Pick a random subset of the integers [0, total), in random order. Note that + this can behave badly if num_samples is close to total; runtime could be + unlimited! + + This uses a quadratic rejection strategy and should only be used for small + num_samples. + + \param num_samples The number of samples to produce. + \param total_samples The number of samples available. + \param samples num_samples of numbers in [0, total_samples) is placed + here on return. +*/ +static void UniformSample(int num_samples, + int total_samples, + vector *samples) { + samples->resize(0); + while (samples->size() < num_samples) { + int sample = rand() % total_samples; + bool found = false; + for (int j = 0; j < samples->size(); ++j) { + found = (*samples)[j] == sample; + if (found) { + break; + } + } + if (!found) { + samples->push_back(sample); + } + } +} + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_RANDOM_SAMPLE_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/resection.h b/modules/sfm/src/libmv_light/libmv/multiview/resection.h new file mode 100644 index 0000000000..c142d6deeb --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/resection.h @@ -0,0 +1,62 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Compute the projection matrix from a set of 3D points X and their +// projections x = PX in 2D. This is useful if a point cloud is reconstructed. +// +// Algorithm is the standard DLT as described in Hartley & Zisserman, page 179. + +#ifndef LIBMV_MULTIVIEW_RESECTION_H +#define LIBMV_MULTIVIEW_RESECTION_H + +#include "libmv/logging/logging.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { +namespace resection { + +// x's are 2D image coordinates, (x,y,1), and X's are homogeneous four vectors. +template +void Resection(const Matrix &x, + const Matrix &X, + Matrix *P) { + int N = x.cols(); + assert(X.cols() == N); + + Matrix design(2*N, 12); + design.setZero(); + for (int i = 0; i < N; i++) { + T xi = x(0, i); + T yi = x(1, i); + // See equation (7.2) on page 179 of H&Z. + design.template block<1, 4>(2*i, 4) = -X.col(i).transpose(); + design.template block<1, 4>(2*i, 8) = yi*X.col(i).transpose(); + design.template block<1, 4>(2*i + 1, 0) = X.col(i).transpose(); + design.template block<1, 4>(2*i + 1, 8) = -xi*X.col(i).transpose(); + } + Matrix p; + Nullspace(&design, &p); + reshape(p, 3, 4, P); +} + +} // namespace resection +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_RESECTION_H diff --git a/modules/sfm/src/libmv_light/libmv/multiview/resection_kernel.h b/modules/sfm/src/libmv_light/libmv/multiview/resection_kernel.h new file mode 100644 index 0000000000..ed749c70c2 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/resection_kernel.h @@ -0,0 +1,66 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_RESECTION_KERNEL_H +#define LIBMV_MULTIVIEW_RESECTION_KERNEL_H + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/resection.h" +#include "libmv/multiview/projection.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { +namespace resection { +namespace kernel { + +class Kernel { + public: + typedef Mat34 Model; + enum { MINIMUM_SAMPLES = 6 }; + + Kernel(const Mat2X &x, const Mat4X &X) : x_(x), X_(X) { + CHECK(x.cols() == X.cols()); + } + void Fit(const vector &samples, vector *models) const { + Mat2X x = ExtractColumns(x_, samples); + Mat4X X = ExtractColumns(X_, samples); + Mat34 P; + Resection(x, X, &P); + models->push_back(P); + } + double Error(int sample, const Model &model) const { + Mat4X X = X_.col(sample); + Mat2X error = Project(model, X) - x_.col(sample); + return error.col(0).squaredNorm(); + } + int NumSamples() const { + return x_.cols(); + } + private: + const Mat2X &x_; + const Mat4X &X_; +}; + +} // namespace kernel +} // namespace resection +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_RESECTION_KERNEL_H diff --git a/modules/sfm/src/libmv_light/libmv/multiview/robust_estimation.cc b/modules/sfm/src/libmv_light/libmv/multiview/robust_estimation.cc new file mode 100644 index 0000000000..78f74450e0 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/robust_estimation.cc @@ -0,0 +1,31 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include +#include +#include +#include + +#include "libmv/multiview/robust_estimation.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/robust_estimation.h b/modules/sfm/src/libmv_light/libmv/multiview/robust_estimation.h new file mode 100644 index 0000000000..a677c5db88 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/robust_estimation.h @@ -0,0 +1,154 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_ROBUST_ESTIMATION_H_ +#define LIBMV_MULTIVIEW_ROBUST_ESTIMATION_H_ + +#include + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/random_sample.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +template +class MLEScorer { + public: + MLEScorer(double threshold) : threshold_(threshold) {} + double Score(const Kernel &kernel, + const typename Kernel::Model &model, + const vector &samples, + vector *inliers) const { + double cost = 0.0; + for (int j = 0; j < samples.size(); ++j) { + double error = kernel.Error(samples[j], model); + if (error < threshold_) { + cost += error; + inliers->push_back(samples[j]); + } else { + cost += threshold_; + } + } + return cost; + } + private: + double threshold_; +}; + +static uint IterationsRequired(int min_samples, + double outliers_probability, + double inlier_ratio) { + return static_cast( + log(outliers_probability) / log(1.0 - pow(inlier_ratio, min_samples))); +} + +// 1. The model. +// 2. The minimum number of samples needed to fit. +// 3. A way to convert samples to a model. +// 4. A way to convert samples and a model to an error. +// +// 1. Kernel::Model +// 2. Kernel::MINIMUM_SAMPLES +// 3. Kernel::Fit(vector, vector *) +// 4. Kernel::Error(Model, int) -> error +template +typename Kernel::Model Estimate(const Kernel &kernel, + const Scorer &scorer, + vector *best_inliers = NULL, + double *best_score = NULL, + double outliers_probability = 1e-2) { + CHECK(outliers_probability < 1.0); + CHECK(outliers_probability > 0.0); + size_t iteration = 0; + const size_t min_samples = Kernel::MINIMUM_SAMPLES; + const size_t total_samples = kernel.NumSamples(); + + size_t max_iterations = 100; + const size_t really_max_iterations = 1000; + + int best_num_inliers = 0; + double best_cost = HUGE_VAL; + double best_inlier_ratio = 0.0; + typename Kernel::Model best_model; + + // Test if we have sufficient points to for the kernel. + if (total_samples < min_samples) { + if (best_inliers) { + best_inliers->resize(0); + } + return best_model; + } + + // In this robust estimator, the scorer always works on all the data points + // at once. So precompute the list ahead of time. + vector all_samples; + for (int i = 0; i < total_samples; ++i) { + all_samples.push_back(i); + } + + vector sample; + for (iteration = 0; + iteration < max_iterations && + iteration < really_max_iterations; ++iteration) { + UniformSample(min_samples, total_samples, &sample); + + vector models; + kernel.Fit(sample, &models); + VLOG(4) << "Fitted subset; found " << models.size() << " model(s)."; + + // Compute costs for each fit. + for (int i = 0; i < models.size(); ++i) { + vector inliers; + double cost = scorer.Score(kernel, models[i], all_samples, &inliers); + VLOG(5) << "Fit cost: " << cost + << ", number of inliers: " << inliers.size(); + + if (cost < best_cost) { + best_cost = cost; + best_inlier_ratio = inliers.size() / double(total_samples); + best_num_inliers = inliers.size(); + best_model = models[i]; + if (best_inliers) { + best_inliers->swap(inliers); + } + VLOG(4) << "New best cost: " << best_cost << " with " + << best_num_inliers << " inlying of " + << total_samples << " total samples."; + } + if (best_inlier_ratio) { + max_iterations = IterationsRequired(min_samples, + outliers_probability, + best_inlier_ratio); + } + + VLOG(5) << "Max iterations needed given best inlier ratio: " + << max_iterations << "; best inlier ratio: " << best_inlier_ratio; + } + } + if (best_score) + *best_score = best_cost; + return best_model; +} + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_ROBUST_ESTIMATION_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/robust_fundamental.cc b/modules/sfm/src/libmv_light/libmv/multiview/robust_fundamental.cc new file mode 100644 index 0000000000..0462411a87 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/robust_fundamental.cc @@ -0,0 +1,69 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/fundamental_kernel.h" +#include "libmv/multiview/robust_estimation.h" +#include "libmv/multiview/robust_fundamental.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +// TODO(keir): This interface is a bit ugly; consider fixing it. +double FundamentalFromCorrespondences8PointRobust(const Mat &x1, + const Mat &x2, + double max_error, + Mat3 *F, + vector *inliers, + double outliers_probability) { + // The threshold is on the sum of the squared errors in the two images. + // Actually, Sampson's approximation of this error. + double threshold = 2 * Square(max_error); + double best_score = HUGE_VAL; + typedef fundamental::kernel::NormalizedEightPointKernel Kernel; + Kernel kernel(x1, x2); + *F = Estimate(kernel, MLEScorer(threshold), inliers, + &best_score, outliers_probability); + if (best_score == HUGE_VAL) + return HUGE_VAL; + else + return std::sqrt(best_score / 2.0); +} + +double FundamentalFromCorrespondences7PointRobust(const Mat &x1, + const Mat &x2, + double max_error, + Mat3 * F, + vector *inliers, + double outliers_probability) { + // The threshold is on the sum of the squared errors in the two images. + // Actually, Sampson's approximation of this error. + double threshold = 2 * Square(max_error); + double best_score = HUGE_VAL; + typedef fundamental::kernel::NormalizedSevenPointKernel Kernel; + Kernel kernel(x1, x2); + *F = Estimate(kernel, MLEScorer(threshold), inliers, + &best_score, outliers_probability); + if (best_score == HUGE_VAL) + return HUGE_VAL; + else + return std::sqrt(best_score / 2.0); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/robust_fundamental.h b/modules/sfm/src/libmv_light/libmv/multiview/robust_fundamental.h new file mode 100644 index 0000000000..52ccb03d13 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/robust_fundamental.h @@ -0,0 +1,53 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_ROBUST_FUNDAMENTAL_H_ +#define LIBMV_MULTIVIEW_ROBUST_FUNDAMENTAL_H_ + +#include "libmv/base/vector.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +// Estimate robustly the fundamental matrix between two dataset of 2D point +// (image coords space). The fundamental solver relies on the 8 point solution. +// Returns the score associated to the solution F +double FundamentalFromCorrespondences8PointRobust( + const Mat &x1, + const Mat &x2, + double max_error, + Mat3 *F, + vector *inliers = NULL, + double outliers_probability = 1e-2); + +// Estimate robustly the fundamental matrix between two dataset of 2D point +// (image coords space). The fundamental solver relies on the 7 point solution. +// Returns the score associated to the solution F +double FundamentalFromCorrespondences7PointRobust( + const Mat &x1, + const Mat &x2, + double max_error, + Mat3 * F, + vector *inliers = NULL, + double outliers_probability = 1e-2); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_ROBUST_FUNDAMENTAL_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/robust_resection.cc b/modules/sfm/src/libmv_light/libmv/multiview/robust_resection.cc new file mode 100644 index 0000000000..40be83a79b --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/robust_resection.cc @@ -0,0 +1,48 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/resection_kernel.h" +#include "libmv/multiview/robust_estimation.h" +#include "libmv/multiview/robust_resection.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { +// Estimate robustly the the projection matrix of a uncalibrated +// camera from 6 or more 3D points and their images. +double ResectionRobust(const Mat2X &x_image, + const Mat4X &X_world, + double max_error, + Mat34 *P, + vector *inliers, + double outliers_probability) { + // The threshold is on the sum of the squared errors. + double threshold = Square(max_error); + double best_score = HUGE_VAL; + typedef libmv::resection::kernel::Kernel Kernel; + Kernel kernel(x_image, X_world); + *P = Estimate(kernel, MLEScorer(threshold), inliers, + &best_score, outliers_probability); + if (best_score == HUGE_VAL) + return HUGE_VAL; + else + return std::sqrt(best_score / 2.0); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/robust_resection.h b/modules/sfm/src/libmv_light/libmv/multiview/robust_resection.h new file mode 100644 index 0000000000..2520789fd7 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/robust_resection.h @@ -0,0 +1,41 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_ROBUST_RESECTION_H_ +#define LIBMV_MULTIVIEW_ROBUST_RESECTION_H_ + +#include "libmv/base/vector.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +// Estimate robustly the the projection matrix of a uncalibrated +// camera from 6 or more 3D points and their images. +// Returns the score associated to the solution P +double ResectionRobust(const Mat2X &x_image, + const Mat4X &X_world, + double max_error, + Mat34 *P, + vector *inliers = NULL, + double outliers_probability = 1e-2); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_ROBUST_RESECTION_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/triangulation.cc b/modules/sfm/src/libmv_light/libmv/multiview/triangulation.cc new file mode 100644 index 0000000000..4d146c8f21 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/triangulation.cc @@ -0,0 +1,50 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/triangulation.h" + +#include "libmv/numeric/numeric.h" +#include "libmv/multiview/projection.h" + +namespace libmv { + +// HZ 12.2 pag.312 +void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, + const Mat34 &P2, const Vec2 &x2, + Vec4 *X_homogeneous) { + Mat4 design; + for (int i = 0; i < 4; ++i) { + design(0, i) = x1(0) * P1(2, i) - P1(0, i); + design(1, i) = x1(1) * P1(2, i) - P1(1, i); + design(2, i) = x2(0) * P2(2, i) - P2(0, i); + design(3, i) = x2(1) * P2(2, i) - P2(1, i); + } + Nullspace(&design, X_homogeneous); +} + +void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, + const Mat34 &P2, const Vec2 &x2, + Vec3 *X_euclidean) { + Vec4 X_homogeneous; + TriangulateDLT(P1, x1, P2, x2, &X_homogeneous); + HomogeneousToEuclidean(X_homogeneous, X_euclidean); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/triangulation.h b/modules/sfm/src/libmv_light/libmv/multiview/triangulation.h new file mode 100644 index 0000000000..be87889024 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/triangulation.h @@ -0,0 +1,38 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_TRIANGULATION_H_ +#define LIBMV_MULTIVIEW_TRIANGULATION_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, + const Mat34 &P2, const Vec2 &x2, + Vec4 *X_homogeneous); + +void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, + const Mat34 &P2, const Vec2 &x2, + Vec3 *X_euclidean); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_TRIANGULATION_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/two_view_kernel.h b/modules/sfm/src/libmv_light/libmv/multiview/two_view_kernel.h new file mode 100644 index 0000000000..7af0ed5dda --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/two_view_kernel.h @@ -0,0 +1,137 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_TWO_VIEW_KERNEL_H_ +#define LIBMV_MULTIVIEW_TWO_VIEW_KERNEL_H_ + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/conditioning.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { +namespace two_view { +namespace kernel { + +template +struct NormalizedSolver { + enum { MINIMUM_SAMPLES = Solver::MINIMUM_SAMPLES }; + static void Solve(const Mat &x1, const Mat &x2, vector *models) { + assert(2 == x1.rows()); + assert(MINIMUM_SAMPLES <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + // Normalize the data. + Mat3 T1, T2; + Mat x1_normalized, x2_normalized; + NormalizePoints(x1, &x1_normalized, &T1); + NormalizePoints(x2, &x2_normalized, &T2); + + Solver::Solve(x1_normalized, x2_normalized, models); + + for (int i = 0; i < models->size(); ++i) { + Unnormalizer::Unnormalize(T1, T2, &(*models)[i]); + } + } +}; + +template +struct IsotropicNormalizedSolver { + enum { MINIMUM_SAMPLES = Solver::MINIMUM_SAMPLES }; + static void Solve(const Mat &x1, const Mat &x2, vector *models) { + assert(2 == x1.rows()); + assert(MINIMUM_SAMPLES <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + // Normalize the data. + Mat3 T1, T2; + Mat x1_normalized, x2_normalized; + NormalizeIsotropicPoints(x1, &x1_normalized, &T1); + NormalizeIsotropicPoints(x2, &x2_normalized, &T2); + + Solver::Solve(x1_normalized, x2_normalized, models); + + for (int i = 0; i < models->size(); ++i) { + Unnormalizer::Unnormalize(T1, T2, &(*models)[i]); + } + } +}; +// This is one example (targeted at solvers that operate on correspondences +// between two views) that shows the "kernel" part of a robust fitting +// problem: +// +// 1. The model; Mat3 in the case of the F or H matrix. +// 2. The minimum number of samples needed to fit; 7 or 8 (or 4). +// 3. A way to convert samples to a model. +// 4. A way to convert a sample and a model to an error. +// +// Of particular note is that the kernel does not expose what the samples are. +// All the robust fitting algorithm sees is that there is some number of +// samples; it is able to fit subsets of them (via the kernel) and check their +// error, but can never access the samples themselves. +// +// The Kernel objects must follow the following concept so that the robust +// fitting alogrithm can fit this type of relation: +// +// 1. Kernel::Model +// 2. Kernel::MINIMUM_SAMPLES +// 3. Kernel::Fit(vector, vector *) +// 4. Kernel::Error(int, Model) -> error +// +// The fit routine must not clear existing entries in the vector of models; it +// should append new solutions to the end. +template +class Kernel { + public: + Kernel(const Mat &x1, const Mat &x2) : x1_(x1), x2_(x2) {} + typedef SolverArg Solver; + typedef ModelArg Model; + enum { MINIMUM_SAMPLES = Solver::MINIMUM_SAMPLES }; + void Fit(const vector &samples, vector *models) const { + Mat x1 = ExtractColumns(x1_, samples); + Mat x2 = ExtractColumns(x2_, samples); + Solver::Solve(x1, x2, models); + } + double Error(int sample, const Model &model) const { + return ErrorArg::Error(model, + static_cast(x1_.col(sample)), + static_cast(x2_.col(sample))); + } + int NumSamples() const { + return x1_.cols(); + } + static void Solve(const Mat &x1, const Mat &x2, vector *models) { + // By offering this, Kernel types can be passed to templates. + Solver::Solve(x1, x2, models); + } + protected: + const Mat &x1_; + const Mat &x2_; +}; + +} // namespace kernel +} // namespace two_view +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_TWO_VIEW_KERNEL_H_ diff --git a/modules/sfm/src/libmv_light/libmv/multiview/twoviewtriangulation.cc b/modules/sfm/src/libmv_light/libmv/multiview/twoviewtriangulation.cc new file mode 100644 index 0000000000..805bc73e90 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/twoviewtriangulation.cc @@ -0,0 +1,90 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/numeric/numeric.h" +#include "libmv/multiview/projection.h" +#include "libmv/multiview/twoviewtriangulation.h" +#include "libmv/multiview/projection.h" + + +namespace libmv { + +void TwoViewTriangulationByPlanes(const Vec3 &x1, const Vec3 &x2, + const Mat34 &P, const Mat3 &E, + Vec4 *X) { + Vec3 a = E.transpose() * x2; + Vec3 a0 = a; + a0(2) = 0; + Vec3 b = x1; + b = b.cross(a0); + + Vec3 c = E * x1; + c(2) = 0; + c = c.cross(x2); + Vec4 C = P.transpose() * c; + + Vec3 d = a.cross(b); + Vec3 q = d * C[3]; + (*X)[0] = q[0]; + (*X)[1] = q[1]; + (*X)[2] = q[2]; + (*X)[3] = -(d[0] * C[0] + d[1] * C[1] + d[2] * C[2]); +} + +void TwoViewTriangulationByPlanes(const Vec2 &x1, const Vec2 &x2, + const Mat34 &P,const Mat3 &E, + Vec3 *X) { + Vec3 x1_homogenious = EuclideanToHomogeneous(x1); + Vec3 x2_homogenious = EuclideanToHomogeneous(x2); + Vec4 X_homogenious; + TwoViewTriangulationByPlanes(x1_homogenious, + x2_homogenious, + P, E, &X_homogenious); + (*X) = HomogeneousToEuclidean(X_homogenious); +} + +void TwoViewTriangulationIdeal(const Vec3 &x1, const Vec3 &x2, + const Mat34 &P, const Mat3 &E, + Vec4 *X){ + Vec3 c = E * x1; + c(2) = 0; + c = c.cross(x2); + Vec4 C = P.transpose() * c; + + Vec3 q = x1 * C[3]; + (*X)[0] = q[0]; + (*X)[1] = q[1]; + (*X)[2] = q[2]; + (*X)[3] = -(x1[0] * C[0] + x1[1] * C[1] + x1[2] * C[2]); +} + +void TwoViewTriangulationIdeal(const Vec2 &x1, const Vec2 &x2, + const Mat34 &P, const Mat3 &E, + Vec3 *X) { + Vec3 x1_homogenious = EuclideanToHomogeneous(x1); + Vec3 x2_homogenious = EuclideanToHomogeneous(x2); + Vec4 X_homogenious; + TwoViewTriangulationIdeal(x1_homogenious, + x2_homogenious, + P, E, &X_homogenious); + (*X) = HomogeneousToEuclidean(X_homogenious); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/multiview/twoviewtriangulation.h b/modules/sfm/src/libmv_light/libmv/multiview/twoviewtriangulation.h new file mode 100644 index 0000000000..384620798f --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/multiview/twoviewtriangulation.h @@ -0,0 +1,82 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Compute a 3D position of a point from several images of it. In particular, +// compute the projective point X in R^4 such that x = PX. +// +// Algorithm is the standard DLT; for derivation see appendix of Keir's thesis. + +#ifndef LIBMV_TWOVIEW_NVIEWTRIANGULATION_H +#define LIBMV_TWOVIEW_NVIEWTRIANGULATION_H + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +/** +* Two view triangulation for cameras in canonical form, +* where the reference camera is in the form [I|0] and P is in +* the form [R|t]. The algorithm minimizes the re-projection error +* in the first image only, i.e. the error in the second image is 0 +* while the point in the first image is the point lying on the +* epipolar line that is closest to x1. +* +* \param x1 The normalized image point in the first camera +* (inv(K1)*x1_image) +* \param x2 The normalized image point in the second camera +* (inv(K2)*x2_image) +* \param P The second camera matrix in the form [R|t] +* \param E The essential matrix between the two cameras +* \param X The 3D homogeneous point +* +* This is the algorithm described in Appendix A in: +* "An efficient solution to the five-point relative pose problem", +* by D. Nist\'er, IEEE PAMI, vol. 26 +*/ +void TwoViewTriangulationByPlanes(const Vec3 &x1, const Vec3 &x2, + const Mat34 &P,const Mat3 &E, Vec4 *X); +void TwoViewTriangulationByPlanes(const Vec2 &x1, const Vec2 &x2, + const Mat34 &P,const Mat3 &E, Vec3 *X); + +/** +* The same algorithm as above generalized for ideal points, +* e.i. where x1*E*x2' = 0. This will not work if the points are +* not ideal. In the case of measured image points it is best to +* either use the TwoViewTriangulationByPlanes function or correct +* the points so that they lay on the corresponding epipolar lines. +* +* \param x1 The normalized image point in the first camera +* (inv(K1)*x1_image) +* \param x2 The normalized image point in the second camera +* (inv(K2)*x2_image) +* \param P The second camera matrix in the form [R|t] +* \param E The essential matrix between the two cameras +* \param X The 3D homogeneous point +*/ +void TwoViewTriangulationIdeal(const Vec3 &x1, const Vec3 &x2, + const Mat34 &P, const Mat3 &E, + Vec4 *X); +void TwoViewTriangulationIdeal(const Vec2 &x1, const Vec2 &x2, + const Mat34 &P, const Mat3 &E, + Vec3 *X); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_RESECTION_H diff --git a/modules/sfm/src/libmv_light/libmv/numeric/CMakeLists.txt b/modules/sfm/src/libmv_light/libmv/numeric/CMakeLists.txt new file mode 100644 index 0000000000..5ecd541cce --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/numeric/CMakeLists.txt @@ -0,0 +1,12 @@ +# define the source files +SET(NUMERIC_SRC numeric.cc + poly.cc) + +# define the header files (make the headers appear in IDEs.) +FILE(GLOB NUMERIC_HDRS *.h) + +ADD_LIBRARY(numeric STATIC ${NUMERIC_SRC} ${NUMERIC_HDRS}) + +TARGET_LINK_LIBRARIES(numeric) + +LIBMV_INSTALL_LIB(numeric) \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/libmv/numeric/function_derivative.h b/modules/sfm/src/libmv_light/libmv/numeric/function_derivative.h new file mode 100644 index 0000000000..9820885f04 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/numeric/function_derivative.h @@ -0,0 +1,107 @@ +// Copyright (c) 2007, 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_NUMERIC_DERIVATIVE_H +#define LIBMV_NUMERIC_DERIVATIVE_H + +#include + +#include "libmv/numeric/numeric.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +// Numeric derivative of a function. +// TODO(keir): Consider adding a quadratic approximation. + +enum NumericJacobianMode { + CENTRAL, + FORWARD, +}; + +template +class NumericJacobian { + public: + typedef typename Function::XMatrixType Parameters; + typedef typename Function::XMatrixType::RealScalar XScalar; + typedef typename Function::FMatrixType FMatrixType; + typedef Matrix + JMatrixType; + + NumericJacobian(const Function &f) : f_(f) {} + + // TODO(keir): Perhaps passing the jacobian back by value is not a good idea. + JMatrixType operator()(const Parameters &x) { + // Empirically determined constant. + Parameters eps = x.array().abs() * XScalar(1e-5); + // To handle cases where a paremeter is exactly zero, instead use the mean + // eps for the other dimensions. + XScalar mean_eps = eps.sum() / eps.rows(); + if (mean_eps == XScalar(0)) { + // TODO(keir): Do something better here. + mean_eps = 1e-8; // ~sqrt(machine precision). + } + // TODO(keir): Elimininate this needless function evaluation for the + // central difference case. + FMatrixType fx = f_(x); + const int rows = fx.rows(); + const int cols = x.rows(); + JMatrixType jacobian(rows, cols); + Parameters x_plus_delta = x; + for (int c = 0; c < cols; ++c) { + if (eps(c) == XScalar(0)) { + eps(c) = mean_eps; + } + x_plus_delta(c) = x(c) + eps(c); + jacobian.col(c) = f_(x_plus_delta); + + XScalar one_over_h = 1 / eps(c); + if (mode == CENTRAL) { + x_plus_delta(c) = x(c) - eps(c); + jacobian.col(c) -= f_(x_plus_delta); + one_over_h /= 2; + } else { + jacobian.col(c) -= fx; + } + x_plus_delta(c) = x(c); + jacobian.col(c) = jacobian.col(c) * one_over_h; + } + return jacobian; + } + private: + const Function &f_; +}; + +template +bool CheckJacobian(const Function &f, const typename Function::XMatrixType &x) { + Jacobian j_analytic(f); + NumericJacobian j_numeric(f); + + typename NumericJacobian::JMatrixType J_numeric = j_numeric(x); + typename NumericJacobian::JMatrixType J_analytic = j_analytic(x); + LG << J_numeric - J_analytic; + return true; +} + +} // namespace libmv + +#endif // LIBMV_NUMERIC_DERIVATIVE_H diff --git a/modules/sfm/src/libmv_light/libmv/numeric/levenberg_marquardt.h b/modules/sfm/src/libmv_light/libmv/numeric/levenberg_marquardt.h new file mode 100644 index 0000000000..2af9a62cf7 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/numeric/levenberg_marquardt.h @@ -0,0 +1,183 @@ +// Copyright (c) 2007, 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// A simple implementation of levenberg marquardt. +// +// [1] K. Madsen, H. Nielsen, O. Tingleoff. Methods for Non-linear Least +// Squares Problems. +// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf +// +// TODO(keir): Cite the Lourakis' dogleg paper. + +#ifndef LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H +#define LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H + +#include + +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/function_derivative.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +template, + typename Solver = Eigen::PartialPivLU< + Matrix > > +class LevenbergMarquardt { + public: + typedef typename Function::XMatrixType::RealScalar Scalar; + typedef typename Function::FMatrixType FVec; + typedef typename Function::XMatrixType Parameters; + typedef Matrix JMatrixType; + typedef Matrix AMatrixType; + + // TODO(keir): Some of these knobs can be derived from each other and + // removed, instead of requiring the user to set them. + enum Status { + RUNNING, + GRADIENT_TOO_SMALL, // eps > max(J'*f(x)) + RELATIVE_STEP_SIZE_TOO_SMALL, // eps > ||dx|| / ||x|| + ERROR_TOO_SMALL, // eps > ||f(x)|| + HIT_MAX_ITERATIONS, + }; + + LevenbergMarquardt(const Function &f) + : f_(f), df_(f) {} + + struct SolverParameters { + SolverParameters() + : gradient_threshold(1e-16), + relative_step_threshold(1e-16), + error_threshold(1e-16), + initial_scale_factor(1e-3), + max_iterations(100) {} + Scalar gradient_threshold; // eps > max(J'*f(x)) + Scalar relative_step_threshold; // eps > ||dx|| / ||x|| + Scalar error_threshold; // eps > ||f(x)|| + Scalar initial_scale_factor; // Initial u for solving normal equations. + int max_iterations; // Maximum number of solver iterations. + }; + + struct Results { + Scalar error_magnitude; // ||f(x)|| + Scalar gradient_magnitude; // ||J'f(x)|| + int iterations; + Status status; + }; + + Status Update(const Parameters &x, const SolverParameters ¶ms, + JMatrixType *J, AMatrixType *A, FVec *error, Parameters *g) { + *J = df_(x); + *A = (*J).transpose() * (*J); + *error = -f_(x); + *g = (*J).transpose() * *error; + if (g->array().abs().maxCoeff() < params.gradient_threshold) { + return GRADIENT_TOO_SMALL; + } else if (error->norm() < params.error_threshold) { + return ERROR_TOO_SMALL; + } + return RUNNING; + } + + Results minimize(Parameters *x_and_min) { + SolverParameters params; + minimize(params, x_and_min); + } + + Results minimize(const SolverParameters ¶ms, Parameters *x_and_min) { + Parameters &x = *x_and_min; + JMatrixType J; + AMatrixType A; + FVec error; + Parameters g; + + Results results; + results.status = Update(x, params, &J, &A, &error, &g); + + Scalar u = Scalar(params.initial_scale_factor*A.diagonal().maxCoeff()); + Scalar v = 2; + + Parameters dx, x_new; + int i; + for (i = 0; results.status == RUNNING && i < params.max_iterations; ++i) { + VLOG(3) << "iteration: " << i; + VLOG(3) << "||f(x)||: " << f_(x).norm(); + VLOG(3) << "max(g): " << g.array().abs().maxCoeff(); + VLOG(3) << "u: " << u; + VLOG(3) << "v: " << v; + + AMatrixType A_augmented = A + u*AMatrixType::Identity(J.cols(), J.cols()); + Solver solver(A_augmented); + dx = solver.solve(g); + bool solved = (A_augmented * dx).isApprox(g); + if (!solved) { + LOG(ERROR) << "Failed to solve"; + } + if (solved && dx.norm() <= params.relative_step_threshold * x.norm()) { + results.status = RELATIVE_STEP_SIZE_TOO_SMALL; + break; + } + if (solved) { + x_new = x + dx; + // Rho is the ratio of the actual reduction in error to the reduction + // in error that would be obtained if the problem was linear. + // See [1] for details. + Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm()) + / dx.dot(u*dx + g)); + if (rho > 0) { + // Accept the Gauss-Newton step because the linear model fits well. + x = x_new; + results.status = Update(x, params, &J, &A, &error, &g); + Scalar tmp = Scalar(2*rho-1); + u = u*std::max(1/3., 1 - (tmp*tmp*tmp)); + v = 2; + continue; + } + } + // Reject the update because either the normal equations failed to solve + // or the local linear model was not good (rho < 0). Instead, increase u + // to move closer to gradient descent. + u *= v; + v *= 2; + } + if (results.status == RUNNING) { + results.status = HIT_MAX_ITERATIONS; + } + results.error_magnitude = error.norm(); + results.gradient_magnitude = g.norm(); + results.iterations = i; + return results; + } + + private: + const Function &f_; + Jacobian df_; +}; + +} // namespace mv + +#endif // LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H diff --git a/modules/sfm/src/libmv_light/libmv/numeric/numeric.cc b/modules/sfm/src/libmv_light/libmv/numeric/numeric.cc new file mode 100644 index 0000000000..9007663c8e --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/numeric/numeric.cc @@ -0,0 +1,136 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +Mat3 RotationAroundX(double angle) { + double c, s; + sincos(angle, &s, &c); + Mat3 R; + R << 1, 0, 0, + 0, c, -s, + 0, s, c; + return R; +} + +Mat3 RotationAroundY(double angle) { + double c, s; + sincos(angle, &s, &c); + Mat3 R; + R << c, 0, s, + 0, 1, 0, + -s, 0, c; + return R; +} + +Mat3 RotationAroundZ(double angle) { + double c, s; + sincos(angle, &s, &c); + Mat3 R; + R << c, -s, 0, + s, c, 0, + 0, 0, 1; + return R; +} + + +Mat3 RotationRodrigues(const Vec3 &axis) { + double theta = axis.norm(); + Vec3 w = axis / theta; + Mat3 W = CrossProductMatrix(w); + + return Mat3::Identity() + sin(theta) * W + (1 - cos(theta)) * W * W; +} + + +Mat3 LookAt(Vec3 center) { + Vec3 zc = center.normalized(); + Vec3 xc = Vec3::UnitY().cross(zc).normalized(); + Vec3 yc = zc.cross(xc); + Mat3 R; + R.row(0) = xc; + R.row(1) = yc; + R.row(2) = zc; + return R; +} + +Mat3 CrossProductMatrix(const Vec3 &x) { + Mat3 X; + X << 0, -x(2), x(1), + x(2), 0, -x(0), + -x(1), x(0), 0; + return X; +} + +void MeanAndVarianceAlongRows(const Mat &A, + Vec *mean_pointer, + Vec *variance_pointer) { + Vec &mean = *mean_pointer; + Vec &variance = *variance_pointer; + int n = A.rows(); + int m = A.cols(); + mean.resize(n); + variance.resize(n); + + for (int i = 0; i < n; ++i) { + mean(i) = 0; + variance(i) = 0; + for (int j = 0; j < m; ++j) { + double x = A(i, j); + mean(i) += x; + variance(i) += x * x; + } + } + + mean /= m; + for (int i = 0; i < n; ++i) { + variance(i) = variance(i) / m - Square(mean(i)); + } +} + +void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked) { + assert(left.rows() == left.rows()); + int n = left.rows(); + int m1 = left.cols(); + int m2 = right.cols(); + + stacked->resize(n, m1 + m2); + stacked->block(0, 0, n, m1) = left; + stacked->block(0, m1, n, m2) = right; +} + +void MatrixColumn(const Mat &A, int i, Vec2 *v) { + assert(A.rows() == 2); + *v << A(0, i), A(1, i); +} +void MatrixColumn(const Mat &A, int i, Vec3 *v) { + assert(A.rows() == 3); + *v << A(0, i), A(1, i), A(2, i); +} +void MatrixColumn(const Mat &A, int i, Vec4 *v) { + assert(A.rows() == 4); + *v << A(0, i), A(1, i), A(2, i), A(3, i); +} + +} // namespace libmv + diff --git a/modules/sfm/src/libmv_light/libmv/numeric/numeric.h b/modules/sfm/src/libmv_light/libmv/numeric/numeric.h new file mode 100644 index 0000000000..55d4c7d465 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/numeric/numeric.h @@ -0,0 +1,502 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Matrix and vector classes, based on Eigen2. +// +// Avoid using Eigen2 classes directly; instead typedef them here. + +#ifndef LIBMV_NUMERIC_NUMERIC_H +#define LIBMV_NUMERIC_NUMERIC_H + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(__MINGW64__) +# if defined(_WIN32) || defined(__APPLE__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) +static void sincos(double x, double *sinx, double *cosx) { + *sinx = sin(x); + *cosx = cos(x); +} +# endif +#endif // !__MINGW64__ + +#if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW32__) +inline long lround(double d) { + return (long)(d>0 ? d+0.5 : ceil(d-0.5)); +} +# if _MSC_VER < 1800 +inline int round(double d) { + return (d>0) ? int(d+0.5) : int(d-0.5); +} +# endif // _MSC_VER < 1800 +typedef unsigned int uint; +#endif // _WIN32 + +namespace libmv { + +typedef Eigen::MatrixXd Mat; +typedef Eigen::VectorXd Vec; + +typedef Eigen::MatrixXf Matf; +typedef Eigen::VectorXf Vecf; + +typedef Eigen::Matrix Matu; +typedef Eigen::Matrix Vecu; +typedef Eigen::Matrix Vec2u; + +typedef Eigen::Matrix Mat2; +typedef Eigen::Matrix Mat23; +typedef Eigen::Matrix Mat3; +typedef Eigen::Matrix Mat34; +typedef Eigen::Matrix Mat35; +typedef Eigen::Matrix Mat41; +typedef Eigen::Matrix Mat43; +typedef Eigen::Matrix Mat4; +typedef Eigen::Matrix Mat46; +typedef Eigen::Matrix Mat2f; +typedef Eigen::Matrix Mat23f; +typedef Eigen::Matrix Mat3f; +typedef Eigen::Matrix Mat34f; +typedef Eigen::Matrix Mat35f; +typedef Eigen::Matrix Mat43f; +typedef Eigen::Matrix Mat4f; +typedef Eigen::Matrix Mat46f; + +typedef Eigen::Matrix RMat3; +typedef Eigen::Matrix RMat4; + +typedef Eigen::Matrix Mat2X; +typedef Eigen::Matrix Mat3X; +typedef Eigen::Matrix Mat4X; +typedef Eigen::Matrix MatX2; +typedef Eigen::Matrix MatX3; +typedef Eigen::Matrix MatX4; +typedef Eigen::Matrix MatX5; +typedef Eigen::Matrix MatX6; +typedef Eigen::Matrix MatX7; +typedef Eigen::Matrix MatX8; +typedef Eigen::Matrix MatX9; +typedef Eigen::Matrix MatX15; +typedef Eigen::Matrix MatX16; + +typedef Eigen::Vector2d Vec2; +typedef Eigen::Vector3d Vec3; +typedef Eigen::Vector4d Vec4; +typedef Eigen::Matrix Vec5; +typedef Eigen::Matrix Vec6; +typedef Eigen::Matrix Vec7; +typedef Eigen::Matrix Vec8; +typedef Eigen::Matrix Vec9; +typedef Eigen::Matrix Vec10; +typedef Eigen::Matrix Vec11; +typedef Eigen::Matrix Vec12; +typedef Eigen::Matrix Vec13; +typedef Eigen::Matrix Vec14; +typedef Eigen::Matrix Vec15; +typedef Eigen::Matrix Vec16; +typedef Eigen::Matrix Vec17; +typedef Eigen::Matrix Vec18; +typedef Eigen::Matrix Vec19; +typedef Eigen::Matrix Vec20; + +typedef Eigen::Vector2f Vec2f; +typedef Eigen::Vector3f Vec3f; +typedef Eigen::Vector4f Vec4f; + +typedef Eigen::VectorXi VecXi; + +typedef Eigen::Vector2i Vec2i; +typedef Eigen::Vector3i Vec3i; +typedef Eigen::Vector4i Vec4i; + +typedef Eigen::Matrix RMatf; + +typedef Eigen::NumTraits EigenDouble; + +using Eigen::Map; +using Eigen::Dynamic; +using Eigen::Matrix; + +// Find U, s, and VT such that +// +// A = U * diag(s) * VT +// +template +inline void SVD(TMat *A, Vec *s, Mat *U, Mat *VT) { + assert(0); +} + +// Solve the linear system Ax = 0 via SVD. Store the solution in x, such that +// ||x|| = 1.0. Return the singluar value corresponding to the solution. +// Destroys A and resizes x if necessary. +// TODO(maclean): Take the SVD of the transpose instead of this zero padding. +template +double Nullspace(TMat *A, TVec *nullspace) { + Eigen::JacobiSVD svd(*A, Eigen::ComputeFullV); + (*nullspace) = svd.matrixV().col(A->cols()-1); + if (A->rows() >= A->cols()) + return svd.singularValues()(A->cols()-1); + else + return 0.0; +} + +// Solve the linear system Ax = 0 via SVD. Finds two solutions, x1 and x2, such +// that x1 is the best solution and x2 is the next best solution (in the L2 +// norm sense). Store the solution in x1 and x2, such that ||x|| = 1.0. Return +// the singluar value corresponding to the solution x1. Destroys A and resizes +// x if necessary. +template +double Nullspace2(TMat *A, TVec1 *x1, TVec2 *x2) { + Eigen::JacobiSVD svd(*A, Eigen::ComputeFullV); + *x1 = svd.matrixV().col(A->cols() - 1); + *x2 = svd.matrixV().col(A->cols() - 2); + if (A->rows() >= A->cols()) + return svd.singularValues()(A->cols()-1); + else + return 0.0; +} + +// In place transpose for square matrices. +template +inline void TransposeInPlace(TA *A) { + *A = A->transpose().eval(); +} + +template +inline double NormL1(const TVec &x) { + return x.array().abs().sum(); +} + +template +inline double NormL2(const TVec &x) { + return x.norm(); +} + +template +inline double NormLInfinity(const TVec &x) { + return x.array().abs().maxCoeff(); +} + +template +inline double DistanceL1(const TVec &x, const TVec &y) { + return (x - y).array().abs().sum(); +} + +template +inline double DistanceL2(const TVec &x, const TVec &y) { + return (x - y).norm(); +} +template +inline double DistanceLInfinity(const TVec &x, const TVec &y) { + return (x - y).array().abs().maxCoeff(); +} + +// Normalize a vector with the L1 norm, and return the norm before it was +// normalized. +template +inline double NormalizeL1(TVec *x) { + double norm = NormL1(*x); + *x /= norm; + return norm; +} + +// Normalize a vector with the L2 norm, and return the norm before it was +// normalized. +template +inline double NormalizeL2(TVec *x) { + double norm = NormL2(*x); + *x /= norm; + return norm; +} + +// Normalize a vector with the L^Infinity norm, and return the norm before it +// was normalized. +template +inline double NormalizeLInfinity(TVec *x) { + double norm = NormLInfinity(*x); + *x /= norm; + return norm; +} + +// Return the square of a number. +template +inline T Square(T x) { + return x * x; +} + +Mat3 RotationAroundX(double angle); +Mat3 RotationAroundY(double angle); +Mat3 RotationAroundZ(double angle); + +// Returns the rotation matrix of a rotation of angle |axis| around axis. +// This is computed using the Rodrigues formula, see: +// http://mathworld.wolfram.com/RodriguesRotationFormula.html +Mat3 RotationRodrigues(const Vec3 &axis); + +// Make a rotation matrix such that center becomes the direction of the +// positive z-axis, and y is oriented close to up. +Mat3 LookAt(Vec3 center); + +// Return a diagonal matrix from a vector containg the diagonal values. +template +inline Mat Diag(const TVec &x) { + return x.asDiagonal(); +} + +template +inline double FrobeniusNorm(const TMat &A) { + return sqrt(A.array().abs2().sum()); +} + +template +inline double FrobeniusDistance(const TMat &A, const TMat &B) { + return FrobeniusNorm(A - B); +} + +inline Vec3 CrossProduct(const Vec3 &x, const Vec3 &y) { + return x.cross(y); +} + +Mat3 CrossProductMatrix(const Vec3 &x); + +void MeanAndVarianceAlongRows(const Mat &A, + Vec *mean_pointer, + Vec *variance_pointer); + +#if _WIN32 + // TODO(bomboze): un-#if this for both platforms once tested under Windows + /* This solution was extensively discussed here + http://forum.kde.org/viewtopic.php?f=74&t=61940 */ + #define SUM_OR_DYNAMIC(x, y) (x == Eigen::Dynamic || y == Eigen::Dynamic) ? Eigen::Dynamic : (x+y) + + template + struct hstack_return { + typedef typename Derived1::Scalar Scalar; + enum { + RowsAtCompileTime = Derived1::RowsAtCompileTime, + ColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::ColsAtCompileTime, + Derived2::ColsAtCompileTime), + Options = Derived1::Flags&Eigen::RowMajorBit ? Eigen::RowMajor : 0, + MaxRowsAtCompileTime = Derived1::MaxRowsAtCompileTime, + MaxColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxColsAtCompileTime, + Derived2::MaxColsAtCompileTime) + }; + typedef Eigen::Matrix type; + }; + + template + typename hstack_return::type + HStack(const Eigen::MatrixBase& lhs, + const Eigen::MatrixBase& rhs) { + typename hstack_return::type res; + res.resize(lhs.rows(), lhs.cols()+rhs.cols()); + res << lhs, rhs; + return res; + }; + + + template + struct vstack_return { + typedef typename Derived1::Scalar Scalar; + enum { + RowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::RowsAtCompileTime, + Derived2::RowsAtCompileTime), + ColsAtCompileTime = Derived1::ColsAtCompileTime, + Options = Derived1::Flags&Eigen::RowMajorBit ? Eigen::RowMajor : 0, + MaxRowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxRowsAtCompileTime, + Derived2::MaxRowsAtCompileTime), + MaxColsAtCompileTime = Derived1::MaxColsAtCompileTime + }; + typedef Eigen::Matrix type; + }; + + template + typename vstack_return::type + VStack(const Eigen::MatrixBase& lhs, + const Eigen::MatrixBase& rhs) { + typename vstack_return::type res; + res.resize(lhs.rows()+rhs.rows(), lhs.cols()); + res << lhs, rhs; + return res; + }; + + +#else // _WIN32 + + // Since it is not possible to typedef privately here, use a macro. + // Always take dynamic columns if either side is dynamic. + #define COLS \ + ((ColsLeft == Eigen::Dynamic || ColsRight == Eigen::Dynamic) \ + ? Eigen::Dynamic : (ColsLeft + ColsRight)) + + // Same as above, except that prefer fixed size if either is fixed. + #define ROWS \ + ((RowsLeft == Eigen::Dynamic && RowsRight == Eigen::Dynamic) \ + ? Eigen::Dynamic \ + : ((RowsLeft == Eigen::Dynamic) \ + ? RowsRight \ + : RowsLeft \ + ) \ + ) + + // TODO(keir): Add a static assert if both rows are at compiletime. + template + Eigen::Matrix + HStack(const Eigen::Matrix &left, + const Eigen::Matrix &right) { + assert(left.rows() == right.rows()); + int n = left.rows(); + int m1 = left.cols(); + int m2 = right.cols(); + + Eigen::Matrix stacked(n, m1 + m2); + stacked.block(0, 0, n, m1) = left; + stacked.block(0, m1, n, m2) = right; + return stacked; + } + + // Reuse the above macros by swapping the order of Rows and Cols. Nasty, but + // the duplication is worse. + // TODO(keir): Add a static assert if both rows are at compiletime. + // TODO(keir): Mail eigen list about making this work for general expressions + // rather than only matrix types. + template + Eigen::Matrix + VStack(const Eigen::Matrix &top, + const Eigen::Matrix &bottom) { + assert(top.cols() == bottom.cols()); + int n1 = top.rows(); + int n2 = bottom.rows(); + int m = top.cols(); + + Eigen::Matrix stacked(n1 + n2, m); + stacked.block(0, 0, n1, m) = top; + stacked.block(n1, 0, n2, m) = bottom; + return stacked; + } + #undef COLS + #undef ROWS +#endif // _WIN32 + + + +void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked); + +template +void VerticalStack(const TTop &top, const TBot &bottom, TStacked *stacked) { + assert(top.cols() == bottom.cols()); + int n1 = top.rows(); + int n2 = bottom.rows(); + int m = top.cols(); + + stacked->resize(n1 + n2, m); + stacked->block(0, 0, n1, m) = top; + stacked->block(n1, 0, n2, m) = bottom; +} + +void MatrixColumn(const Mat &A, int i, Vec2 *v); +void MatrixColumn(const Mat &A, int i, Vec3 *v); +void MatrixColumn(const Mat &A, int i, Vec4 *v); + +template +TMat ExtractColumns(const TMat &A, const TCols &columns) { + TMat compressed(A.rows(), columns.size()); + for (int i = 0; i < columns.size(); ++i) { + compressed.col(i) = A.col(columns[i]); + } + return compressed; +} + +template +void reshape(const TMat &a, int rows, int cols, TDest *b) { + assert(a.rows()*a.cols() == rows*cols); + b->resize(rows, cols); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + (*b)(i, j) = a[cols*i + j]; + } + } +} + +inline bool isnan(double i) { +#ifdef WIN32 + return _isnan(i) > 0; +#else + return std::isnan(i); +#endif +} + +/// Ceil function that has the same behaviour for positive +/// and negative values +template +FloatType ceil0(const FloatType& value) { + FloatType result = std::ceil(std::fabs(value)); + return (value < 0.0) ? -result : result; +} + +/// Returns the skew anti-symmetric matrix of a vector +inline Mat3 SkewMat(const Vec3 &x) { + Mat3 skew; + skew << 0 , -x(2), x(1), + x(2), 0 , -x(0), + -x(1), x(0), 0; + return skew; +} +/// Returns the skew anti-symmetric matrix of a vector with only +/// the first two (independent) lines +inline Mat23 SkewMatMinimal(const Vec2 &x) { + Mat23 skew; + skew << 0, -1, x(1), + 1, 0, -x(0); + return skew; +} + +/// Returns the rotaiton matrix built from given vector of euler angles +inline Mat3 RotationFromEulerVector(Vec3 euler_vector) { + double theta = euler_vector.norm(); + if (theta == 0.0) { + return Mat3::Identity(); + } + Vec3 w = euler_vector / theta; + Mat3 w_hat = CrossProductMatrix(w); + return Mat3::Identity() + w_hat*sin(theta) + w_hat*w_hat*(1 - cos(theta)); +} +} // namespace libmv + +#endif // LIBMV_NUMERIC_NUMERIC_H diff --git a/modules/sfm/src/libmv_light/libmv/numeric/poly.cc b/modules/sfm/src/libmv_light/libmv/numeric/poly.cc new file mode 100644 index 0000000000..376403616c --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/numeric/poly.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Routines for solving polynomials. + +// TODO(keir): Add a solver for degree > 3 polynomials. diff --git a/modules/sfm/src/libmv_light/libmv/numeric/poly.h b/modules/sfm/src/libmv_light/libmv/numeric/poly.h new file mode 100644 index 0000000000..76ba062d47 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/numeric/poly.h @@ -0,0 +1,123 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_NUMERIC_POLY_H_ +#define LIBMV_NUMERIC_POLY_H_ + +#include +#include + +namespace libmv { + +// Solve the cubic polynomial +// +// x^3 + a*x^2 + b*x + c = 0 +// +// The number of roots (from zero to three) is returned. If the number of roots +// is less than three, then higher numbered x's are not changed. For example, +// if there are 2 roots, only x0 and x1 are set. +// +// The GSL cubic solver was used as a reference for this routine. +template +int SolveCubicPolynomial(Real a, Real b, Real c, + Real *x0, Real *x1, Real *x2) { + Real q = a * a - 3 * b; + Real r = 2 * a * a * a - 9 * a * b + 27 * c; + + Real Q = q / 9; + Real R = r / 54; + + Real Q3 = Q * Q * Q; + Real R2 = R * R; + + Real CR2 = 729 * r * r; + Real CQ3 = 2916 * q * q * q; + + if (R == 0 && Q == 0) { + // Tripple root in one place. + *x0 = *x1 = *x2 = -a / 3; + return 3; + + } else if (CR2 == CQ3) { + // This test is actually R2 == Q3, written in a form suitable for exact + // computation with integers. + // + // Due to finite precision some double roots may be missed, and considered + // to be a pair of complex roots z = x +/- epsilon i close to the real + // axis. + Real sqrtQ = sqrt(Q); + if (R > 0) { + *x0 = -2 * sqrtQ - a / 3; + *x1 = sqrtQ - a / 3; + *x2 = sqrtQ - a / 3; + } else { + *x0 = -sqrtQ - a / 3; + *x1 = -sqrtQ - a / 3; + *x2 = 2 * sqrtQ - a / 3; + } + return 3; + + } else if (CR2 < CQ3) { + // This case is equivalent to R2 < Q3. + Real sqrtQ = sqrt(Q); + Real sqrtQ3 = sqrtQ * sqrtQ * sqrtQ; + Real theta = acos(R / sqrtQ3); + Real norm = -2 * sqrtQ; + *x0 = norm * cos(theta / 3) - a / 3; + *x1 = norm * cos((theta + 2.0 * M_PI) / 3) - a / 3; + *x2 = norm * cos((theta - 2.0 * M_PI) / 3) - a / 3; + + // Put the roots in ascending order. + if (*x0 > *x1) { + std::swap(*x0, *x1); + } + if (*x1 > *x2) { + std::swap(*x1, *x2); + if (*x0 > *x1) { + std::swap(*x0, *x1); + } + } + return 3; + } + Real sgnR = (R >= 0 ? 1 : -1); + Real A = -sgnR * pow(fabs(R) + sqrt(R2 - Q3), 1.0/3.0); + Real B = Q / A; + *x0 = A + B - a / 3; + return 1; +} + +// The coefficients are in ascending powers, i.e. coeffs[N]*x^N. +template +int SolveCubicPolynomial(const Real *coeffs, Real *solutions) { + if (coeffs[0] == 0.0) { + // TODO(keir): This is a quadratic not a cubic. Implement a quadratic + // solver! + return 0; + } + Real a = coeffs[2] / coeffs[3]; + Real b = coeffs[1] / coeffs[3]; + Real c = coeffs[0] / coeffs[3]; + return SolveCubicPolynomial(a, b, c, + solutions + 0, + solutions + 1, + solutions + 2); +} +} // namespace libmv +#endif // LIBMV_NUMERIC_POLY_H_ diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/CMakeLists.txt b/modules/sfm/src/libmv_light/libmv/simple_pipeline/CMakeLists.txt new file mode 100644 index 0000000000..42e3791980 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/CMakeLists.txt @@ -0,0 +1,22 @@ +SET(SIMPLE_PIPELINE_SRC + bundle.cc + camera_intrinsics.cc + distortion_models.cc + initialize_reconstruction.cc + intersect.cc + keyframe_selection.cc + pipeline.cc + reconstruction.cc + reconstruction_scale.cc + resect.cc + tracks.cc +) + +# Define the header files so that they appear in IDEs. +FILE(GLOB SIMPLE_PIPELINE_HDRS *.h) + +ADD_LIBRARY(simple_pipeline STATIC ${SIMPLE_PIPELINE_SRC} ${SIMPLE_PIPELINE_HDRS}) + +TARGET_LINK_LIBRARIES(simple_pipeline multiview ${CERES_LIBRARIES}) + +LIBMV_INSTALL_LIB(simple_pipeline) \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/bundle.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/bundle.cc new file mode 100644 index 0000000000..e61650fb37 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/bundle.cc @@ -0,0 +1,658 @@ +// Copyright (c) 2011, 2012, 2013 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/bundle.h" + +#include + +#include "ceres/ceres.h" +#include "ceres/rotation.h" +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/fundamental.h" +#include "libmv/multiview/projection.h" +#include "libmv/numeric/numeric.h" +#include "libmv/simple_pipeline/camera_intrinsics.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/distortion_models.h" + +#ifdef _OPENMP +# include +#endif + +namespace libmv { + +// The intrinsics need to get combined into a single parameter block; use these +// enums to index instead of numeric constants. +enum { + // Camera calibration values. + OFFSET_FOCAL_LENGTH, + OFFSET_PRINCIPAL_POINT_X, + OFFSET_PRINCIPAL_POINT_Y, + + // Distortion model coefficients. + OFFSET_K1, + OFFSET_K2, + OFFSET_K3, + OFFSET_P1, + OFFSET_P2, + + // Maximal possible offset. + OFFSET_MAX, +}; + +#define FIRST_DISTORTION_COEFFICIENT OFFSET_K1 +#define LAST_DISTORTION_COEFFICIENT OFFSET_P2 +#define NUM_DISTORTION_COEFFICIENTS \ + (LAST_DISTORTION_COEFFICIENT - FIRST_DISTORTION_COEFFICIENT + 1) + +namespace { + +// Cost functor which computes reprojection error of 3D point X +// on camera defined by angle-axis rotation and it's translation +// (which are in the same block due to optimization reasons). +// +// This functor uses a radial distortion model. +struct OpenCVReprojectionError { + OpenCVReprojectionError(const DistortionModelType distortion_model, + const double observed_x, + const double observed_y, + const double weight) + : distortion_model_(distortion_model), + observed_x_(observed_x), observed_y_(observed_y), + weight_(weight) {} + + template + bool operator()(const T* const intrinsics, + const T* const R_t, // Rotation denoted by angle axis + // followed with translation + const T* const X, // Point coordinates 3x1. + T* residuals) const { + // Unpack the intrinsics. + const T& focal_length = intrinsics[OFFSET_FOCAL_LENGTH]; + const T& principal_point_x = intrinsics[OFFSET_PRINCIPAL_POINT_X]; + const T& principal_point_y = intrinsics[OFFSET_PRINCIPAL_POINT_Y]; + + // Compute projective coordinates: x = RX + t. + T x[3]; + + ceres::AngleAxisRotatePoint(R_t, X, x); + x[0] += R_t[3]; + x[1] += R_t[4]; + x[2] += R_t[5]; + + // Prevent points from going behind the camera. + if (x[2] < T(0)) { + return false; + } + + // Compute normalized coordinates: x /= x[2]. + T xn = x[0] / x[2]; + T yn = x[1] / x[2]; + + T predicted_x, predicted_y; + + // Apply distortion to the normalized points to get (xd, yd). + // TODO(keir): Do early bailouts for zero distortion; these are expensive + // jet operations. + switch (distortion_model_) { + case DISTORTION_MODEL_POLYNOMIAL: + { + const T& k1 = intrinsics[OFFSET_K1]; + const T& k2 = intrinsics[OFFSET_K2]; + const T& k3 = intrinsics[OFFSET_K3]; + const T& p1 = intrinsics[OFFSET_P1]; + const T& p2 = intrinsics[OFFSET_P2]; + + ApplyPolynomialDistortionModel(focal_length, + focal_length, + principal_point_x, + principal_point_y, + k1, k2, k3, + p1, p2, + xn, yn, + &predicted_x, + &predicted_y); + break; + } + case DISTORTION_MODEL_DIVISION: + { + const T& k1 = intrinsics[OFFSET_K1]; + const T& k2 = intrinsics[OFFSET_K2]; + + ApplyDivisionDistortionModel(focal_length, + focal_length, + principal_point_x, + principal_point_y, + k1, k2, + xn, yn, + &predicted_x, + &predicted_y); + break; + } + default: + LOG(FATAL) << "Unknown distortion model"; + } + + // The error is the difference between the predicted and observed position. + residuals[0] = (predicted_x - T(observed_x_)) * weight_; + residuals[1] = (predicted_y - T(observed_y_)) * weight_; + return true; + } + + const DistortionModelType distortion_model_; + const double observed_x_; + const double observed_y_; + const double weight_; +}; + +// Print a message to the log which camera intrinsics are gonna to be optimixed. +void BundleIntrinsicsLogMessage(const int bundle_intrinsics) { + if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) { + LOG(INFO) << "Bundling only camera positions."; + } else { + std::string bundling_message = ""; + +#define APPEND_BUNDLING_INTRINSICS(name, flag) \ + if (bundle_intrinsics & flag) { \ + if (!bundling_message.empty()) { \ + bundling_message += ", "; \ + } \ + bundling_message += name; \ + } (void)0 + + APPEND_BUNDLING_INTRINSICS("f", BUNDLE_FOCAL_LENGTH); + APPEND_BUNDLING_INTRINSICS("px, py", BUNDLE_PRINCIPAL_POINT); + APPEND_BUNDLING_INTRINSICS("k1", BUNDLE_RADIAL_K1); + APPEND_BUNDLING_INTRINSICS("k2", BUNDLE_RADIAL_K2); + APPEND_BUNDLING_INTRINSICS("p1", BUNDLE_TANGENTIAL_P1); + APPEND_BUNDLING_INTRINSICS("p2", BUNDLE_TANGENTIAL_P2); + + LOG(INFO) << "Bundling " << bundling_message << "."; + } +} + +// Pack intrinsics from object to an array for easier +// and faster minimization. +void PackIntrinisicsIntoArray(const CameraIntrinsics &intrinsics, + double ceres_intrinsics[OFFSET_MAX]) { + ceres_intrinsics[OFFSET_FOCAL_LENGTH] = intrinsics.focal_length(); + ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X] = intrinsics.principal_point_x(); + ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y] = intrinsics.principal_point_y(); + + int num_distortion_parameters = intrinsics.num_distortion_parameters(); + assert(num_distortion_parameters <= NUM_DISTORTION_COEFFICIENTS); + + const double *distortion_parameters = intrinsics.distortion_parameters(); + for (int i = 0; i < num_distortion_parameters; ++i) { + ceres_intrinsics[FIRST_DISTORTION_COEFFICIENT + i] = + distortion_parameters[i]; + } +} + +// Unpack intrinsics back from an array to an object. +void UnpackIntrinsicsFromArray(const double ceres_intrinsics[OFFSET_MAX], + CameraIntrinsics *intrinsics) { + intrinsics->SetFocalLength(ceres_intrinsics[OFFSET_FOCAL_LENGTH], + ceres_intrinsics[OFFSET_FOCAL_LENGTH]); + + intrinsics->SetPrincipalPoint(ceres_intrinsics[OFFSET_PRINCIPAL_POINT_X], + ceres_intrinsics[OFFSET_PRINCIPAL_POINT_Y]); + + int num_distortion_parameters = intrinsics->num_distortion_parameters(); + assert(num_distortion_parameters <= NUM_DISTORTION_COEFFICIENTS); + + double *distortion_parameters = intrinsics->distortion_parameters(); + for (int i = 0; i < num_distortion_parameters; ++i) { + distortion_parameters[i] = + ceres_intrinsics[FIRST_DISTORTION_COEFFICIENT + i]; + } +} + +// Get a vector of camera's rotations denoted by angle axis +// conjuncted with translations into single block +// +// Element with index i matches to a rotation+translation for +// camera at image i. +vector PackCamerasRotationAndTranslation( + const Tracks &tracks, + const EuclideanReconstruction &reconstruction) { + vector all_cameras_R_t; + int max_image = tracks.MaxImage(); + + all_cameras_R_t.resize(max_image + 1); + + for (int i = 0; i <= max_image; i++) { + const EuclideanCamera *camera = reconstruction.CameraForImage(i); + + if (!camera) { + continue; + } + + ceres::RotationMatrixToAngleAxis(&camera->R(0, 0), + &all_cameras_R_t[i](0)); + all_cameras_R_t[i].tail<3>() = camera->t; + } + return all_cameras_R_t; +} + +// Convert cameras rotations fro mangle axis back to rotation matrix. +void UnpackCamerasRotationAndTranslation( + const Tracks &tracks, + const vector &all_cameras_R_t, + EuclideanReconstruction *reconstruction) { + int max_image = tracks.MaxImage(); + + for (int i = 0; i <= max_image; i++) { + EuclideanCamera *camera = reconstruction->CameraForImage(i); + + if (!camera) { + continue; + } + + ceres::AngleAxisToRotationMatrix(&all_cameras_R_t[i](0), + &camera->R(0, 0)); + camera->t = all_cameras_R_t[i].tail<3>(); + } +} + +// Converts sparse CRSMatrix to Eigen matrix, so it could be used +// all over in the pipeline. +// +// TODO(sergey): currently uses dense Eigen matrices, best would +// be to use sparse Eigen matrices +void CRSMatrixToEigenMatrix(const ceres::CRSMatrix &crs_matrix, + Mat *eigen_matrix) { + eigen_matrix->resize(crs_matrix.num_rows, crs_matrix.num_cols); + eigen_matrix->setZero(); + + for (int row = 0; row < crs_matrix.num_rows; ++row) { + int start = crs_matrix.rows[row]; + int end = crs_matrix.rows[row + 1] - 1; + + for (int i = start; i <= end; i++) { + int col = crs_matrix.cols[i]; + double value = crs_matrix.values[i]; + + (*eigen_matrix)(row, col) = value; + } + } +} + +void EuclideanBundlerPerformEvaluation(const Tracks &tracks, + EuclideanReconstruction *reconstruction, + vector *all_cameras_R_t, + ceres::Problem *problem, + BundleEvaluation *evaluation) { + int max_track = tracks.MaxTrack(); + // Number of camera rotations equals to number of translation, + int num_cameras = all_cameras_R_t->size(); + int num_points = 0; + + vector minimized_points; + for (int i = 0; i <= max_track; i++) { + EuclideanPoint *point = reconstruction->PointForTrack(i); + if (point) { + // We need to know whether the track is constant zero weight, + // and it so it wouldn't have parameter block in the problem. + // + // Getting all markers for track is not so bac currently since + // this code is only used by keyframe selection when there are + // not so much tracks and only 2 frames anyway. + vector markera_of_track = tracks.MarkersForTrack(i); + for (int j = 0; j < markera_of_track.size(); j++) { + if (markera_of_track.at(j).weight != 0.0) { + minimized_points.push_back(point); + num_points++; + break; + } + } + } + } + + LG << "Number of cameras " << num_cameras; + LG << "Number of points " << num_points; + + evaluation->num_cameras = num_cameras; + evaluation->num_points = num_points; + + if (evaluation->evaluate_jacobian) { // Evaluate jacobian matrix. + ceres::CRSMatrix evaluated_jacobian; + ceres::Problem::EvaluateOptions eval_options; + + // Cameras goes first in the ordering. + int max_image = tracks.MaxImage(); + for (int i = 0; i <= max_image; i++) { + const EuclideanCamera *camera = reconstruction->CameraForImage(i); + if (camera) { + double *current_camera_R_t = &(*all_cameras_R_t)[i](0); + + // All cameras are variable now. + problem->SetParameterBlockVariable(current_camera_R_t); + + eval_options.parameter_blocks.push_back(current_camera_R_t); + } + } + + // Points goes at the end of ordering, + for (int i = 0; i < minimized_points.size(); i++) { + EuclideanPoint *point = minimized_points.at(i); + eval_options.parameter_blocks.push_back(&point->X(0)); + } + + problem->Evaluate(eval_options, + NULL, NULL, NULL, + &evaluated_jacobian); + + CRSMatrixToEigenMatrix(evaluated_jacobian, &evaluation->jacobian); + } +} + +// This is an utility function to only bundle 3D position of +// given markers list. +// +// Main purpose of this function is to adjust positions of tracks +// which does have constant zero weight and so far only were using +// algebraic intersection to obtain their 3D positions. +// +// At this point we only need to bundle points positions, cameras +// are to be totally still here. +void EuclideanBundlePointsOnly(const DistortionModelType distortion_model, + const vector &markers, + vector &all_cameras_R_t, + double ceres_intrinsics[OFFSET_MAX], + EuclideanReconstruction *reconstruction) { + ceres::Problem::Options problem_options; + ceres::Problem problem(problem_options); + int num_residuals = 0; + for (int i = 0; i < markers.size(); ++i) { + const Marker &marker = markers[i]; + EuclideanCamera *camera = reconstruction->CameraForImage(marker.image); + EuclideanPoint *point = reconstruction->PointForTrack(marker.track); + if (camera == NULL || point == NULL) { + continue; + } + + // Rotation of camera denoted in angle axis followed with + // camera translaiton. + double *current_camera_R_t = &all_cameras_R_t[camera->image](0); + + problem.AddResidualBlock(new ceres::AutoDiffCostFunction< + OpenCVReprojectionError, 2, OFFSET_MAX, 6, 3>( + new OpenCVReprojectionError( + distortion_model, + marker.x, + marker.y, + 1.0)), + NULL, + ceres_intrinsics, + current_camera_R_t, + &point->X(0)); + + problem.SetParameterBlockConstant(current_camera_R_t); + num_residuals++; + } + + LG << "Number of residuals: " << num_residuals; + if (!num_residuals) { + LG << "Skipping running minimizer with zero residuals"; + return; + } + + problem.SetParameterBlockConstant(ceres_intrinsics); + + // Configure the solver. + ceres::Solver::Options options; + options.use_nonmonotonic_steps = true; + options.preconditioner_type = ceres::SCHUR_JACOBI; + options.linear_solver_type = ceres::ITERATIVE_SCHUR; + options.use_explicit_schur_complement = true; + options.use_inner_iterations = true; + options.max_num_iterations = 100; + +#ifdef _OPENMP + options.num_threads = omp_get_max_threads(); + options.num_linear_solver_threads = omp_get_max_threads(); +#endif + + // Solve! + ceres::Solver::Summary summary; + ceres::Solve(options, &problem, &summary); + + LG << "Final report:\n" << summary.FullReport(); + +} + +} // namespace + +void EuclideanBundle(const Tracks &tracks, + EuclideanReconstruction *reconstruction) { + PolynomialCameraIntrinsics empty_intrinsics; + EuclideanBundleCommonIntrinsics(tracks, + BUNDLE_NO_INTRINSICS, + BUNDLE_NO_CONSTRAINTS, + reconstruction, + &empty_intrinsics, + NULL); +} + +void EuclideanBundleCommonIntrinsics( + const Tracks &tracks, + const int bundle_intrinsics, + const int bundle_constraints, + EuclideanReconstruction *reconstruction, + CameraIntrinsics *intrinsics, + BundleEvaluation *evaluation) { + LG << "Original intrinsics: " << *intrinsics; + vector markers = tracks.AllMarkers(); + + // N-th element denotes whether track N is a constant zero-weigthed track. + vector zero_weight_tracks_flags(tracks.MaxTrack() + 1, true); + + // Residual blocks with 10 parameters are unwieldly with Ceres, so pack the + // intrinsics into a single block and rely on local parameterizations to + // control which intrinsics are allowed to vary. + double ceres_intrinsics[OFFSET_MAX]; + PackIntrinisicsIntoArray(*intrinsics, ceres_intrinsics); + + // Convert cameras rotations to angle axis and merge with translation + // into single parameter block for maximal minimization speed. + // + // Block for minimization has got the following structure: + // <3 elements for angle-axis> <3 elements for translation> + vector all_cameras_R_t = + PackCamerasRotationAndTranslation(tracks, *reconstruction); + + // Parameterization used to restrict camera motion for modal solvers. + ceres::SubsetParameterization *constant_translation_parameterization = NULL; + if (bundle_constraints & BUNDLE_NO_TRANSLATION) { + std::vector constant_translation; + + // First three elements are rotation, ast three are translation. + constant_translation.push_back(3); + constant_translation.push_back(4); + constant_translation.push_back(5); + + constant_translation_parameterization = + new ceres::SubsetParameterization(6, constant_translation); + } + + // Add residual blocks to the problem. + ceres::Problem::Options problem_options; + ceres::Problem problem(problem_options); + int num_residuals = 0; + bool have_locked_camera = false; + for (int i = 0; i < markers.size(); ++i) { + const Marker &marker = markers[i]; + EuclideanCamera *camera = reconstruction->CameraForImage(marker.image); + EuclideanPoint *point = reconstruction->PointForTrack(marker.track); + if (camera == NULL || point == NULL) { + continue; + } + + // Rotation of camera denoted in angle axis followed with + // camera translaiton. + double *current_camera_R_t = &all_cameras_R_t[camera->image](0); + + // Skip residual block for markers which does have absolutely + // no affect on the final solution. + // This way ceres is not gonna to go crazy. + if (marker.weight != 0.0) { + problem.AddResidualBlock(new ceres::AutoDiffCostFunction< + OpenCVReprojectionError, 2, OFFSET_MAX, 6, 3>( + new OpenCVReprojectionError( + intrinsics->GetDistortionModelType(), + marker.x, + marker.y, + marker.weight)), + NULL, + ceres_intrinsics, + current_camera_R_t, + &point->X(0)); + + // We lock the first camera to better deal with scene orientation ambiguity. + if (!have_locked_camera) { + problem.SetParameterBlockConstant(current_camera_R_t); + have_locked_camera = true; + } + + if (bundle_constraints & BUNDLE_NO_TRANSLATION) { + problem.SetParameterization(current_camera_R_t, + constant_translation_parameterization); + } + + zero_weight_tracks_flags[marker.track] = false; + num_residuals++; + } + } + LG << "Number of residuals: " << num_residuals; + + if (!num_residuals) { + LG << "Skipping running minimizer with zero residuals"; + return; + } + + if (intrinsics->GetDistortionModelType() == DISTORTION_MODEL_DIVISION && + (bundle_intrinsics & BUNDLE_TANGENTIAL) != 0) { + LOG(FATAL) << "Division model doesn't support bundling " + "of tangential distortion"; + } + + BundleIntrinsicsLogMessage(bundle_intrinsics); + + if (bundle_intrinsics == BUNDLE_NO_INTRINSICS) { + // No camera intrinsics are being refined, + // set the whole parameter block as constant for best performance. + problem.SetParameterBlockConstant(ceres_intrinsics); + } else { + // Set the camera intrinsics that are not to be bundled as + // constant using some macro trickery. + + std::vector constant_intrinsics; +#define MAYBE_SET_CONSTANT(bundle_enum, offset) \ + if (!(bundle_intrinsics & bundle_enum)) { \ + constant_intrinsics.push_back(offset); \ + } + MAYBE_SET_CONSTANT(BUNDLE_FOCAL_LENGTH, OFFSET_FOCAL_LENGTH); + MAYBE_SET_CONSTANT(BUNDLE_PRINCIPAL_POINT, OFFSET_PRINCIPAL_POINT_X); + MAYBE_SET_CONSTANT(BUNDLE_PRINCIPAL_POINT, OFFSET_PRINCIPAL_POINT_Y); + MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K1, OFFSET_K1); + MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K2, OFFSET_K2); + MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P1, OFFSET_P1); + MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P2, OFFSET_P2); +#undef MAYBE_SET_CONSTANT + + // Always set K3 constant, it's not used at the moment. + constant_intrinsics.push_back(OFFSET_K3); + + ceres::SubsetParameterization *subset_parameterization = + new ceres::SubsetParameterization(OFFSET_MAX, constant_intrinsics); + + problem.SetParameterization(ceres_intrinsics, subset_parameterization); + } + + // Configure the solver. + ceres::Solver::Options options; + options.use_nonmonotonic_steps = true; + options.preconditioner_type = ceres::SCHUR_JACOBI; + options.linear_solver_type = ceres::ITERATIVE_SCHUR; + options.use_explicit_schur_complement = true; + options.use_inner_iterations = true; + options.max_num_iterations = 100; + +#ifdef _OPENMP + options.num_threads = omp_get_max_threads(); + options.num_linear_solver_threads = omp_get_max_threads(); +#endif + + // Solve! + ceres::Solver::Summary summary; + ceres::Solve(options, &problem, &summary); + + LG << "Final report:\n" << summary.FullReport(); + + // Copy rotations and translations back. + UnpackCamerasRotationAndTranslation(tracks, + all_cameras_R_t, + reconstruction); + + // Copy intrinsics back. + if (bundle_intrinsics != BUNDLE_NO_INTRINSICS) + UnpackIntrinsicsFromArray(ceres_intrinsics, intrinsics); + + LG << "Final intrinsics: " << *intrinsics; + + if (evaluation) { + EuclideanBundlerPerformEvaluation(tracks, reconstruction, &all_cameras_R_t, + &problem, evaluation); + } + + // Separate step to adjust positions of tracks which are + // constant zero-weighted. + vector zero_weight_markers; + for (int track = 0; track < tracks.MaxTrack(); ++track) { + if (zero_weight_tracks_flags[track]) { + vector current_markers = tracks.MarkersForTrack(track); + zero_weight_markers.reserve(zero_weight_markers.size() + + current_markers.size()); + for (int i = 0; i < current_markers.size(); ++i) { + zero_weight_markers.push_back(current_markers[i]); + } + } + } + + if (zero_weight_markers.size()) { + LG << "Refining position of constant zero-weighted tracks"; + EuclideanBundlePointsOnly(intrinsics->GetDistortionModelType(), + zero_weight_markers, + all_cameras_R_t, + ceres_intrinsics, + reconstruction); + } +} + +void ProjectiveBundle(const Tracks & /*tracks*/, + ProjectiveReconstruction * /*reconstruction*/) { + // TODO(keir): Implement this! This can't work until we have a better bundler + // than SSBA, since SSBA has no support for projective bundling. +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/bundle.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/bundle.h new file mode 100644 index 0000000000..06aafdf876 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/bundle.h @@ -0,0 +1,147 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_BUNDLE_H +#define LIBMV_SIMPLE_PIPELINE_BUNDLE_H + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +class CameraIntrinsics; +class EuclideanReconstruction; +class ProjectiveReconstruction; +class Tracks; + +struct BundleEvaluation { + BundleEvaluation() : + num_cameras(0), + num_points(0), + evaluate_jacobian(false) { + } + + // Number of cameras appeared in bundle adjustment problem + int num_cameras; + + // Number of points appeared in bundle adjustment problem + int num_points; + + // When set to truth, jacobian of the problem after optimization + // will be evaluated and stored in \parameter jacobian + bool evaluate_jacobian; + + // Contains evaluated jacobian of the problem. + // Parameters are ordered in the following way: + // - Intrinsics block + // - Cameras (for each camera rotation goes first, then translation) + // - Points + Mat jacobian; +}; + +/*! + Refine camera poses and 3D coordinates using bundle adjustment. + + This routine adjusts all cameras and points in \a *reconstruction. This + assumes a full observation for reconstructed tracks; this implies that if + there is a reconstructed 3D point (a bundle) for a track, then all markers + for that track will be included in the minimization. \a tracks should + contain markers used in the initial reconstruction. + + The cameras and bundles (3D points) are refined in-place. + + \note This assumes an outlier-free set of markers. + \note This assumes a calibrated reconstruction, e.g. the markers are + already corrected for camera intrinsics and radial distortion. + + \sa EuclideanResect, EuclideanIntersect, EuclideanReconstructTwoFrames +*/ +void EuclideanBundle(const Tracks &tracks, + EuclideanReconstruction *reconstruction); + +/*! + Refine camera poses and 3D coordinates using bundle adjustment. + + This routine adjusts all cameras positions, points, and the camera + intrinsics (assumed common across all images) in \a *reconstruction. This + assumes a full observation for reconstructed tracks; this implies that if + there is a reconstructed 3D point (a bundle) for a track, then all markers + for that track will be included in the minimization. \a tracks should + contain markers used in the initial reconstruction. + + The cameras, bundles, and intrinsics are refined in-place. + + Constraints denotes which blocks to keep constant during bundling. + For example it is useful to keep camera translations constant + when bundling tripod motions. + + If evaluaiton is not null, different evaluation statistics is filled in + there, plus all the requested additional information (like jacobian) is + also calculating there. Also see comments for BundleEvaluation. + + \note This assumes an outlier-free set of markers. + + \sa EuclideanResect, EuclideanIntersect, EuclideanReconstructTwoFrames +*/ +enum BundleIntrinsics { + BUNDLE_NO_INTRINSICS = 0, + BUNDLE_FOCAL_LENGTH = 1, + BUNDLE_PRINCIPAL_POINT = 2, + BUNDLE_RADIAL_K1 = 4, + BUNDLE_RADIAL_K2 = 8, + BUNDLE_RADIAL = 12, + BUNDLE_TANGENTIAL_P1 = 16, + BUNDLE_TANGENTIAL_P2 = 32, + BUNDLE_TANGENTIAL = 48, +}; +enum BundleConstraints { + BUNDLE_NO_CONSTRAINTS = 0, + BUNDLE_NO_TRANSLATION = 1, +}; +void EuclideanBundleCommonIntrinsics( + const Tracks &tracks, + const int bundle_intrinsics, + const int bundle_constraints, + EuclideanReconstruction *reconstruction, + CameraIntrinsics *intrinsics, + BundleEvaluation *evaluation = NULL); + +/*! + Refine camera poses and 3D coordinates using bundle adjustment. + + This routine adjusts all cameras and points in \a *reconstruction. This + assumes a full observation for reconstructed tracks; this implies that if + there is a reconstructed 3D point (a bundle) for a track, then all markers + for that track will be included in the minimization. \a tracks should + contain markers used in the initial reconstruction. + + The cameras and bundles (homogeneous 3D points) are refined in-place. + + \note This assumes an outlier-free set of markers. + \note This assumes that radial distortion is already corrected for, but + does not assume that that other intrinsics are. + + \sa ProjectiveResect, ProjectiveIntersect, ProjectiveReconstructTwoFrames +*/ +void ProjectiveBundle(const Tracks &tracks, + ProjectiveReconstruction *reconstruction); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_BUNDLE_H \ No newline at end of file diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/callbacks.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/callbacks.h new file mode 100644 index 0000000000..58f7b0d3cc --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/callbacks.h @@ -0,0 +1,34 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_CALLBACKS_H_ +#define LIBMV_SIMPLE_PIPELINE_CALLBACKS_H_ + +namespace libmv { + +class ProgressUpdateCallback { + public: + virtual ~ProgressUpdateCallback() {} + virtual void invoke(double progress, const char *message) = 0; +}; + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_MARKERS_H_ diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics.cc new file mode 100644 index 0000000000..5e4e07b3c4 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics.cc @@ -0,0 +1,293 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/camera_intrinsics.h" + +#include "libmv/logging/logging.h" +#include "libmv/simple_pipeline/distortion_models.h" + +namespace libmv { + +namespace internal { + +LookupWarpGrid::LookupWarpGrid() + : offset_(NULL), + width_(0), + height_(0), + overscan_(0.0), + threads_(1) {} + +LookupWarpGrid::LookupWarpGrid(const LookupWarpGrid &from) + : offset_(NULL), + width_(from.width_), + height_(from.height_), + overscan_(from.overscan_), + threads_(from.threads_) { + if (from.offset_) { + offset_ = new Offset[width_ * height_]; + memcpy(offset_, from.offset_, sizeof(Offset) * width_ * height_); + } +} + +LookupWarpGrid::~LookupWarpGrid() { + delete [] offset_; +} + +void LookupWarpGrid::Reset() { + delete [] offset_; + offset_ = NULL; +} + +// Set number of threads used for threaded buffer distortion/undistortion. +void LookupWarpGrid::SetThreads(int threads) { + threads_ = threads; +} + +} // namespace internal + +CameraIntrinsics::CameraIntrinsics() + : image_width_(0), + image_height_(0), + K_(Mat3::Identity()) {} + +CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from) + : image_width_(from.image_width_), + image_height_(from.image_height_), + K_(from.K_), + distort_(from.distort_), + undistort_(from.undistort_) {} + +// Set the image size in pixels. +void CameraIntrinsics::SetImageSize(int width, int height) { + image_width_ = width; + image_height_ = height; + ResetLookupGrids(); +} + +// Set the entire calibration matrix at once. +void CameraIntrinsics::SetK(const Mat3 new_k) { + K_ = new_k; + ResetLookupGrids(); +} + +// Set both x and y focal length in pixels. +void CameraIntrinsics::SetFocalLength(double focal_x, + double focal_y) { + K_(0, 0) = focal_x; + K_(1, 1) = focal_y; + ResetLookupGrids(); +} + +// Set principal point in pixels. +void CameraIntrinsics::SetPrincipalPoint(double cx, + double cy) { + K_(0, 2) = cx; + K_(1, 2) = cy; + ResetLookupGrids(); +} + +// Set number of threads used for threaded buffer distortion/undistortion. +void CameraIntrinsics::SetThreads(int threads) { + distort_.SetThreads(threads); + undistort_.SetThreads(threads); +} + +void CameraIntrinsics::ImageSpaceToNormalized(double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const { + *normalized_x = (image_x - principal_point_x()) / focal_length_x(); + *normalized_y = (image_y - principal_point_y()) / focal_length_y(); +} + +void CameraIntrinsics::NormalizedToImageSpace(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const { + *image_x = normalized_x * focal_length_x() + principal_point_x(); + *image_y = normalized_y * focal_length_y() + principal_point_y(); +} + +// Reset lookup grids after changing the distortion model. +void CameraIntrinsics::ResetLookupGrids() { + distort_.Reset(); + undistort_.Reset(); +} + +PolynomialCameraIntrinsics::PolynomialCameraIntrinsics() + : CameraIntrinsics() { + SetRadialDistortion(0.0, 0.0, 0.0); + SetTangentialDistortion(0.0, 0.0); +} + +PolynomialCameraIntrinsics::PolynomialCameraIntrinsics( + const PolynomialCameraIntrinsics &from) + : CameraIntrinsics(from) { + SetRadialDistortion(from.k1(), from.k2(), from.k3()); + SetTangentialDistortion(from.p1(), from.p2()); +} + +void PolynomialCameraIntrinsics::SetRadialDistortion(double k1, + double k2, + double k3) { + parameters_[OFFSET_K1] = k1; + parameters_[OFFSET_K2] = k2; + parameters_[OFFSET_K3] = k3; + ResetLookupGrids(); +} + +void PolynomialCameraIntrinsics::SetTangentialDistortion(double p1, + double p2) { + parameters_[OFFSET_P1] = p1; + parameters_[OFFSET_P2] = p2; + ResetLookupGrids(); +} + +void PolynomialCameraIntrinsics::ApplyIntrinsics(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const { + ApplyPolynomialDistortionModel(focal_length_x(), + focal_length_y(), + principal_point_x(), + principal_point_y(), + k1(), k2(), k3(), + p1(), p2(), + normalized_x, + normalized_y, + image_x, + image_y); +} + +void PolynomialCameraIntrinsics::InvertIntrinsics( + double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const { + InvertPolynomialDistortionModel(focal_length_x(), + focal_length_y(), + principal_point_x(), + principal_point_y(), + k1(), k2(), k3(), + p1(), p2(), + image_x, + image_y, + normalized_x, + normalized_y); +} + +DivisionCameraIntrinsics::DivisionCameraIntrinsics() + : CameraIntrinsics() { + SetDistortion(0.0, 0.0); +} + +DivisionCameraIntrinsics::DivisionCameraIntrinsics( + const DivisionCameraIntrinsics &from) + : CameraIntrinsics(from) { + SetDistortion(from.k1(), from.k1()); +} + +void DivisionCameraIntrinsics::SetDistortion(double k1, + double k2) { + parameters_[OFFSET_K1] = k1; + parameters_[OFFSET_K2] = k2; + ResetLookupGrids(); +} + +void DivisionCameraIntrinsics::ApplyIntrinsics(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const { + ApplyDivisionDistortionModel(focal_length_x(), + focal_length_y(), + principal_point_x(), + principal_point_y(), + k1(), k2(), + normalized_x, + normalized_y, + image_x, + image_y); +} + +void DivisionCameraIntrinsics::InvertIntrinsics(double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const { + InvertDivisionDistortionModel(focal_length_x(), + focal_length_y(), + principal_point_x(), + principal_point_y(), + k1(), k2(), + image_x, + image_y, + normalized_x, + normalized_y); +} + +std::ostream& operator <<(std::ostream &os, + const CameraIntrinsics &intrinsics) { + if (intrinsics.focal_length_x() == intrinsics.focal_length_x()) { + os << "f=" << intrinsics.focal_length(); + } else { + os << "fx=" << intrinsics.focal_length_x() + << " fy=" << intrinsics.focal_length_y(); + } + os << " cx=" << intrinsics.principal_point_x() + << " cy=" << intrinsics.principal_point_y() + << " w=" << intrinsics.image_width() + << " h=" << intrinsics.image_height(); + +#define PRINT_NONZERO_COEFFICIENT(intrinsics, coeff) \ + { \ + if (intrinsics->coeff() != 0.0) { \ + os << " " #coeff "=" << intrinsics->coeff(); \ + } \ + } (void) 0 + + switch (intrinsics.GetDistortionModelType()) { + case DISTORTION_MODEL_POLYNOMIAL: + { + const PolynomialCameraIntrinsics *polynomial_intrinsics = + static_cast(&intrinsics); + PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k1); + PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k2); + PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, k3); + PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, p1); + PRINT_NONZERO_COEFFICIENT(polynomial_intrinsics, p2); + break; + } + case DISTORTION_MODEL_DIVISION: + { + const DivisionCameraIntrinsics *division_intrinsics = + static_cast(&intrinsics); + PRINT_NONZERO_COEFFICIENT(division_intrinsics, k1); + PRINT_NONZERO_COEFFICIENT(division_intrinsics, k2); + break; + } + default: + LOG(FATAL) << "Unknown distortion model."; + } + +#undef PRINT_NONZERO_COEFFICIENT + + return os; +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics.h new file mode 100644 index 0000000000..6a3ade8108 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics.h @@ -0,0 +1,406 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_ +#define LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_ + +#include +#include + +#include + +#include "libmv/numeric/numeric.h" +#include "libmv/simple_pipeline/distortion_models.h" + +namespace libmv { + +class CameraIntrinsics; + +namespace internal { + +// This class is responsible to store a lookup grid to perform +// image warping using this lookup grid. Such a magic is needed +// to make (un)distortion as fast as possible in cases multiple +// images are to be processed. +class LookupWarpGrid { + public: + LookupWarpGrid(); + LookupWarpGrid(const LookupWarpGrid &from); + ~LookupWarpGrid(); + + // Width and height og the image, measured in pixels. + int width() const { return width_; } + int height() const { return height_; } + + // Overscan factor of the image, so that + // - 0.0 is overscan of 0 pixels, + // - 1.0 is overscan of image weight pixels in horizontal direction + // and image height pixels in vertical direction. + double overscan() const { return overscan_; } + + // Update lookup grid in order to be sure it's calculated for + // given image width, height and overscan. + // + // See comment for CameraIntrinsics::DistortBuffer to get more + // details about what overscan is. + template + void Update(const CameraIntrinsics &intrinsics, + int width, + int height, + double overscan); + + // Apply coordinate lookup grid on a giver input buffer. + // + // See comment for CameraIntrinsics::DistortBuffer to get more + // details about template type. + template + void Apply(const PixelType *input_buffer, + int width, + int height, + int channels, + PixelType *output_buffer); + + // Reset lookup grids. + // This will tag the grid for update without re-computing it. + void Reset(); + + // Set number of threads used for threaded buffer distortion/undistortion. + void SetThreads(int threads); + + private: + // This structure contains an offset in both x,y directions + // in an optimized way sawing some bytes per pixel in the memory. + // + // TODO(sergey): This is rather questionable optimizations, memory + // is cheap nowadays and storing offset in such a way implies much + // more operations comparing to using bare floats. + struct Offset { + // Integer part of the offset. + short ix, iy; + + // Float part of an offset, to get a real float value divide this + // value by 255. + unsigned char fx, fy; + }; + + // Compute coordinate lookup grid using a giver warp functor. + // + // width and height corresponds to a size of buffer which will + // be warped later. + template + void Compute(const CameraIntrinsics &intrinsics, + int width, + int height, + double overscan); + + // This is a buffer which contains per-pixel offset of the + // pixels from input buffer to correspond the warping function. + Offset *offset_; + + // Dimensions of the image this lookup grid processes. + int width_, height_; + + // Overscan of the image being processed by this grid. + double overscan_; + + // Number of threads which will be used for buffer istortion/undistortion. + int threads_; +}; + +} // namespace internal + +class CameraIntrinsics { + public: + CameraIntrinsics(); + CameraIntrinsics(const CameraIntrinsics &from); + virtual ~CameraIntrinsics() {} + + virtual DistortionModelType GetDistortionModelType() const = 0; + + int image_width() const { return image_width_; } + int image_height() const { return image_height_; } + + const Mat3 &K() const { return K_; } + + double focal_length() const { return K_(0, 0); } + double focal_length_x() const { return K_(0, 0); } + double focal_length_y() const { return K_(1, 1); } + + double principal_point_x() const { return K_(0, 2); } + double principal_point_y() const { return K_(1, 2); } + + virtual int num_distortion_parameters() const = 0; + virtual double *distortion_parameters() = 0; + virtual const double *distortion_parameters() const = 0; + + // Set the image size in pixels. + // Image is the size of image camera intrinsics were calibrated with. + void SetImageSize(int width, int height); + + // Set the entire calibration matrix at once. + void SetK(const Mat3 new_k); + + // Set both x and y focal length in pixels. + void SetFocalLength(double focal_x, double focal_y); + + // Set principal point in pixels. + void SetPrincipalPoint(double cx, double cy); + + // Set number of threads used for threaded buffer distortion/undistortion. + void SetThreads(int threads); + + // Convert image space coordinates to normalized. + void ImageSpaceToNormalized(double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const; + + // Convert normalized coordinates to image space. + void NormalizedToImageSpace(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const; + + // Apply camera intrinsics to the normalized point to get image coordinates. + // + // This applies the lens distortion to a point which is in normalized + // camera coordinates (i.e. the principal point is at (0, 0)) to get image + // coordinates in pixels. + virtual void ApplyIntrinsics(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const = 0; + + // Invert camera intrinsics on the image point to get normalized coordinates. + // + // This reverses the effect of lens distortion on a point which is in image + // coordinates to get normalized camera coordinates. + virtual void InvertIntrinsics(double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const = 0; + + // Distort an image using the current camera instrinsics + // + // The distorted image is computed in output_buffer using samples from + // input_buffer. Both buffers should be width x height x channels sized. + // + // Overscan is a percentage value of how much overcan the image have. + // For example overscal value of 0.2 means 20% of overscan in the + // buffers. + // + // Overscan is usually used in cases when one need to distort an image + // and don't have a barrel in the distorted buffer. For example, when + // one need to render properly distorted FullHD frame without barrel + // visible. For such cases renderers usually renders bigger images and + // crops them after the distortion. + // + // This method is templated to be able to distort byte and float buffers + // without having separate methods for this two types. So basically only + // + // But in fact PixelType might be any type for which multiplication by + // a scalar and addition are implemented. For example PixelType might be + // Vec3 as well. + template + void DistortBuffer(const PixelType *input_buffer, + int width, + int height, + double overscan, + int channels, + PixelType *output_buffer); + + // Undistort an image using the current camera instrinsics + // + // The undistorted image is computed in output_buffer using samples from + // input_buffer. Both buffers should be width x height x channels sized. + // + // Overscan is a percentage value of how much overcan the image have. + // For example overscal value of 0.2 means 20% of overscan in the + // buffers. + // + // Overscan is usually used in cases when one need to distort an image + // and don't have a barrel in the distorted buffer. For example, when + // one need to render properly distorted FullHD frame without barrel + // visible. For such cases renderers usually renders bigger images and + // crops them after the distortion. + // + // This method is templated to be able to distort byte and float buffers + // without having separate methods for this two types. So basically only + // + // But in fact PixelType might be any type for which multiplication by + // a scalar and addition are implemented. For example PixelType might be + // Vec3 as well. + template + void UndistortBuffer(const PixelType *input_buffer, + int width, + int height, + double overscan, + int channels, + PixelType *output_buffer); + + private: + // This is the size of the image. This is necessary to, for example, handle + // the case of processing a scaled image. + int image_width_; + int image_height_; + + // The traditional intrinsics matrix from x = K[R|t]X. + Mat3 K_; + + // Coordinate lookup grids for distortion and undistortion. + internal::LookupWarpGrid distort_; + internal::LookupWarpGrid undistort_; + + protected: + // Reset lookup grids after changing the distortion model. + void ResetLookupGrids(); +}; + +class PolynomialCameraIntrinsics : public CameraIntrinsics { + public: + // This constants defines an offset of corresponding coefficients + // in the arameters_ array. + enum { + OFFSET_K1, + OFFSET_K2, + OFFSET_K3, + OFFSET_P1, + OFFSET_P2, + + // This defines the size of array which we need to have in order + // to store all the coefficients. + NUM_PARAMETERS, + }; + + PolynomialCameraIntrinsics(); + PolynomialCameraIntrinsics(const PolynomialCameraIntrinsics &from); + + DistortionModelType GetDistortionModelType() const { + return DISTORTION_MODEL_POLYNOMIAL; + } + + int num_distortion_parameters() const { return NUM_PARAMETERS; } + double *distortion_parameters() { return parameters_; }; + const double *distortion_parameters() const { return parameters_; }; + + double k1() const { return parameters_[OFFSET_K1]; } + double k2() const { return parameters_[OFFSET_K2]; } + double k3() const { return parameters_[OFFSET_K3]; } + double p1() const { return parameters_[OFFSET_P1]; } + double p2() const { return parameters_[OFFSET_P2]; } + + // Set radial distortion coeffcients. + void SetRadialDistortion(double k1, double k2, double k3); + + // Set tangential distortion coeffcients. + void SetTangentialDistortion(double p1, double p2); + + // Apply camera intrinsics to the normalized point to get image coordinates. + // + // This applies the lens distortion to a point which is in normalized + // camera coordinates (i.e. the principal point is at (0, 0)) to get image + // coordinates in pixels. + void ApplyIntrinsics(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const; + + // Invert camera intrinsics on the image point to get normalized coordinates. + // + // This reverses the effect of lens distortion on a point which is in image + // coordinates to get normalized camera coordinates. + void InvertIntrinsics(double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const; + + private: + // OpenCV's distortion model with third order polynomial radial distortion + // terms and second order tangential distortion. The distortion is applied to + // the normalized coordinates before the focal length, which makes them + // independent of image size. + double parameters_[NUM_PARAMETERS]; +}; + +class DivisionCameraIntrinsics : public CameraIntrinsics { + public: + // This constants defines an offset of corresponding coefficients + // in the arameters_ array. + enum { + OFFSET_K1, + OFFSET_K2, + + // This defines the size of array which we need to have in order + // to store all the coefficients. + NUM_PARAMETERS, + }; + + DivisionCameraIntrinsics(); + DivisionCameraIntrinsics(const DivisionCameraIntrinsics &from); + + DistortionModelType GetDistortionModelType() const { + return DISTORTION_MODEL_DIVISION; + } + + int num_distortion_parameters() const { return NUM_PARAMETERS; } + double *distortion_parameters() { return parameters_; }; + const double *distortion_parameters() const { return parameters_; }; + + double k1() const { return parameters_[OFFSET_K1]; } + double k2() const { return parameters_[OFFSET_K2]; } + + // Set radial distortion coeffcients. + void SetDistortion(double k1, double k2); + + // Apply camera intrinsics to the normalized point to get image coordinates. + // + // This applies the lens distortion to a point which is in normalized + // camera coordinates (i.e. the principal point is at (0, 0)) to get image + // coordinates in pixels. + void ApplyIntrinsics(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const; + + // Invert camera intrinsics on the image point to get normalized coordinates. + // + // This reverses the effect of lens distortion on a point which is in image + // coordinates to get normalized camera coordinates. + void InvertIntrinsics(double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const; + + private: + // Double-parameter division distortion model. + double parameters_[NUM_PARAMETERS]; +}; + +/// A human-readable representation of the camera intrinsic parameters. +std::ostream& operator <<(std::ostream &os, + const CameraIntrinsics &intrinsics); + +} // namespace libmv + +// Include implementation of all templated methods here, +// so they're visible to the compiler. +#include "libmv/simple_pipeline/camera_intrinsics_impl.h" + +#endif // LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_ diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics_impl.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics_impl.h new file mode 100644 index 0000000000..97abee7ab0 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/camera_intrinsics_impl.h @@ -0,0 +1,192 @@ +// Copyright (c) 2014 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +namespace libmv { + +namespace { + +// FIXME: C++ templates limitations makes thing complicated, +// but maybe there is a simpler method. +struct ApplyIntrinsicsFunction { + ApplyIntrinsicsFunction(const CameraIntrinsics &intrinsics, + double x, + double y, + double *warp_x, + double *warp_y) { + double normalized_x, normalized_y; + intrinsics.ImageSpaceToNormalized(x, y, &normalized_x, &normalized_y); + intrinsics.ApplyIntrinsics(normalized_x, normalized_y, warp_x, warp_y); + } +}; + +struct InvertIntrinsicsFunction { + InvertIntrinsicsFunction(const CameraIntrinsics &intrinsics, + double x, + double y, + double *warp_x, + double *warp_y) { + double normalized_x, normalized_y; + intrinsics.InvertIntrinsics(x, y, &normalized_x, &normalized_y); + intrinsics.NormalizedToImageSpace(normalized_x, normalized_y, warp_x, warp_y); + } +}; + +} // namespace + +namespace internal { + +// TODO(MatthiasF): downsample lookup +template +void LookupWarpGrid::Compute(const CameraIntrinsics &intrinsics, + int width, + int height, + double overscan) { + double w = (double) width / (1.0 + overscan); + double h = (double) height / (1.0 + overscan); + double aspx = (double) w / intrinsics.image_width(); + double aspy = (double) h / intrinsics.image_height(); +#if defined(_OPENMP) +# pragma omp parallel for schedule(dynamic) num_threads(threads_) \ + if (threads_ > 1 && height > 100) +#endif + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + double src_x = (x - 0.5 * overscan * w) / aspx, + src_y = (y - 0.5 * overscan * h) / aspy; + double warp_x, warp_y; + WarpFunction(intrinsics, src_x, src_y, &warp_x, &warp_y); + warp_x = warp_x * aspx + 0.5 * overscan * w; + warp_y = warp_y * aspy + 0.5 * overscan * h; + int ix = int(warp_x), iy = int(warp_y); + int fx = round((warp_x - ix) * 256), fy = round((warp_y - iy) * 256); + if (fx == 256) { fx = 0; ix++; } // NOLINT + if (fy == 256) { fy = 0; iy++; } // NOLINT + // Use nearest border pixel + if (ix < 0) { ix = 0, fx = 0; } // NOLINT + if (iy < 0) { iy = 0, fy = 0; } // NOLINT + if (ix >= width - 2) ix = width - 2; + if (iy >= height - 2) iy = height - 2; + + Offset offset = { (short) (ix - x), + (short) (iy - y), + (unsigned char) fx, + (unsigned char) fy }; + offset_[y * width + x] = offset; + } + } +} + +template +void LookupWarpGrid::Update(const CameraIntrinsics &intrinsics, + int width, + int height, + double overscan) { + if (width_ != width || + height_ != height || + overscan_ != overscan) { + Reset(); + } + + if (offset_ == NULL) { + offset_ = new Offset[width * height]; + Compute(intrinsics, + width, + height, + overscan); + } + + width_ = width; + height_ = height; + overscan_ = overscan; +} + +// TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup +template +void LookupWarpGrid::Apply(const PixelType *input_buffer, + int width, + int height, + int channels, + PixelType *output_buffer) { +#if defined(_OPENMP) +# pragma omp parallel for schedule(dynamic) num_threads(threads_) \ + if (threads_ > 1 && height > 100) +#endif + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Offset offset = offset_[y * width + x]; + const int pixel_index = ((y + offset.iy) * width + + (x + offset.ix)) * channels; + const PixelType *s = &input_buffer[pixel_index]; + for (int i = 0; i < channels; i++) { + output_buffer[(y * width + x) * channels + i] = + ((s[i] * (256 - offset.fx) + + s[channels + i] * offset.fx) * (256 - offset.fy) + + (s[width * channels + i] * (256 - offset.fx) + + s[width * channels + channels + i] * offset.fx) * offset.fy) + / (256 * 256); + } + } + } +} + +} // namespace internal + +template +void CameraIntrinsics::DistortBuffer(const PixelType *input_buffer, + int width, + int height, + double overscan, + int channels, + PixelType *output_buffer) { + assert(channels >= 1); + assert(channels <= 4); + distort_.Update(*this, + width, + height, + overscan); + distort_.Apply(input_buffer, + width, + height, + channels, + output_buffer); +} + +template +void CameraIntrinsics::UndistortBuffer(const PixelType *input_buffer, + int width, + int height, + double overscan, + int channels, + PixelType *output_buffer) { + assert(channels >= 1); + assert(channels <= 4); + undistort_.Update(*this, + width, + height, + overscan); + + undistort_.Apply(input_buffer, + width, + height, + channels, + output_buffer); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/distortion_models.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/distortion_models.cc new file mode 100644 index 0000000000..9b6dca2678 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/distortion_models.cc @@ -0,0 +1,197 @@ +// Copyright (c) 2014 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/distortion_models.h" +#include "libmv/numeric/levenberg_marquardt.h" + +namespace libmv { + +namespace { + +struct InvertPolynomialIntrinsicsCostFunction { + public: + typedef Vec2 FMatrixType; + typedef Vec2 XMatrixType; + + InvertPolynomialIntrinsicsCostFunction(const double focal_length_x, + const double focal_length_y, + const double principal_point_x, + const double principal_point_y, + const double k1, + const double k2, + const double k3, + const double p1, + const double p2, + const double image_x, + const double image_y) + : focal_length_x_(focal_length_x), + focal_length_y_(focal_length_y), + principal_point_x_(principal_point_x), + principal_point_y_(principal_point_y), + k1_(k1), k2_(k2), k3_(k3), + p1_(p1), p2_(p2), + x_(image_x), y_(image_y) {} + + Vec2 operator()(const Vec2 &u) const { + double xx, yy; + + ApplyPolynomialDistortionModel(focal_length_x_, + focal_length_y_, + principal_point_x_, + principal_point_y_, + k1_, k2_, k3_, + p1_, p2_, + u(0), u(1), + &xx, &yy); + + Vec2 fx; + fx << (xx - x_), (yy - y_); + return fx; + } + double focal_length_x_; + double focal_length_y_; + double principal_point_x_; + double principal_point_y_; + double k1_, k2_, k3_; + double p1_, p2_; + double x_, y_; +}; + +struct InvertDivisionIntrinsicsCostFunction { + public: + typedef Vec2 FMatrixType; + typedef Vec2 XMatrixType; + + InvertDivisionIntrinsicsCostFunction(const double focal_length_x, + const double focal_length_y, + const double principal_point_x, + const double principal_point_y, + const double k1, + const double k2, + const double image_x, + const double image_y) + : focal_length_x_(focal_length_x), + focal_length_y_(focal_length_y), + principal_point_x_(principal_point_x), + principal_point_y_(principal_point_y), + k1_(k1), k2_(k2), + x_(image_x), y_(image_y) {} + + Vec2 operator()(const Vec2 &u) const { + double xx, yy; + + ApplyDivisionDistortionModel(focal_length_x_, + focal_length_y_, + principal_point_x_, + principal_point_y_, + k1_, k2_, + u(0), u(1), + &xx, &yy); + + Vec2 fx; + fx << (xx - x_), (yy - y_); + return fx; + } + double focal_length_x_; + double focal_length_y_; + double principal_point_x_; + double principal_point_y_; + double k1_, k2_; + double x_, y_; +}; + +} // namespace + +void InvertPolynomialDistortionModel(const double focal_length_x, + const double focal_length_y, + const double principal_point_x, + const double principal_point_y, + const double k1, + const double k2, + const double k3, + const double p1, + const double p2, + const double image_x, + const double image_y, + double *normalized_x, + double *normalized_y) { + // Compute the initial guess. For a camera with no distortion, this will also + // be the final answer; the LM iteration will terminate immediately. + Vec2 normalized; + normalized(0) = (image_x - principal_point_x) / focal_length_x; + normalized(1) = (image_y - principal_point_y) / focal_length_y; + + typedef LevenbergMarquardt Solver; + + InvertPolynomialIntrinsicsCostFunction intrinsics_cost(focal_length_x, + focal_length_y, + principal_point_x, + principal_point_y, + k1, k2, k3, + p1, p2, + image_x, image_y); + Solver::SolverParameters params; + Solver solver(intrinsics_cost); + + /*Solver::Results results =*/ solver.minimize(params, &normalized); + + // TODO(keir): Better error handling. + + *normalized_x = normalized(0); + *normalized_y = normalized(1); +} + +void InvertDivisionDistortionModel(const double focal_length_x, + const double focal_length_y, + const double principal_point_x, + const double principal_point_y, + const double k1, + const double k2, + const double image_x, + const double image_y, + double *normalized_x, + double *normalized_y) { + // Compute the initial guess. For a camera with no distortion, this will also + // be the final answer; the LM iteration will terminate immediately. + Vec2 normalized; + normalized(0) = (image_x - principal_point_x) / focal_length_x; + normalized(1) = (image_y - principal_point_y) / focal_length_y; + + // TODO(sergey): Use Ceres minimizer instead. + typedef LevenbergMarquardt Solver; + + InvertDivisionIntrinsicsCostFunction intrinsics_cost(focal_length_x, + focal_length_y, + principal_point_x, + principal_point_y, + k1, k2, + image_x, image_y); + Solver::SolverParameters params; + Solver solver(intrinsics_cost); + + /*Solver::Results results =*/ solver.minimize(params, &normalized); + + // TODO(keir): Better error handling. + + *normalized_x = normalized(0); + *normalized_y = normalized(1); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/distortion_models.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/distortion_models.h new file mode 100644 index 0000000000..4f8e2295a0 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/distortion_models.h @@ -0,0 +1,131 @@ +// Copyright (c) 2014 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_ +#define LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_ + +namespace libmv { + +enum DistortionModelType { + DISTORTION_MODEL_POLYNOMIAL, + DISTORTION_MODEL_DIVISION +}; + +// Invert camera intrinsics on the image point to get normalized coordinates. +// This inverts the radial lens distortion to a point which is in image pixel +// coordinates to get normalized coordinates. +void InvertPolynomialDistortionModel(const double focal_length_x, + const double focal_length_y, + const double principal_point_x, + const double principal_point_y, + const double k1, + const double k2, + const double k3, + const double p1, + const double p2, + const double image_x, + const double image_y, + double *normalized_x, + double *normalized_y); + +// Apply camera intrinsics to the normalized point to get image coordinates. +// This applies the radial lens distortion to a point which is in normalized +// camera coordinates (i.e. the principal point is at (0, 0)) to get image +// coordinates in pixels. Templated for use with autodifferentiation. +template +inline void ApplyPolynomialDistortionModel(const T &focal_length_x, + const T &focal_length_y, + const T &principal_point_x, + const T &principal_point_y, + const T &k1, + const T &k2, + const T &k3, + const T &p1, + const T &p2, + const T &normalized_x, + const T &normalized_y, + T *image_x, + T *image_y) { + T x = normalized_x; + T y = normalized_y; + + // Apply distortion to the normalized points to get (xd, yd). + T r2 = x*x + y*y; + T r4 = r2 * r2; + T r6 = r4 * r2; + T r_coeff = (T(1) + k1*r2 + k2*r4 + k3*r6); + T xd = x * r_coeff + T(2)*p1*x*y + p2*(r2 + T(2)*x*x); + T yd = y * r_coeff + T(2)*p2*x*y + p1*(r2 + T(2)*y*y); + + // Apply focal length and principal point to get the final image coordinates. + *image_x = focal_length_x * xd + principal_point_x; + *image_y = focal_length_y * yd + principal_point_y; +} + +// Invert camera intrinsics on the image point to get normalized coordinates. +// This inverts the radial lens distortion to a point which is in image pixel +// coordinates to get normalized coordinates. +// +// Uses division distortion model. +void InvertDivisionDistortionModel(const double focal_length_x, + const double focal_length_y, + const double principal_point_x, + const double principal_point_y, + const double k1, + const double k2, + const double image_x, + const double image_y, + double *normalized_x, + double *normalized_y); + +// Apply camera intrinsics to the normalized point to get image coordinates. +// This applies the radial lens distortion to a point which is in normalized +// camera coordinates (i.e. the principal point is at (0, 0)) to get image +// coordinates in pixels. Templated for use with autodifferentiation. +// +// Uses division distortion model. +template +inline void ApplyDivisionDistortionModel(const T &focal_length_x, + const T &focal_length_y, + const T &principal_point_x, + const T &principal_point_y, + const T &k1, + const T &k2, + const T &normalized_x, + const T &normalized_y, + T *image_x, + T *image_y) { + + T x = normalized_x; + T y = normalized_y; + T r2 = x*x + y*y; + T r4 = r2 * r2; + + T xd = x / (T(1) + k1 * r2 + k2 * r4); + T yd = y / (T(1) + k1 * r2 + k2 * r4); + + // Apply focal length and principal point to get the final image coordinates. + *image_x = focal_length_x * xd + principal_point_x; + *image_y = focal_length_y * yd + principal_point_y; +} + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_DISTORTION_MODELS_H_ diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/initialize_reconstruction.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/initialize_reconstruction.cc new file mode 100644 index 0000000000..7a086c375d --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/initialize_reconstruction.cc @@ -0,0 +1,195 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/initialize_reconstruction.h" + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/fundamental.h" +#include "libmv/multiview/projection.h" +#include "libmv/numeric/levenberg_marquardt.h" +#include "libmv/numeric/numeric.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" + +namespace libmv { +namespace { + +void GetImagesInMarkers(const vector &markers, + int *image1, int *image2) { + if (markers.size() < 2) { + return; + } + *image1 = markers[0].image; + for (int i = 1; i < markers.size(); ++i) { + if (markers[i].image != *image1) { + *image2 = markers[i].image; + return; + } + } + *image2 = -1; + LOG(FATAL) << "Only one image in the markers."; +} + +} // namespace + +bool EuclideanReconstructTwoFrames(const vector &markers, + EuclideanReconstruction *reconstruction) { + if (markers.size() < 16) { + LG << "Not enough markers to initialize from two frames: " << markers.size(); + return false; + } + + int image1, image2; + GetImagesInMarkers(markers, &image1, &image2); + + Mat x1, x2; + CoordinatesForMarkersInImage(markers, image1, &x1); + CoordinatesForMarkersInImage(markers, image2, &x2); + + Mat3 F; + NormalizedEightPointSolver(x1, x2, &F); + + // The F matrix should be an E matrix, but squash it just to be sure. + Mat3 E; + FundamentalToEssential(F, &E); + + // Recover motion between the two images. Since this function assumes a + // calibrated camera, use the identity for K. + Mat3 R; + Vec3 t; + Mat3 K = Mat3::Identity(); + if (!MotionFromEssentialAndCorrespondence(E, + K, x1.col(0), + K, x2.col(0), + &R, &t)) { + LG << "Failed to compute R and t from E and K."; + return false; + } + + // Image 1 gets the reference frame, image 2 gets the relative motion. + reconstruction->InsertCamera(image1, Mat3::Identity(), Vec3::Zero()); + reconstruction->InsertCamera(image2, R, t); + + LG << "From two frame reconstruction got:\nR:\n" << R + << "\nt:" << t.transpose(); + return true; +} + +namespace { + +Mat3 DecodeF(const Vec9 &encoded_F) { + // Decode F and force it to be rank 2. + Map full_rank_F(encoded_F.data(), 3, 3); + Eigen::JacobiSVD svd(full_rank_F, + Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec3 diagonal = svd.singularValues(); + diagonal(2) = 0; + Mat3 F = svd.matrixU() * diagonal.asDiagonal() * svd.matrixV().transpose(); + return F; +} + +// This is the stupidest way to refine F known to mankind, since it requires +// doing a full SVD of F at each iteration. This uses sampson error. +struct FundamentalSampsonCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec9 XMatrixType; + + // Assumes markers are ordered by track. + explicit FundamentalSampsonCostFunction(const vector &markers) + : markers(markers) {} + + Vec operator()(const Vec9 &encoded_F) const { + // Decode F and force it to be rank 2. + Mat3 F = DecodeF(encoded_F); + + Vec residuals(markers.size() / 2); + residuals.setZero(); + for (int i = 0; i < markers.size() / 2; ++i) { + const Marker &marker1 = markers[2*i + 0]; + const Marker &marker2 = markers[2*i + 1]; + CHECK_EQ(marker1.track, marker2.track); + Vec2 x1(marker1.x, marker1.y); + Vec2 x2(marker2.x, marker2.y); + + residuals[i] = SampsonDistance(F, x1, x2); + } + return residuals; + } + const vector &markers; +}; + +} // namespace + +bool ProjectiveReconstructTwoFrames(const vector &markers, + ProjectiveReconstruction *reconstruction) { + if (markers.size() < 16) { + return false; + } + + int image1, image2; + GetImagesInMarkers(markers, &image1, &image2); + + Mat x1, x2; + CoordinatesForMarkersInImage(markers, image1, &x1); + CoordinatesForMarkersInImage(markers, image2, &x2); + + Mat3 F; + NormalizedEightPointSolver(x1, x2, &F); + + // XXX Verify sampson distance. +#if 0 + // Refine the resulting projection fundamental matrix using Sampson's + // approximation of geometric error. This avoids having to do a full bundle + // at the cost of some accuracy. + // + // TODO(keir): After switching to a better bundling library, use a proper + // full bundle adjust here instead of this lame bundle adjustment. + typedef LevenbergMarquardt Solver; + + FundamentalSampsonCostFunction fundamental_cost(markers); + + // Pack the initial P matrix into a size-12 vector.. + Vec9 encoded_F = Map(F.data(), 3, 3); + + Solver solver(fundamental_cost); + + Solver::SolverParameters params; + Solver::Results results = solver.minimize(params, &encoded_F); + // TODO(keir): Check results to ensure clean termination. + + // Recover F from the minimization. + F = DecodeF(encoded_F); +#endif + + // Image 1 gets P = [I|0], image 2 gets arbitrary P. + Mat34 P1 = Mat34::Zero(); + P1.block<3, 3>(0, 0) = Mat3::Identity(); + Mat34 P2; + ProjectionsFromFundamental(F, &P1, &P2); + + reconstruction->InsertCamera(image1, P1); + reconstruction->InsertCamera(image2, P2); + + LG << "From two frame reconstruction got P2:\n" << P2; + return true; +} +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/initialize_reconstruction.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/initialize_reconstruction.h new file mode 100644 index 0000000000..744436246b --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/initialize_reconstruction.h @@ -0,0 +1,74 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H +#define LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H + +#include "libmv/base/vector.h" + +namespace libmv { + +struct Marker; +class EuclideanReconstruction; +class ProjectiveReconstruction; + +/*! + Initialize the \link EuclideanReconstruction reconstruction \endlink using + two frames. + + \a markers should contain all \l Marker markers \endlink belonging to + tracks visible in both frames. The pose estimation of the camera for + these frames will be inserted into \a *reconstruction. + + \note The two frames need to have both enough parallax and enough common tracks + for accurate reconstruction. At least 8 tracks are suggested. + \note The origin of the coordinate system is defined to be the camera of + the first keyframe. + \note This assumes a calibrated reconstruction, e.g. the markers are + already corrected for camera intrinsics and radial distortion. + \note This assumes an outlier-free set of markers. + + \sa EuclideanResect, EuclideanIntersect, EuclideanBundle +*/ +bool EuclideanReconstructTwoFrames(const vector &markers, + EuclideanReconstruction *reconstruction); + +/*! + Initialize the \link ProjectiveReconstruction reconstruction \endlink using + two frames. + + \a markers should contain all \l Marker markers \endlink belonging to + tracks visible in both frames. An estimate of the projection matrices for + the two frames will get added to the reconstruction. + + \note The two frames need to have both enough parallax and enough common tracks + for accurate reconstruction. At least 8 tracks are suggested. + \note The origin of the coordinate system is defined to be the camera of + the first keyframe. + \note This assumes the markers are already corrected for radial distortion. + \note This assumes an outlier-free set of markers. + + \sa ProjectiveResect, ProjectiveIntersect, ProjectiveBundle +*/ +bool ProjectiveReconstructTwoFrames(const vector &markers, + ProjectiveReconstruction *reconstruction); +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/intersect.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/intersect.cc new file mode 100644 index 0000000000..d625c11195 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/intersect.cc @@ -0,0 +1,254 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/intersect.h" + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/projection.h" +#include "libmv/multiview/triangulation.h" +#include "libmv/multiview/nviewtriangulation.h" +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/levenberg_marquardt.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" + +#include "ceres/ceres.h" + +namespace libmv { + +namespace { + +class EuclideanIntersectCostFunctor { + public: + EuclideanIntersectCostFunctor(const Marker &marker, + const EuclideanCamera &camera) + : marker_(marker), camera_(camera) {} + + template + bool operator()(const T *X, T *residuals) const { + typedef Eigen::Matrix Mat3; + typedef Eigen::Matrix Vec3; + + Vec3 x(X); + Mat3 R(camera_.R.cast()); + Vec3 t(camera_.t.cast()); + + Vec3 projected = R * x + t; + projected /= projected(2); + + residuals[0] = (projected(0) - T(marker_.x)) * marker_.weight; + residuals[1] = (projected(1) - T(marker_.y)) * marker_.weight; + + return true; + } + + const Marker &marker_; + const EuclideanCamera &camera_; +}; + +} // namespace + +bool EuclideanIntersect(const vector &markers, + EuclideanReconstruction *reconstruction) { + if (markers.size() < 2) { + return false; + } + + // Compute projective camera matrices for the cameras the intersection is + // going to use. + Mat3 K = Mat3::Identity(); + vector cameras; + Mat34 P; + for (int i = 0; i < markers.size(); ++i) { + EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image); + P_From_KRt(K, camera->R, camera->t, &P); + cameras.push_back(P); + } + + // Stack the 2D coordinates together as required by NViewTriangulate. + Mat2X points(2, markers.size()); + for (int i = 0; i < markers.size(); ++i) { + points(0, i) = markers[i].x; + points(1, i) = markers[i].y; + } + + Vec4 Xp; + LG << "Intersecting with " << markers.size() << " markers."; + NViewTriangulateAlgebraic(points, cameras, &Xp); + + // Get euclidean version of the homogeneous point. + Xp /= Xp(3); + Vec3 X = Xp.head<3>(); + + ceres::Problem problem; + + // Add residual blocks to the problem. + int num_residuals = 0; + for (int i = 0; i < markers.size(); ++i) { + const Marker &marker = markers[i]; + if (marker.weight != 0.0) { + const EuclideanCamera &camera = + *reconstruction->CameraForImage(marker.image); + + problem.AddResidualBlock( + new ceres::AutoDiffCostFunction< + EuclideanIntersectCostFunctor, + 2, /* num_residuals */ + 3>(new EuclideanIntersectCostFunctor(marker, camera)), + NULL, + &X(0)); + num_residuals++; + } + } + + // TODO(sergey): Once we'll update Ceres to the next version + // we wouldn't need this check anymore -- Ceres will deal with + // zero-sized problems nicely. + LG << "Number of residuals: " << num_residuals; + if (!num_residuals) { + LG << "Skipping running minimizer with zero residuals"; + + // We still add 3D point for the track regardless it was + // optimized or not. If track is a constant zero it'll use + // algebraic intersection result as a 3D coordinate. + + Vec3 point = X.head<3>(); + reconstruction->InsertPoint(markers[0].track, point); + + return true; + } + + // Configure the solve. + ceres::Solver::Options solver_options; + solver_options.linear_solver_type = ceres::DENSE_QR; + solver_options.max_num_iterations = 50; + solver_options.update_state_every_iteration = true; + solver_options.parameter_tolerance = 1e-16; + solver_options.function_tolerance = 1e-16; + + // Run the solve. + ceres::Solver::Summary summary; + ceres::Solve(solver_options, &problem, &summary); + + VLOG(1) << "Summary:\n" << summary.FullReport(); + + // Try projecting the point; make sure it's in front of everyone. + for (int i = 0; i < cameras.size(); ++i) { + const EuclideanCamera &camera = + *reconstruction->CameraForImage(markers[i].image); + Vec3 x = camera.R * X + camera.t; + if (x(2) < 0) { + LOG(ERROR) << "POINT BEHIND CAMERA " << markers[i].image + << ": " << x.transpose(); + return false; + } + } + + Vec3 point = X.head<3>(); + reconstruction->InsertPoint(markers[0].track, point); + + // TODO(keir): Add proper error checking. + return true; +} + +namespace { + +struct ProjectiveIntersectCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec4 XMatrixType; + + ProjectiveIntersectCostFunction( + const vector &markers, + const ProjectiveReconstruction &reconstruction) + : markers(markers), reconstruction(reconstruction) {} + + Vec operator()(const Vec4 &X) const { + Vec residuals(2 * markers.size()); + residuals.setZero(); + for (int i = 0; i < markers.size(); ++i) { + const ProjectiveCamera &camera = + *reconstruction.CameraForImage(markers[i].image); + Vec3 projected = camera.P * X; + projected /= projected(2); + residuals[2*i + 0] = projected(0) - markers[i].x; + residuals[2*i + 1] = projected(1) - markers[i].y; + } + return residuals; + } + const vector &markers; + const ProjectiveReconstruction &reconstruction; +}; + +} // namespace + +bool ProjectiveIntersect(const vector &markers, + ProjectiveReconstruction *reconstruction) { + if (markers.size() < 2) { + return false; + } + + // Get the cameras to use for the intersection. + vector cameras; + for (int i = 0; i < markers.size(); ++i) { + ProjectiveCamera *camera = reconstruction->CameraForImage(markers[i].image); + cameras.push_back(camera->P); + } + + // Stack the 2D coordinates together as required by NViewTriangulate. + Mat2X points(2, markers.size()); + for (int i = 0; i < markers.size(); ++i) { + points(0, i) = markers[i].x; + points(1, i) = markers[i].y; + } + + Vec4 X; + LG << "Intersecting with " << markers.size() << " markers."; + NViewTriangulateAlgebraic(points, cameras, &X); + X /= X(3); + + typedef LevenbergMarquardt Solver; + + ProjectiveIntersectCostFunction triangulate_cost(markers, *reconstruction); + Solver::SolverParameters params; + Solver solver(triangulate_cost); + + Solver::Results results = solver.minimize(params, &X); + (void) results; // TODO(keir): Ensure results are good. + + // Try projecting the point; make sure it's in front of everyone. + for (int i = 0; i < cameras.size(); ++i) { + const ProjectiveCamera &camera = + *reconstruction->CameraForImage(markers[i].image); + Vec3 x = camera.P * X; + if (x(2) < 0) { + LOG(ERROR) << "POINT BEHIND CAMERA " << markers[i].image + << ": " << x.transpose(); + } + } + + reconstruction->InsertPoint(markers[0].track, X); + + // TODO(keir): Add proper error checking. + return true; +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/intersect.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/intersect.h new file mode 100644 index 0000000000..3a0ffa7418 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/intersect.h @@ -0,0 +1,77 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_INTERSECT_H +#define LIBMV_SIMPLE_PIPELINE_INTERSECT_H + +#include "libmv/base/vector.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/reconstruction.h" + +namespace libmv { + +/*! + Estimate the 3D coordinates of a track by intersecting rays from images. + + This takes a set of markers, where each marker is for the same track but + different images, and reconstructs the 3D position of that track. Each of + the frames for which there is a marker for that track must have a + corresponding reconstructed camera in \a *reconstruction. + + \a markers should contain all \l Marker markers \endlink belonging to + tracks visible in all frames. + \a reconstruction should contain the cameras for all frames. + The new \l Point points \endlink will be inserted in \a reconstruction. + + \note This assumes a calibrated reconstruction, e.g. the markers are + already corrected for camera intrinsics and radial distortion. + \note This assumes an outlier-free set of markers. + + \sa EuclideanResect +*/ +bool EuclideanIntersect(const vector &markers, + EuclideanReconstruction *reconstruction); + +/*! + Estimate the homogeneous coordinates of a track by intersecting rays. + + This takes a set of markers, where each marker is for the same track but + different images, and reconstructs the homogeneous 3D position of that + track. Each of the frames for which there is a marker for that track must + have a corresponding reconstructed camera in \a *reconstruction. + + \a markers should contain all \l Marker markers \endlink belonging to + tracks visible in all frames. + \a reconstruction should contain the cameras for all frames. + The new \l Point points \endlink will be inserted in \a reconstruction. + + \note This assumes that radial distortion is already corrected for, but + does not assume that e.g. focal length and principal point are + accounted for. + \note This assumes an outlier-free set of markers. + + \sa Resect +*/ +bool ProjectiveIntersect(const vector &markers, + ProjectiveReconstruction *reconstruction); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_INTERSECT_H diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/keyframe_selection.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/keyframe_selection.cc new file mode 100644 index 0000000000..241b560050 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/keyframe_selection.cc @@ -0,0 +1,450 @@ +// Copyright (c) 2012 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/keyframe_selection.h" + +#include "libmv/numeric/numeric.h" +#include "ceres/ceres.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/homography.h" +#include "libmv/multiview/fundamental.h" +#include "libmv/simple_pipeline/intersect.h" +#include "libmv/simple_pipeline/bundle.h" + +#include + +namespace libmv { +namespace { + +Mat3 IntrinsicsNormalizationMatrix(const CameraIntrinsics &intrinsics) { + Mat3 T = Mat3::Identity(), S = Mat3::Identity(); + + T(0, 2) = -intrinsics.principal_point_x(); + T(1, 2) = -intrinsics.principal_point_y(); + + S(0, 0) /= intrinsics.focal_length_x(); + S(1, 1) /= intrinsics.focal_length_y(); + + return S * T; +} + +// P.H.S. Torr +// Geometric Motion Segmentation and Model Selection +// +// http://reference.kfupm.edu.sa/content/g/e/geometric_motion_segmentation_and_model__126445.pdf +// +// d is the number of dimensions modeled +// (d = 3 for a fundamental matrix or 2 for a homography) +// k is the number of degrees of freedom in the model +// (k = 7 for a fundamental matrix or 8 for a homography) +// r is the dimension of the data +// (r = 4 for 2D correspondences between two frames) +double GRIC(const Vec &e, int d, int k, int r) { + int n = e.rows(); + double lambda1 = log(static_cast(r)); + double lambda2 = log(static_cast(r * n)); + + // lambda3 limits the residual error, and this paper + // http://elvera.nue.tu-berlin.de/files/0990Knorr2006.pdf + // suggests using lambda3 of 2 + // same value is used in Torr's Problem of degeneracy in structure + // and motion recovery from uncalibrated image sequences + // http://www.robots.ox.ac.uk/~vgg/publications/papers/torr99.ps.gz + double lambda3 = 2.0; + + // Variance of tracker position. Physically, this is typically about 0.1px, + // and when squared becomes 0.01 px^2. + double sigma2 = 0.01; + + // Finally, calculate the GRIC score. + double gric = 0.0; + for (int i = 0; i < n; i++) { + gric += std::min(e(i) * e(i) / sigma2, lambda3 * (r - d)); + } + gric += lambda1 * d * n; + gric += lambda2 * k; + return gric; +} + +// Compute a generalized inverse using eigen value decomposition, clamping the +// smallest eigenvalues if requested. This is needed to compute the variance of +// reconstructed 3D points. +// +// TODO(keir): Consider moving this into the numeric code, since this is not +// related to keyframe selection. +Mat PseudoInverseWithClampedEigenvalues(const Mat &matrix, + int num_eigenvalues_to_clamp) { + Eigen::EigenSolver eigen_solver(matrix); + Mat D = eigen_solver.pseudoEigenvalueMatrix(); + Mat V = eigen_solver.pseudoEigenvectors(); + + // Clamp too-small singular values to zero to prevent numeric blowup. + double epsilon = std::numeric_limits::epsilon(); + for (int i = 0; i < D.cols(); ++i) { + if (D(i, i) > epsilon) { + D(i, i) = 1.0 / D(i, i); + } else { + D(i, i) = 0.0; + } + } + + // Apply the clamp. + for (int i = D.cols() - num_eigenvalues_to_clamp; i < D.cols(); ++i) { + D(i, i) = 0.0; + } + return V * D * V.inverse(); +} + +void FilterZeroWeightMarkersFromTracks(const Tracks &tracks, + Tracks *filtered_tracks) { + vector all_markers = tracks.AllMarkers(); + + for (int i = 0; i < all_markers.size(); ++i) { + Marker &marker = all_markers[i]; + if (marker.weight != 0.0) { + filtered_tracks->Insert(marker.image, + marker.track, + marker.x, + marker.y, + marker.weight); + } + } +} + +} // namespace + +void SelectKeyframesBasedOnGRICAndVariance(const Tracks &_tracks, + const CameraIntrinsics &intrinsics, + vector &keyframes) { + // Mirza Tahir Ahmed, Matthew N. Dailey + // Robust key frame extraction for 3D reconstruction from video streams + // + // http://www.cs.ait.ac.th/~mdailey/papers/Tahir-KeyFrame.pdf + + Tracks filtered_tracks; + FilterZeroWeightMarkersFromTracks(_tracks, &filtered_tracks); + + int max_image = filtered_tracks.MaxImage(); + int next_keyframe = 1; + int number_keyframes = 0; + + // Limit correspondence ratio from both sides. + // On the one hand if number of correspondent features is too low, + // triangulation will suffer. + // On the other hand high correspondence likely means short baseline. + // which also will affect om accuracy + const double Tmin = 0.8; + const double Tmax = 1.0; + + Mat3 N = IntrinsicsNormalizationMatrix(intrinsics); + Mat3 N_inverse = N.inverse(); + + double Sc_best = std::numeric_limits::max(); + double success_intersects_factor_best = 0.0f; + + while (next_keyframe != -1) { + int current_keyframe = next_keyframe; + double Sc_best_candidate = std::numeric_limits::max(); + + LG << "Found keyframe " << next_keyframe; + + number_keyframes++; + next_keyframe = -1; + + for (int candidate_image = current_keyframe + 1; + candidate_image <= max_image; + candidate_image++) { + // Conjunction of all markers from both keyframes + vector all_markers = + filtered_tracks.MarkersInBothImages(current_keyframe, + candidate_image); + + // Match keypoints between frames current_keyframe and candidate_image + vector tracked_markers = + filtered_tracks.MarkersForTracksInBothImages(current_keyframe, + candidate_image); + + // Correspondences in normalized space + Mat x1, x2; + CoordinatesForMarkersInImage(tracked_markers, current_keyframe, &x1); + CoordinatesForMarkersInImage(tracked_markers, candidate_image, &x2); + + LG << "Found " << x1.cols() + << " correspondences between " << current_keyframe + << " and " << candidate_image; + + // Not enough points to construct fundamental matrix + if (x1.cols() < 8 || x2.cols() < 8) + continue; + + // STEP 1: Correspondence ratio constraint + int Tc = tracked_markers.size(); + int Tf = all_markers.size(); + double Rc = static_cast(Tc) / Tf; + + LG << "Correspondence between " << current_keyframe + << " and " << candidate_image + << ": " << Rc; + + if (Rc < Tmin || Rc > Tmax) + continue; + + Mat3 H, F; + + // Estimate homography using default options. + EstimateHomographyOptions estimate_homography_options; + EstimateHomography2DFromCorrespondences(x1, + x2, + estimate_homography_options, + &H); + + // Convert homography to original pixel space. + H = N_inverse * H * N; + + EstimateFundamentalOptions estimate_fundamental_options; + EstimateFundamentalFromCorrespondences(x1, + x2, + estimate_fundamental_options, + &F); + + // Convert fundamental to original pixel space. + F = N_inverse * F * N; + + // TODO(sergey): STEP 2: Discard outlier matches + + // STEP 3: Geometric Robust Information Criteria + + // Compute error values for homography and fundamental matrices + Vec H_e, F_e; + H_e.resize(x1.cols()); + F_e.resize(x1.cols()); + for (int i = 0; i < x1.cols(); i++) { + Vec2 current_x1, current_x2; + + intrinsics.NormalizedToImageSpace(x1(0, i), x1(1, i), + ¤t_x1(0), ¤t_x1(1)); + + intrinsics.NormalizedToImageSpace(x2(0, i), x2(1, i), + ¤t_x2(0), ¤t_x2(1)); + + H_e(i) = SymmetricGeometricDistance(H, current_x1, current_x2); + F_e(i) = SymmetricEpipolarDistance(F, current_x1, current_x2); + } + + LG << "H_e: " << H_e.transpose(); + LG << "F_e: " << F_e.transpose(); + + // Degeneracy constraint + double GRIC_H = GRIC(H_e, 2, 8, 4); + double GRIC_F = GRIC(F_e, 3, 7, 4); + + LG << "GRIC values for frames " << current_keyframe + << " and " << candidate_image + << ", H-GRIC: " << GRIC_H + << ", F-GRIC: " << GRIC_F; + + if (GRIC_H <= GRIC_F) + continue; + + // TODO(sergey): STEP 4: PELC criterion + + // STEP 5: Estimation of reconstruction error + // + // Uses paper Keyframe Selection for Camera Motion and Structure + // Estimation from Multiple Views + // Uses ftp://ftp.tnt.uni-hannover.de/pub/papers/2004/ECCV2004-TTHBAW.pdf + // Basically, equation (15) + // + // TODO(sergey): separate all the constraints into functions, + // this one is getting to much cluttered already + + // Definitions in equation (15): + // - I is the number of 3D feature points + // - A is the number of essential parameters of one camera + + EuclideanReconstruction reconstruction; + + // The F matrix should be an E matrix, but squash it just to be sure + + // Reconstruction should happen using normalized fundamental matrix + Mat3 F_normal = N * F * N_inverse; + + Mat3 E; + FundamentalToEssential(F_normal, &E); + + // Recover motion between the two images. Since this function assumes a + // calibrated camera, use the identity for K + Mat3 R; + Vec3 t; + Mat3 K = Mat3::Identity(); + + if (!MotionFromEssentialAndCorrespondence(E, + K, x1.col(0), + K, x2.col(0), + &R, &t)) { + LG << "Failed to compute R and t from E and K"; + continue; + } + + LG << "Camera transform between frames " << current_keyframe + << " and " << candidate_image + << ":\nR:\n" << R + << "\nt:" << t.transpose(); + + // First camera is identity, second one is relative to it + reconstruction.InsertCamera(current_keyframe, + Mat3::Identity(), + Vec3::Zero()); + reconstruction.InsertCamera(candidate_image, R, t); + + // Reconstruct 3D points + int intersects_total = 0, intersects_success = 0; + for (int i = 0; i < tracked_markers.size(); i++) { + if (!reconstruction.PointForTrack(tracked_markers[i].track)) { + vector reconstructed_markers; + + int track = tracked_markers[i].track; + + reconstructed_markers.push_back(tracked_markers[i]); + + // We know there're always only two markers for a track + // Also, we're using brute-force search because we don't + // actually know about markers layout in a list, but + // at this moment this cycle will run just once, which + // is not so big deal + + for (int j = i + 1; j < tracked_markers.size(); j++) { + if (tracked_markers[j].track == track) { + reconstructed_markers.push_back(tracked_markers[j]); + break; + } + } + + intersects_total++; + + if (EuclideanIntersect(reconstructed_markers, &reconstruction)) { + LG << "Ran Intersect() for track " << track; + intersects_success++; + } else { + LG << "Filed to intersect track " << track; + } + } + } + + double success_intersects_factor = + (double) intersects_success / intersects_total; + + if (success_intersects_factor < success_intersects_factor_best) { + LG << "Skip keyframe candidate because of " + "lower successful intersections ratio"; + + continue; + } + + success_intersects_factor_best = success_intersects_factor; + + Tracks two_frames_tracks(tracked_markers); + PolynomialCameraIntrinsics empty_intrinsics; + BundleEvaluation evaluation; + evaluation.evaluate_jacobian = true; + + EuclideanBundleCommonIntrinsics(two_frames_tracks, + BUNDLE_NO_INTRINSICS, + BUNDLE_NO_CONSTRAINTS, + &reconstruction, + &empty_intrinsics, + &evaluation); + + Mat &jacobian = evaluation.jacobian; + + Mat JT_J = jacobian.transpose() * jacobian; + // There are 7 degrees of freedom, so clamp them out. + Mat JT_J_inv = PseudoInverseWithClampedEigenvalues(JT_J, 7); + + Mat temp_derived = JT_J * JT_J_inv * JT_J; + bool is_inversed = (temp_derived - JT_J).cwiseAbs2().sum() < + 1e-4 * std::min(temp_derived.cwiseAbs2().sum(), + JT_J.cwiseAbs2().sum()); + + LG << "Check on inversed: " << (is_inversed ? "true" : "false" ) + << ", det(JT_J): " << JT_J.determinant(); + + if (!is_inversed) { + LG << "Ignoring candidature due to poor jacobian stability"; + continue; + } + + Mat Sigma_P; + Sigma_P = JT_J_inv.bottomRightCorner(evaluation.num_points * 3, + evaluation.num_points * 3); + + int I = evaluation.num_points; + int A = 12; + + double Sc = static_cast(I + A) / Square(3 * I) * Sigma_P.trace(); + + LG << "Expected estimation error between " + << current_keyframe << " and " + << candidate_image << ": " << Sc; + + // Pairing with a lower Sc indicates a better choice + if (Sc > Sc_best_candidate) + continue; + + Sc_best_candidate = Sc; + + next_keyframe = candidate_image; + } + + // This is a bit arbitrary and main reason of having this is to deal + // better with situations when there's no keyframes were found for + // current keyframe this could happen when there's no so much parallax + // in the beginning of image sequence and then most of features are + // getting occluded. In this case there could be good keyframe pair in + // the middle of the sequence + // + // However, it's just quick hack and smarter way to do this would be nice + if (next_keyframe == -1) { + next_keyframe = current_keyframe + 10; + number_keyframes = 0; + + if (next_keyframe >= max_image) + break; + + LG << "Starting searching for keyframes starting from " << next_keyframe; + } else { + // New pair's expected reconstruction error is lower + // than existing pair's one. + // + // For now let's store just one candidate, easy to + // store more candidates but needs some thoughts + // how to choose best one automatically from them + // (or allow user to choose pair manually). + if (Sc_best > Sc_best_candidate) { + keyframes.clear(); + keyframes.push_back(current_keyframe); + keyframes.push_back(next_keyframe); + Sc_best = Sc_best_candidate; + } + } + } +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/keyframe_selection.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/keyframe_selection.h new file mode 100644 index 0000000000..aa3eeaf193 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/keyframe_selection.h @@ -0,0 +1,53 @@ +// Copyright (c) 2010, 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_KEYFRAME_SELECTION_H_ +#define LIBMV_SIMPLE_PIPELINE_KEYFRAME_SELECTION_H_ + +#include "libmv/base/vector.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/camera_intrinsics.h" + +namespace libmv { + +// Get list of all images which are good enough to be as keyframes from +// camera reconstruction. Based on GRIC criteria and uses Pollefeys' +// approach for correspondence ratio constraint. +// +// As an additional, additional criteria based on reconstruction +// variance is used. This means if correspondence and GRIC criteria +// are passed, two-frames reconstruction using candidate keyframes +// happens. After reconstruction variance of 3D points is calculating +// and if expected error estimation is too large, keyframe candidate +// is rejecting. +// +// \param tracks contains all tracked correspondences between frames +// expected to be undistorted and normalized +// \param intrinsics is camera intrinsics +// \param keyframes will contain all images number which are considered +// good to be used for reconstruction +void SelectKeyframesBasedOnGRICAndVariance( + const Tracks &tracks, + const CameraIntrinsics &intrinsics, + vector &keyframes); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_KEYFRAME_SELECTION_H_ diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/pipeline.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/pipeline.cc new file mode 100644 index 0000000000..6c8592baa0 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/pipeline.cc @@ -0,0 +1,368 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/pipeline.h" + +#include + +#include "libmv/logging/logging.h" +#include "libmv/simple_pipeline/bundle.h" +#include "libmv/simple_pipeline/intersect.h" +#include "libmv/simple_pipeline/resect.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/camera_intrinsics.h" + +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +namespace libmv { +namespace { + +// These are "strategy" classes which make it possible to use the same code for +// both projective and euclidean reconstruction. +// FIXME(MatthiasF): OOP would achieve the same goal while avoiding +// template bloat and making interface changes much easier. +struct EuclideanPipelineRoutines { + typedef EuclideanReconstruction Reconstruction; + typedef EuclideanCamera Camera; + typedef EuclideanPoint Point; + + static void Bundle(const Tracks &tracks, + EuclideanReconstruction *reconstruction) { + EuclideanBundle(tracks, reconstruction); + } + + static bool Resect(const vector &markers, + EuclideanReconstruction *reconstruction, bool final_pass) { + return EuclideanResect(markers, reconstruction, final_pass); + } + + static bool Intersect(const vector &markers, + EuclideanReconstruction *reconstruction) { + return EuclideanIntersect(markers, reconstruction); + } + + static Marker ProjectMarker(const EuclideanPoint &point, + const EuclideanCamera &camera, + const CameraIntrinsics &intrinsics) { + Vec3 projected = camera.R * point.X + camera.t; + projected /= projected(2); + + Marker reprojected_marker; + intrinsics.ApplyIntrinsics(projected(0), + projected(1), + &reprojected_marker.x, + &reprojected_marker.y); + + reprojected_marker.image = camera.image; + reprojected_marker.track = point.track; + return reprojected_marker; + } +}; + +struct ProjectivePipelineRoutines { + typedef ProjectiveReconstruction Reconstruction; + typedef ProjectiveCamera Camera; + typedef ProjectivePoint Point; + + static void Bundle(const Tracks &tracks, + ProjectiveReconstruction *reconstruction) { + ProjectiveBundle(tracks, reconstruction); + } + + static bool Resect(const vector &markers, + ProjectiveReconstruction *reconstruction, bool final_pass) { + (void) final_pass; // Ignored. + + return ProjectiveResect(markers, reconstruction); + } + + static bool Intersect(const vector &markers, + ProjectiveReconstruction *reconstruction) { + return ProjectiveIntersect(markers, reconstruction); + } + + static Marker ProjectMarker(const ProjectivePoint &point, + const ProjectiveCamera &camera, + const CameraIntrinsics &intrinsics) { + Vec3 projected = camera.P * point.X; + projected /= projected(2); + + Marker reprojected_marker; + intrinsics.ApplyIntrinsics(projected(0), + projected(1), + &reprojected_marker.x, + &reprojected_marker.y); + + reprojected_marker.image = camera.image; + reprojected_marker.track = point.track; + return reprojected_marker; + } +}; + +} // namespace + +static void CompleteReconstructionLogProgress( + ProgressUpdateCallback *update_callback, + double progress, + const char *step = NULL) { + if (update_callback) { + char message[256]; + + if (step) + snprintf(message, sizeof(message), "Completing solution %d%% | %s", + (int)(progress*100), step); + else + snprintf(message, sizeof(message), "Completing solution %d%%", + (int)(progress*100)); + + update_callback->invoke(progress, message); + } +} + +template +void InternalCompleteReconstruction( + const Tracks &tracks, + typename PipelineRoutines::Reconstruction *reconstruction, + ProgressUpdateCallback *update_callback = NULL) { + int max_track = tracks.MaxTrack(); + int max_image = tracks.MaxImage(); + int num_resects = -1; + int num_intersects = -1; + int tot_resects = 0; + LG << "Max track: " << max_track; + LG << "Max image: " << max_image; + LG << "Number of markers: " << tracks.NumMarkers(); + while (num_resects != 0 || num_intersects != 0) { + // Do all possible intersections. + num_intersects = 0; + for (int track = 0; track <= max_track; ++track) { + if (reconstruction->PointForTrack(track)) { + LG << "Skipping point: " << track; + continue; + } + vector all_markers = tracks.MarkersForTrack(track); + LG << "Got " << all_markers.size() << " markers for track " << track; + + vector reconstructed_markers; + for (int i = 0; i < all_markers.size(); ++i) { + if (reconstruction->CameraForImage(all_markers[i].image)) { + reconstructed_markers.push_back(all_markers[i]); + } + } + LG << "Got " << reconstructed_markers.size() + << " reconstructed markers for track " << track; + if (reconstructed_markers.size() >= 2) { + CompleteReconstructionLogProgress(update_callback, + (double)tot_resects/(max_image)); + if (PipelineRoutines::Intersect(reconstructed_markers, + reconstruction)) { + num_intersects++; + LG << "Ran Intersect() for track " << track; + } else { + LG << "Failed Intersect() for track " << track; + } + } + } + if (num_intersects) { + CompleteReconstructionLogProgress(update_callback, + (double)tot_resects/(max_image), + "Bundling..."); + PipelineRoutines::Bundle(tracks, reconstruction); + LG << "Ran Bundle() after intersections."; + } + LG << "Did " << num_intersects << " intersects."; + + // Do all possible resections. + num_resects = 0; + for (int image = 0; image <= max_image; ++image) { + if (reconstruction->CameraForImage(image)) { + LG << "Skipping frame: " << image; + continue; + } + vector all_markers = tracks.MarkersInImage(image); + LG << "Got " << all_markers.size() << " markers for image " << image; + + vector reconstructed_markers; + for (int i = 0; i < all_markers.size(); ++i) { + if (reconstruction->PointForTrack(all_markers[i].track)) { + reconstructed_markers.push_back(all_markers[i]); + } + } + LG << "Got " << reconstructed_markers.size() + << " reconstructed markers for image " << image; + if (reconstructed_markers.size() >= 5) { + CompleteReconstructionLogProgress(update_callback, + (double)tot_resects/(max_image)); + if (PipelineRoutines::Resect(reconstructed_markers, + reconstruction, false)) { + num_resects++; + tot_resects++; + LG << "Ran Resect() for image " << image; + } else { + LG << "Failed Resect() for image " << image; + } + } + } + if (num_resects) { + CompleteReconstructionLogProgress(update_callback, + (double)tot_resects/(max_image), + "Bundling..."); + PipelineRoutines::Bundle(tracks, reconstruction); + } + LG << "Did " << num_resects << " resects."; + } + + // One last pass... + num_resects = 0; + for (int image = 0; image <= max_image; ++image) { + if (reconstruction->CameraForImage(image)) { + LG << "Skipping frame: " << image; + continue; + } + vector all_markers = tracks.MarkersInImage(image); + + vector reconstructed_markers; + for (int i = 0; i < all_markers.size(); ++i) { + if (reconstruction->PointForTrack(all_markers[i].track)) { + reconstructed_markers.push_back(all_markers[i]); + } + } + if (reconstructed_markers.size() >= 5) { + CompleteReconstructionLogProgress(update_callback, + (double)tot_resects/(max_image)); + if (PipelineRoutines::Resect(reconstructed_markers, + reconstruction, true)) { + num_resects++; + LG << "Ran final Resect() for image " << image; + } else { + LG << "Failed final Resect() for image " << image; + } + } + } + if (num_resects) { + CompleteReconstructionLogProgress(update_callback, + (double)tot_resects/(max_image), + "Bundling..."); + PipelineRoutines::Bundle(tracks, reconstruction); + } +} + +template +double InternalReprojectionError( + const Tracks &image_tracks, + const typename PipelineRoutines::Reconstruction &reconstruction, + const CameraIntrinsics &intrinsics) { + int num_skipped = 0; + int num_reprojected = 0; + double total_error = 0.0; + vector markers = image_tracks.AllMarkers(); + for (int i = 0; i < markers.size(); ++i) { + double weight = markers[i].weight; + const typename PipelineRoutines::Camera *camera = + reconstruction.CameraForImage(markers[i].image); + const typename PipelineRoutines::Point *point = + reconstruction.PointForTrack(markers[i].track); + if (!camera || !point || weight == 0.0) { + num_skipped++; + continue; + } + num_reprojected++; + + Marker reprojected_marker = + PipelineRoutines::ProjectMarker(*point, *camera, intrinsics); + double ex = (reprojected_marker.x - markers[i].x) * weight; + double ey = (reprojected_marker.y - markers[i].y) * weight; + + const int N = 100; + char line[N]; + snprintf(line, N, + "image %-3d track %-3d " + "x %7.1f y %7.1f " + "rx %7.1f ry %7.1f " + "ex %7.1f ey %7.1f" + " e %7.1f", + markers[i].image, + markers[i].track, + markers[i].x, + markers[i].y, + reprojected_marker.x, + reprojected_marker.y, + ex, + ey, + sqrt(ex*ex + ey*ey)); + VLOG(1) << line; + + total_error += sqrt(ex*ex + ey*ey); + } + LG << "Skipped " << num_skipped << " markers."; + LG << "Reprojected " << num_reprojected << " markers."; + LG << "Total error: " << total_error; + LG << "Average error: " << (total_error / num_reprojected) << " [pixels]."; + return total_error / num_reprojected; +} + +double EuclideanReprojectionError(const Tracks &image_tracks, + const EuclideanReconstruction &reconstruction, + const CameraIntrinsics &intrinsics) { + return InternalReprojectionError(image_tracks, + reconstruction, + intrinsics); +} + +double ProjectiveReprojectionError( + const Tracks &image_tracks, + const ProjectiveReconstruction &reconstruction, + const CameraIntrinsics &intrinsics) { + return InternalReprojectionError(image_tracks, + reconstruction, + intrinsics); +} + +void EuclideanCompleteReconstruction(const Tracks &tracks, + EuclideanReconstruction *reconstruction, + ProgressUpdateCallback *update_callback) { + InternalCompleteReconstruction(tracks, + reconstruction, + update_callback); +} + +void ProjectiveCompleteReconstruction(const Tracks &tracks, + ProjectiveReconstruction *reconstruction) { + InternalCompleteReconstruction(tracks, + reconstruction); +} + +void InvertIntrinsicsForTracks(const Tracks &raw_tracks, + const CameraIntrinsics &camera_intrinsics, + Tracks *calibrated_tracks) { + vector markers = raw_tracks.AllMarkers(); + for (int i = 0; i < markers.size(); ++i) { + camera_intrinsics.InvertIntrinsics(markers[i].x, + markers[i].y, + &(markers[i].x), + &(markers[i].y)); + } + *calibrated_tracks = Tracks(markers); +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/pipeline.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/pipeline.h new file mode 100644 index 0000000000..4d1bd00c51 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/pipeline.h @@ -0,0 +1,98 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_PIPELINE_H_ +#define LIBMV_SIMPLE_PIPELINE_PIPELINE_H_ + +#include "libmv/simple_pipeline/callbacks.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/reconstruction.h" + +namespace libmv { + +/*! + Estimate camera poses and scene 3D coordinates for all frames and tracks. + + This method should be used once there is an initial reconstruction in + place, for example by reconstructing from two frames that have a sufficient + baseline and number of tracks in common. This function iteratively + triangulates points that are visible by cameras that have their pose + estimated, then resections (i.e. estimates the pose) of cameras that are + not estimated yet that can see triangulated points. This process is + repeated until all points and cameras are estimated. Periodically, bundle + adjustment is run to ensure a quality reconstruction. + + \a tracks should contain markers used in the reconstruction. + \a reconstruction should contain at least some 3D points or some estimated + cameras. The minimum number of cameras is two (with no 3D points) and the + minimum number of 3D points (with no estimated cameras) is 5. + + \sa EuclideanResect, EuclideanIntersect, EuclideanBundle +*/ +void EuclideanCompleteReconstruction( + const Tracks &tracks, + EuclideanReconstruction *reconstruction, + ProgressUpdateCallback *update_callback = NULL); + +/*! + Estimate camera matrices and homogeneous 3D coordinates for all frames and + tracks. + + This method should be used once there is an initial reconstruction in + place, for example by reconstructing from two frames that have a sufficient + baseline and number of tracks in common. This function iteratively + triangulates points that are visible by cameras that have their pose + estimated, then resections (i.e. estimates the pose) of cameras that are + not estimated yet that can see triangulated points. This process is + repeated until all points and cameras are estimated. Periodically, bundle + adjustment is run to ensure a quality reconstruction. + + \a tracks should contain markers used in the reconstruction. + \a reconstruction should contain at least some 3D points or some estimated + cameras. The minimum number of cameras is two (with no 3D points) and the + minimum number of 3D points (with no estimated cameras) is 5. + + \sa ProjectiveResect, ProjectiveIntersect, ProjectiveBundle +*/ +void ProjectiveCompleteReconstruction(const Tracks &tracks, + ProjectiveReconstruction *reconstruction); + + +class CameraIntrinsics; + +// TODO(keir): Decide if we want these in the public API, and if so, what the +// appropriate include file is. + +double EuclideanReprojectionError(const Tracks &image_tracks, + const EuclideanReconstruction &reconstruction, + const CameraIntrinsics &intrinsics); + +double ProjectiveReprojectionError( + const Tracks &image_tracks, + const ProjectiveReconstruction &reconstruction, + const CameraIntrinsics &intrinsics); + +void InvertIntrinsicsForTracks(const Tracks &raw_tracks, + const CameraIntrinsics &camera_intrinsics, + Tracks *calibrated_tracks); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_PIPELINE_H_ diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction.cc new file mode 100644 index 0000000000..65e5dd27d5 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction.cc @@ -0,0 +1,191 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/numeric/numeric.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +EuclideanReconstruction::EuclideanReconstruction() {} +EuclideanReconstruction::EuclideanReconstruction( + const EuclideanReconstruction &other) { + cameras_ = other.cameras_; + points_ = other.points_; +} + +EuclideanReconstruction &EuclideanReconstruction::operator=( + const EuclideanReconstruction &other) { + if (&other != this) { + cameras_ = other.cameras_; + points_ = other.points_; + } + return *this; +} + +void EuclideanReconstruction::InsertCamera(int image, + const Mat3 &R, + const Vec3 &t) { + LG << "InsertCamera " << image << ":\nR:\n"<< R << "\nt:\n" << t; + if (image >= cameras_.size()) { + cameras_.resize(image + 1); + } + cameras_[image].image = image; + cameras_[image].R = R; + cameras_[image].t = t; +} + +void EuclideanReconstruction::InsertPoint(int track, const Vec3 &X) { + LG << "InsertPoint " << track << ":\n" << X; + if (track >= points_.size()) { + points_.resize(track + 1); + } + points_[track].track = track; + points_[track].X = X; +} + +EuclideanCamera *EuclideanReconstruction::CameraForImage(int image) { + return const_cast( + static_cast( + this)->CameraForImage(image)); +} + +const EuclideanCamera *EuclideanReconstruction::CameraForImage( + int image) const { + if (image < 0 || image >= cameras_.size()) { + return NULL; + } + const EuclideanCamera *camera = &cameras_[image]; + if (camera->image == -1) { + return NULL; + } + return camera; +} + +vector EuclideanReconstruction::AllCameras() const { + vector cameras; + for (int i = 0; i < cameras_.size(); ++i) { + if (cameras_[i].image != -1) { + cameras.push_back(cameras_[i]); + } + } + return cameras; +} + +EuclideanPoint *EuclideanReconstruction::PointForTrack(int track) { + return const_cast( + static_cast(this)->PointForTrack(track)); +} + +const EuclideanPoint *EuclideanReconstruction::PointForTrack(int track) const { + if (track < 0 || track >= points_.size()) { + return NULL; + } + const EuclideanPoint *point = &points_[track]; + if (point->track == -1) { + return NULL; + } + return point; +} + +vector EuclideanReconstruction::AllPoints() const { + vector points; + for (int i = 0; i < points_.size(); ++i) { + if (points_[i].track != -1) { + points.push_back(points_[i]); + } + } + return points; +} + +void ProjectiveReconstruction::InsertCamera(int image, + const Mat34 &P) { + LG << "InsertCamera " << image << ":\nP:\n"<< P; + if (image >= cameras_.size()) { + cameras_.resize(image + 1); + } + cameras_[image].image = image; + cameras_[image].P = P; +} + +void ProjectiveReconstruction::InsertPoint(int track, const Vec4 &X) { + LG << "InsertPoint " << track << ":\n" << X; + if (track >= points_.size()) { + points_.resize(track + 1); + } + points_[track].track = track; + points_[track].X = X; +} + +ProjectiveCamera *ProjectiveReconstruction::CameraForImage(int image) { + return const_cast( + static_cast( + this)->CameraForImage(image)); +} + +const ProjectiveCamera *ProjectiveReconstruction::CameraForImage( + int image) const { + if (image < 0 || image >= cameras_.size()) { + return NULL; + } + const ProjectiveCamera *camera = &cameras_[image]; + if (camera->image == -1) { + return NULL; + } + return camera; +} + +vector ProjectiveReconstruction::AllCameras() const { + vector cameras; + for (int i = 0; i < cameras_.size(); ++i) { + if (cameras_[i].image != -1) { + cameras.push_back(cameras_[i]); + } + } + return cameras; +} + +ProjectivePoint *ProjectiveReconstruction::PointForTrack(int track) { + return const_cast( + static_cast(this)->PointForTrack(track)); +} + +const ProjectivePoint *ProjectiveReconstruction::PointForTrack(int track) const { + if (track < 0 || track >= points_.size()) { + return NULL; + } + const ProjectivePoint *point = &points_[track]; + if (point->track == -1) { + return NULL; + } + return point; +} + +vector ProjectiveReconstruction::AllPoints() const { + vector points; + for (int i = 0; i < points_.size(); ++i) { + if (points_[i].track != -1) { + points.push_back(points_[i]); + } + } + return points; +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction.h new file mode 100644 index 0000000000..947a063647 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction.h @@ -0,0 +1,217 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_ +#define LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_ + +#include "libmv/base/vector.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +/*! + A EuclideanCamera is the location and rotation of the camera viewing \a image. + + \a image identify which image from \l Tracks this camera represents. + \a R is a 3x3 matrix representing the rotation of the camera. + \a t is a translation vector representing its positions. + + \sa Reconstruction +*/ +struct EuclideanCamera { + EuclideanCamera() : image(-1) {} + EuclideanCamera(const EuclideanCamera &c) : image(c.image), R(c.R), t(c.t) {} + + int image; + Mat3 R; + Vec3 t; +}; + +/*! + A Point is the 3D location of a track. + + \a track identify which track from \l Tracks this point corresponds to. + \a X represents the 3D position of the track. + + \sa Reconstruction +*/ +struct EuclideanPoint { + EuclideanPoint() : track(-1) {} + EuclideanPoint(const EuclideanPoint &p) : track(p.track), X(p.X) {} + int track; + Vec3 X; +}; + +/*! + The EuclideanReconstruction class stores \link EuclideanCamera cameras + \endlink and \link EuclideanPoint points \endlink. + + The EuclideanReconstruction container is intended as the store of 3D + reconstruction data to be used with the MultiView API. + + The container has lookups to query a \a EuclideanCamera from an \a image or + a \a EuclideanPoint from a \a track. + + \sa Camera, Point +*/ +class EuclideanReconstruction { + public: + // Default constructor starts with no cameras. + EuclideanReconstruction(); + + /// Copy constructor. + EuclideanReconstruction(const EuclideanReconstruction &other); + + EuclideanReconstruction &operator=(const EuclideanReconstruction &other); + + /*! + Insert a camera into the set. If there is already a camera for the given + \a image, the existing camera is replaced. If there is no camera for the + given \a image, a new one is added. + + \a image is the key used to retrieve the cameras with the other methods + in this class. + + \note You should use the same \a image identifier as in \l Tracks. + */ + void InsertCamera(int image, const Mat3 &R, const Vec3 &t); + + /*! + Insert a point into the reconstruction. If there is already a point for + the given \a track, the existing point is replaced. If there is no point + for the given \a track, a new one is added. + + \a track is the key used to retrieve the points with the + other methods in this class. + + \note You should use the same \a track identifier as in \l Tracks. + */ + void InsertPoint(int track, const Vec3 &X); + + /// Returns a pointer to the camera corresponding to \a image. + EuclideanCamera *CameraForImage(int image); + const EuclideanCamera *CameraForImage(int image) const; + + /// Returns all cameras. + vector AllCameras() const; + + /// Returns a pointer to the point corresponding to \a track. + EuclideanPoint *PointForTrack(int track); + const EuclideanPoint *PointForTrack(int track) const; + + /// Returns all points. + vector AllPoints() const; + + private: + vector cameras_; + vector points_; +}; + +/*! + A ProjectiveCamera is the projection matrix for the camera of \a image. + + \a image identify which image from \l Tracks this camera represents. + \a P is the 3x4 projection matrix. + + \sa ProjectiveReconstruction +*/ +struct ProjectiveCamera { + ProjectiveCamera() : image(-1) {} + ProjectiveCamera(const ProjectiveCamera &c) : image(c.image), P(c.P) {} + + int image; + Mat34 P; +}; + +/*! + A Point is the 3D location of a track. + + \a track identifies which track from \l Tracks this point corresponds to. + \a X is the homogeneous 3D position of the track. + + \sa Reconstruction +*/ +struct ProjectivePoint { + ProjectivePoint() : track(-1) {} + ProjectivePoint(const ProjectivePoint &p) : track(p.track), X(p.X) {} + int track; + Vec4 X; +}; + +/*! + The ProjectiveReconstruction class stores \link ProjectiveCamera cameras + \endlink and \link ProjectivePoint points \endlink. + + The ProjectiveReconstruction container is intended as the store of 3D + reconstruction data to be used with the MultiView API. + + The container has lookups to query a \a ProjectiveCamera from an \a image or + a \a ProjectivePoint from a \a track. + + \sa Camera, Point +*/ +class ProjectiveReconstruction { + public: + /*! + Insert a camera into the set. If there is already a camera for the given + \a image, the existing camera is replaced. If there is no camera for the + given \a image, a new one is added. + + \a image is the key used to retrieve the cameras with the other methods + in this class. + + \note You should use the same \a image identifier as in \l Tracks. + */ + void InsertCamera(int image, const Mat34 &P); + + /*! + Insert a point into the reconstruction. If there is already a point for + the given \a track, the existing point is replaced. If there is no point + for the given \a track, a new one is added. + + \a track is the key used to retrieve the points with the + other methods in this class. + + \note You should use the same \a track identifier as in \l Tracks. + */ + void InsertPoint(int track, const Vec4 &X); + + /// Returns a pointer to the camera corresponding to \a image. + ProjectiveCamera *CameraForImage(int image); + const ProjectiveCamera *CameraForImage(int image) const; + + /// Returns all cameras. + vector AllCameras() const; + + /// Returns a pointer to the point corresponding to \a track. + ProjectivePoint *PointForTrack(int track); + const ProjectivePoint *PointForTrack(int track) const; + + /// Returns all points. + vector AllPoints() const; + + private: + vector cameras_; + vector points_; +}; + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_ diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction_scale.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction_scale.cc new file mode 100644 index 0000000000..40ac23be7a --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction_scale.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2013 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/reconstruction_scale.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +void EuclideanScaleToUnity(EuclideanReconstruction *reconstruction) { + vector all_cameras = reconstruction->AllCameras(); + vector all_points = reconstruction->AllPoints(); + + // Calculate center of the mass of all cameras. + Vec3 cameras_mass_center = Vec3::Zero(); + for (int i = 0; i < all_cameras.size(); ++i) { + cameras_mass_center += all_cameras[i].t; + } + cameras_mass_center /= all_cameras.size(); + + // Find the most distant camera from the mass center. + double max_distance = 0.0; + for (int i = 0; i < all_cameras.size(); ++i) { + double distance = (all_cameras[i].t - cameras_mass_center).squaredNorm(); + if (distance > max_distance) { + max_distance = distance; + } + } + + if (max_distance == 0.0) { + LG << "Cameras position variance is too small, can not rescale"; + return; + } + + double scale_factor = 1.0 / sqrt(max_distance); + + // Rescale cameras positions. + for (int i = 0; i < all_cameras.size(); ++i) { + int image = all_cameras[i].image; + EuclideanCamera *camera = reconstruction->CameraForImage(image); + camera->t = camera->t * scale_factor; + } + + // Rescale points positions. + for (int i = 0; i < all_points.size(); ++i) { + int track = all_points[i].track; + EuclideanPoint *point = reconstruction->PointForTrack(track); + point->X = point->X * scale_factor; + } +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction_scale.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction_scale.h new file mode 100644 index 0000000000..f2349ff514 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/reconstruction_scale.h @@ -0,0 +1,36 @@ +// Copyright (c) 2013 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_SCALE_H_ +#define LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_SCALE_H_ + +#include "libmv/simple_pipeline/reconstruction.h" + +namespace libmv { + +/*! + Scale euclidean reconstruction in a way variance of + camera centers equals to one. + */ +void EuclideanScaleToUnity(EuclideanReconstruction *reconstruction); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_SCALE_H_ diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/resect.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/resect.cc new file mode 100644 index 0000000000..e73fc44df2 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/resect.cc @@ -0,0 +1,270 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/resect.h" + +#include + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/euclidean_resection.h" +#include "libmv/multiview/resection.h" +#include "libmv/multiview/projection.h" +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/levenberg_marquardt.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" + +namespace libmv { +namespace { + +Mat2X PointMatrixFromMarkers(const vector &markers) { + Mat2X points(2, markers.size()); + for (int i = 0; i < markers.size(); ++i) { + points(0, i) = markers[i].x; + points(1, i) = markers[i].y; + } + return points; +} + +// Uses an incremental rotation: +// +// x = R' * R * X + t; +// +// to avoid issues with the rotation representation. R' is derived from a +// euler vector encoding the rotation in 3 parameters; the direction is the +// axis to rotate around and the magnitude is the amount of the rotation. +struct EuclideanResectCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec6 XMatrixType; + + EuclideanResectCostFunction(const vector &markers, + const EuclideanReconstruction &reconstruction, + const Mat3 &initial_R) + : markers(markers), + reconstruction(reconstruction), + initial_R(initial_R) {} + + // dRt has dR (delta R) encoded as a euler vector in the first 3 parameters, + // followed by t in the next 3 parameters. + Vec operator()(const Vec6 &dRt) const { + // Unpack R, t from dRt. + Mat3 R = RotationFromEulerVector(dRt.head<3>()) * initial_R; + Vec3 t = dRt.tail<3>(); + + // Compute the reprojection error for each coordinate. + Vec residuals(2 * markers.size()); + residuals.setZero(); + for (int i = 0; i < markers.size(); ++i) { + const EuclideanPoint &point = + *reconstruction.PointForTrack(markers[i].track); + Vec3 projected = R * point.X + t; + projected /= projected(2); + residuals[2*i + 0] = projected(0) - markers[i].x; + residuals[2*i + 1] = projected(1) - markers[i].y; + } + return residuals; + } + + const vector &markers; + const EuclideanReconstruction &reconstruction; + const Mat3 &initial_R; +}; + +} // namespace + +bool EuclideanResect(const vector &markers, + EuclideanReconstruction *reconstruction, bool final_pass) { + if (markers.size() < 5) { + return false; + } + Mat2X points_2d = PointMatrixFromMarkers(markers); + Mat3X points_3d(3, markers.size()); + for (int i = 0; i < markers.size(); i++) { + points_3d.col(i) = reconstruction->PointForTrack(markers[i].track)->X; + } + LG << "Points for resect:\n" << points_2d; + + Mat3 R; + Vec3 t; + + if (0 || !euclidean_resection::EuclideanResection( + points_2d, points_3d, &R, &t, + euclidean_resection::RESECTION_EPNP)) { + // printf("Resection for image %d failed\n", markers[0].image); + LG << "Resection for image " << markers[0].image << " failed;" + << " trying fallback projective resection."; + + LG << "No fallback; failing resection for " << markers[0].image; + return false; + + if (!final_pass) return false; + // Euclidean resection failed. Fall back to projective resection, which is + // less reliable but better conditioned when there are many points. + Mat34 P; + Mat4X points_3d_homogeneous(4, markers.size()); + for (int i = 0; i < markers.size(); i++) { + points_3d_homogeneous.col(i).head<3>() = points_3d.col(i); + points_3d_homogeneous(3, i) = 1.0; + } + resection::Resection(points_2d, points_3d_homogeneous, &P); + if ((P * points_3d_homogeneous.col(0))(2) < 0) { + LG << "Point behind camera; switch sign."; + P = -P; + } + + Mat3 ignored; + KRt_From_P(P, &ignored, &R, &t); + + // The R matrix should be a rotation, but don't rely on it. + Eigen::JacobiSVD svd(R, Eigen::ComputeFullU | Eigen::ComputeFullV); + + LG << "Resection rotation is: " << svd.singularValues().transpose(); + LG << "Determinant is: " << R.determinant(); + + // Correct to make R a rotation. + R = svd.matrixU() * svd.matrixV().transpose(); + + Vec3 xx = R * points_3d.col(0) + t; + if (xx(2) < 0.0) { + LG << "Final point is still behind camera..."; + } + // XXX Need to check if error is horrible and fail here too in that case. + } + + // Refine the result. + typedef LevenbergMarquardt Solver; + + // Give the cost our initial guess for R. + EuclideanResectCostFunction resect_cost(markers, *reconstruction, R); + + // Encode the initial parameters: start with zero delta rotation, and the + // guess for t obtained from resection. + Vec6 dRt = Vec6::Zero(); + dRt.tail<3>() = t; + + Solver solver(resect_cost); + + Solver::SolverParameters params; + /* Solver::Results results = */ solver.minimize(params, &dRt); + LG << "LM found incremental rotation: " << dRt.head<3>().transpose(); + // TODO(keir): Check results to ensure clean termination. + + // Unpack the rotation and translation. + R = RotationFromEulerVector(dRt.head<3>()) * R; + t = dRt.tail<3>(); + + LG << "Resection for image " << markers[0].image << " got:\n" + << "R:\n" << R << "\nt:\n" << t; + reconstruction->InsertCamera(markers[0].image, R, t); + return true; +} + +namespace { + +// Directly parameterize the projection matrix, P, which is a 12 parameter +// homogeneous entry. In theory P should be parameterized with only 11 +// parametetrs, but in practice it works fine to let the extra degree of +// freedom drift. +struct ProjectiveResectCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec12 XMatrixType; + + ProjectiveResectCostFunction(const vector &markers, + const ProjectiveReconstruction &reconstruction) + : markers(markers), + reconstruction(reconstruction) {} + + Vec operator()(const Vec12 &vector_P) const { + // Unpack P from vector_P. + Map P(vector_P.data(), 3, 4); + + // Compute the reprojection error for each coordinate. + Vec residuals(2 * markers.size()); + residuals.setZero(); + for (int i = 0; i < markers.size(); ++i) { + const ProjectivePoint &point = + *reconstruction.PointForTrack(markers[i].track); + Vec3 projected = P * point.X; + projected /= projected(2); + residuals[2*i + 0] = projected(0) - markers[i].x; + residuals[2*i + 1] = projected(1) - markers[i].y; + } + return residuals; + } + + const vector &markers; + const ProjectiveReconstruction &reconstruction; +}; + +} // namespace + +bool ProjectiveResect(const vector &markers, + ProjectiveReconstruction *reconstruction) { + if (markers.size() < 5) { + return false; + } + + // Stack the homogeneous 3D points as the columns of a matrix. + Mat2X points_2d = PointMatrixFromMarkers(markers); + Mat4X points_3d_homogeneous(4, markers.size()); + for (int i = 0; i < markers.size(); i++) { + points_3d_homogeneous.col(i) = + reconstruction->PointForTrack(markers[i].track)->X; + } + LG << "Points for resect:\n" << points_2d; + + // Resection the point. + Mat34 P; + resection::Resection(points_2d, points_3d_homogeneous, &P); + + // Flip the sign of P if necessary to keep the point in front of the camera. + if ((P * points_3d_homogeneous.col(0))(2) < 0) { + LG << "Point behind camera; switch sign."; + P = -P; + } + + // TODO(keir): Check if error is horrible and fail in that case. + + // Refine the resulting projection matrix using geometric error. + typedef LevenbergMarquardt Solver; + + ProjectiveResectCostFunction resect_cost(markers, *reconstruction); + + // Pack the initial P matrix into a size-12 vector.. + Vec12 vector_P = Map(P.data()); + + Solver solver(resect_cost); + + Solver::SolverParameters params; + /* Solver::Results results = */ solver.minimize(params, &vector_P); + // TODO(keir): Check results to ensure clean termination. + + // Unpack the projection matrix. + P = Map(vector_P.data(), 3, 4); + + LG << "Resection for image " << markers[0].image << " got:\n" + << "P:\n" << P; + reconstruction->InsertCamera(markers[0].image, P); + return true; +} +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/resect.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/resect.h new file mode 100644 index 0000000000..7ca3237437 --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/resect.h @@ -0,0 +1,86 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_RESECT_H +#define LIBMV_SIMPLE_PIPELINE_RESECT_H + +#include "libmv/base/vector.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/reconstruction.h" + +namespace libmv { + +/*! + Estimate the Euclidean pose of a camera from 2D to 3D correspondences. + + This takes a set of markers visible in one frame (which is the one to + resection), such that the markers are also reconstructed in 3D in the + reconstruction object, and solves for the pose and orientation of the + camera for that frame. + + \a markers should contain \l Marker markers \endlink belonging to tracks + visible in the one frame to be resectioned. Each of the tracks associated + with the markers must have a corresponding reconstructed 3D position in the + \a *reconstruction object. + + \a *reconstruction should contain the 3D points associated with the tracks + for the markers present in \a markers. + + \note This assumes a calibrated reconstruction, e.g. the markers are + already corrected for camera intrinsics and radial distortion. + \note This assumes an outlier-free set of markers. + + \return True if the resection was successful, false otherwise. + + \sa EuclideanIntersect, EuclideanReconstructTwoFrames +*/ +bool EuclideanResect(const vector &markers, + EuclideanReconstruction *reconstruction, bool final_pass); + +/*! + Estimate the projective pose of a camera from 2D to 3D correspondences. + + This takes a set of markers visible in one frame (which is the one to + resection), such that the markers are also reconstructed in a projective + frame in the reconstruction object, and solves for the projective matrix of + the camera for that frame. + + \a markers should contain \l Marker markers \endlink belonging to tracks + visible in the one frame to be resectioned. Each of the tracks associated + with the markers must have a corresponding reconstructed homogeneous 3D + position in the \a *reconstruction object. + + \a *reconstruction should contain the homogeneous 3D points associated with + the tracks for the markers present in \a markers. + + \note This assumes radial distortion has already been corrected, but + otherwise works for uncalibrated sequences. + \note This assumes an outlier-free set of markers. + + \return True if the resection was successful, false otherwise. + + \sa ProjectiveIntersect, ProjectiveReconstructTwoFrames +*/ +bool ProjectiveResect(const vector &markers, + ProjectiveReconstruction *reconstruction); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_RESECT_H diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/tracks.cc b/modules/sfm/src/libmv_light/libmv/simple_pipeline/tracks.cc new file mode 100644 index 0000000000..d5d009708b --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/tracks.cc @@ -0,0 +1,187 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/tracks.h" + +#include +#include +#include + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +Tracks::Tracks(const Tracks &other) { + markers_ = other.markers_; +} + +Tracks::Tracks(const vector &markers) : markers_(markers) {} + +void Tracks::Insert(int image, int track, double x, double y, double weight) { + // TODO(keir): Wow, this is quadratic for repeated insertions. Fix this by + // adding a smarter data structure like a set<>. + for (int i = 0; i < markers_.size(); ++i) { + if (markers_[i].image == image && + markers_[i].track == track) { + markers_[i].x = x; + markers_[i].y = y; + return; + } + } + Marker marker = { image, track, x, y, weight }; + markers_.push_back(marker); +} + +vector Tracks::AllMarkers() const { + return markers_; +} + +vector Tracks::MarkersInImage(int image) const { + vector markers; + for (int i = 0; i < markers_.size(); ++i) { + if (image == markers_[i].image) { + markers.push_back(markers_[i]); + } + } + return markers; +} + +vector Tracks::MarkersForTrack(int track) const { + vector markers; + for (int i = 0; i < markers_.size(); ++i) { + if (track == markers_[i].track) { + markers.push_back(markers_[i]); + } + } + return markers; +} + +vector Tracks::MarkersInBothImages(int image1, int image2) const { + vector markers; + for (int i = 0; i < markers_.size(); ++i) { + int image = markers_[i].image; + if (image == image1 || image == image2) + markers.push_back(markers_[i]); + } + return markers; +} + +vector Tracks::MarkersForTracksInBothImages(int image1, + int image2) const { + std::vector image1_tracks; + std::vector image2_tracks; + + for (int i = 0; i < markers_.size(); ++i) { + int image = markers_[i].image; + if (image == image1) { + image1_tracks.push_back(markers_[i].track); + } else if (image == image2) { + image2_tracks.push_back(markers_[i].track); + } + } + + std::sort(image1_tracks.begin(), image1_tracks.end()); + std::sort(image2_tracks.begin(), image2_tracks.end()); + + std::vector intersection; + std::set_intersection(image1_tracks.begin(), image1_tracks.end(), + image2_tracks.begin(), image2_tracks.end(), + std::back_inserter(intersection)); + + vector markers; + for (int i = 0; i < markers_.size(); ++i) { + if ((markers_[i].image == image1 || markers_[i].image == image2) && + std::binary_search(intersection.begin(), intersection.end(), + markers_[i].track)) { + markers.push_back(markers_[i]); + } + } + return markers; +} + +Marker Tracks::MarkerInImageForTrack(int image, int track) const { + for (int i = 0; i < markers_.size(); ++i) { + if (markers_[i].image == image && markers_[i].track == track) { + return markers_[i]; + } + } + Marker null = { -1, -1, -1, -1, 0.0 }; + return null; +} + +void Tracks::RemoveMarkersForTrack(int track) { + int size = 0; + for (int i = 0; i < markers_.size(); ++i) { + if (markers_[i].track != track) { + markers_[size++] = markers_[i]; + } + } + markers_.resize(size); +} + +void Tracks::RemoveMarker(int image, int track) { + int size = 0; + for (int i = 0; i < markers_.size(); ++i) { + if (markers_[i].image != image || markers_[i].track != track) { + markers_[size++] = markers_[i]; + } + } + markers_.resize(size); +} + +int Tracks::MaxImage() const { + // TODO(MatthiasF): maintain a max_image_ member (updated on Insert) + int max_image = 0; + for (int i = 0; i < markers_.size(); ++i) { + max_image = std::max(markers_[i].image, max_image); + } + return max_image; +} + +int Tracks::MaxTrack() const { + // TODO(MatthiasF): maintain a max_track_ member (updated on Insert) + int max_track = 0; + for (int i = 0; i < markers_.size(); ++i) { + max_track = std::max(markers_[i].track, max_track); + } + return max_track; +} + +int Tracks::NumMarkers() const { + return markers_.size(); +} + +void CoordinatesForMarkersInImage(const vector &markers, + int image, + Mat *coordinates) { + vector coords; + for (int i = 0; i < markers.size(); ++i) { + const Marker &marker = markers[i]; + if (markers[i].image == image) { + coords.push_back(Vec2(marker.x, marker.y)); + } + } + coordinates->resize(2, coords.size()); + for (int i = 0; i < coords.size(); i++) { + coordinates->col(i) = coords[i]; + } +} + +} // namespace libmv diff --git a/modules/sfm/src/libmv_light/libmv/simple_pipeline/tracks.h b/modules/sfm/src/libmv_light/libmv/simple_pipeline/tracks.h new file mode 100644 index 0000000000..a54a43659b --- /dev/null +++ b/modules/sfm/src/libmv_light/libmv/simple_pipeline/tracks.h @@ -0,0 +1,138 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_TRACKS_H_ +#define LIBMV_SIMPLE_PIPELINE_TRACKS_H_ + +#include "libmv/base/vector.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +/*! + A Marker is the 2D location of a tracked point in an image. + + \a x, \a y is the position of the marker in pixels from the top left corner + in the image identified by \a image. All markers for to the same target + form a track identified by a common \a track number. + + \a weight is used by bundle adjustment and weight means how much the + track affects on a final solution. + + \note Markers are typically aggregated with the help of the \l Tracks class. + + \sa Tracks +*/ +// TODO(sergey): Consider using comment for every member separately +// instead of having one giantic comment block. +struct Marker { + int image; + int track; + double x, y; + double weight; +}; + +/*! + The Tracks class stores \link Marker reconstruction markers \endlink. + + The Tracks container is intended as the store of correspondences between + images, which must get created before any 3D reconstruction can take place. + + The container has several fast lookups for queries typically needed for + structure from motion algorithms, such as \l MarkersForTracksInBothImages(). + + \sa Marker +*/ +class Tracks { + public: + Tracks() { } + + // Copy constructor for a tracks object. + Tracks(const Tracks &other); + + /// Construct a new tracks object using the given markers to start. + explicit Tracks(const vector &markers); + + /*! + Inserts a marker into the set. If there is already a marker for the given + \a image and \a track, the existing marker is replaced. If there is no + marker for the given \a image and \a track, a new one is added. + + \a image and \a track are the keys used to retrieve the markers with the + other methods in this class. + + \a weight is used by bundle adjustment and weight means how much the + track affects on a final solution. + + \note To get an identifier for a new track, use \l MaxTrack() + 1. + */ + // TODO(sergey): Consider using InsetWeightedMarker istead of using + // stupid default value? + void Insert(int image, int track, double x, double y, double weight = 1.0); + + /// Returns all the markers. + vector AllMarkers() const; + + /// Returns all the markers belonging to a track. + vector MarkersForTrack(int track) const; + + /// Returns all the markers visible in \a image. + vector MarkersInImage(int image) const; + + /// Returns all the markers visible in \a image1 and \a image2. + vector MarkersInBothImages(int image1, int image2) const; + + /*! + Returns the markers in \a image1 and \a image2 which have a common track. + + This is not the same as the union of the markers in \a image1 and \a + image2; each marker is for a track that appears in both images. + */ + vector MarkersForTracksInBothImages(int image1, int image2) const; + + /// Returns the marker in \a image belonging to \a track. + Marker MarkerInImageForTrack(int image, int track) const; + + /// Removes all the markers belonging to \a track. + void RemoveMarkersForTrack(int track); + + /// Removes the marker in \a image belonging to \a track. + void RemoveMarker(int image, int track); + + /// Returns the maximum image identifier used. + int MaxImage() const; + + /// Returns the maximum track identifier used. + int MaxTrack() const; + + /// Returns the number of markers. + int NumMarkers() const; + + private: + vector markers_; +}; + +void CoordinatesForMarkersInImage(const vector &markers, + int image, + Mat *coordinates); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_MARKERS_H_ diff --git a/modules/sfm/src/numeric.cpp b/modules/sfm/src/numeric.cpp new file mode 100644 index 0000000000..221afcf95c --- /dev/null +++ b/modules/sfm/src/numeric.cpp @@ -0,0 +1,173 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" + +// Eigen +#include + +// OpenCV +#include +#include + +// libmv headers +#include "libmv/numeric/numeric.h" + +#include + +namespace cv +{ +namespace sfm +{ + +template +void +meanAndVarianceAlongRows( const Mat_ &A, + Mat_ mean, + Mat_ variance ) +{ + const int n = A.rows, m = A.cols; + + for( int i = 0; i < n; ++i ) + { + mean(i) = 0; + variance(i) = 0; + + for( int j = 0; j < m; ++j ) + { + T x = A(i,j); + mean(i) += x; + variance(i) += x*x; + } + } + + mean /= m; + for (int i = 0; i < n; ++i) { + variance(i) = variance(i) / m - (mean(i)*mean(i)); + } +} + +void +meanAndVarianceAlongRows( InputArray _A, + OutputArray _mean, + OutputArray _variance ) +{ + const Mat A = _A.getMat(); + const int depth = A.depth(); + CV_Assert( depth == CV_32F || depth == CV_64F ); + + _mean.create(A.rows, 1, depth); + _variance.create(A.rows, 1, depth); + + Mat mean = _mean.getMat(), variance = _variance.getMat(); + + if( depth == CV_32F ) + { + meanAndVarianceAlongRows( A, mean, variance ); + } + else + { + meanAndVarianceAlongRows( A, mean, variance ); + } +} + + +//template +//inline Mat +//skewMatMinimal( const Mat_ &x ) +//{ +// Mat_ skew(2,3); +// skew << 0, -1, x(1), +// 1, 0, -x(0); +// return skew; +//} +// +//Mat +//skewMatMinimal( InputArray _x ) +//{ +// Mat x = _x.getMat(); +// CV_Assert( x.rows == 3 && x.cols == 1 ); +// +// int depth = x.depth(); +// if( depth == CV_32F ) +// { +// return skewMatMinimal(x); +// } +// else +// { +// return skewMatMinimal(x); +// } +//} + +template +Mat +skewMat( const Mat_ &x ) +{ + Mat_ skew(3,3); + skew << 0 , -x(2), x(1), + x(2), 0 , -x(0), + -x(1), x(0), 0; + + return skew; +} + +Mat +skew( InputArray _x ) +{ + const Mat x = _x.getMat(); + const int depth = x.depth(); + CV_Assert( x.size() == Size(3,1) || x.size() == Size(1,3) ); + CV_Assert( depth == CV_32F || depth == CV_64F ); + + Mat skewMatrix; + if( depth == CV_32F ) + { + skewMatrix = skewMat(x); + } + else if( depth == CV_64F ) + { + skewMatrix = skewMat(x); + } + else + { + //CV_Error(CV_StsBadArg, "The DataType must be CV_32F or CV_64F"); + } + + return skewMatrix; +} + + +} /* namespace sfm */ +} /* namespace cv */ diff --git a/modules/sfm/src/precomp.hpp b/modules/sfm/src/precomp.hpp new file mode 100644 index 0000000000..15d5b8739b --- /dev/null +++ b/modules/sfm/src/precomp.hpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// + // + // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + // + // By downloading, copying, installing or using the software you agree to this license. + // If you do not agree to this license, do not download, install, + // copy or use the software. + // + // + // License Agreement + // For Open Source Computer Vision Library + // + // Copyright (C) 2015, OpenCV Foundation, all rights reserved. + // Third party copyrights are property of their respective owners. + // + // Redistribution and use in source and binary forms, with or without modification, + // are permitted provided that the following conditions are met: + // + // * Redistribution's of source code must retain the above copyright notice, + // this list of conditions and the following disclaimer. + // + // * Redistribution's in binary form must reproduce the above copyright notice, + // this list of conditions and the following disclaimer in the documentation + // and/or other materials provided with the distribution. + // + // * The name of the copyright holders may not be used to endorse or promote products + // derived from this software without specific prior written permission. + // + // This software is provided by the copyright holders and contributors "as is" and + // any express or implied warranties, including, but not limited to, the implied + // warranties of merchantability and fitness for a particular purpose are disclaimed. + // In no event shall the Intel Corporation or contributors be liable for any direct, + // indirect, incidental, special, exemplary, or consequential damages + // (including, but not limited to, procurement of substitute goods or services; + // loss of use, data, or profits; or business interruption) however caused + // and on any theory of liability, whether in contract, strict liability, + // or tort (including negligence or otherwise) arising in any way out of + // the use of this software, even if advised of the possibility of such damage. + // + //M*/ + +#ifndef __OPENCV_SFM_PRECOMP__ +#define __OPENCV_SFM_PRECOMP__ + +#include + +#endif diff --git a/modules/sfm/src/projection.cpp b/modules/sfm/src/projection.cpp new file mode 100644 index 0000000000..756e9bb558 --- /dev/null +++ b/modules/sfm/src/projection.cpp @@ -0,0 +1,223 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" + +// Eigen +#include + +// OpenCV +#include +#include +#include + +// libmv headers +#include "libmv/multiview/projection.h" + +#include + +namespace cv +{ +namespace sfm +{ + +template +void +homogeneousToEuclidean(const Mat & _X, Mat & _x) +{ + int d = _X.rows - 1; + + const Mat_ & X_rows = _X.rowRange(0,d); + const Mat_ h = _X.row(d); + + const T * h_ptr = h[0], *h_ptr_end = h_ptr + h.cols; + const T * X_ptr = X_rows[0]; + T * x_ptr = _x.ptr(0); + for (; h_ptr != h_ptr_end; ++h_ptr, ++X_ptr, ++x_ptr) + { + const T * X_col_ptr = X_ptr; + T * x_col_ptr = x_ptr, *x_col_ptr_end = x_col_ptr + d * _x.step1(); + for (; x_col_ptr != x_col_ptr_end; X_col_ptr+=X_rows.step1(), x_col_ptr+=_x.step1() ) + *x_col_ptr = (*X_col_ptr) / (*h_ptr); + } +} + +void +homogeneousToEuclidean(const InputArray _X, OutputArray _x) +{ + // src + const Mat X = _X.getMat(); + + // dst + _x.create(X.rows-1, X.cols, X.type()); + Mat x = _x.getMat(); + + // type + if( X.depth() == CV_32F ) + { + homogeneousToEuclidean(X,x); + } + else + { + homogeneousToEuclidean(X,x); + } +} + +void +euclideanToHomogeneous(const InputArray _x, OutputArray _X) +{ + const Mat x = _x.getMat(); + const Mat last_row = Mat::ones(1, x.cols, x.type()); + vconcat(x, last_row, _X); +} + +template +void +projectionFromKRt(const Mat_ &K, const Mat_ &R, const Mat_ &t, Mat_ P) +{ + hconcat( K*R, K*t, P ); +} + +void +projectionFromKRt(InputArray _K, InputArray _R, InputArray _t, OutputArray _P) +{ + const Mat K = _K.getMat(), R = _R.getMat(), t = _t.getMat(); + const int depth = K.depth(); + CV_Assert((K.cols == 3 && K.rows == 3) && (t.cols == 1 && t.rows == 3) && (K.size() == R.size())); + CV_Assert((depth == CV_32F || depth == CV_64F) && depth == R.depth() && depth == t.depth()); + + _P.create(3, 4, depth); + + Mat P = _P.getMat(); + + // type + if( depth == CV_32F ) + { + projectionFromKRt(K, R, t, P); + } + else + { + projectionFromKRt(K, R, t, P); + } + +} + +template +void +KRtFromProjection( const Mat_ &_P, Mat_ _K, Mat_ _R, Mat_ _t ) +{ + libmv::Mat34 P; + libmv::Mat3 K, R; + libmv::Vec3 t; + + cv2eigen( _P, P ); + + libmv::KRt_From_P( P, &K, &R, &t ); + + eigen2cv( K, _K ); + eigen2cv( R, _R ); + eigen2cv( t, _t ); +} + +void +KRtFromProjection( InputArray _P, OutputArray _K, OutputArray _R, OutputArray _t ) +{ + const Mat P = _P.getMat(); + const int depth = P.depth(); + CV_Assert((P.cols == 4 && P.rows == 3) && (depth == CV_32F || depth == CV_64F)); + + _K.create(3, 3, depth); + _R.create(3, 3, depth); + _t.create(3, 1, depth); + + Mat K = _K.getMat(), R = _R.getMat(), t = _t.getMat(); + + // type + if( depth == CV_32F ) + { + KRtFromProjection(P, K, R, t); + } + else + { + KRtFromProjection(P, K, R, t); + } +} + +template +T +depthValue( const Mat_ &_R, const Mat_ &_t, const Mat_ &_X ) +{ + Matx R(_R); + Vec t(_t); + + if ( _X.rows == 3) + { + Vec X(_X); + return (R*X)(2) + t(2); + } + else + { + Vec X(_X); + Vec Xe; + homogeneousToEuclidean(X,Xe); + return depthValue( Mat(R), Mat(t), Mat(Xe) ); + } +} + +double +depth( InputArray _R, InputArray _t, InputArray _X) +{ + const Mat R = _R.getMat(), t = _t.getMat(), X = _X.getMat(); + const int depth = R.depth(); + CV_Assert( R.rows == 3 && R.cols == 3 && t.rows == 3 && t.cols == 1 ); + CV_Assert( (X.rows == 3 && X.cols == 1) || (X.rows == 4 && X.cols == 1) ); + CV_Assert( depth == CV_32F || depth == CV_64F ); + + double depth_value = 0.0; + + if ( depth == CV_32F ) + { + depth_value = static_cast(depthValue(R, t, X)); + } + else + { + depth_value = depthValue(R, t, X); + } + + return depth_value; +} + +} /* namespace sfm */ +} /* namespace cv */ diff --git a/modules/sfm/src/reconstruct.cpp b/modules/sfm/src/reconstruct.cpp new file mode 100644 index 0000000000..1d40f23491 --- /dev/null +++ b/modules/sfm/src/reconstruct.cpp @@ -0,0 +1,258 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" + +#if CERES_FOUND + +// Eigen +#include + +// OpenCV +#include + +#include + +using namespace cv; +using namespace cv::sfm; +using namespace std; + +namespace cv +{ +namespace sfm +{ + + template + void + reconstruct_(const T &input, OutputArray Rs, OutputArray Ts, InputOutputArray K, OutputArray points3d, const bool refinement=true) + { + // Initial reconstruction + const int keyframe1 = 1, keyframe2 = 2; + const int select_keyframes = 1; // enable automatic keyframes selection + const int verbosity_level = -1; // mute libmv logs + + // Refinement parameters + const int refine_intrinsics = ( !refinement ) ? 0 : + SFM_REFINE_FOCAL_LENGTH | SFM_REFINE_PRINCIPAL_POINT | SFM_REFINE_RADIAL_DISTORTION_K1 | SFM_REFINE_RADIAL_DISTORTION_K2; + + // Camera data + Matx33d Ka = K.getMat(); + const double focal_length = Ka(0,0); + const double principal_x = Ka(0,2), principal_y = Ka(1,2), k1 = 0, k2 = 0, k3 = 0; + + // Set reconstruction options + libmv_ReconstructionOptions reconstruction_options(keyframe1, keyframe2, refine_intrinsics, select_keyframes, verbosity_level); + + libmv_CameraIntrinsicsOptions camera_instrinsic_options = + libmv_CameraIntrinsicsOptions(SFM_DISTORTION_MODEL_POLYNOMIAL, + focal_length, principal_x, principal_y, + k1, k2, k3); + + //-- Instantiate reconstruction pipeline + Ptr reconstruction = + SFMLibmvEuclideanReconstruction::create(camera_instrinsic_options, reconstruction_options); + + //-- Run reconstruction pipeline + reconstruction->run(input, K, Rs, Ts, points3d); + + } + + + // Reconstruction function for API + void + reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, InputOutputArray K, + bool is_projective) + { + const int nviews = points2d.total(); + CV_Assert( nviews >= 2 ); + + // OpenCV data types + std::vector pts2d; + points2d.getMatVector(pts2d); + const int depth = pts2d[0].depth(); + + Matx33d Ka = K.getMat(); + + // Projective reconstruction + + if (is_projective) + { + + if ( nviews == 2 ) + { + // Get Projection matrices + Matx33d F; + Matx34d P, Pp; + + normalizedEightPointSolver(pts2d[0], pts2d[1], F); + projectionsFromFundamental(F, P, Pp); + Ps.create(2, 1, depth); + Mat(P).copyTo(Ps.getMatRef(0)); + Mat(Pp).copyTo(Ps.getMatRef(1)); + + // Triangulate and find 3D points using inliers + triangulatePoints(points2d, Ps, points3d); + } + else + { + std::vector Rs, Ts; + reconstruct(points2d, Rs, Ts, Ka, points3d, is_projective); + + // From Rs and Ts, extract Ps + const int nviews = Rs.size(); + Ps.create(nviews, 1, depth); + + Matx34d P; + for (size_t i = 0; i < nviews; ++i) + { + projectionFromKRt(Ka, Rs[i], Vec3d(Ts[i]), P); + Mat(P).copyTo(Ps.getMatRef(i)); + } + + Mat(Ka).copyTo(K.getMat()); + } + + } + + + // Affine reconstruction + + else + { + // TODO: implement me + } + + } + + + void + reconstruct(InputArrayOfArrays points2d, OutputArray Rs, OutputArray Ts, InputOutputArray K, + OutputArray points3d, bool is_projective) + { + const int nviews = points2d.total(); + CV_Assert( nviews >= 2 ); + + + // Projective reconstruction + + if (is_projective) + { + + // calls simple pipeline + reconstruct_(points2d, Rs, Ts, K, points3d); + + } + + // Affine reconstruction + + else + { + // TODO: implement me + } + + } + + + void + reconstruct(const std::vector images, OutputArray Ps, OutputArray points3d, + InputOutputArray K, bool is_projective) + { + const int nviews = static_cast(images.size()); + CV_Assert( nviews >= 2 ); + + Matx33d Ka = K.getMat(); + const int depth = Mat(Ka).depth(); + + // Projective reconstruction + + if ( is_projective ) + { + std::vector Rs, Ts; + reconstruct(images, Rs, Ts, Ka, points3d, is_projective); + + // From Rs and Ts, extract Ps + + const int nviews_est = Rs.size(); + Ps.create(nviews_est, 1, depth); + + Matx34d P; + for (size_t i = 0; i < nviews_est; ++i) + { + projectionFromKRt(Ka, Rs[i], Vec3d(Ts[i]), P); + Mat(P).copyTo(Ps.getMatRef(i)); + } + + Mat(Ka).copyTo(K.getMat()); + } + + + // Affine reconstruction + + else + { + // TODO: implement me + } + + } + + + void + reconstruct(const std::vector images, OutputArray Rs, OutputArray Ts, + InputOutputArray K, OutputArray points3d, bool is_projective) + { + const int nviews = static_cast(images.size()); + CV_Assert( nviews >= 2 ); + + // Projective reconstruction + + if ( is_projective ) + { + reconstruct_(images, Rs, Ts, K, points3d, false); + } + + + // Affine reconstruction + + else + { + // TODO: implement me + } + + } + +} // namespace sfm +} // namespace cv + +#endif /* HAVE_CERES */ \ No newline at end of file diff --git a/modules/sfm/src/robust.cpp b/modules/sfm/src/robust.cpp new file mode 100644 index 0000000000..5116485bae --- /dev/null +++ b/modules/sfm/src/robust.cpp @@ -0,0 +1,195 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" + +// Eigen +#include + +// OpenCV +#include +#include +#include + +// libmv headers +#include "libmv/multiview/robust_fundamental.h" + +using namespace std; + +namespace cv +{ +namespace sfm +{ + +// TODO: unify algorithms +template +double +fundamentalFromCorrespondences8PointRobust( const Mat_ &_x1, + const Mat_ &_x2, + const double max_error, + Mat_ _F, + std::vector &_inliers, + const double outliers_probability ) +{ + libmv::Mat x1, x2; + libmv::Mat3 F; + libmv::vector inliers; + + cv2eigen( _x1, x1 ); + cv2eigen( _x2, x2 ); + + T solution_error = + libmv::FundamentalFromCorrespondences8PointRobust( x1, x2, max_error, &F, &inliers, outliers_probability ); + + eigen2cv( F, _F ); + + // transform from libmv::vector to std::vector + int n = inliers.size(); + _inliers.resize(n); + for( int i=0; i < n; ++i ) + { + _inliers[i] = inliers.at(i); + } + + return static_cast(solution_error); +} + + +double +fundamentalFromCorrespondences8PointRobust( InputArray _x1, + InputArray _x2, + double max_error, + OutputArray _F, + OutputArray _inliers, + double outliers_probability ) +{ + const Mat x1 = _x1.getMat(), x2 = _x2.getMat(); + const int depth = x1.depth(); + CV_Assert(x1.size() == x2.size() && (depth == CV_32F || depth == CV_64F)); + + _F.create(3, 3, depth); + + Mat F = _F.getMat(); + std::vector& inliers = *(std::vector*)_inliers.getObj(); + + double solution_error = 0.0; + + // type + if( depth == CV_32F ) + { + solution_error = + fundamentalFromCorrespondences8PointRobust( + x1, x2, max_error, F, inliers, outliers_probability); + } + else + { + solution_error = + fundamentalFromCorrespondences8PointRobust( + x1, x2, max_error, F, inliers, outliers_probability); + } + + return solution_error; +} + +template +double +fundamentalFromCorrespondences7PointRobust( const Mat_ &_x1, + const Mat_ &_x2, + const double max_error, + Mat_ _F, + std::vector &_inliers, + const double outliers_probability ) +{ + libmv::Mat x1, x2; + libmv::Mat3 F; + libmv::vector inliers; + + cv2eigen( _x1, x1 ); + cv2eigen( _x2, x2 ); + + T solution_error = + libmv::FundamentalFromCorrespondences7PointRobust( x1, x2, max_error, &F, &inliers, outliers_probability ); + + eigen2cv( F, _F ); + + // transform from libmv::vector to std::vector + int n = inliers.size(); + _inliers.resize(n); + for( int i=0; i < n; ++i ) + { + _inliers[i] = inliers.at(i); + } + + return static_cast(solution_error); +} + +double +fundamentalFromCorrespondences7PointRobust( InputArray _x1, + InputArray _x2, + double max_error, + OutputArray _F, + OutputArray _inliers, + double outliers_probability ) +{ + const Mat x1 = _x1.getMat(), x2 = _x2.getMat(); + const int depth = x1.depth(); + CV_Assert(x1.size() == x2.size() && (depth == CV_32F || depth == CV_64F)); + + _F.create(3, 3, depth); + + Mat F = _F.getMat(); + std::vector& inliers = *(std::vector*)_inliers.getObj(); + + double solution_error = 0.0; + + // type + if( depth == CV_32F ) + { + solution_error = + fundamentalFromCorrespondences7PointRobust( + x1, x2, max_error, F, inliers, outliers_probability); + } + else + { + solution_error = + fundamentalFromCorrespondences7PointRobust( + x1, x2, max_error, F, inliers, outliers_probability); + } + + return solution_error; +} + +} /* namespace sfm */ +} /* namespace cv */ \ No newline at end of file diff --git a/modules/sfm/src/simple_pipeline.cpp b/modules/sfm/src/simple_pipeline.cpp new file mode 100644 index 0000000000..0694057826 --- /dev/null +++ b/modules/sfm/src/simple_pipeline.cpp @@ -0,0 +1,319 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" + +#if CERES_FOUND + +#include +#include + +#include "libmv_capi.h" + +using namespace std; + +namespace cv +{ +namespace sfm +{ + +/* Parses a given array of 2d points into the libmv tracks structure + */ + +void +parser_2D_tracks( const std::vector &points2d, libmv::Tracks &tracks ) +{ + const int nframes = static_cast(points2d.size()); + for (int frame = 0; frame < nframes; ++frame) { + const int ntracks = points2d[frame].cols; + for (int track = 0; track < ntracks; ++track) { + const Vec2d track_pt = points2d[frame].col(track); + if ( track_pt[0] > 0 && track_pt[1] > 0 ) + tracks.Insert(frame, track, track_pt[0], track_pt[1]); + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////// + +/* Parses a given set of matches into the libmv tracks structure + */ + +void +parser_2D_tracks( const libmv::Matches &matches, libmv::Tracks &tracks ) +{ + std::set::const_iterator iter_image = + matches.get_images().begin(); + + bool is_first_time = true; + + for (; iter_image != matches.get_images().end(); ++iter_image) { + // Exports points + Matches::Features pfeatures = + matches.InImage(*iter_image); + + while(pfeatures) { + + double x = pfeatures.feature()->x(), + y = pfeatures.feature()->y(); + + // valid marker + if ( x > 0 && y > 0 ) + { + tracks.Insert(*iter_image, pfeatures.track(), x, y); + + if ( is_first_time ) + is_first_time = false; + } + + // lost track + else if ( x < 0 && y < 0 ) + { + is_first_time = true; + } + + pfeatures.operator++(); + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////// + +/* Computes the 2d features matches between a given set of images and call the + * reconstruction pipeline. + */ + +libmv_Reconstruction *libmv_solveReconstructionImpl( + const std::vector &images, + const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options, + libmv_ReconstructionOptions* libmv_reconstruction_options) +{ + Ptr edetector = ORB::create(10000); + Ptr edescriber = xfeatures2d::DAISY::create(); + //Ptr edescriber = xfeatures2d::LATCH::create(64, true, 4); + + cout << "Initialize nViewMatcher ... "; + libmv::correspondence::nRobustViewMatching nViewMatcher(edetector, edescriber); + + cout << "OK" << endl << "Performing Cross Matching ... "; + nViewMatcher.computeCrossMatch(images); cout << "OK" << endl; + + // Building tracks + libmv::Tracks tracks; + libmv::Matches matches = nViewMatcher.getMatches(); + parser_2D_tracks( matches, tracks ); + + // Perform reconstruction + return libmv_solveReconstruction(tracks, + libmv_camera_intrinsics_options, + libmv_reconstruction_options); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// + +template +class SFMLibmvReconstructionImpl : public T +{ +public: + SFMLibmvReconstructionImpl(const libmv_CameraIntrinsicsOptions &camera_instrinsic_options, + const libmv_ReconstructionOptions &reconstruction_options) : + libmv_reconstruction_options_(reconstruction_options), + libmv_camera_intrinsics_options_(camera_instrinsic_options) {} + + /* Run the pipeline given 2d points + */ + + virtual void run(InputArrayOfArrays _points2d) + { + std::vector points2d; + _points2d.getMatVector(points2d); + CV_Assert( _points2d.total() >= 2 ); + + // Parse 2d points to Tracks + Tracks tracks; + parser_2D_tracks(points2d, tracks); + + // Set libmv logs level + libmv_initLogging(""); + + if (libmv_reconstruction_options_.verbosity_level >= 0) + { + libmv_startDebugLogging(); + libmv_setLoggingVerbosity( + libmv_reconstruction_options_.verbosity_level); + } + + // Perform reconstruction + libmv_reconstruction_ = + *libmv_solveReconstruction(tracks, + &libmv_camera_intrinsics_options_, + &libmv_reconstruction_options_); + } + + virtual void run(InputArrayOfArrays points2d, InputOutputArray K, OutputArray Rs, + OutputArray Ts, OutputArray points3d) + { + // Run the pipeline + run(points2d); + + // Extract Data + extractLibmvReconstructionData(K, Rs, Ts, points3d); + } + + + /* Run the pipeline given a set of images + */ + + virtual void run(const std::vector &images) + { + // Set libmv logs level + libmv_initLogging(""); + + if (libmv_reconstruction_options_.verbosity_level >= 0) + { + libmv_startDebugLogging(); + libmv_setLoggingVerbosity( + libmv_reconstruction_options_.verbosity_level); + } + + // Perform reconstruction + + libmv_reconstruction_ = + *libmv_solveReconstructionImpl(images, + &libmv_camera_intrinsics_options_, + &libmv_reconstruction_options_); + } + + + virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, + OutputArray Ts, OutputArray points3d) + { + // Run the pipeline + run(images); + + // Extract Data + extractLibmvReconstructionData(K, Rs, Ts, points3d); + } + + virtual double getError() const { return libmv_reconstruction_.error; } + + virtual void + getPoints(OutputArray points3d) { + const size_t n_points = + libmv_reconstruction_.reconstruction.AllPoints().size(); + + points3d.create(n_points, 1, CV_64F); + + Vec3d point3d; + for ( size_t i = 0; i < n_points; ++i ) + { + for ( int j = 0; j < 3; ++j ) + point3d[j] = + libmv_reconstruction_.reconstruction.AllPoints()[i].X[j]; + Mat(point3d).copyTo(points3d.getMatRef(i)); + } + + } + + virtual cv::Mat getIntrinsics() const { + Mat K; + eigen2cv(libmv_reconstruction_.intrinsics->K(), K); + return K; + } + + virtual void + getCameras(OutputArray Rs, OutputArray Ts) { + const size_t n_views = + libmv_reconstruction_.reconstruction.AllCameras().size(); + + Rs.create(n_views, 1, CV_64F); + Ts.create(n_views, 1, CV_64F); + + Matx33d R; + Vec3d t; + for(size_t i = 0; i < n_views; ++i) + { + eigen2cv(libmv_reconstruction_.reconstruction.AllCameras()[i].R, R); + eigen2cv(libmv_reconstruction_.reconstruction.AllCameras()[i].t, t); + Mat(R).copyTo(Rs.getMatRef(i)); + Mat(t).copyTo(Ts.getMatRef(i)); + } + } + + virtual void setReconstructionOptions( + const libmv_ReconstructionOptions &libmv_reconstruction_options) { + libmv_reconstruction_options_ = libmv_reconstruction_options; + } + + virtual void setCameraIntrinsicOptions( + const libmv_CameraIntrinsicsOptions &libmv_camera_intrinsics_options) { + libmv_camera_intrinsics_options_ = libmv_camera_intrinsics_options; + } + +private: + + void + extractLibmvReconstructionData(InputOutputArray K, + OutputArray Rs, + OutputArray Ts, + OutputArray points3d) + { + getCameras(Rs, Ts); + getPoints(points3d); + getIntrinsics().copyTo(K.getMat()); + } + + libmv_Reconstruction libmv_reconstruction_; + libmv_ReconstructionOptions libmv_reconstruction_options_; + libmv_CameraIntrinsicsOptions libmv_camera_intrinsics_options_; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////// + +Ptr +SFMLibmvEuclideanReconstruction::create(const libmv_CameraIntrinsicsOptions &camera_instrinsic_options, + const libmv_ReconstructionOptions &reconstruction_options) +{ + return makePtr >(camera_instrinsic_options,reconstruction_options); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// + +} /* namespace cv */ +} /* namespace sfm */ + +#endif + +/* End of file. */ \ No newline at end of file diff --git a/modules/sfm/src/triangulation.cpp b/modules/sfm/src/triangulation.cpp new file mode 100644 index 0000000000..a77aa75189 --- /dev/null +++ b/modules/sfm/src/triangulation.cpp @@ -0,0 +1,196 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "precomp.hpp" + +// Eigen +#include + +// OpenCV +#include +#include +#include + +// libmv headers +#include "libmv/multiview/twoviewtriangulation.h" +#include "libmv/multiview/fundamental.h" + +using namespace cv; +using namespace std; + +namespace cv +{ +namespace sfm +{ + +/** @brief Triangulates the a 3d position between two 2d correspondences, using the DLT. + @param xl Input vector with first 2d point. + @param xr Input vector with second 2d point. + @param Pl Input 3x4 first projection matrix. + @param Pr Input 3x4 second projection matrix. + @param objectPoint Output vector with computed 3d point. + + Reference: @cite HartleyZ00 12.2 pag.312 + */ +void +triangulateDLT( const Vec2d &xl, const Vec2d &xr, + const Matx34d &Pl, const Matx34d &Pr, + Vec3d &point3d ) +{ + Matx44d design; + for (int i = 0; i < 4; ++i) + { + design(0,i) = xl(0) * Pl(2,i) - Pl(0,i); + design(1,i) = xl(1) * Pl(2,i) - Pl(1,i); + design(2,i) = xr(0) * Pr(2,i) - Pr(0,i); + design(3,i) = xr(1) * Pr(2,i) - Pr(1,i); + } + + Vec4d XHomogeneous; + cv::SVD::solveZ(design, XHomogeneous); + + homogeneousToEuclidean(XHomogeneous, point3d); +} + + +/** @brief Triangulates the 3d position of 2d correspondences between n images, using the DLT + * @param x Input vectors of 2d points (the inner vector is per image). Has to be 2xN + * @param Ps Input vector with 3x4 projections matrices of each image. + * @param X Output vector with computed 3d point. + + * Reference: it is the standard DLT; for derivation see appendix of Keir's thesis + */ +void +triangulateNViews(const Mat_ &x, const std::vector &Ps, Vec3d &X) +{ + CV_Assert(x.rows == 2); + unsigned nviews = x.cols; + CV_Assert(nviews == Ps.size()); + + cv::Mat_ design = cv::Mat_::zeros(3*nviews, 4 + nviews); + for (unsigned i=0; i < nviews; ++i) { + for(char jj=0; jj<3; ++jj) + for(char ii=0; ii<4; ++ii) + design(3*i+jj, ii) = -Ps[i](jj, ii); + design(3*i + 0, 4 + i) = x(0, i); + design(3*i + 1, 4 + i) = x(1, i); + design(3*i + 2, 4 + i) = 1.0; + } + + Mat X_and_alphas; + cv::SVD::solveZ(design, X_and_alphas); + homogeneousToEuclidean(X_and_alphas.rowRange(0, 4), X); +} + + +void +triangulatePoints(InputArrayOfArrays _points2d, InputArrayOfArrays _projection_matrices, + OutputArray _points3d) +{ + // check + size_t nviews = (unsigned) _points2d.total(); + CV_Assert(nviews >= 2 && nviews == _projection_matrices.total()); + + // inputs + size_t n_points; + std::vector > points2d(nviews); + std::vector projection_matrices(nviews); + { + std::vector points2d_tmp; + _points2d.getMatVector(points2d_tmp); + n_points = points2d_tmp[0].cols; + + std::vector projection_matrices_tmp; + _projection_matrices.getMatVector(projection_matrices_tmp); + + // Make sure the dimensions are right + for(size_t i=0; i &xl = points2d[0], &xr = points2d[1]; + + const Matx34d & Pl = projection_matrices[0]; // left matrix projection + const Matx34d & Pr = projection_matrices[1]; // right matrix projection + + // triangulate + for( unsigned i = 0; i < n_points; ++i ) + { + Vec3d point3d; + triangulateDLT( Vec2d(xl(0,i), xl(1,i)), Vec2d(xr(0,i), xr(1,i)), Pl, Pr, point3d ); + for(char j=0; j<3; ++j) + points3d.at(j, i) = point3d[j]; + } + } + else if( nviews > 2 ) + { + // triangulate + for( unsigned i=0; i < n_points; ++i ) + { + // build x matrix (one point per view) + Mat_ x( 2, nviews ); + for( unsigned k=0; k < nviews; ++k ) + { + points2d.at(k).col(i).copyTo( x.col(k) ); + } + + Vec3d point3d; + triangulateNViews( x, projection_matrices, point3d ); + for(char j=0; j<3; ++j) + points3d.at(j, i) = point3d[j]; + } + } +} + +} /* namespace sfm */ +} /* namespace cv */ \ No newline at end of file diff --git a/modules/sfm/test/scene.cpp b/modules/sfm/test/scene.cpp new file mode 100644 index 0000000000..922d32260a --- /dev/null +++ b/modules/sfm/test/scene.cpp @@ -0,0 +1,122 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include "test_precomp.hpp" + +cv::Matx33d +randomK(bool is_projective) +{ + static cv::RNG rng; + + cv::Matx33d K = cv::Matx33d::zeros(); + K(0, 0) = rng.uniform(100, 1000); + K(1, 1) = rng.uniform(100, 1000); + if (is_projective) + { + K(0, 2) = rng.uniform(-100, 100); + K(1, 2) = rng.uniform(-100, 100); + } + K(2, 2) = 1.0; + + return K; +} + +void +generateScene(size_t n_views, size_t n_points, bool is_projective, cv::Matx33d & K, std::vector & R, + std::vector & t, std::vector & P, cv::Mat_ & points3d, + std::vector > & points2d) +{ + R.resize(n_views); + t.resize(n_views); + + cv::RNG rng; + + // Generate a bunch of random 3d points in a 0, 1 cube + points3d.create(3, n_points); + rng.fill(points3d, cv::RNG::UNIFORM, 0, 1); + + // Generate random intrinsics + K = randomK(is_projective); + + // Generate random camera poses + // TODO deal with smooth camera poses (e.g. from a video sequence) + for (size_t i = 0; i < n_views; ++i) + { + // Get a random rotation axis + cv::Vec3d vec; + rng.fill(vec, cv::RNG::UNIFORM, 0, 1); + // Give a random angle to the rotation vector + vec = vec / cv::norm(vec) * rng.uniform(0.0f, float(2 * CV_PI)); + cv::Rodrigues(vec, R[i]); + // Create a random translation + t[i] = cv::Vec3d(rng.uniform(-0.5f, 0.5f), rng.uniform(-0.5f, 0.5f), rng.uniform(1.0f, 2.0f)); + // Make sure the shape is in front of the camera + cv::Mat_ points3d_transformed = cv::Mat(R[i]) * points3d + cv::Mat(t[i]) * cv::Mat_ ::ones(1, n_points); + double min_dist, max_dist; + cv::minMaxIdx(points3d_transformed.row(2), &min_dist, &max_dist); + if (min_dist < 0) + t[i][2] = t[i][2] - min_dist + 1.0; + } + + // Compute projection matrices + P.resize(n_views); + for (size_t i = 0; i < n_views; ++i) + { + cv::Matx33d K3 = K, R3 = R[i]; + cv::Vec3d t3 = t[i]; + cv::sfm::projectionFromKRt(K3, R3, t3, P[i]); + } + + // Compute homogeneous 3d points + cv::Mat_ points3d_homogeneous(4, n_points); + points3d.copyTo(points3d_homogeneous.rowRange(0, 3)); + points3d_homogeneous.row(3).setTo(1); + // Project those points for every view + points2d.resize(n_views); + for (size_t i = 0; i < n_views; ++i) + { + cv::Mat_ points2d_tmp = cv::Mat(P[i]) * points3d_homogeneous; + points2d[i].create(2, n_points); + for (unsigned char j = 0; j < 2; ++j) + cv::Mat(points2d_tmp.row(j) / points2d_tmp.row(2)).copyTo(points2d[i].row(j)); + } + +// TODO: remove a certain number of points per view +// TODO: add a certain number of outliers per view + +} diff --git a/modules/sfm/test/scene.h b/modules/sfm/test/scene.h new file mode 100644 index 0000000000..239f34e4c5 --- /dev/null +++ b/modules/sfm/test/scene.h @@ -0,0 +1,41 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +void +generateScene(size_t n_views, size_t n_points, bool is_projective, cv::Matx33d & K, std::vector & R, + std::vector & t, std::vector & P, cv::Mat_ & points3d, + std::vector > & points2d); diff --git a/modules/sfm/test/test_common.cpp b/modules/sfm/test/test_common.cpp new file mode 100644 index 0000000000..19e91051d4 --- /dev/null +++ b/modules/sfm/test/test_common.cpp @@ -0,0 +1,132 @@ +#include "test_precomp.hpp" + +#include +#include + +using namespace cv; +using namespace cv::sfm; +using namespace std; + +namespace cvtest +{ + +void generateTwoViewRandomScene( cvtest::TwoViewDataSet &data ) +{ + vector > points2d; + vector Rs; + vector ts; + vector Ps; + Matx33d K; + Mat_ points3d; + + int nviews = 2; + int npoints = 30; + bool is_projective = true; + + generateScene(nviews, npoints, is_projective, K, Rs, ts, Ps, points3d, points2d); + + // Internal parameters (same K) + data.K1 = K; + data.K2 = K; + + // Rotation + data.R1 = Rs[0]; + data.R2 = Rs[1]; + + // Translation + data.t1 = ts[0]; + data.t2 = ts[1]; + + // Projection matrix, P = K(R|t) + data.P1 = Ps[0]; + data.P2 = Ps[1]; + + // Fundamental matrix + fundamentalFromProjections( data.P1, data.P2, data.F ); + + // 3D points + data.X = points3d; + + // Projected points + data.x1 = points2d[0]; + data.x2 = points2d[1]; +} + +/** Check the properties of a fundamental matrix: +* +* 1. The determinant is 0 (rank deficient) +* 2. The condition x'T*F*x = 0 is satisfied to precision. +*/ +void +expectFundamentalProperties( const cv::Matx33d &F, + const cv::Mat_ &ptsA, + const cv::Mat_ &ptsB, + double precision ) +{ + EXPECT_NEAR( 0, determinant(F), precision ); + + int n = ptsA.cols; + EXPECT_EQ( n, ptsB.cols ); + + cv::Mat_ x1, x2; + euclideanToHomogeneous( ptsA, x1 ); + euclideanToHomogeneous( ptsB, x2 ); + + for( int i = 0; i < n; ++i ) + { + double residual = Vec3d(x2(0,i),x2(1,i),x2(2,i)).ddot( F * Vec3d(x1(0,i),x1(1,i),x1(2,i)) ); + EXPECT_NEAR( 0.0, residual, precision ); + } +} + + +void +parser_2D_tracks(const string &_filename, std::vector &points2d ) +{ + ifstream myfile(_filename.c_str()); + + if (!myfile.is_open()) + { + cout << "Unable to read file: " << _filename << endl; + exit(0); + + } else { + + double x, y; + string line_str; + Mat nan_mat = Mat(2, 1 , CV_64F, -1); + int n_frames = 0, n_tracks = 0, track = 0; + + while ( getline(myfile, line_str) ) + { + istringstream line(line_str); + + if ( track > n_tracks ) + { + n_tracks = track; + + for (int i = 0; i < n_frames; ++i) + cv::hconcat(points2d[i], nan_mat, points2d[i]); + } + + for (int frame = 1; line >> x >> y; ++frame) + { + if ( frame > n_frames ) + { + n_frames = frame; + points2d.push_back(nan_mat); + } + + points2d[frame-1].at(0,track) = x; + points2d[frame-1].at(1,track) = y; + } + + ++track; + } + + myfile.close(); + } + +} + +} // namespace cvtest diff --git a/modules/sfm/test/test_conditioning.cpp b/modules/sfm/test/test_conditioning.cpp new file mode 100644 index 0000000000..5e5194dc9e --- /dev/null +++ b/modules/sfm/test/test_conditioning.cpp @@ -0,0 +1,64 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace cv::sfm; +using namespace std; + +TEST(Sfm_conditioning, normalizePoints) +{ + int n = 4; + Mat_ points(2, n); + points << 0, 0, 1, 1, + 0, 2, 1, 3; + + Mat_ T, normalized_points; + normalizePoints( points, normalized_points, T ); + + Mat_ mean, variance; + meanAndVarianceAlongRows(normalized_points, mean, variance); + + EXPECT_NEAR(0, mean(0), 1e-8); + EXPECT_NEAR(0, mean(1), 1e-8); + EXPECT_NEAR(2, variance(0), 1e-8); + EXPECT_NEAR(2, variance(1), 1e-8); +} + +TEST(Sfm_conditioning, normalizeIsotropicPoints) +{ + //TODO: implement me +} diff --git a/modules/sfm/test/test_fundamental.cpp b/modules/sfm/test/test_fundamental.cpp new file mode 100644 index 0000000000..02f28981ec --- /dev/null +++ b/modules/sfm/test/test_fundamental.cpp @@ -0,0 +1,176 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace cv::sfm; +using namespace cvtest; +using namespace std; + +TEST(Sfm_fundamental, fundamentalFromProjections) +{ + double tolerance_prop = 1e-7; + double tolerance_near = 1e-15; + + Matx34d P1_gt, P2_gt; + P1_gt << 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0; + P2_gt << 1, 1, 1, 3, + 0, 2, 0, 3, + 0, 1, 1, 0; + + Matx33d F_gt; + fundamentalFromProjections(P1_gt, P2_gt, F_gt); + + Matx34d P1, P2; + projectionsFromFundamental(F_gt, P1, P2); + + Matx33d F; + fundamentalFromProjections(P1, P2, F); + + Matx33d F_gt_norm, F_norm; + normalizeFundamental(F_gt, F_gt_norm); + normalizeFundamental(F, F_norm); + + EXPECT_MATRIX_PROP(F_gt, F, tolerance_prop); + EXPECT_MATRIX_NEAR(F_gt_norm, F_norm, tolerance_near); +} + + +TEST(Sfm_fundamental, normalizedEightPointSolver) +{ + double tolerance = 1e-14; + + TwoViewDataSet d; + generateTwoViewRandomScene( d ); + + Matx33d F; + normalizedEightPointSolver( d.x1, d.x2, F ); + expectFundamentalProperties( F, d.x1, d.x2, tolerance ); +} + + +TEST(Sfm_fundamental, motionFromEssential) +{ + double tolerance = 1e-8; + + cvtest::TwoViewDataSet d; + generateTwoViewRandomScene(d); + + Matx33d E; + essentialFromRt(d.R1, d.t1, d.R2, d.t2, E); + + Matx33d R; + cv::Vec3d t; + relativeCameraMotion(d.R1, d.t1, d.R2, d.t2, R, t); + cv::normalize(t, t); + + std::vector Rs; + std::vector ts; + motionFromEssential(E, Rs, ts); + bool one_solution_is_correct = false; + for ( int i = 0; i < Rs.size(); ++i ) + { + if ( (norm(Rs[i], R) < tolerance) && (norm(ts[i], t) < tolerance) ) + { + one_solution_is_correct = true; + break; + } + } + EXPECT_TRUE(one_solution_is_correct); +} + + +TEST(Sfm_fundamental, fundamentalToAndFromEssential) +{ + double tolerance = 1e-15; + TwoViewDataSet d; + generateTwoViewRandomScene(d); + + Matx33d F, E; + essentialFromFundamental(d.F, d.K1, d.K2, E); + fundamentalFromEssential(E, d.K1, d.K2, F); + + Matx33d F_gt_norm, F_norm; + normalizeFundamental(d.F, F_gt_norm); + normalizeFundamental(F, F_norm); + + EXPECT_MATRIX_NEAR(F_gt_norm, F_norm, tolerance); +} + + +TEST(Sfm_fundamental, essentialFromFundamental) +{ + TwoViewDataSet d; + generateTwoViewRandomScene(d); + + Matx33d E_from_Rt; + essentialFromRt(d.R1, d.t1, d.R2, d.t2, E_from_Rt); + + Matx33d E_from_F; + essentialFromFundamental(d.F, d.K1, d.K2, E_from_F); + + EXPECT_MATRIX_PROP(E_from_Rt, E_from_F, 1e-6); +} + + +TEST(Sfm_fundamental, motionFromEssentialChooseSolution) +{ + TwoViewDataSet d; + generateTwoViewRandomScene(d); + + Matx33d E; + essentialFromRt(d.R1, d.t1, d.R2, d.t2, E); + + Matx33d R; + cv::Vec3d t; + relativeCameraMotion(d.R1, d.t1, d.R2, d.t2, R, t); + normalize(t, t); + + std::vector < Mat > Rs; + std::vector < cv::Mat > ts; + motionFromEssential(E, Rs, ts); + + cv::Vec2d x1(d.x1(0, 0), d.x1(1, 0)); + cv::Vec2d x2(d.x2(0, 0), d.x2(1, 0)); + int solution = motionFromEssentialChooseSolution(Rs, ts, d.K1, x1, d.K2, x2); + + EXPECT_LE(0, solution); + EXPECT_LE(solution, 3); + EXPECT_LE(norm(Rs[solution]-Mat(R)), 1e-8); + EXPECT_LE(norm(ts[solution]-Mat(t)), 1e-8); +} \ No newline at end of file diff --git a/modules/sfm/test/test_main.cpp b/modules/sfm/test/test_main.cpp new file mode 100644 index 0000000000..74b896b3d1 --- /dev/null +++ b/modules/sfm/test/test_main.cpp @@ -0,0 +1,3 @@ +#include "test_precomp.hpp" + +CV_TEST_MAIN("cv") \ No newline at end of file diff --git a/modules/sfm/test/test_numeric.cpp b/modules/sfm/test/test_numeric.cpp new file mode 100644 index 0000000000..dc28e6d65a --- /dev/null +++ b/modules/sfm/test/test_numeric.cpp @@ -0,0 +1,91 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace cv::sfm; +using namespace std; + + +template +static void +test_meanAndVarianceAlongRows( void ) +{ + int n = 4; + Mat_ points(2,n); + points << 0, 0, 1, 1, + 0, 2, 1, 3; + + Mat_ mean, variance; + meanAndVarianceAlongRows(points, mean, variance); + + EXPECT_NEAR(0.5, mean(0), 1e-8); + EXPECT_NEAR(1.5, mean(1), 1e-8); + EXPECT_NEAR(0.25, variance(0), 1e-8); + EXPECT_NEAR(1.25, variance(1), 1e-8); +} + +TEST(Sfm_numeric, meanAndVarianceAlongRows) +{ + test_meanAndVarianceAlongRows(); + test_meanAndVarianceAlongRows(); +} + + +TEST(Sfm_numeric, skewMat) +{ + // Testing with floats + Vec3f a; + a << 1,2,3; + + Matx33f ax = skew(a); + + EXPECT_FLOAT_EQ( 0, trace(ax) ); + EXPECT_FLOAT_EQ( ax(0,1), -ax(1,0) ); + EXPECT_FLOAT_EQ( ax(0,2), -ax(2,0) ); + EXPECT_FLOAT_EQ( ax(1,2), -ax(2,1) ); + + // Testing with doubles + Vec3d b; + b << 1,2,3; + + Matx33d bx = skew(b); + + EXPECT_DOUBLE_EQ( 0, trace(bx) ); + EXPECT_DOUBLE_EQ( bx(0,1), -bx(1,0) ); + EXPECT_DOUBLE_EQ( bx(0,2), -bx(2,0) ); + EXPECT_DOUBLE_EQ( bx(1,2), -bx(2,1) ); +} diff --git a/modules/sfm/test/test_precomp.hpp b/modules/sfm/test/test_precomp.hpp new file mode 100644 index 0000000000..6002f30ab7 --- /dev/null +++ b/modules/sfm/test/test_precomp.hpp @@ -0,0 +1,140 @@ +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +#endif + +#ifndef __OPENCV_TEST_PRECOMP_HPP__ +#define __OPENCV_TEST_PRECOMP_HPP__ + +#include +#include +#include +#include + +#include "scene.h" + +#define OPEN_TESTFILE(FNAME,FS) \ + FS.open(FNAME, FileStorage::READ); \ + if (!FS.isOpened())\ + {\ + std::cerr << "Cannot find file: " << FNAME << std::endl;\ + return;\ + } + +namespace cvtest +{ + + template + inline void + EXPECT_MATRIX_NEAR(const T a, const T b, double tolerance) + { + bool dims_match = (a.rows == b.rows) && (a.cols == b.cols); + EXPECT_EQ((int)a.rows, (int)b.rows); + EXPECT_EQ((int)a.cols, (int)b.cols); + + if (dims_match) + { + for (int r = 0; r < a.rows; ++r) + { + for (int c = 0; c < a.cols; ++c) + { + EXPECT_NEAR(a(r, c), b(r, c), tolerance) << "r=" << r << ", c=" << c << "."; + } + } + } + } + + template + inline void + EXPECT_VECTOR_NEAR(const T a, const T b, double tolerance) + { + bool dims_match = (a.rows == b.rows); + EXPECT_EQ((int)a.rows,(int)b.rows) << "Matrix rows don't match."; + + if (dims_match) + { + for (int r = 0; r < a.rows; ++r) + { + EXPECT_NEAR(a(r), b(r), tolerance) << "r=" << r << "."; + } + } + } + + template + inline double + cosinusBetweenMatrices(const T &a, const T &b) + { + double s = cv::sum( a.mul(b) )[0]; + return ( s / norm(a) / norm(b) ); + } + + // Check that sin(angle(a, b)) < tolerance + template + inline void + EXPECT_MATRIX_PROP(const T a, const T b, double tolerance) + { + bool dims_match = (a.rows == b.rows) && (a.cols == b.cols); + EXPECT_EQ((int)a.rows, (int)b.rows); + EXPECT_EQ((int)a.cols, (int)b.cols); + + if (dims_match) + { + double c = cosinusBetweenMatrices(a, b); + if (c * c < 1) + { + double s = sqrt(1 - c * c); + EXPECT_NEAR(0, s, tolerance); + } + } + } + + + + + struct TwoViewDataSet + { + cv::Matx33d K1, K2; // Internal parameters + cv::Matx33d R1, R2; // Rotation + cv::Vec3d t1, t2; // Translation + cv::Matx34d P1, P2; // Projection matrix, P = K(R|t) + cv::Matx33d F; // Fundamental matrix + cv::Mat_ X; // 3D points + cv::Mat_ x1, x2; // Projected points + }; + + void + generateTwoViewRandomScene(TwoViewDataSet &data); + + /** Check the properties of a fundamental matrix: + * + * 1. The determinant is 0 (rank deficient) + * 2. The condition x'T*F*x = 0 is satisfied to precision. + */ + void + expectFundamentalProperties( const cv::Matx33d &F, + const cv::Mat_ &ptsA, + const cv::Mat_ &ptsB, + double precision = 1e-9 ); + + /** + * 2D tracked points + * ----------------- + * + * The format is: + * + * row1 : x1 y1 x2 y2 ... x36 y36 for track 1 + * row2 : x1 y1 x2 y2 ... x36 y36 for track 2 + * etc + * + * i.e. a row gives the 2D measured position of a point as it is tracked + * through frames 1 to 36. If there is no match found in a view then x + * and y are -1. + * + * Each row corresponds to a different point. + * + */ + void + parser_2D_tracks(const std::string &_filename, std::vector &points2d ); + +} // namespace cvtest + +#endif diff --git a/modules/sfm/test/test_projection.cpp b/modules/sfm/test/test_projection.cpp new file mode 100644 index 0000000000..c6d8830f99 --- /dev/null +++ b/modules/sfm/test/test_projection.cpp @@ -0,0 +1,113 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test_precomp.hpp" +#include + +using namespace cv; +using namespace cv::sfm; +using namespace cvtest; +using namespace std; + +TEST(Sfm_projection, homogeneousToEuclidean) +{ + Matx33f X(1, 2, 3, + 4, 5, 6, + 2, 1, 0); + + Matx23f XEuclidean; + homogeneousToEuclidean(X,XEuclidean); + + EXPECT_EQ((int) X.rows-1,(int) XEuclidean.rows ); + + for(int y=0;y& Ps, + const std::vector >& xs, float err_max2d) +{ + cv::Mat X; + euclideanToHomogeneous(X_estimated, X); // 3D point + + for (int m = 0; m < xs.size(); ++m) + { + cv::Mat x; + homogeneousToEuclidean(cv::Mat(Ps[m]) * X, x); // 2d projection + cv::Mat projerr = xs[m] - x; + + for (int n = 0; n < projerr.cols; ++n) + { + double d = cv::norm(projerr.col(n)); + EXPECT_NEAR(0, d, err_max2d); + } + } +} + +#if CERES_FOUND + +TEST(Sfm_reconstruct, twoViewProjectiveOutliers) +{ + float err_max2d = 1e-7; + int nviews = 2; + int npoints = 50; + bool is_projective = true; + + std::vector > points2d; + std::vector Rs; + std::vector ts; + std::vector Ps; + Matx33d K; + Mat_ points3d; + generateScene(nviews, npoints, is_projective, K, Rs, ts, Ps, points3d, points2d); + + Mat_ points3d_estimated; + std::vector Ps_estimated; + reconstruct(points2d, Ps_estimated, points3d_estimated, K, is_projective); + + /* Check projection errors on GT */ + check_projection_errors(points3d, Ps, points2d, err_max2d); + + /* Check projection errors on estimates */ + std::vector Ps_estimated_d; + Ps_estimated_d.resize(Ps_estimated.size()); + for(size_t i=0; i x1(2,n); + x1 << 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, + 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 5; + + Mat_ x2 = x1.clone(); + for (int i = 0; i < n; ++i) + { + x2(0,i) += i % 2; // Multiple horizontal disparities. + } + x2(0,n - 1) = 10; + x2(1,n - 1) = 10; // The outlier has vertical disparity. + + Matx33d F; + vector inliers; + fundamentalFromCorrespondences8PointRobust(x1, x2, 0.1, F, inliers); + + // F should be 0, 0, 0, + // 0, 0, -1, + // 0, 1, 0 + EXPECT_NEAR(0.0, F(0,0), tolerance); + EXPECT_NEAR(0.0, F(0,1), tolerance); + EXPECT_NEAR(0.0, F(0,2), tolerance); + EXPECT_NEAR(0.0, F(1,0), tolerance); + EXPECT_NEAR(0.0, F(1,1), tolerance); + EXPECT_NEAR(0.0, F(2,0), tolerance); + EXPECT_NEAR(0.0, F(2,2), tolerance); + EXPECT_NEAR(F(1,2), -F(2,1), tolerance); + + EXPECT_EQ(n - 1, inliers.size()); +} + + +TEST(Sfm_robust, fundamentalFromCorrespondences8PointRealisticNoOutliers) +{ + double tolerance = 1e-8; + cvtest::TwoViewDataSet d; + generateTwoViewRandomScene(d); + + Matx33d F_estimated; + + vector inliers; + fundamentalFromCorrespondences8PointRobust(d.x1, d.x2, 3.0, F_estimated, inliers); + EXPECT_EQ(d.x1.cols, inliers.size()); + + // Normalize. + Matx33d F_gt_norm, F_estimated_norm; + normalizeFundamental(d.F, F_gt_norm); + normalizeFundamental(F_estimated, F_estimated_norm); + EXPECT_MATRIX_NEAR(F_gt_norm, F_estimated_norm, tolerance); + + // Check fundamental properties. + expectFundamentalProperties( F_estimated, d.x1, d.x2, tolerance); +} + + +TEST(Sfm_robust, fundamentalFromCorrespondences7PointRobust) +{ + double tolerance = 1e-8; + const int n = 16; + Mat_ x1(2,n); + x1 << 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, + 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 5; + + Mat_ x2 = x1.clone(); + for (int i = 0; i < n; ++i) + { + x2(0,i) += i % 2; // Multiple horizontal disparities. + } + x2(0,n - 1) = 10; + x2(1,n - 1) = 10; // The outlier has vertical disparity. + + Matx33d F; + vector inliers; + fundamentalFromCorrespondences7PointRobust(x1, x2, 0.1, F, inliers); + + // F should be 0, 0, 0, + // 0, 0, -1, + // 0, 1, 0 + EXPECT_NEAR(0.0, F(0,0), tolerance); + EXPECT_NEAR(0.0, F(0,1), tolerance); + EXPECT_NEAR(0.0, F(0,2), tolerance); + EXPECT_NEAR(0.0, F(1,0), tolerance); + EXPECT_NEAR(0.0, F(1,1), tolerance); + EXPECT_NEAR(0.0, F(2,0), tolerance); + EXPECT_NEAR(0.0, F(2,2), tolerance); + EXPECT_NEAR(F(1,2), -F(2,1), tolerance); + + EXPECT_EQ(n - 1, inliers.size()); +} + + +TEST(Sfm_robust, fundamentalFromCorrespondences7PointRealisticNoOutliers) +{ + double tolerance = 1e-8; + cvtest::TwoViewDataSet d; + generateTwoViewRandomScene(d); + + Matx33d F_estimated; + + vector inliers; + fundamentalFromCorrespondences7PointRobust(d.x1, d.x2, 3.0, F_estimated, inliers); + EXPECT_EQ(d.x1.cols, inliers.size()); + + // Normalize. + Matx33d F_gt_norm, F_estimated_norm; + normalizeFundamental(d.F, F_gt_norm); + normalizeFundamental(F_estimated, F_estimated_norm); + EXPECT_MATRIX_NEAR(F_gt_norm, F_estimated_norm, tolerance); + + // Check fundamental properties. + expectFundamentalProperties( F_estimated, d.x1, d.x2, tolerance); +} \ No newline at end of file diff --git a/modules/sfm/test/test_simple_pipeline.cpp b/modules/sfm/test/test_simple_pipeline.cpp new file mode 100644 index 0000000000..db269c1475 --- /dev/null +++ b/modules/sfm/test/test_simple_pipeline.cpp @@ -0,0 +1,89 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#if CERES_FOUND + +#include "test_precomp.hpp" + +#include + +using namespace cv; +using namespace cv::sfm; +using namespace cvtest; +using namespace std; + +const string SFM_DIR = "sfm"; +const string TRACK_FILENAME = "backyard_tracks.txt"; + +TEST(Sfm_simple_pipeline, backyard) +{ + string trackFilename = + string(TS::ptr()->get_data_path()) + SFM_DIR + "/" + TRACK_FILENAME; + + // Get tracks from file: check backyard.blend file + std::vector points2d; + parser_2D_tracks( trackFilename, points2d ); + + // Initial reconstruction + int keyframe1 = 1, keyframe2 = 30; + + // Camera data + double focal_length = 860.986572265625; // f = 24mm (checked debugging blender) + double principal_x = 400, principal_y = 225, k1 = -0.158, k2 = 0.131, k3 = 0; + + int refine_intrinsics = SFM_REFINE_FOCAL_LENGTH | SFM_REFINE_PRINCIPAL_POINT | SFM_REFINE_RADIAL_DISTORTION_K1 | SFM_REFINE_RADIAL_DISTORTION_K2; + int select_keyframes = 0; // disable automatic keyframes selection + int verbosity_level = -1; // mute logs + + libmv_CameraIntrinsicsOptions camera_instrinsic_options = + libmv_CameraIntrinsicsOptions(SFM_DISTORTION_MODEL_POLYNOMIAL, + focal_length, principal_x, principal_y, + k1, k2, k3); + libmv_ReconstructionOptions reconstruction_options(keyframe1, keyframe2, refine_intrinsics, select_keyframes, verbosity_level); + + Ptr euclidean_reconstruction = + SFMLibmvEuclideanReconstruction::create(camera_instrinsic_options, reconstruction_options); + + // Run reconstruction pipeline + euclidean_reconstruction->run(points2d); + + double error = euclidean_reconstruction->getError(); + //cout << "euclidean_reconstruction error = " << error << endl; + + EXPECT_LE( error, 1.4 ); // actually 1.38671 + // UPDATE: 1.38894 +} + +#endif /* CERES_FOUND */ diff --git a/modules/sfm/test/test_triangulation.cpp b/modules/sfm/test/test_triangulation.cpp new file mode 100644 index 0000000000..d1bf6d8259 --- /dev/null +++ b/modules/sfm/test/test_triangulation.cpp @@ -0,0 +1,96 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2009, Willow Garage, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Willow Garage, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace cv::sfm; +using namespace std; + +static void +checkTriangulation(int nviews, int npoints, bool is_projective, float err_max2d, float err_max3d) +{ + std::vector > points2d; + std::vector Rs; + std::vector ts; + std::vector Ps; + Matx33d K; + Mat_ points3d; + generateScene(nviews, npoints, is_projective, K, Rs, ts, Ps, points3d, points2d); + + // get 3d points + cv::Mat X, X_homogeneous; + std::vector > Ps_d(Ps.size()); + for(size_t i=0; i(Ps[i]); + triangulatePoints(points2d, Ps_d, X); + euclideanToHomogeneous(X, X_homogeneous); + + for (int i = 0; i < npoints; ++i) + { + for (int k = 0; k < nviews; ++k) + { + cv::Mat x_reprojected; + homogeneousToEuclidean( cv::Mat(Ps[k])*X_homogeneous.col(i), x_reprojected ); + + // Check reprojection error. Should be nearly zero. + double error = norm( x_reprojected - points2d[k].col(i) ); + EXPECT_LE(error*error, err_max2d); + } + + // Check 3d error. Should be nearly zero. + double error = norm( X.col(i) - points3d.col(i) ); + EXPECT_LE(error*error, err_max3d); + } +} + + +TEST(Sfm_triangulate, TriangulateDLT) +{ + int nviews = 2; + int npoints = 30; + bool is_projective = true; + + checkTriangulation(nviews, npoints, is_projective, 1e-7, 1e-9); +} + +TEST(Sfm_triangulate, NViewTriangulate_FiveViews) +{ + int nviews = 5; + int npoints = 6; + bool is_projective = true; + + checkTriangulation(nviews, npoints, is_projective, 1e-7, 1e-9); +} diff --git a/modules/sfm/tutorials/sfm_installation/sfm_installation.markdown b/modules/sfm/tutorials/sfm_installation/sfm_installation.markdown new file mode 100644 index 0000000000..7b7d5df1f9 --- /dev/null +++ b/modules/sfm/tutorials/sfm_installation/sfm_installation.markdown @@ -0,0 +1,63 @@ +SFM module installation {#tutorial_sfm_installation} +======================= + +Dependencies +------------ + +The Structure from Motion module depends on some open source libraries. + + - [Eigen](http://eigen.tuxfamily.org) 3.2.2 or later. \b Required + - [GLog](http://code.google.com/p/google-glog) 0.3.1 or later. \b Required + - [GFlags](http://code.google.com/p/gflags). \b Required + - [Ceres Solver](http://ceres-solver.org). Needed by the reconstruction API in order to solve part of the Bundle Adjustment plus the points Intersect. If Ceres Solver is not installed on your system, the reconstruction funcionality will be disabled. \b Recommended + +@note The module is only available for Linux/GNU systems. + + +Installation +------------ + +__Required Dependencies__ + +In case you are on [Ubuntu](http://www.ubuntu.com) you can simply install the required dependencies by typing the following command: + +@code{.bash} + sudo apt-get install libeigen3-dev libgflags-dev libgoogle-glog-dev +@endcode + +__Ceres Solver__ + +Start by installing all the dependencies: + +@code{.bash} + # CMake + sudo apt-get install cmake + # google-glog + gflags + sudo apt-get install libgoogle-glog-dev + # BLAS & LAPACK + sudo apt-get install libatlas-base-dev + # Eigen3 + sudo apt-get install libeigen3-dev + # SuiteSparse and CXSparse (optional) + # - If you want to build Ceres as a *static* library (the default) + # you can use the SuiteSparse package in the main Ubuntu package + # repository: + sudo apt-get install libsuitesparse-dev + # - However, if you want to build Ceres as a *shared* library, you must + # add the following PPA: + sudo add-apt-repository ppa:bzindovic/suitesparse-bugfix-1319687 + sudo apt-get update + sudo apt-get install libsuitesparse-dev +@endcode + +We are now ready to build, test, and install Ceres: + +@code{.bash} + git clone https://ceres-solver.googlesource.com/ceres-solver + cd ceres-solver + mkdir build && cd build + cmake .. + make -j4 + make test + sudo make install +@endcode \ No newline at end of file diff --git a/modules/sfm/tutorials/sfm_scene reconstruction/sfm_scene_reconstruction.markdown b/modules/sfm/tutorials/sfm_scene reconstruction/sfm_scene_reconstruction.markdown new file mode 100644 index 0000000000..bf9ed7b238 --- /dev/null +++ b/modules/sfm/tutorials/sfm_scene reconstruction/sfm_scene_reconstruction.markdown @@ -0,0 +1,104 @@ +Scene Reconstruction {#tutorial_sfm_scene_reconstruction} +==================== + +Goal +---- + +In this tutorial you will learn how to use the reconstruction api for sparse reconstruction: + +- Load and file with a list of image paths. +- Run libmv reconstruction pipeline. +- Show obtained results using Viz. + + +Code +---- + +@include sfm/samples/scene_reconstruction.cpp + +Explanation +----------- + +Firstly, we need to load the file containing list of image paths in order to feed the reconstruction api: + +@code{.cpp} + /home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2889.jpg + /home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2890.jpg + /home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2891.jpg + /home/eriba/software/opencv_contrib/modules/sfm/samples/data/images/resized_IMG_2892.jpg + + ... + + int getdir(const string _filename, vector &files) + { + ifstream myfile(_filename.c_str()); + if (!myfile.is_open()) { + cout << "Unable to read file: " << _filename << endl; + exit(0); + } else { + string line_str; + while ( getline(myfile, line_str) ) + files.push_back(line_str); + } + return 1; + } +@endcode + +Secondly, the built container will be used to feed the reconstruction api. It is important outline that the estimated results must be stored in a vector. In this +case is called the overloaded signature for real images which from the images, internally extracts and compute the sparse 2d features using DAISY descriptors in order to be matched using FlannBasedMatcher and build the tracks structure. + +@code{.cpp} + bool is_projective = true; + vector Rs_est, ts_est, points3d_estimated; + reconstruct(images_paths, Rs_est, ts_est, K, points3d_estimated, is_projective); + + // Print output + + cout << "\n----------------------------\n" << endl; + cout << "Reconstruction: " << endl; + cout << "============================" << endl; + cout << "Estimated 3D points: " << points3d_estimated.size() << endl; + cout << "Estimated cameras: " << Rs_est.size() << endl; + cout << "Refined intrinsics: " << endl << K << endl << endl; +@endcode + +Finally, the obtained results will be shown in Viz. + +Usage and Results +----------------- + +In order to run this sample we need to specify the path to the image paths files, the focal lenght of the camera in addition to the center projection coordinates (in pixels). + +**1. Middlebury temple** + +Using following image sequence [1] and the followings camera parameters we can compute the sparse 3d reconstruction: + +@code{.bash} + ./example_sfm_scene_reconstruction image_paths_file.txt 800 400 225 +@endcode + +![](pics/temple_input.jpg) + +The following picture shows the obtained camera motion in addition to the estimated sparse 3d reconstruction: + +![](pics/temple_reconstruction.jpg) + + +**2. Sagrada Familia** + +Using following image sequence [2] and the followings camera parameters we can compute the sparse 3d reconstruction: + +@code{.bash} + ./example_sfm_scene_reconstruction image_paths_file.txt 350 240 360 +@endcode + +![](pics/sagrada_familia_input.jpg) + +The following picture shows the obtained camera motion in addition to the estimated sparse 3d reconstruction: + +![](pics/sagrada_familia_reconstruction.jpg) + +[1] [http://vision.middlebury.edu/mview/data](http://vision.middlebury.edu/mview/data) + +[2] Penate Sanchez, A. and Moreno-Noguer, F. and Andrade Cetto, J. and Fleuret, F. (2014). LETHA: Learning from High Quality Inputs for 3D Pose Estimation in Low Quality Images. Proceedings of the International Conference on 3D vision (3DV). +[URL](http://www.iri.upc.edu/research/webprojects/pau/datasets/sagfam) diff --git a/modules/sfm/tutorials/sfm_trajectory_estimation/sfm_trajectory_estimation.markdown b/modules/sfm/tutorials/sfm_trajectory_estimation/sfm_trajectory_estimation.markdown new file mode 100644 index 0000000000..f39bba23cf --- /dev/null +++ b/modules/sfm/tutorials/sfm_trajectory_estimation/sfm_trajectory_estimation.markdown @@ -0,0 +1,82 @@ +Camera Motion Estimation {#tutorial_sfm_trajectory_estimation} +======================== + +Goal +---- + +In this tutorial you will learn how to use the reconstruction api for camera motion estimation: + +- Load and file with the tracked 2d points and build the container over all the frames. +- Run libmv reconstruction pipeline. +- Show obtained results using Viz. + + +Code +---- + +@include sfm/samples/trajectory_reconstruccion.cpp + +Explanation +----------- + +Firstly, we need to load the file containing the 2d points tracked over all the frames and construct the container to feed the reconstruction api. In this case the tracked 2d points will have the following structure, a vector of 2d points array, where each inner array represents a different frame. Every frame is composed by a list of 2d points which e.g. the first point in frame 1 is the same point in frame 2. If there is no point in a frame the assigned value will be (-1,-1): + +@code{.cpp} + /* Build the following structure data + * + * frame1 frame2 frameN + * track1 | (x11,y11) | -> | (x12,y12) | -> | (x1N,y1N) | + * track2 | (x21,y11) | -> | (x22,y22) | -> | (x2N,y2N) | + * trackN | (xN1,yN1) | -> | (xN2,yN2) | -> | (xNN,yNN) | + * + * + * In case a marker (x,y) does not appear in a frame its + * values will be (-1,-1). + */ + + ... + + for (int i = 0; i < n_frames; ++i) + { + Mat_ frame(2, n_tracks); + + for (int j = 0; j < n_tracks; ++j) + { + frame(0,j) = tracks[j][i][0]; + frame(1,j) = tracks[j][i][1]; + } + points2d.push_back(Mat(frame)); + } +@endcode + +Secondly, the built container will be used to feed the reconstruction api. It is important outline that the estimated results must be stored in a vector: + +@code{.cpp} + bool is_projective = true; + vector Rs_est, ts_est, points3d_estimated; + reconstruct(points2d, Rs_est, ts_est, K, points3d_estimated, is_projective); + + // Print output + + cout << "\n----------------------------\n" << endl; + cout << "Reconstruction: " << endl; + cout << "============================" << endl; + cout << "Estimated 3D points: " << points3d_estimated.size() << endl; + cout << "Estimated cameras: " << Rs_est.size() << endl; + cout << "Refined intrinsics: " << endl << K << endl << endl; +@endcode + +Finally, the obtained results will be shown in Viz, in this case reproducing the camera with an oscillation effect. + +Usage and Results +----------------- + +In order to run this sample we need to specify the path to the tracked points file, the focal lenght of the camera in addition to the center projection coordinates (in pixels). You can find a sample file in samples/data/desktop_trakcks.txt + +@code{.bash} + ./example_sfm_trajectory_reconstruction desktop_tracks.txt 1914 640 360 +@endcode + +The following picture shows the obtained camera motion obtained from the tracked 2d points: + +![](pics/desktop_trajectory.png) \ No newline at end of file diff --git a/modules/sfm/tutorials/table_of_content_sfm.markdown b/modules/sfm/tutorials/table_of_content_sfm.markdown new file mode 100644 index 0000000000..7d9423e2df --- /dev/null +++ b/modules/sfm/tutorials/table_of_content_sfm.markdown @@ -0,0 +1,26 @@ +Structure From Motion {#tutorial_table_of_content_sfm} +===================== + +- @subpage tutorial_sfm_installation + + *Compatibility:* \> OpenCV 3.0 + + *Author:* Edgar Riba + + Instructions in order to properly setup the Structure from Motion module. + +- @subpage tutorial_sfm_trajectory_estimation + + *Compatibility:* \> OpenCV 3.0 + + *Author:* Edgar Riba + + Camera motion estimation from a given set of tracked 2d points. + +- @subpage tutorial_sfm_scene_reconstruction + + *Compatibility:* \> OpenCV 3.0 + + *Author:* Edgar Riba + + Sparse scene reconstruction from a given set of images. \ No newline at end of file From 8fdf85e0a2bbbcd213931ebfbd708b381927b0c5 Mon Sep 17 00:00:00 2001 From: edgarriba Date: Tue, 6 Oct 2015 09:32:47 +0200 Subject: [PATCH 2/4] fixing ARM issue with glog --- modules/sfm/CMakeLists.txt | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/modules/sfm/CMakeLists.txt b/modules/sfm/CMakeLists.txt index 2e74a432b4..e5810c8b10 100644 --- a/modules/sfm/CMakeLists.txt +++ b/modules/sfm/CMakeLists.txt @@ -6,6 +6,11 @@ set(the_description "SFM algorithms") find_package(Ceres QUIET) if(NOT DEFINED SFM_DEPS_OK) + + if(NOT DEFINED GLOG_LIBRARIES) + set(GLOG_LIBRARIES "glog") + endif() + set(_fname "${CMAKE_CURRENT_BINARY_DIR}/test_sfm_deps.cpp") file(WRITE "${_fname}" "#include \n#include \nint main() { (void)(0); return 0; }\n") try_compile(SFM_DEPS_OK "${CMAKE_CURRENT_BINARY_DIR}" "${_fname}" @@ -60,21 +65,21 @@ endif() ### CREATE OPENCV SFM MODULE ### ocv_add_module(sfm - opencv_core - opencv_calib3d - opencv_features2d - opencv_xfeatures2d + opencv_core + opencv_calib3d + opencv_features2d + opencv_xfeatures2d ) ocv_warnings_disable(CMAKE_CXX_FLAGS - -Wundef - -Wshadow - -Wsign-compare - -Wmissing-declarations - -Wunused-but-set-variable - -Wunused-parameter - -Wunused-function + -Wundef + -Wshadow + -Wsign-compare + -Wmissing-declarations + -Wunused-but-set-variable + -Wunused-parameter + -Wunused-function ) if(UNIX) From a1460ef3ebaf6a7349ddd3390085bd934c577e29 Mon Sep 17 00:00:00 2001 From: edgarriba Date: Wed, 14 Oct 2015 16:06:34 +0200 Subject: [PATCH 3/4] adding python bindings --- modules/sfm/CMakeLists.txt | 1 + .../sfm/include/opencv2/sfm/conditioning.hpp | 10 +-- .../sfm/include/opencv2/sfm/fundamental.hpp | 22 +++--- modules/sfm/include/opencv2/sfm/numeric.hpp | 4 +- .../sfm/include/opencv2/sfm/projection.hpp | 10 +-- .../sfm/include/opencv2/sfm/reconstruct.hpp | 8 +- modules/sfm/include/opencv2/sfm/robust.hpp | 4 +- .../include/opencv2/sfm/simple_pipeline.hpp | 75 ++++++++++++------- .../sfm/include/opencv2/sfm/triangulation.hpp | 2 +- 9 files changed, 80 insertions(+), 56 deletions(-) diff --git a/modules/sfm/CMakeLists.txt b/modules/sfm/CMakeLists.txt index e5810c8b10..e4e23fb55f 100644 --- a/modules/sfm/CMakeLists.txt +++ b/modules/sfm/CMakeLists.txt @@ -69,6 +69,7 @@ ocv_add_module(sfm opencv_calib3d opencv_features2d opencv_xfeatures2d + WRAP python ) diff --git a/modules/sfm/include/opencv2/sfm/conditioning.hpp b/modules/sfm/include/opencv2/sfm/conditioning.hpp index 052a6cd663..45505d3c76 100644 --- a/modules/sfm/include/opencv2/sfm/conditioning.hpp +++ b/modules/sfm/include/opencv2/sfm/conditioning.hpp @@ -54,7 +54,7 @@ namespace sfm forming an approximately symmetric circular cloud of points of radius 1 about the origin.\n Reference: @cite HartleyZ00 4.4.4 pag.109 */ -CV_EXPORTS +CV_EXPORTS_W void preconditionerFromPoints( InputArray points, OutputArray T ); @@ -67,7 +67,7 @@ preconditionerFromPoints( InputArray points, bringing the centroid to the origin with an average centroid \f$(1,1,1)^T\f$.\n Reference: @cite HartleyZ00 4.4.4 pag.107. */ -CV_EXPORTS +CV_EXPORTS_W void isotropicPreconditionerFromPoints( InputArray points, OutputArray T ); @@ -77,7 +77,7 @@ isotropicPreconditionerFromPoints( InputArray points, @param T Input 3x3 transformation matrix such that \f$x = T*X\f$, where \f$X\f$ are the points to transform and \f$x\f$ the transformed points. @param transformed_points Output vector of N-dimensional transformed points. */ -CV_EXPORTS +CV_EXPORTS_W void applyTransformationToPoints( InputArray points, InputArray T, @@ -92,7 +92,7 @@ applyTransformationToPoints( InputArray points, This operation is an essential step before applying the DLT algorithm in order to consider the result as optimal.\n Reference: @cite HartleyZ00 4.4.4 pag.109 */ -CV_EXPORTS +CV_EXPORTS_W void normalizePoints( InputArray points, OutputArray normalized_points, @@ -107,7 +107,7 @@ normalizePoints( InputArray points, This operation is an essential step before applying the DLT algorithm in order to consider the result as optimal.\n Reference: @cite HartleyZ00 4.4.4 pag.107. */ -CV_EXPORTS +CV_EXPORTS_W void normalizeIsotropicPoints( InputArray points, OutputArray normalized_points, diff --git a/modules/sfm/include/opencv2/sfm/fundamental.hpp b/modules/sfm/include/opencv2/sfm/fundamental.hpp index 8dfdc4050d..34b3d534f4 100644 --- a/modules/sfm/include/opencv2/sfm/fundamental.hpp +++ b/modules/sfm/include/opencv2/sfm/fundamental.hpp @@ -53,7 +53,7 @@ namespace sfm @param P1 Output 3x4 one possible projection matrix. @param P2 Output 3x4 another possible projection matrix. */ -CV_EXPORTS +CV_EXPORTS_W void projectionsFromFundamental( InputArray F, OutputArray P1, @@ -64,7 +64,7 @@ projectionsFromFundamental( InputArray F, @param P2 Input 3x4 second projection matrix. @param F Output 3x3 fundamental matrix. */ -CV_EXPORTS +CV_EXPORTS_W void fundamentalFromProjections( InputArray P1, InputArray P2, @@ -78,7 +78,7 @@ fundamentalFromProjections( InputArray P1, Uses the normalized 8-point fundamental matrix solver. Reference: @cite HartleyZ00 11.2 pag.281 (x1 = x, x2 = x') */ -CV_EXPORTS +CV_EXPORTS_W void normalizedEightPointSolver( InputArray x1, InputArray x2, @@ -96,7 +96,7 @@ normalizedEightPointSolver( InputArray x1, of the second one assuming the first one to be at the origin. If T1 and T2 are the camera motions, the computed relative motion is \f$T = T_2 T_1^{-1}\f$ */ -CV_EXPORTS +CV_EXPORTS_W void relativeCameraMotion( InputArray R1, InputArray t1, @@ -112,7 +112,7 @@ relativeCameraMotion( InputArray R1, Reference: @cite HartleyZ00 9.6 pag 259 (Result 9.19) */ -CV_EXPORTS +CV_EXPORTS_W void motionFromEssential( InputArray E, OutputArrayOfArrays Rs, @@ -131,7 +131,7 @@ motionFromEssential( InputArray E, Reference: See @cite HartleyZ00 9.6 pag 259 (9.6.3 Geometrical interpretation of the 4 solutions). */ -CV_EXPORTS +CV_EXPORTS_W int motionFromEssentialChooseSolution( InputArrayOfArrays Rs, InputArrayOfArrays ts, InputArray K1, @@ -147,7 +147,7 @@ int motionFromEssentialChooseSolution( InputArrayOfArrays Rs, Reference: @cite HartleyZ00 9.6 pag 257 (formula 9.12) or http://ai.stanford.edu/~birch/projective/node20.html */ -CV_EXPORTS +CV_EXPORTS_W void fundamentalFromEssential( InputArray E, InputArray K1, @@ -162,7 +162,7 @@ fundamentalFromEssential( InputArray E, Reference: @cite HartleyZ00 9.6 pag 257 (formula 9.12) */ -CV_EXPORTS +CV_EXPORTS_W void essentialFromFundamental( InputArray F, InputArray K1, @@ -178,7 +178,7 @@ essentialFromFundamental( InputArray F, Reference: @cite HartleyZ00 9.6 pag 257 (formula 9.12) */ -CV_EXPORTS +CV_EXPORTS_W void essentialFromRt( InputArray R1, InputArray t1, @@ -192,7 +192,7 @@ essentialFromRt( InputArray R1, By default divides the fundamental matrix by its L2 norm. */ -CV_EXPORTS +CV_EXPORTS_W void normalizeFundamental( InputArray F, OutputArray F_normalized ); @@ -207,7 +207,7 @@ normalizeFundamental( InputArray F, Find the best transformation such that xp=projection*(s*R*x+t) (same as Pose Estimation, ePNP). The routines below are only for the orthographic case for now. */ -CV_EXPORTS +CV_EXPORTS_W void computeOrientation( InputArrayOfArrays x1, InputArrayOfArrays x2, diff --git a/modules/sfm/include/opencv2/sfm/numeric.hpp b/modules/sfm/include/opencv2/sfm/numeric.hpp index e3c2f9ded1..f191b2b9f2 100644 --- a/modules/sfm/include/opencv2/sfm/numeric.hpp +++ b/modules/sfm/include/opencv2/sfm/numeric.hpp @@ -55,7 +55,7 @@ namespace sfm It computes in the same way as woud do @ref reduce but with \a Variance function. */ -CV_EXPORTS +CV_EXPORTS_W void meanAndVarianceAlongRows( InputArray A, OutputArray mean, @@ -66,7 +66,7 @@ meanAndVarianceAlongRows( InputArray A, Reference: @cite HartleyZ00, p581, equation (A4.5). */ -CV_EXPORTS +CV_EXPORTS_W Mat skew( InputArray x ); diff --git a/modules/sfm/include/opencv2/sfm/projection.hpp b/modules/sfm/include/opencv2/sfm/projection.hpp index 8794702060..d796878382 100644 --- a/modules/sfm/include/opencv2/sfm/projection.hpp +++ b/modules/sfm/include/opencv2/sfm/projection.hpp @@ -50,7 +50,7 @@ namespace sfm @param src Input vector of N-dimensional points. @param dst Output vector of N-1-dimensional points. */ -CV_EXPORTS +CV_EXPORTS_W void homogeneousToEuclidean(InputArray src, OutputArray dst); @@ -58,7 +58,7 @@ homogeneousToEuclidean(InputArray src, OutputArray dst); @param src Input vector of N-dimensional points. @param dst Output vector of N+1-dimensional points. */ -CV_EXPORTS +CV_EXPORTS_W void euclideanToHomogeneous(InputArray src, OutputArray dst); @@ -71,7 +71,7 @@ euclideanToHomogeneous(InputArray src, OutputArray dst); This function estimate the projection matrix by solving the following equation: \f$P = K * [R|t]\f$ */ -CV_EXPORTS +CV_EXPORTS_W void projectionFromKRt(InputArray K, InputArray R, InputArray t, OutputArray P); @@ -83,7 +83,7 @@ projectionFromKRt(InputArray K, InputArray R, InputArray t, OutputArray P); Reference: @cite HartleyZ00 A4.1.1 pag.579 */ -CV_EXPORTS +CV_EXPORTS_W void KRtFromProjection( InputArray P, OutputArray K, OutputArray R, OutputArray t ); @@ -92,7 +92,7 @@ KRtFromProjection( InputArray P, OutputArray K, OutputArray R, OutputArray t ); @param t Input 3x1 translation vector. @param X Input 3x1 or 4x1 vector with the 3d point. */ -CV_EXPORTS +CV_EXPORTS_W double depth( InputArray R, InputArray t, InputArray X); diff --git a/modules/sfm/include/opencv2/sfm/reconstruct.hpp b/modules/sfm/include/opencv2/sfm/reconstruct.hpp index 2c1267deb7..639daebbfb 100644 --- a/modules/sfm/include/opencv2/sfm/reconstruct.hpp +++ b/modules/sfm/include/opencv2/sfm/reconstruct.hpp @@ -69,7 +69,7 @@ namespace sfm @note - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. */ -CV_EXPORTS +/* CV_EXPORTS_W */ // error: ‘reconstruct’ is not a member of ‘cv::sfm’ void reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, InputOutputArray K, bool is_projective = false); @@ -88,7 +88,7 @@ reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, I - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. - To see a working example for camera motion reconstruction, check the following tutorial: @ref tutorial_sfm_trajectory_estimation. */ -CV_EXPORTS +/* CV_EXPORTS_W */ // error: ‘reconstruct’ is not a member of ‘cv::sfm’ void reconstruct(InputArrayOfArrays points2d, OutputArray Rs, OutputArray Ts, InputOutputArray K, OutputArray points3d, bool is_projective = false); @@ -106,7 +106,7 @@ reconstruct(InputArrayOfArrays points2d, OutputArray Rs, OutputArray Ts, InputOu - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. */ -CV_EXPORTS +/* CV_EXPORTS_W */ // error: ‘vector_string’ was not declared in this scope void reconstruct(const std::vector images, OutputArray Ps, OutputArray points3d, InputOutputArray K, bool is_projective = false); @@ -126,7 +126,7 @@ reconstruct(const std::vector images, OutputArray Ps, OutputArray p - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. - To see a working example for scene reconstruction, check the following tutorial: @ref tutorial_sfm_scene_reconstruction. */ -CV_EXPORTS +/* CV_EXPORTS_W */ // error: ‘vector_string’ was not declared in this scope void reconstruct(const std::vector images, OutputArray Rs, OutputArray Ts, InputOutputArray K, OutputArray points3d, bool is_projective = false); diff --git a/modules/sfm/include/opencv2/sfm/robust.hpp b/modules/sfm/include/opencv2/sfm/robust.hpp index 4aedc6e463..368b32a902 100644 --- a/modules/sfm/include/opencv2/sfm/robust.hpp +++ b/modules/sfm/include/opencv2/sfm/robust.hpp @@ -62,7 +62,7 @@ namespace sfm The fundamental solver relies on the 8 point solution. Returns the best error (in pixels), associated to the solution F. */ -CV_EXPORTS +CV_EXPORTS_W double fundamentalFromCorrespondences8PointRobust( InputArray x1, InputArray x2, @@ -85,7 +85,7 @@ fundamentalFromCorrespondences8PointRobust( InputArray x1, The fundamental solver relies on the 7 point solution. Returns the best error (in pixels), associated to the solution F. */ -CV_EXPORTS +CV_EXPORTS_W double fundamentalFromCorrespondences7PointRobust( InputArray x1, InputArray x2, diff --git a/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp b/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp index fc7166027e..746574e9a2 100644 --- a/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp +++ b/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp @@ -68,7 +68,10 @@ enum { In case that the camera model was SFM_DISTORTION_MODEL_DIVISION, it's only needed to provide _polynomial_k1 and _polynomial_k2 which will be assigned as division distortion parameters. */ -typedef struct libmv_CameraIntrinsicsOptions { +class CV_EXPORTS_W_SIMPLE libmv_CameraIntrinsicsOptions +{ +public: + CV_WRAP libmv_CameraIntrinsicsOptions(const int _distortion_model=0, const double _focal_length=0, const double _principal_point_x=0, @@ -87,8 +90,8 @@ typedef struct libmv_CameraIntrinsicsOptions { polynomial_k1(_polynomial_k1), polynomial_k2(_polynomial_k2), polynomial_k3(_polynomial_k3), - division_k1(0), - division_k2(0) + division_k1(_polynomial_p1), + division_k2(_polynomial_p2) { if ( _distortion_model == SFM_DISTORTION_MODEL_DIVISION ) { @@ -98,18 +101,18 @@ typedef struct libmv_CameraIntrinsicsOptions { } // Common settings of all distortion models. - int distortion_model; - int image_width, image_height; - double focal_length; - double principal_point_x, principal_point_y; + CV_PROP_RW int distortion_model; + CV_PROP_RW int image_width, image_height; + CV_PROP_RW double focal_length; + CV_PROP_RW double principal_point_x, principal_point_y; // Radial distortion model. - double polynomial_k1, polynomial_k2, polynomial_k3; - double polynomial_p1, polynomial_p2; + CV_PROP_RW double polynomial_k1, polynomial_k2, polynomial_k3; + CV_PROP_RW double polynomial_p1, polynomial_p2; // Division distortion model. - double division_k1, division_k2; -} libmv_CameraIntrinsicsOptions; + CV_PROP_RW double division_k1, division_k2; +}; /** @brief All internal camera parameters that libmv is able to refine. @@ -128,7 +131,10 @@ enum { SFM_REFINE_FOCAL_LENGTH = (1 << 0), // libmv::BUNDLE_FOCAL_LENGT @param _select_keyframes allows to select automatically the initial keyframes. If 1 then autoselection is enabled. If 0 then is disabled. @param _verbosity_level verbosity logs level for Glog. If -1 then logs are disabled, otherwise the log level will be the input integer. */ -typedef struct libmv_ReconstructionOptions { +class CV_EXPORTS_W_SIMPLE libmv_ReconstructionOptions +{ +public: + CV_WRAP libmv_ReconstructionOptions(const int _keyframe1=1, const int _keyframe2=2, const int _refine_intrinsics=1, @@ -138,21 +144,25 @@ typedef struct libmv_ReconstructionOptions { refine_intrinsics(_refine_intrinsics), select_keyframes(_select_keyframes), verbosity_level(_verbosity_level) {} - int keyframe1, keyframe2; - int refine_intrinsics; - int select_keyframes; - int verbosity_level; -} libmv_ReconstructionOptions; + + CV_PROP_RW int keyframe1, keyframe2; + CV_PROP_RW int refine_intrinsics; + CV_PROP_RW int select_keyframes; + CV_PROP_RW int verbosity_level; +}; /** @brief base class BaseSFM declares a common API that would be used in a typical scene reconstruction scenario */ -class CV_EXPORTS BaseSFM +class CV_EXPORTS_W BaseSFM { public: virtual ~BaseSFM() {}; + CV_WRAP virtual void run(InputArrayOfArrays points2d) = 0; + + CV_WRAP virtual void run(InputArrayOfArrays points2d, InputOutputArray K, OutputArray Rs, OutputArray Ts, OutputArray points3d) = 0; @@ -160,21 +170,23 @@ class CV_EXPORTS BaseSFM virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, OutputArray Ts, OutputArray points3d) = 0; - virtual double getError() const = 0; - virtual void getPoints(OutputArray points3d) = 0; - virtual cv::Mat getIntrinsics() const = 0; - virtual void getCameras(OutputArray Rs, OutputArray Ts) = 0; + CV_WRAP virtual double getError() const = 0; + CV_WRAP virtual void getPoints(OutputArray points3d) = 0; + CV_WRAP virtual cv::Mat getIntrinsics() const = 0; + CV_WRAP virtual void getCameras(OutputArray Rs, OutputArray Ts) = 0; + CV_WRAP virtual void setReconstructionOptions(const libmv_ReconstructionOptions &libmv_reconstruction_options) = 0; + CV_WRAP virtual void setCameraIntrinsicOptions(const libmv_CameraIntrinsicsOptions &libmv_camera_intrinsics_options) = 0; }; /** @brief SFMLibmvEuclideanReconstruction class provides an interface with the Libmv Structure From Motion pipeline. */ -class CV_EXPORTS SFMLibmvEuclideanReconstruction : public BaseSFM +class CV_EXPORTS_W SFMLibmvEuclideanReconstruction : public BaseSFM { public: /** @brief Calls the pipeline in order to perform Eclidean reconstruction. @@ -183,6 +195,7 @@ class CV_EXPORTS SFMLibmvEuclideanReconstruction : public BaseSFM @note - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. */ + CV_WRAP virtual void run(InputArrayOfArrays points2d) = 0; /** @brief Calls the pipeline in order to perform Eclidean reconstruction. @@ -195,6 +208,7 @@ class CV_EXPORTS SFMLibmvEuclideanReconstruction : public BaseSFM @note - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. */ + CV_WRAP virtual void run(InputArrayOfArrays points2d, InputOutputArray K, OutputArray Rs, OutputArray Ts, OutputArray points3d) = 0; @@ -205,6 +219,7 @@ class CV_EXPORTS SFMLibmvEuclideanReconstruction : public BaseSFM - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. */ + /* CV_WRAP */ // error: ‘vector_string’ was not declared in this scope virtual void run(const std::vector &images) = 0; /** @brief Calls the pipeline in order to perform Eclidean reconstruction. @@ -218,32 +233,38 @@ class CV_EXPORTS SFMLibmvEuclideanReconstruction : public BaseSFM - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. */ + /* CV_WRAP */ // error: ‘vector_string’ was not declared in this scope virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, OutputArray Ts, OutputArray points3d) = 0; /** @brief Returns the computed reprojection error. */ + CV_WRAP virtual double getError() const = 0; /** @brief Returns the estimated 3d points. @param points3d Output array with estimated 3d points. */ + CV_WRAP virtual void getPoints(OutputArray points3d) = 0; /** @brief Returns the refined camera calibration matrix. */ + CV_WRAP virtual cv::Mat getIntrinsics() const = 0; /** @brief Returns the estimated camera extrinsic parameters. @param Rs Output vector of 3x3 rotations of the camera. @param Ts Output vector of 3x1 translations of the camera. */ + CV_WRAP virtual void getCameras(OutputArray Rs, OutputArray Ts) = 0; /** @brief Setter method for reconstruction options. @param libmv_reconstruction_options struct with reconstruction options such as initial keyframes, automatic keyframe selection, parameters to refine and the verbosity level. */ + CV_WRAP virtual void setReconstructionOptions(const libmv_ReconstructionOptions &libmv_reconstruction_options) = 0; @@ -251,14 +272,16 @@ class CV_EXPORTS SFMLibmvEuclideanReconstruction : public BaseSFM @param libmv_camera_intrinsics_options struct with camera intrinsic options such as camera model and the internal camera parameters. */ + CV_WRAP virtual void setCameraIntrinsicOptions(const libmv_CameraIntrinsicsOptions &libmv_camera_intrinsics_options) = 0; /** @brief Creates an instance of the SFMLibmvEuclideanReconstruction class. Initializes Libmv. */ + /* CV_WRAP */ // error: ‘SFMLibmvEuclideanReruction’ was not declared in this scope static Ptr - create(const libmv_CameraIntrinsicsOptions &camera_instrinsic_options=libmv_CameraIntrinsicsOptions(), - const libmv_ReconstructionOptions &reconstruction_options=libmv_ReconstructionOptions()); -}; + create(const libmv_CameraIntrinsicsOptions &camera_instrinsic_options=libmv_CameraIntrinsicsOptions(), + const libmv_ReconstructionOptions &reconstruction_options=libmv_ReconstructionOptions()); + }; //! @} sfm diff --git a/modules/sfm/include/opencv2/sfm/triangulation.hpp b/modules/sfm/include/opencv2/sfm/triangulation.hpp index 0f76bcd293..99bf05b524 100644 --- a/modules/sfm/include/opencv2/sfm/triangulation.hpp +++ b/modules/sfm/include/opencv2/sfm/triangulation.hpp @@ -54,7 +54,7 @@ namespace sfm Triangulates the 3d position of 2d correspondences between several images. Reference: Internally it uses DLT method @cite HartleyZ00 12.2 pag.312 */ -CV_EXPORTS +CV_EXPORTS_W void triangulatePoints(InputArrayOfArrays points2d, InputArrayOfArrays projection_matrices, OutputArray points3d); From 905227711867783377394de06d4aa56930f8d402 Mon Sep 17 00:00:00 2001 From: edgarriba Date: Wed, 14 Oct 2015 18:13:29 +0200 Subject: [PATCH 4/4] fixing building issue --- modules/sfm/include/opencv2/sfm/reconstruct.hpp | 8 ++++---- modules/sfm/include/opencv2/sfm/simple_pipeline.hpp | 11 ++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/modules/sfm/include/opencv2/sfm/reconstruct.hpp b/modules/sfm/include/opencv2/sfm/reconstruct.hpp index 639daebbfb..2c1267deb7 100644 --- a/modules/sfm/include/opencv2/sfm/reconstruct.hpp +++ b/modules/sfm/include/opencv2/sfm/reconstruct.hpp @@ -69,7 +69,7 @@ namespace sfm @note - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. */ -/* CV_EXPORTS_W */ // error: ‘reconstruct’ is not a member of ‘cv::sfm’ +CV_EXPORTS void reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, InputOutputArray K, bool is_projective = false); @@ -88,7 +88,7 @@ reconstruct(InputArrayOfArrays points2d, OutputArray Ps, OutputArray points3d, I - Tracks must be as precise as possible. It does not handle outliers and is very sensible to them. - To see a working example for camera motion reconstruction, check the following tutorial: @ref tutorial_sfm_trajectory_estimation. */ -/* CV_EXPORTS_W */ // error: ‘reconstruct’ is not a member of ‘cv::sfm’ +CV_EXPORTS void reconstruct(InputArrayOfArrays points2d, OutputArray Rs, OutputArray Ts, InputOutputArray K, OutputArray points3d, bool is_projective = false); @@ -106,7 +106,7 @@ reconstruct(InputArrayOfArrays points2d, OutputArray Rs, OutputArray Ts, InputOu - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. */ -/* CV_EXPORTS_W */ // error: ‘vector_string’ was not declared in this scope +CV_EXPORTS void reconstruct(const std::vector images, OutputArray Ps, OutputArray points3d, InputOutputArray K, bool is_projective = false); @@ -126,7 +126,7 @@ reconstruct(const std::vector images, OutputArray Ps, OutputArray p - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. - To see a working example for scene reconstruction, check the following tutorial: @ref tutorial_sfm_scene_reconstruction. */ -/* CV_EXPORTS_W */ // error: ‘vector_string’ was not declared in this scope +CV_EXPORTS void reconstruct(const std::vector images, OutputArray Rs, OutputArray Ts, InputOutputArray K, OutputArray points3d, bool is_projective = false); diff --git a/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp b/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp index 746574e9a2..79e96e5874 100644 --- a/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp +++ b/modules/sfm/include/opencv2/sfm/simple_pipeline.hpp @@ -166,8 +166,8 @@ class CV_EXPORTS_W BaseSFM virtual void run(InputArrayOfArrays points2d, InputOutputArray K, OutputArray Rs, OutputArray Ts, OutputArray points3d) = 0; - virtual void run(const std::vector &images) = 0; - virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, + virtual void run(const std::vector &images) = 0; + virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, OutputArray Ts, OutputArray points3d) = 0; CV_WRAP virtual double getError() const = 0; @@ -219,8 +219,7 @@ class CV_EXPORTS_W SFMLibmvEuclideanReconstruction : public BaseSFM - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. */ - /* CV_WRAP */ // error: ‘vector_string’ was not declared in this scope - virtual void run(const std::vector &images) = 0; + virtual void run(const std::vector &images) = 0; /** @brief Calls the pipeline in order to perform Eclidean reconstruction. @param images a vector of string with the images paths. @@ -233,8 +232,7 @@ class CV_EXPORTS_W SFMLibmvEuclideanReconstruction : public BaseSFM - The images must be ordered as they were an image sequence. Additionally, each frame should be as close as posible to the previous and posterior. - For now DAISY features are used in order to compute the 2d points tracks and it only works for 3-4 images. */ - /* CV_WRAP */ // error: ‘vector_string’ was not declared in this scope - virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, + virtual void run(const std::vector &images, InputOutputArray K, OutputArray Rs, OutputArray Ts, OutputArray points3d) = 0; /** @brief Returns the computed reprojection error. @@ -277,7 +275,6 @@ class CV_EXPORTS_W SFMLibmvEuclideanReconstruction : public BaseSFM setCameraIntrinsicOptions(const libmv_CameraIntrinsicsOptions &libmv_camera_intrinsics_options) = 0; /** @brief Creates an instance of the SFMLibmvEuclideanReconstruction class. Initializes Libmv. */ - /* CV_WRAP */ // error: ‘SFMLibmvEuclideanReruction’ was not declared in this scope static Ptr create(const libmv_CameraIntrinsicsOptions &camera_instrinsic_options=libmv_CameraIntrinsicsOptions(), const libmv_ReconstructionOptions &reconstruction_options=libmv_ReconstructionOptions());