diff --git a/3rdparty/libtiff/tif_config.h.cmakein b/3rdparty/libtiff/tif_config.h.cmakein index 182f2833d1..24f58119ba 100644 --- a/3rdparty/libtiff/tif_config.h.cmakein +++ b/3rdparty/libtiff/tif_config.h.cmakein @@ -54,7 +54,7 @@ /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */ -#define HOST_BIGENDIAN 0 +#define HOST_BIGENDIAN @WORDS_BIGENDIAN@ /* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ #define HOST_FILLORDER FILLORDER_LSB2MSB @@ -156,15 +156,7 @@ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif -#endif +#cmakedefine WORDS_BIGENDIAN 1 /* Support Deflate compression */ #define ZIP_SUPPORT 1 diff --git a/CMakeLists.txt b/CMakeLists.txt index eb25cd3474..b5fbb9f2b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,7 @@ OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS) OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE ) OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) ) +OCV_OPTION(WITH_VTK "Include VTK library support (and build opencv_viz module eiher)" OFF IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) ) OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) ) OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS AND NOT APPLE) ) @@ -141,7 +142,7 @@ OCV_OPTION(WITH_IPP "Include Intel IPP support" OFF OCV_OPTION(WITH_JASPER "Include JPEG2K support" ON IF (NOT IOS) ) OCV_OPTION(WITH_JPEG "Include JPEG support" ON) OCV_OPTION(WITH_OPENEXR "Include ILM support via OpenEXR" ON IF (NOT IOS) ) -OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF IF (NOT ANDROID AND NOT APPLE) ) +OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF IF (NOT ANDROID) ) OCV_OPTION(WITH_OPENNI "Include OpenNI support" OFF IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_PNG "Include PNG support" ON) OCV_OPTION(WITH_PVAPI "Include Prosilica GigE support" ON IF (NOT ANDROID AND NOT IOS) ) @@ -197,7 +198,7 @@ OCV_OPTION(INSTALL_C_EXAMPLES "Install C examples" OFF ) OCV_OPTION(INSTALL_PYTHON_EXAMPLES "Install Python examples" OFF ) OCV_OPTION(INSTALL_ANDROID_EXAMPLES "Install Android examples" OFF IF ANDROID ) OCV_OPTION(INSTALL_TO_MANGLED_PATHS "Enables mangled install paths, that help with side by side installs." OFF IF (UNIX AND NOT ANDROID AND NOT IOS AND BUILD_SHARED_LIBS) ) - +OCV_OPTION(INSTALL_TESTS "Install accuracy and performance test binaries and test data" OFF) # OpenCV build options # =================================================== @@ -205,6 +206,7 @@ OCV_OPTION(ENABLE_DYNAMIC_CUDA "Enabled dynamic CUDA linkage" OCV_OPTION(ENABLE_PRECOMPILED_HEADERS "Use precompiled headers" ON IF (NOT IOS) ) OCV_OPTION(ENABLE_SOLUTION_FOLDERS "Solution folder in Visual Studio or in other IDEs" (MSVC_IDE OR CMAKE_GENERATOR MATCHES Xcode) IF (CMAKE_VERSION VERSION_GREATER "2.8.0") ) OCV_OPTION(ENABLE_PROFILING "Enable profiling in the GCC compiler (Add flags: -g -pg)" OFF IF CMAKE_COMPILER_IS_GNUCXX ) +OCV_OPTION(ENABLE_COVERAGE "Enable coverage collection with GCov" OFF IF CMAKE_COMPILER_IS_GNUCXX ) OCV_OPTION(ENABLE_OMIT_FRAME_POINTER "Enable -fomit-frame-pointer for GCC" ON IF CMAKE_COMPILER_IS_GNUCXX AND NOT (APPLE AND CMAKE_COMPILER_IS_CLANGCXX) ) OCV_OPTION(ENABLE_POWERPC "Enable PowerPC for GCC" ON IF (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_SYSTEM_PROCESSOR MATCHES powerpc.*) ) OCV_OPTION(ENABLE_FAST_MATH "Enable -ffast-math (not recommended for GCC 4.6.x)" OFF IF (CMAKE_COMPILER_IS_GNUCXX AND (X86 OR X86_64)) ) @@ -268,13 +270,27 @@ if(WIN32) message(STATUS "Can't detect runtime and/or arch") set(OpenCV_INSTALL_BINARIES_PREFIX "") endif() +elseif(ANDROID) + set(OpenCV_INSTALL_BINARIES_PREFIX "sdk/native/") else() set(OpenCV_INSTALL_BINARIES_PREFIX "") endif() -set(OPENCV_SAMPLES_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}samples") +if(ANDROID) + set(OPENCV_SAMPLES_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}samples/${ANDROID_NDK_ABI_NAME}") +else() + set(OPENCV_SAMPLES_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}samples") +endif() -set(OPENCV_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}bin") +if(ANDROID) + set(OPENCV_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}bin/${ANDROID_NDK_ABI_NAME}") +else() + set(OPENCV_BIN_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}bin") +endif() + +if(NOT OPENCV_TEST_INSTALL_PATH) + set(OPENCV_TEST_INSTALL_PATH "${OPENCV_BIN_INSTALL_PATH}") +endif() if(ANDROID) set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib/${ANDROID_NDK_ABI_NAME}") @@ -283,6 +299,7 @@ if(ANDROID) set(OPENCV_3P_LIB_INSTALL_PATH sdk/native/3rdparty/libs/${ANDROID_NDK_ABI_NAME}) set(OPENCV_CONFIG_INSTALL_PATH sdk/native/jni) set(OPENCV_INCLUDE_INSTALL_PATH sdk/native/jni/include) + set(OPENCV_SAMPLES_SRC_INSTALL_PATH samples/native) else() set(LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/lib") set(3P_LIBRARY_OUTPUT_PATH "${OpenCV_BINARY_DIR}/3rdparty/lib${LIB_SUFFIX}") @@ -293,9 +310,11 @@ else() set(OPENCV_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}lib${LIB_SUFFIX}") endif() set(OPENCV_3P_LIB_INSTALL_PATH "${OpenCV_INSTALL_BINARIES_PREFIX}staticlib${LIB_SUFFIX}") + set(OPENCV_SAMPLES_SRC_INSTALL_PATH samples/native) else() set(OPENCV_LIB_INSTALL_PATH lib${LIB_SUFFIX}) set(OPENCV_3P_LIB_INSTALL_PATH share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH}) + set(OPENCV_SAMPLES_SRC_INSTALL_PATH share/OpenCV/samples) endif() set(OPENCV_INCLUDE_INSTALL_PATH "include") @@ -426,6 +445,12 @@ endif() include(cmake/OpenCVPCHSupport.cmake) include(cmake/OpenCVModule.cmake) +# ---------------------------------------------------------------------------- +# Detect endianness of build platform +# ---------------------------------------------------------------------------- +include(TestBigEndian) +test_big_endian(WORDS_BIGENDIAN) + # ---------------------------------------------------------------------------- # Detect 3rd-party libraries # ---------------------------------------------------------------------------- @@ -471,6 +496,9 @@ if(WITH_OPENCL) include(cmake/OpenCVDetectOpenCL.cmake) endif() +# --- VTK support --- +include(cmake/OpenCVDetectVTK.cmake) + # ---------------------------------------------------------------------------- # Add CUDA libraries (needed for apps/tools, samples) # ---------------------------------------------------------------------------- @@ -558,6 +586,49 @@ include(cmake/OpenCVGenConfig.cmake) # Generate Info.plist for the IOS framework include(cmake/OpenCVGenInfoPlist.cmake) +# Generate environment setup file +if(INSTALL_TESTS AND OPENCV_TEST_DATA_PATH AND UNIX) + if(ANDROID) + get_filename_component(TEST_PATH ${OPENCV_TEST_INSTALL_PATH} DIRECTORY) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/opencv_run_all_tests_android.sh.in" + "${CMAKE_BINARY_DIR}/unix-install/opencv_run_all_tests.sh" @ONLY) + install(PROGRAMS "${CMAKE_BINARY_DIR}/unix-install/opencv_run_all_tests.sh" + DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT tests) + else() + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/opencv_testing.sh.in" + "${CMAKE_BINARY_DIR}/unix-install/opencv_testing.sh" @ONLY) + install(FILES "${CMAKE_BINARY_DIR}/unix-install/opencv_testing.sh" + DESTINATION /etc/profile.d/ COMPONENT tests) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/opencv_run_all_tests_unix.sh.in" + "${CMAKE_BINARY_DIR}/unix-install/opencv_run_all_tests.sh" @ONLY) + install(PROGRAMS "${CMAKE_BINARY_DIR}/unix-install/opencv_run_all_tests.sh" + DESTINATION ${OPENCV_TEST_INSTALL_PATH} COMPONENT tests) + + endif() +endif() + +if(NOT OPENCV_README_FILE) + if(ANDROID) + set(OPENCV_README_FILE ${CMAKE_CURRENT_SOURCE_DIR}/platforms/android/README.android) + endif() +endif() + +if(NOT OPENCV_LICENSE_FILE) + set(OPENCV_LICENSE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE) +endif() + +# for UNIX it does not make sense as LICENSE and readme will be part of the package automatically +if(ANDROID OR NOT UNIX) + install(FILES ${OPENCV_LICENSE_FILE} + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ + DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT libs) + if(OPENCV_README_FILE) + install(FILES ${OPENCV_README_FILE} + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ + DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT libs) + endif() +endif() + # ---------------------------------------------------------------------------- # Summary: # ---------------------------------------------------------------------------- @@ -705,6 +776,7 @@ else() endif() status(" OpenGL support:" HAVE_OPENGL THEN "YES (${OPENGL_LIBRARIES})" ELSE NO) +status(" VTK support:" HAVE_VTK THEN "YES (ver ${VTK_VERSION})" ELSE NO) # ========================== MEDIA IO ========================== status("") diff --git a/README.md b/README.md index 403f118eed..3a26ad8555 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ### OpenCV: Open Source Computer Vision Library +[![Gittip](http://img.shields.io/gittip/OpenCV.png)](https://www.gittip.com/OpenCV/) + #### Resources * Homepage: @@ -18,6 +20,3 @@ Summary of guidelines: * Include tests and documentation; * Clean up "oops" commits before submitting; * Follow the coding style guide. - -[![Donate OpenCV project](http://opencv.org/wp-content/uploads/2013/07/gittip1.png)](https://www.gittip.com/OpenCV/) -[![Donate OpenCV project](http://opencv.org/wp-content/uploads/2013/07/paypal-donate-button.png)](https://www.paypal.com/cgi-bin/webscr?item_name=Donation+to+OpenCV&cmd=_donations&business=accountant%40opencv.org) \ No newline at end of file diff --git a/cmake/OpenCVCompilerOptions.cmake b/cmake/OpenCVCompilerOptions.cmake index a4b039280f..d525609d18 100644 --- a/cmake/OpenCVCompilerOptions.cmake +++ b/cmake/OpenCVCompilerOptions.cmake @@ -187,6 +187,11 @@ if(CMAKE_COMPILER_IS_GNUCXX) add_extra_compiler_option(-ffunction-sections) endif() + if(ENABLE_COVERAGE) + set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} --coverage") + set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} --coverage") + endif() + set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} -DNDEBUG") set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG} -O0 -DDEBUG -D_DEBUG") endif() diff --git a/cmake/OpenCVDetectAndroidSDK.cmake b/cmake/OpenCVDetectAndroidSDK.cmake index 7a37051e49..af7427194e 100644 --- a/cmake/OpenCVDetectAndroidSDK.cmake +++ b/cmake/OpenCVDetectAndroidSDK.cmake @@ -180,7 +180,7 @@ unset(__android_project_chain CACHE) # add_android_project(target_name ${path} NATIVE_DEPS opencv_core LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11) macro(add_android_project target path) # parse arguments - set(android_proj_arglist NATIVE_DEPS LIBRARY_DEPS SDK_TARGET IGNORE_JAVA IGNORE_MANIFEST) + set(android_proj_arglist NATIVE_DEPS LIBRARY_DEPS SDK_TARGET IGNORE_JAVA IGNORE_MANIFEST EMBED_CUDA FORCE_EMBED_OPENCV) set(__varname "android_proj_") foreach(v ${android_proj_arglist}) set(${__varname}${v} "") @@ -303,6 +303,46 @@ macro(add_android_project target path) add_custom_command(TARGET ${JNI_LIB_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${android_proj_jni_location}") endif() endif() + + # copy opencv_java, tbb if it is shared and dynamicuda if present if FORCE_EMBED_OPENCV flag is set + if(android_proj_FORCE_EMBED_OPENCV) + set(native_deps ${android_proj_NATIVE_DEPS}) + # filter out gpu module as it is always static library on Android + list(REMOVE_ITEM native_deps "opencv_gpu") + if(ENABLE_DYNAMIC_CUDA) + list(APPEND native_deps "opencv_dynamicuda") + endif() + foreach(lib ${native_deps}) + get_property(f TARGET ${lib} PROPERTY LOCATION) + get_filename_component(f_name ${f} NAME) + add_custom_command( + OUTPUT "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f_name}" + COMMAND ${CMAKE_COMMAND} -E copy "${f}" "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f_name}" + DEPENDS "${lib}" VERBATIM + COMMENT "Embedding ${f}") + list(APPEND android_proj_file_deps "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f_name}") + endforeach() + endif() + + # copy all needed CUDA libs to project if EMBED_CUDA flag is present + if(android_proj_EMBED_CUDA) + set(android_proj_culibs ${CUDA_npp_LIBRARY} ${CUDA_LIBRARIES}) + if(HAVE_CUFFT) + list(INSERT android_proj_culibs 0 ${CUDA_cufft_LIBRARY}) + endif() + if(HAVE_CUBLAS) + list(INSERT android_proj_culibs 0 ${CUDA_cublas_LIBRARY}) + endif() + foreach(lib ${android_proj_culibs}) + get_filename_component(f "${lib}" NAME) + add_custom_command( + OUTPUT "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f}" + COMMAND ${CMAKE_COMMAND} -E copy "${lib}" "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f}" + DEPENDS "${lib}" VERBATIM + COMMENT "Embedding ${f}") + list(APPEND android_proj_file_deps "${android_proj_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${f}") + endforeach() + endif() endif() # build java part @@ -365,7 +405,7 @@ macro(add_android_project target path) endif() install(CODE "EXECUTE_PROCESS(COMMAND ${ANDROID_EXECUTABLE} --silent update project --path . --target \"${android_proj_sdk_target}\" --name \"${target}\" ${inst_lib_opt} WORKING_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}\" - )" COMPONENT dev) + )" COMPONENT samples) #empty 'gen' install(CODE "MAKE_DIRECTORY(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/samples/${sample_dir}/gen\")" COMPONENT samples) endif() diff --git a/cmake/OpenCVDetectCUDA.cmake b/cmake/OpenCVDetectCUDA.cmake index b35a7977c3..56b142970e 100644 --- a/cmake/OpenCVDetectCUDA.cmake +++ b/cmake/OpenCVDetectCUDA.cmake @@ -180,6 +180,9 @@ if(CUDA_FOUND) # we remove -Wsign-promo as it generates warnings under linux string(REPLACE "-Wsign-promo" "" ${var} "${${var}}") + # we remove -Wno-sign-promo as it generates warnings under linux + string(REPLACE "-Wno-sign-promo" "" ${var} "${${var}}") + # we remove -Wno-delete-non-virtual-dtor because it's used for C++ compiler # but NVCC uses C compiler by default string(REPLACE "-Wno-delete-non-virtual-dtor" "" ${var} "${${var}}") diff --git a/cmake/OpenCVDetectVTK.cmake b/cmake/OpenCVDetectVTK.cmake new file mode 100644 index 0000000000..78d1a73b69 --- /dev/null +++ b/cmake/OpenCVDetectVTK.cmake @@ -0,0 +1,26 @@ +if(NOT WITH_VTK OR ANDROID OR IOS) + return() +endif() + +if (HAVE_QT5) + message(STATUS "VTK is disabled because OpenCV is linked with Q5. Some VTK disributives are compiled with Q4 and therefore can't be linked together Qt5.") + return() +endif() + +find_package(VTK 6.0 QUIET COMPONENTS vtkRenderingCore vtkInteractionWidgets vtkInteractionStyle vtkIOLegacy vtkIOPLY vtkRenderingFreeType vtkRenderingLOD vtkFiltersTexture vtkIOExport NO_MODULE) + +if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND) + find_package(VTK 5.10 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE) +endif() + +if(NOT DEFINED VTK_FOUND OR NOT VTK_FOUND) + find_package(VTK 5.8 QUIET COMPONENTS vtkCommon vtkFiltering vtkRendering vtkWidgets vtkImaging NO_MODULE) +endif() + +if(VTK_FOUND) + set(HAVE_VTK ON) + message(STATUS "Found VTK ver. ${VTK_VERSION} (usefile: ${VTK_USE_FILE})") +else() + set(HAVE_VTK OFF) + message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or set $VTK_DIR enviroment variable to VTK install subdirectory with VTKConfig.cmake file (for windows)") +endif() diff --git a/cmake/OpenCVExtraTargets.cmake b/cmake/OpenCVExtraTargets.cmake index b4d339155a..ecb2a3b36a 100644 --- a/cmake/OpenCVExtraTargets.cmake +++ b/cmake/OpenCVExtraTargets.cmake @@ -4,7 +4,7 @@ CONFIGURE_FILE( "${OpenCV_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - IMMEDIATE @ONLY) + @ONLY) ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") if(ENABLE_SOLUTION_FOLDERS) diff --git a/cmake/OpenCVFindIPP.cmake b/cmake/OpenCVFindIPP.cmake index 772cae886f..db02e6acbf 100644 --- a/cmake/OpenCVFindIPP.cmake +++ b/cmake/OpenCVFindIPP.cmake @@ -163,9 +163,16 @@ function(set_ipp_new_libraries _LATEST_VERSION) ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCV}${IPP_SUFFIX}${IPP_LIB_SUFFIX} ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPI}${IPP_SUFFIX}${IPP_LIB_SUFFIX} ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPS}${IPP_SUFFIX}${IPP_LIB_SUFFIX} - ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCORE}${IPP_SUFFIX}${IPP_LIB_SUFFIX} - PARENT_SCOPE) - + ${IPP_LIB_PREFIX}${IPP_PREFIX}${IPPCORE}${IPP_SUFFIX}${IPP_LIB_SUFFIX}) + + if (UNIX) + set(IPP_LIBRARIES + ${IPP_LIBRARIES} + ${IPP_LIB_PREFIX}irc${CMAKE_SHARED_LIBRARY_SUFFIX} + ${IPP_LIB_PREFIX}imf${CMAKE_SHARED_LIBRARY_SUFFIX} + ${IPP_LIB_PREFIX}svml${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() + set(IPP_LIBRARIES ${IPP_LIBRARIES} PARENT_SCOPE) return() endfunction() @@ -208,18 +215,38 @@ function(set_ipp_variables _LATEST_VERSION) set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/include PARENT_SCOPE) if (APPLE) - set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib PARENT_SCOPE) + set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib) elseif (IPP_X64) if(NOT EXISTS ${IPP_ROOT_DIR}/lib/intel64) message(SEND_ERROR "IPP EM64T libraries not found") endif() - set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib/intel64 PARENT_SCOPE) + set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib/intel64) else() if(NOT EXISTS ${IPP_ROOT_DIR}/lib/ia32) message(SEND_ERROR "IPP IA32 libraries not found") endif() - set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib/ia32 PARENT_SCOPE) + set(IPP_LIBRARY_DIRS ${IPP_ROOT_DIR}/lib/ia32) + endif() + + if (UNIX) + get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../lib REALPATH) + if (IPP_X64) + if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/intel64) + message(SEND_ERROR "Intel compiler EM64T libraries not found") + endif() + set(IPP_LIBRARY_DIRS + ${IPP_LIBRARY_DIRS} + ${INTEL_COMPILER_LIBRARY_DIR}/intel64) + else() + if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/ia32) + message(SEND_ERROR "Intel compiler IA32 libraries not found") + endif() + set(IPP_LIBRARY_DIRS + ${IPP_LIBRARY_DIRS} + ${INTEL_COMPILER_LIBRARY_DIR}/ia32) + endif() endif() + set(IPP_LIBRARY_DIRS ${IPP_LIBRARY_DIRS} PARENT_SCOPE) # set IPP_LIBRARIES variable (7.x or 8.x lib names) set_ipp_new_libraries(${_LATEST_VERSION}) diff --git a/cmake/OpenCVGenAndroidMK.cmake b/cmake/OpenCVGenAndroidMK.cmake index 45193a2732..ee52fa6886 100644 --- a/cmake/OpenCVGenAndroidMK.cmake +++ b/cmake/OpenCVGenAndroidMK.cmake @@ -59,6 +59,24 @@ if(ANDROID) ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "libcu") ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "libnpp") + if(HAVE_CUDA) + # CUDA runtime libraries and are required always + set(culibs ${CUDA_LIBRARIES}) + + # right now NPP is requared always too + list(INSERT culibs 0 ${CUDA_npp_LIBRARY}) + + if(HAVE_CUFFT) + list(INSERT culibs 0 ${CUDA_cufft_LIBRARY}) + endif() + + if(HAVE_CUBLAS) + list(INSERT culibs 0 ${CUDA_cublas_LIBRARY}) + endif() + endif() + + ocv_convert_to_lib_name(CUDA_RUNTIME_LIBS_CONFIGMAKE ${culibs}) + # split 3rdparty libs and modules foreach(mod ${OPENCV_MODULES_CONFIGMAKE}) if(NOT mod MATCHES "^opencv_.+$") @@ -69,6 +87,10 @@ if(ANDROID) list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) endif() + if(ENABLE_DYNAMIC_CUDA) + set(OPENCV_DYNAMICUDA_MODULE_CONFIGMAKE "dynamicuda") + endif() + # GPU module enabled separately list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE "opencv_gpu") list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE "opencv_dynamicuda") @@ -84,6 +106,7 @@ if(ANDROID) string(REPLACE ";" " " ${lst} "${${lst}}") endforeach() string(REPLACE "opencv_" "" OPENCV_MODULES_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}") + string(REPLACE ";" " " CUDA_RUNTIME_LIBS_CONFIGMAKE "${CUDA_RUNTIME_LIBS_CONFIGMAKE}") # prepare 3rd-party component list without TBB for armeabi and mips platforms. TBB is useless there. set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) @@ -105,7 +128,7 @@ if(ANDROID) set(OPENCV_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/lib/\$(OPENCV_TARGET_ARCH_ABI)") set(OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/3rdparty/lib/\$(OPENCV_TARGET_ARCH_ABI)") - configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/OpenCV.mk" IMMEDIATE @ONLY) + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/OpenCV.mk" @ONLY) # ------------------------------------------------------------------------------------------- # Part 2/2: ${BIN_DIR}/unix-install/OpenCV.mk -> For use with "make install" @@ -115,6 +138,6 @@ if(ANDROID) set(OPENCV_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../libs/\$(OPENCV_TARGET_ARCH_ABI)") set(OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../3rdparty/libs/\$(OPENCV_TARGET_ARCH_ABI)") - configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk" IMMEDIATE @ONLY) + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk" @ONLY) install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk DESTINATION ${OPENCV_CONFIG_INSTALL_PATH} COMPONENT dev) endif(ANDROID) diff --git a/cmake/OpenCVGenConfig.cmake b/cmake/OpenCVGenConfig.cmake index 18411e8786..cdf418ec82 100644 --- a/cmake/OpenCVGenConfig.cmake +++ b/cmake/OpenCVGenConfig.cmake @@ -83,9 +83,9 @@ endif() export(TARGETS ${OpenCVModules_TARGETS} FILE "${CMAKE_BINARY_DIR}/OpenCVModules${modules_file_suffix}.cmake") -configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" IMMEDIATE @ONLY) +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" @ONLY) #support for version checking when finding opencv. find_package(OpenCV 2.3.1 EXACT) should now work. -configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig-version.cmake" IMMEDIATE @ONLY) +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig-version.cmake" @ONLY) # -------------------------------------------------------------------------------------------- # Part 2/3: ${BIN_DIR}/unix-install/OpenCVConfig.cmake -> For use *with* "make install" @@ -98,8 +98,8 @@ if(INSTALL_TO_MANGLED_PATHS) set(OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE "\"\${OpenCV_INSTALL_PATH}/${OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE}\"") endif() -configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" IMMEDIATE @ONLY) -configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake" IMMEDIATE @ONLY) +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig.cmake" @ONLY) +configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCVConfig-version.cmake" @ONLY) if(UNIX) # ANDROID configuration is created here also #http://www.vtk.org/Wiki/CMake/Tutorials/Packaging reference @@ -131,8 +131,8 @@ if(WIN32) set(OpenCV2_INCLUDE_DIRS_CONFIGCMAKE "\"\"") exec_program(mkdir ARGS "-p \"${CMAKE_BINARY_DIR}/win-install/\"" OUTPUT_VARIABLE RET_VAL) - configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" IMMEDIATE @ONLY) - configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" IMMEDIATE @ONLY) + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" @ONLY) + configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCVConfig-version.cmake.in" "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig-version.cmake" @ONLY) if(BUILD_SHARED_LIBS) install(FILES "${CMAKE_BINARY_DIR}/win-install/OpenCVConfig.cmake" DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib" COMPONENT dev) install(EXPORT OpenCVModules DESTINATION "${OpenCV_INSTALL_BINARIES_PREFIX}lib" FILE OpenCVModules${modules_file_suffix}.cmake COMPONENT dev) diff --git a/cmake/OpenCVGenPkgconfig.cmake b/cmake/OpenCVGenPkgconfig.cmake index 13b1e44970..fa57db9d3c 100644 --- a/cmake/OpenCVGenPkgconfig.cmake +++ b/cmake/OpenCVGenPkgconfig.cmake @@ -78,7 +78,7 @@ else() endif() configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/opencv-XXX.pc.in" "${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME}" - @ONLY IMMEDIATE) + @ONLY) if(UNIX AND NOT ANDROID) install(FILES ${CMAKE_BINARY_DIR}/unix-install/${OPENCV_PC_FILE_NAME} DESTINATION ${OPENCV_LIB_INSTALL_PATH}/pkgconfig COMPONENT dev) diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 6734462fc2..03818018d9 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -135,13 +135,13 @@ macro(ocv_add_module _name) # parse list of dependencies if("${ARGV1}" STREQUAL "INTERNAL" OR "${ARGV1}" STREQUAL "BINDINGS") - set(OPENCV_MODULE_${the_module}_CLASS "${ARGV1}" CACHE INTERNAL "The cathegory of the module") + set(OPENCV_MODULE_${the_module}_CLASS "${ARGV1}" CACHE INTERNAL "The category of the module") set(__ocv_argn__ ${ARGN}) list(REMOVE_AT __ocv_argn__ 0) ocv_add_dependencies(${the_module} ${__ocv_argn__}) unset(__ocv_argn__) else() - set(OPENCV_MODULE_${the_module}_CLASS "PUBLIC" CACHE INTERNAL "The cathegory of the module") + set(OPENCV_MODULE_${the_module}_CLASS "PUBLIC" CACHE INTERNAL "The category of the module") ocv_add_dependencies(${the_module} ${ARGN}) if(BUILD_${the_module}) set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} "${the_module}" CACHE INTERNAL "List of OpenCV modules marked for export") @@ -711,6 +711,9 @@ function(ocv_add_perf_tests) else(OCV_DEPENDENCIES_FOUND) # TODO: warn about unsatisfied dependencies endif(OCV_DEPENDENCIES_FOUND) + if(INSTALL_TESTS) + install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_TEST_INSTALL_PATH} COMPONENT tests) + endif() endif() endfunction() @@ -764,6 +767,10 @@ function(ocv_add_accuracy_tests) else(OCV_DEPENDENCIES_FOUND) # TODO: warn about unsatisfied dependencies endif(OCV_DEPENDENCIES_FOUND) + + if(INSTALL_TESTS) + install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_TEST_INSTALL_PATH} COMPONENT tests) + endif() endif() endfunction() @@ -804,7 +811,7 @@ function(ocv_add_samples) if(INSTALL_C_EXAMPLES AND NOT WIN32 AND EXISTS "${samples_path}") file(GLOB sample_files "${samples_path}/*") install(FILES ${sample_files} - DESTINATION share/OpenCV/samples/${module_id} + DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/${module_id} PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples) endif() endfunction() diff --git a/cmake/OpenCVPackaging.cmake b/cmake/OpenCVPackaging.cmake index 4a81c255bf..91f5940960 100644 --- a/cmake/OpenCVPackaging.cmake +++ b/cmake/OpenCVPackaging.cmake @@ -2,24 +2,29 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") set(CPACK_set_DESTDIR "on") if(NOT OPENCV_CUSTOM_PACKAGE_INFO) - set(CPACK_PACKAGE_DESCRIPTION "Open Computer Vision Library") - set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OpenCV") + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open Computer Vision Library") + set(CPACK_PACKAGE_DESCRIPTION +"OpenCV (Open Source Computer Vision Library) is an open source computer vision +and machine learning software library. OpenCV was built to provide a common +infrastructure for computer vision applications and to accelerate the use of +machine perception in the commercial products. Being a BSD-licensed product, +OpenCV makes it easy for businesses to utilize and modify the code.") set(CPACK_PACKAGE_VENDOR "OpenCV Foundation") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_CONTACT "admin@opencv.org") + set(CPACK_PACKAGE_VERSION_MAJOR "${OPENCV_VERSION_MAJOR}") + set(CPACK_PACKAGE_VERSION_MINOR "${OPENCV_VERSION_MINOR}") + set(CPACK_PACKAGE_VERSION_PATCH "${OPENCV_VERSION_PATCH}") + set(CPACK_PACKAGE_VERSION "${OPENCV_VCSVERSION}") endif(NOT OPENCV_CUSTOM_PACKAGE_INFO) -set(CPACK_PACKAGE_VERSION_MAJOR "${OPENCV_VERSION_MAJOR}") -set(CPACK_PACKAGE_VERSION_MINOR "${OPENCV_VERSION_MINOR}") -set(CPACK_PACKAGE_VERSION_PATCH "${OPENCV_VERSION_PATCH}") - #arch if(X86) set(CPACK_DEBIAN_ARCHITECTURE "i386") set(CPACK_RPM_PACKAGE_ARCHITECTURE "i686") elseif(X86_64) set(CPACK_DEBIAN_ARCHITECTURE "amd64") - set(CPACK_RPM_PACKAGE_ARCHITECTURE "amd64") + set(CPACK_RPM_PACKAGE_ARCHITECTURE "x86_64") elseif(ARM) set(CPACK_DEBIAN_ARCHITECTURE "armhf") set(CPACK_RPM_PACKAGE_ARCHITECTURE "armhf") @@ -41,11 +46,16 @@ set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${OPENCV_VCSVERSION}-$ #rpm options set(CPACK_RPM_COMPONENT_INSTALL TRUE) -set(CPACK_RPM_PACKAGE_LICENSE ${CPACK_RESOURCE_FILE_LICENSE}) +set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) +set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION}) +set(CPACK_RPM_PACKAGE_URL "http://opencv.org") +set(CPACK_RPM_PACKAGE_LICENSE "BSD") #deb options set(CPACK_DEB_COMPONENT_INSTALL TRUE) -set(CPACK_DEBIAN_PACKAGE_PRIORITY "extra") +set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") +set(CPACK_DEBIAN_PACKAGE_SECTION "libs") +set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://opencv.org") #depencencies set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS TRUE) @@ -54,25 +64,36 @@ set(CPACK_COMPONENT_dev_DEPENDS libs) set(CPACK_COMPONENT_docs_DEPENDS libs) set(CPACK_COMPONENT_java_DEPENDS libs) set(CPACK_COMPONENT_python_DEPENDS libs) +set(CPACK_COMPONENT_tests_DEPENDS libs) + +if(HAVE_CUDA) + string(REPLACE "." "-" cuda_version_suffix ${CUDA_VERSION}) + set(CPACK_DEB_libs_PACKAGE_DEPENDS "cuda-core-libs-${cuda_version_suffix}, cuda-extra-libs-${cuda_version_suffix}") + set(CPACK_COMPONENT_dev_DEPENDS libs) + set(CPACK_DEB_dev_PACKAGE_DEPENDS "cuda-headers-${cuda_version_suffix}") +endif() if(NOT OPENCV_CUSTOM_PACKAGE_INFO) set(CPACK_COMPONENT_libs_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}") set(CPACK_COMPONENT_libs_DESCRIPTION "Open Computer Vision Library") set(CPACK_COMPONENT_python_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-python") - set(CPACK_COMPONENT_python_DESCRIPTION "Python bindings for Open Computer Vision Library") + set(CPACK_COMPONENT_python_DESCRIPTION "Python bindings for Open Source Computer Vision Library") set(CPACK_COMPONENT_java_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-java") - set(CPACK_COMPONENT_java_DESCRIPTION "Java bindings for Open Computer Vision Library") + set(CPACK_COMPONENT_java_DESCRIPTION "Java bindings for Open Source Computer Vision Library") set(CPACK_COMPONENT_dev_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-dev") - set(CPACK_COMPONENT_dev_DESCRIPTION "Development files for Open Computer Vision Library") + set(CPACK_COMPONENT_dev_DESCRIPTION "Development files for Open Source Computer Vision Library") set(CPACK_COMPONENT_docs_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-docs") - set(CPACK_COMPONENT_docs_DESCRIPTION "Documentation for Open Computer Vision Library") + set(CPACK_COMPONENT_docs_DESCRIPTION "Documentation for Open Source Computer Vision Library") set(CPACK_COMPONENT_samples_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-samples") - set(CPACK_COMPONENT_samples_DESCRIPTION "Samples for Open Computer Vision Library") + set(CPACK_COMPONENT_samples_DESCRIPTION "Samples for Open Source Computer Vision Library") + + set(CPACK_COMPONENT_tests_DISPLAY_NAME "lib${CMAKE_PROJECT_NAME}-tests") + set(CPACK_COMPONENT_tests_DESCRIPTION "Accuracy and performance tests for Open Source Computer Vision Library") endif(NOT OPENCV_CUSTOM_PACKAGE_INFO) if(NOT OPENCV_CUSTOM_PACKAGE_LAYOUT) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 13461e82c1..9fa94bb8bd 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -448,6 +448,20 @@ macro(ocv_convert_to_full_paths VAR) endmacro() +# convert list of paths to libraries names without lib prefix +macro(ocv_convert_to_lib_name var) + set(__tmp "") + foreach(path ${ARGN}) + get_filename_component(__tmp_name "${path}" NAME_WE) + string(REGEX REPLACE "^lib" "" __tmp_name ${__tmp_name}) + list(APPEND __tmp "${__tmp_name}") + endforeach() + set(${var} ${__tmp}) + unset(__tmp) + unset(__tmp_name) +endmacro() + + # add install command function(ocv_install_target) install(TARGETS ${ARGN}) diff --git a/cmake/templates/OpenCV.mk.in b/cmake/templates/OpenCV.mk.in index 0fd7b9e058..16fc4c9ccb 100644 --- a/cmake/templates/OpenCV.mk.in +++ b/cmake/templates/OpenCV.mk.in @@ -2,6 +2,13 @@ # you might need to define NDK_USE_CYGPATH=1 before calling the ndk-build USER_LOCAL_PATH:=$(LOCAL_PATH) + +USER_LOCAL_C_INCLUDES:=$(LOCAL_C_INCLUDES) +USER_LOCAL_CFLAGS:=$(LOCAL_CFLAGS) +USER_LOCAL_STATIC_LIBRARIES:=$(LOCAL_STATIC_LIBRARIES) +USER_LOCAL_SHARED_LIBRARIES:=$(LOCAL_SHARED_LIBRARIES) +USER_LOCAL_LDLIBS:=$(LOCAL_LDLIBS) + LOCAL_PATH:=$(subst ?,,$(firstword ?$(subst \, ,$(subst /, ,$(call my-dir))))) OPENCV_TARGET_ARCH_ABI:=$(TARGET_ARCH_ABI) @@ -13,7 +20,7 @@ OPENCV_BASEDIR:=@OPENCV_BASE_INCLUDE_DIR_CONFIGCMAKE@ OPENCV_LOCAL_C_INCLUDES:=@OPENCV_INCLUDE_DIRS_CONFIGCMAKE@ OPENCV_MODULES:=@OPENCV_MODULES_CONFIGMAKE@ -OPENCV_HAVE_GPU_MODULE=@OPENCV_HAVE_GPU_MODULE_CONFIGMAKE@ +OPENCV_HAVE_GPU_MODULE:=@OPENCV_HAVE_GPU_MODULE_CONFIGMAKE@ OPENCV_USE_GPU_MODULE:= ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) @@ -22,9 +29,12 @@ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) OPENCV_USE_GPU_MODULE:=on endif endif + OPENCV_DYNAMICUDA_MODULE:=@OPENCV_DYNAMICUDA_MODULE_CONFIGMAKE@ +else + OPENCV_DYNAMICUDA_MODULE:= endif -CUDA_RUNTIME_LIBS:=cufft npps nppi nppc cudart +CUDA_RUNTIME_LIBS:=@CUDA_RUNTIME_LIBS_CONFIGMAKE@ ifeq ($(OPENCV_LIB_TYPE),) OPENCV_LIB_TYPE:=@OPENCV_LIBTYPE_CONFIGMAKE@ @@ -60,7 +70,7 @@ else endif endif -ifeq (${OPENCV_CAMERA_MODULES},on) +ifeq ($(OPENCV_CAMERA_MODULES),on) ifeq ($(TARGET_ARCH_ABI),armeabi) OPENCV_CAMERA_MODULES:=@OPENCV_CAMERA_LIBS_ARMEABI_CONFIGCMAKE@ endif @@ -91,6 +101,13 @@ define add_opencv_module include $(PREBUILT_$(OPENCV_LIB_TYPE)_LIBRARY) endef +define add_cuda_module + include $(CLEAR_VARS) + LOCAL_MODULE:=$1 + LOCAL_SRC_FILES:=$(CUDA_TOOLKIT_DIR)/targets/armv7-linux-androideabi/lib/lib$1.so + include $(PREBUILT_SHARED_LIBRARY) +endef + define add_opencv_3rdparty_component include $(CLEAR_VARS) LOCAL_MODULE:=$1 @@ -108,6 +125,17 @@ endef ifeq ($(OPENCV_MK_$(OPENCV_TARGET_ARCH_ABI)_ALREADY_INCLUDED),) ifeq ($(OPENCV_INSTALL_MODULES),on) $(foreach module,$(OPENCV_LIBS),$(eval $(call add_opencv_module,$(module)))) + ifneq ($(OPENCV_DYNAMICUDA_MODULE),) + ifeq ($(OPENCV_LIB_TYPE),SHARED) + $(eval $(call add_opencv_module,$(OPENCV_DYNAMICUDA_MODULE))) + endif + endif + endif + + ifeq ($(OPENCV_USE_GPU_MODULE),on) + ifeq ($(INSTALL_CUDA_LIBRARIES),on) + $(foreach module,$(CUDA_RUNTIME_LIBS),$(eval $(call add_cuda_module,$(module)))) + endif endif $(foreach module,$(OPENCV_3RDPARTY_COMPONENTS),$(eval $(call add_opencv_3rdparty_component,$(module)))) @@ -136,6 +164,13 @@ ifeq ($(OPENCV_LOCAL_CFLAGS),) endif include $(CLEAR_VARS) + +LOCAL_C_INCLUDES:=$(USER_LOCAL_C_INCLUDES) +LOCAL_CFLAGS:=$(USER_LOCAL_CFLAGS) +LOCAL_STATIC_LIBRARIES:=$(USER_LOCAL_STATIC_LIBRARIES) +LOCAL_SHARED_LIBRARIES:=$(USER_LOCAL_SHARED_LIBRARIES) +LOCAL_LDLIBS:=$(USER_LOCAL_LDLIBS) + LOCAL_C_INCLUDES += $(OPENCV_LOCAL_C_INCLUDES) LOCAL_CFLAGS += $(OPENCV_LOCAL_CFLAGS) @@ -145,6 +180,11 @@ endif ifeq ($(OPENCV_INSTALL_MODULES),on) LOCAL_$(OPENCV_LIB_TYPE)_LIBRARIES += $(foreach mod, $(OPENCV_LIBS), opencv_$(mod)) + ifeq ($(OPENCV_LIB_TYPE),SHARED) + ifneq ($(OPENCV_DYNAMICUDA_MODULE),) + LOCAL_$(OPENCV_LIB_TYPE)_LIBRARIES += $(OPENCV_DYNAMICUDA_MODULE) + endif + endif else LOCAL_LDLIBS += -L$(call host-path,$(LOCAL_PATH)/$(OPENCV_LIBS_DIR)) $(foreach lib, $(OPENCV_LIBS), -lopencv_$(lib)) endif @@ -156,8 +196,12 @@ endif LOCAL_LDLIBS += $(foreach lib,$(OPENCV_EXTRA_COMPONENTS), -l$(lib)) ifeq ($(OPENCV_USE_GPU_MODULE),on) + ifeq ($(INSTALL_CUDA_LIBRARIES),on) + LOCAL_SHARED_LIBRARIES += $(foreach mod, $(CUDA_RUNTIME_LIBS), $(mod)) + else + LOCAL_LDLIBS += -L$(CUDA_TOOLKIT_DIR)/targets/armv7-linux-androideabi/lib $(foreach lib, $(CUDA_RUNTIME_LIBS), -l$(lib)) + endif LOCAL_STATIC_LIBRARIES+=libopencv_gpu - LOCAL_LDLIBS += -L$(CUDA_TOOLKIT_DIR)/lib $(foreach lib, $(CUDA_RUNTIME_LIBS), -l$(lib)) endif #restore the LOCAL_PATH diff --git a/cmake/templates/cvconfig.h.in b/cmake/templates/cvconfig.h.in index a6cee63684..d1c9e65d3d 100644 --- a/cmake/templates/cvconfig.h.in +++ b/cmake/templates/cvconfig.h.in @@ -161,6 +161,6 @@ /* Xine video library */ #cmakedefine HAVE_XINE -/* Define to 1 if your processor stores words with the most significant byte +/* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #cmakedefine WORDS_BIGENDIAN diff --git a/cmake/templates/opencv_run_all_tests_android.sh.in b/cmake/templates/opencv_run_all_tests_android.sh.in new file mode 100644 index 0000000000..93373fa964 --- /dev/null +++ b/cmake/templates/opencv_run_all_tests_android.sh.in @@ -0,0 +1,51 @@ +#!/bin/sh + +BASE_DIR=`dirname $0` +OPENCV_TEST_PATH=$BASE_DIR/@TEST_PATH@ +OPENCV_TEST_DATA_PATH=$BASE_DIR/sdk/etc/testdata/ + +if [ $# -ne 1 ]; then + echo "Device architecture is not preset in command line" + echo "Tests are available for architectures: `ls -m ${OPENCV_TEST_PATH}`" + echo "Usage: $0 " + return 1 +else + TARGET_ARCH=$1 +fi + +if [ -z `which adb` ]; then + echo "adb command was not found in PATH" + return 1 +fi + +adb push $OPENCV_TEST_DATA_PATH /sdcard/opencv_testdata + +adb shell "mkdir -p /data/local/tmp/opencv_test" +SUMMARY_STATUS=0 +for t in "$OPENCV_TEST_PATH/$TARGET_ARCH/"opencv_test_* "$OPENCV_TEST_PATH/$TARGET_ARCH/"opencv_perf_*; +do + test_name=`basename "$t"` + report="$test_name-`date --rfc-3339=date`.xml" + adb push $t /data/local/tmp/opencv_test/ + adb shell "export OPENCV_TEST_DATA_PATH=/sdcard/opencv_testdata && /data/local/tmp/opencv_test/$test_name --perf_min_samples=1 --perf_force_samples=1 --gtest_output=xml:/data/local/tmp/opencv_test/$report" + adb pull "/data/local/tmp/opencv_test/$report" $report + TEST_STATUS=0 + if [ -e $report ]; then + if [ `grep -c " - #include - - using namespace cv; - - int main( int argc, char** argv ) - { - Mat image; - image = imread( argv[1], 1 ); - - if( argc != 2 || !image.data ) - { - printf( "No image data \n" ); - return -1; - } - - namedWindow( "Display Image", CV_WINDOW_AUTOSIZE ); - imshow( "Display Image", image ); - - waitKey(0); - - return 0; - } + #include + #include + + using namespace cv; + + int main(int argc, char** argv ) + { + if ( argc != 2 ) + { + printf("usage: DisplayImage.out \n"); + return -1; + } + + Mat image; + image = imread( argv[1], 1 ); + + if ( !image.data ) + { + printf("No image data \n"); + return -1; + } + namedWindow("Display Image", CV_WINDOW_AUTOSIZE ); + imshow("Display Image", image); + + waitKey(0); + + return 0; + } Create a CMake file --------------------- diff --git a/doc/tutorials/introduction/load_save_image/load_save_image.rst b/doc/tutorials/introduction/load_save_image/load_save_image.rst index 50fb9ea37f..675387efb1 100644 --- a/doc/tutorials/introduction/load_save_image/load_save_image.rst +++ b/doc/tutorials/introduction/load_save_image/load_save_image.rst @@ -100,7 +100,7 @@ Explanation imshow( imageName, image ); imshow( "Gray image", gray_image ); -#. Add add the *waitKey(0)* function call for the program to wait forever for an user key press. +#. Add the *waitKey(0)* function call for the program to wait forever for an user key press. Result diff --git a/doc/tutorials/tutorials.rst b/doc/tutorials/tutorials.rst index cbc51c1956..54cc91acb8 100644 --- a/doc/tutorials/tutorials.rst +++ b/doc/tutorials/tutorials.rst @@ -186,6 +186,21 @@ As always, we would be happy to hear your comments and receive your contribution :width: 80pt :alt: gpu icon +* :ref:`Table-Of-Content-Viz` + + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + =========== ======================================================= + |Viz| These tutorials show how to use Viz module effectively. + + =========== ======================================================= + + .. |Viz| image:: images/viz.jpg + :height: 80pt + :width: 80pt + :alt: viz icon + * :ref:`Table-Of-Content-General` .. tabularcolumns:: m{100pt} m{300pt} @@ -221,4 +236,5 @@ As always, we would be happy to hear your comments and receive your contribution gpu/table_of_content_gpu/table_of_content_gpu contrib/table_of_content_contrib/table_of_content_contrib ios/table_of_content_ios/table_of_content_ios + viz/table_of_content_viz/table_of_content_viz general/table_of_content_general/table_of_content_general diff --git a/doc/tutorials/viz/creating_widgets/creating_widgets.rst b/doc/tutorials/viz/creating_widgets/creating_widgets.rst new file mode 100644 index 0000000000..8858035c34 --- /dev/null +++ b/doc/tutorials/viz/creating_widgets/creating_widgets.rst @@ -0,0 +1,159 @@ +.. _creating_widgets: + +Creating Widgets +**************** + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * Create your own widgets using WidgetAccessor and VTK. + * Show your widget in the visualization window. + +Code +==== + +You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/creating_widgets.cpp>`. + +.. code-block:: cpp + + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + + using namespace cv; + using namespace std; + + /** + * @class WTriangle + * @brief Defining our own 3D Triangle widget + */ + class WTriangle : public viz::Widget3D + { + public: + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + }; + + /** + * @function WTriangle::WTriangle + */ + WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color) + { + // Create a triangle + vtkSmartPointer points = vtkSmartPointer::New(); + points->InsertNextPoint(pt1.x, pt1.y, pt1.z); + points->InsertNextPoint(pt2.x, pt2.y, pt2.z); + points->InsertNextPoint(pt3.x, pt3.y, pt3.z); + + vtkSmartPointer triangle = vtkSmartPointer::New(); + triangle->GetPointIds()->SetId(0,0); + triangle->GetPointIds()->SetId(1,1); + triangle->GetPointIds()->SetId(2,2); + + vtkSmartPointer cells = vtkSmartPointer::New(); + cells->InsertNextCell(triangle); + + // Create a polydata object + vtkSmartPointer polyData = vtkSmartPointer::New(); + + // Add the geometry and topology to the polydata + polyData->SetPoints(points); + polyData->SetPolys(cells); + + // Create mapper and actor + vtkSmartPointer mapper = vtkSmartPointer::New(); + #if VTK_MAJOR_VERSION <= 5 + mapper->SetInput(polyData); + #else + mapper->SetInputData(polyData); + #endif + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + // Store this actor in the widget in order that visualizer can access it + viz::WidgetAccessor::setProp(*this, actor); + + // Set the color of the widget. This has to be called after WidgetAccessor. + setColor(color); + } + + /** + * @function main + */ + int main() + { + /// Create a window + viz::Viz3d myWindow("Creating Widgets"); + + /// Create a triangle widget + WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); + + /// Show widget in the visualizer window + myWindow.showWidget("TRIANGLE", tw); + + /// Start event loop + myWindow.spin(); + + return 0; + } + +Explanation +=========== + +Here is the general structure of the program: + +* Extend Widget3D class to create a new 3D widget. + +.. code-block:: cpp + + class WTriangle : public viz::Widget3D + { + public: + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); + }; + +* Assign a VTK actor to the widget. + +.. code-block:: cpp + + // Store this actor in the widget in order that visualizer can access it + viz::WidgetAccessor::setProp(*this, actor); + +* Set color of the widget. + +.. code-block:: cpp + + // Set the color of the widget. This has to be called after WidgetAccessor. + setColor(color); + +* Construct a triangle widget and display it in the window. + +.. code-block:: cpp + + /// Create a triangle widget + WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); + + /// Show widget in the visualizer window + myWindow.showWidget("TRIANGLE", tw); + +Results +======= + +Here is the result of the program. + +.. image:: images/red_triangle.png + :alt: Creating Widgets + :align: center diff --git a/doc/tutorials/viz/creating_widgets/images/red_triangle.png b/doc/tutorials/viz/creating_widgets/images/red_triangle.png new file mode 100644 index 0000000000..7da6ad0602 Binary files /dev/null and b/doc/tutorials/viz/creating_widgets/images/red_triangle.png differ diff --git a/doc/tutorials/viz/launching_viz/images/window_demo.png b/doc/tutorials/viz/launching_viz/images/window_demo.png new file mode 100644 index 0000000000..b853fe29da Binary files /dev/null and b/doc/tutorials/viz/launching_viz/images/window_demo.png differ diff --git a/doc/tutorials/viz/launching_viz/launching_viz.rst b/doc/tutorials/viz/launching_viz/launching_viz.rst new file mode 100644 index 0000000000..a3dd5d93c6 --- /dev/null +++ b/doc/tutorials/viz/launching_viz/launching_viz.rst @@ -0,0 +1,118 @@ +.. _launching_viz: + +Launching Viz +************* + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * Open a visualization window. + * Access a window by its name. + * Start event loop. + * Start event loop for a given amount of time. + +Code +==== + +You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/launching_viz.cpp>`. + +.. code-block:: cpp + + #include + #include + + using namespace cv; + using namespace std; + + /** + * @function main + */ + int main() + { + /// Create a window + viz::Viz3d myWindow("Viz Demo"); + + /// Start event loop + myWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "First event loop is over" << endl; + + /// Access window via its name + viz::Viz3d sameWindow = viz::getWindowByName("Viz Demo"); + + /// Start event loop + sameWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "Second event loop is over" << endl; + + /// Event loop is over when pressed q, Q, e, E + /// Start event loop once for 1 millisecond + sameWindow.spinOnce(1, true); + while(!sameWindow.wasStopped()) + { + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); + } + + /// Once more event loop is stopped + cout << "Last event loop is over" << endl; + return 0; + } + +Explanation +=========== + +Here is the general structure of the program: + +* Create a window. + +.. code-block:: cpp + + /// Create a window + viz::Viz3d myWindow("Viz Demo"); + +* Start event loop. This event loop will run until user terminates it by pressing **e**, **E**, **q**, **Q**. + +.. code-block:: cpp + + /// Start event loop + myWindow.spin(); + +* Access same window via its name. Since windows are implicitly shared, **sameWindow** is exactly the same with **myWindow**. If the name does not exist, a new window is created. + +.. code-block:: cpp + + /// Access window via its name + viz::Viz3d sameWindow = viz::get("Viz Demo"); + +* Start a controlled event loop. Once it starts, **wasStopped** is set to false. Inside the while loop, in each iteration, **spinOnce** is called to prevent event loop from completely stopping. Inside the while loop, user can execute other statements including those which interact with the window. + +.. code-block:: cpp + + /// Event loop is over when pressed q, Q, e, E + /// Start event loop once for 1 millisecond + sameWindow.spinOnce(1, true); + while(!sameWindow.wasStopped()) + { + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); + } + +Results +======= + +Here is the result of the program. + +.. image:: images/window_demo.png + :alt: Launching Viz + :align: center diff --git a/doc/tutorials/viz/table_of_content_viz/images/facedetect.jpg b/doc/tutorials/viz/table_of_content_viz/images/facedetect.jpg new file mode 100644 index 0000000000..788b7d8262 Binary files /dev/null and b/doc/tutorials/viz/table_of_content_viz/images/facedetect.jpg differ diff --git a/doc/tutorials/viz/table_of_content_viz/images/image_effects.png b/doc/tutorials/viz/table_of_content_viz/images/image_effects.png new file mode 100644 index 0000000000..1a675ce74f Binary files /dev/null and b/doc/tutorials/viz/table_of_content_viz/images/image_effects.png differ diff --git a/doc/tutorials/viz/table_of_content_viz/images/intro.png b/doc/tutorials/viz/table_of_content_viz/images/intro.png new file mode 100644 index 0000000000..4f54cfb916 Binary files /dev/null and b/doc/tutorials/viz/table_of_content_viz/images/intro.png differ diff --git a/doc/tutorials/viz/table_of_content_viz/table_of_content_viz.rst b/doc/tutorials/viz/table_of_content_viz/table_of_content_viz.rst new file mode 100644 index 0000000000..c3d08fe17b --- /dev/null +++ b/doc/tutorials/viz/table_of_content_viz/table_of_content_viz.rst @@ -0,0 +1,94 @@ +.. _Table-Of-Content-Viz: + +**OpenCV Viz** +----------------------------------------------------------- + +.. include:: ../../definitions/tocDefinitions.rst + ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================== =============================================================================== + |VizLaunchingViz| **Title:** :ref:`launching_viz` + + *Compatibility:* > OpenCV 3.0.0 + + *Author:* Ozan Tonkal + + You will learn how to launch a viz window. + + ================== =============================================================================== + + .. |VizLaunchingViz| image:: ../launching_viz/images/window_demo.png + :height: 120pt + :width: 90pt + ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================ ============================================================================ + |WidgetPose| **Title:** :ref:`widget_pose` + + *Compatibility:* > OpenCV 3.0.0 + + *Author:* Ozan Tonkal + + You will learn how to change pose of a widget. + + ================ ============================================================================ + + .. |WidgetPose| image:: ../widget_pose/images/widgetpose.png + :height: 90pt + :width: 90pt + ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================== ============================================================================ + |Transformations| **Title:** :ref:`transformations` + + *Compatibility:* > OpenCV 3.0.0 + + *Author:* Ozan Tonkal + + You will learn how to transform between global and camera frames. + + ================== ============================================================================ + + .. |Transformations| image:: ../transformations/images/global_view_point.png + :height: 120pt + :width: 90pt + ++ + .. tabularcolumns:: m{100pt} m{300pt} + .. cssclass:: toctableopencv + + ================== ============================================================================ + |CreatingWidgets| **Title:** :ref:`creating_widgets` + + *Compatibility:* > OpenCV 3.0.0 + + *Author:* Ozan Tonkal + + You will learn how to create your own widgets. + + ================== ============================================================================ + + .. |CreatingWidgets| image:: ../creating_widgets/images/red_triangle.png + :height: 120pt + :width: 90pt + +.. raw:: latex + + \pagebreak + +.. toctree:: + :hidden: + + ../launching_viz/launching_viz + ../widget_pose/widget_pose + ../transformations/transformations + ../creating_widgets/creating_widgets diff --git a/doc/tutorials/viz/transformations/images/camera_view_point.png b/doc/tutorials/viz/transformations/images/camera_view_point.png new file mode 100644 index 0000000000..e2ac5b0f0d Binary files /dev/null and b/doc/tutorials/viz/transformations/images/camera_view_point.png differ diff --git a/doc/tutorials/viz/transformations/images/global_view_point.png b/doc/tutorials/viz/transformations/images/global_view_point.png new file mode 100644 index 0000000000..fc6de2c1a1 Binary files /dev/null and b/doc/tutorials/viz/transformations/images/global_view_point.png differ diff --git a/doc/tutorials/viz/transformations/transformations.rst b/doc/tutorials/viz/transformations/transformations.rst new file mode 100644 index 0000000000..d1f2d0c2e0 --- /dev/null +++ b/doc/tutorials/viz/transformations/transformations.rst @@ -0,0 +1,202 @@ +.. _transformations: + +Transformations +*************** + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * How to use makeTransformToGlobal to compute pose + * How to use makeCameraPose and Viz3d::setViewerPose + * How to visualize camera position by axes and by viewing frustum + +Code +==== + +You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/transformations.cpp>`. + +.. code-block:: cpp + + #include + #include + #include + + using namespace cv; + using namespace std; + + /** + * @function cvcloud_load + * @brief load bunny.ply + */ + Mat cvcloud_load() + { + Mat cloud(1, 1889, CV_32FC3); + ifstream ifs("bunny.ply"); + + string str; + for(size_t i = 0; i < 12; ++i) + getline(ifs, str); + + Point3f* data = cloud.ptr(); + float dummy1, dummy2; + for(size_t i = 0; i < 1889; ++i) + ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2; + + cloud *= 5.0f; + return cloud; + } + + /** + * @function main + */ + int main(int argn, char **argv) + { + if (argn < 2) + { + cout << "Usage: " << endl << "./transformations [ G | C ]" << endl; + return 1; + } + + bool camera_pov = (argv[1][0] == 'C'); + + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); + + /// Let's assume camera has the following properties + Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); + + /// We can get the pose of the cam using makeCameraPose + Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + + /// We can get the transformation matrix from camera coordinate system to global using + /// - makeTransformToGlobal. We need the axes of the camera + Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); + + /// Create a cloud widget. + Mat bunny_cloud = cvcloud_load(); + viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); + + /// Pose of the widget in camera frame + Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); + /// Pose of the widget in global frame + Affine3f cloud_pose_global = transform * cloud_pose; + + /// Visualize camera frame + if (!camera_pov) + { + viz::WCameraPosition cpw(0.5); // Coordinate axes + viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + myWindow.showWidget("CPW", cpw, cam_pose); + myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); + } + + /// Visualize widget + myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); + + /// Set the viewer pose to that of camera + if (camera_pov) + myWindow.setViewerPose(cam_pose); + + /// Start event loop. + myWindow.spin(); + + return 0; + } + + +Explanation +=========== + +Here is the general structure of the program: + +* Create a visualization window. + +.. code-block:: cpp + + /// Create a window + viz::Viz3d myWindow("Transformations"); + +* Get camera pose from camera position, camera focal point and y direction. + +.. code-block:: cpp + + /// Let's assume camera has the following properties + Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); + + /// We can get the pose of the cam using makeCameraPose + Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + +* Obtain transform matrix knowing the axes of camera coordinate system. + +.. code-block:: cpp + + /// We can get the transformation matrix from camera coordinate system to global using + /// - makeTransformToGlobal. We need the axes of the camera + Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); + +* Create a cloud widget from bunny.ply file + +.. code-block:: cpp + + /// Create a cloud widget. + Mat bunny_cloud = cvcloud_load(); + viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); + +* Given the pose in camera coordinate system, estimate the global pose. + +.. code-block:: cpp + + /// Pose of the widget in camera frame + Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); + /// Pose of the widget in global frame + Affine3f cloud_pose_global = transform * cloud_pose; + +* If the view point is set to be global, visualize camera coordinate frame and viewing frustum. + +.. code-block:: cpp + + /// Visualize camera frame + if (!camera_pov) + { + viz::WCameraPosition cpw(0.5); // Coordinate axes + viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + myWindow.showWidget("CPW", cpw, cam_pose); + myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); + } + +* Visualize the cloud widget with the estimated global pose + +.. code-block:: cpp + + /// Visualize widget + myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); + +* If the view point is set to be camera's, set viewer pose to **cam_pose**. + +.. code-block:: cpp + + /// Set the viewer pose to that of camera + if (camera_pov) + myWindow.setViewerPose(cam_pose); + +Results +======= + +#. Here is the result from the camera point of view. + + .. image:: images/camera_view_point.png + :alt: Camera Viewpoint + :align: center + +#. Here is the result from global point of view. + + .. image:: images/global_view_point.png + :alt: Global Viewpoint + :align: center diff --git a/doc/tutorials/viz/widget_pose/images/widgetpose.png b/doc/tutorials/viz/widget_pose/images/widgetpose.png new file mode 100644 index 0000000000..ef8a5937f9 Binary files /dev/null and b/doc/tutorials/viz/widget_pose/images/widgetpose.png differ diff --git a/doc/tutorials/viz/widget_pose/widget_pose.rst b/doc/tutorials/viz/widget_pose/widget_pose.rst new file mode 100644 index 0000000000..a4466bdedf --- /dev/null +++ b/doc/tutorials/viz/widget_pose/widget_pose.rst @@ -0,0 +1,162 @@ +.. _widget_pose: + +Pose of a widget +**************** + +Goal +==== + +In this tutorial you will learn how to + +.. container:: enumeratevisibleitemswithsquare + + * Add widgets to the visualization window + * Use Affine3 to set pose of a widget + * Rotating and translating a widget along an axis + +Code +==== + +You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/widget_pose.cpp>`. + +.. code-block:: cpp + + #include + #include + #include + + using namespace cv; + using namespace std; + + /** + * @function main + */ + int main() + { + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); + + /// Add line to represent (1,1,1) axis + viz::WLine axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f)); + axis.setRenderingProperty(viz::LINE_WIDTH, 4.0); + myWindow.showWidget("Line Widget", axis); + + /// Construct a cube widget + viz::WCube cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue()); + cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0); + + /// Display widget (update if already displayed) + myWindow.showWidget("Cube Widget", cube_widget); + + /// Rodrigues vector + Mat rot_vec = Mat::zeros(1,3,CV_32F); + float translation_phase = 0.0, translation = 0.0; + while(!myWindow.wasStopped()) + { + /* Rotation using rodrigues */ + /// Rotate around (1,1,1) + rot_vec.at(0,0) += CV_PI * 0.01f; + rot_vec.at(0,1) += CV_PI * 0.01f; + rot_vec.at(0,2) += CV_PI * 0.01f; + + /// Shift on (1,1,1) + translation_phase += CV_PI * 0.01f; + translation = sin(translation_phase); + + Mat rot_mat; + Rodrigues(rot_vec, rot_mat); + + /// Construct pose + Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); + + myWindow.setWidgetPose("Cube Widget", pose); + + myWindow.spinOnce(1, true); + } + + return 0; + } + +Explanation +=========== + +Here is the general structure of the program: + +* Create a visualization window. + +.. code-block:: cpp + + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + +* Show coordinate axes in the window using CoordinateSystemWidget. + +.. code-block:: cpp + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); + +* Display a line representing the axis (1,1,1). + +.. code-block:: cpp + + /// Add line to represent (1,1,1) axis + viz::WLine axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f)); + axis.setRenderingProperty(viz::LINE_WIDTH, 4.0); + myWindow.showWidget("Line Widget", axis); + +* Construct a cube. + +.. code-block:: cpp + + /// Construct a cube widget + viz::WCube cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue()); + cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0); + myWindow.showWidget("Cube Widget", cube_widget); + +* Create rotation matrix from rodrigues vector + +.. code-block:: cpp + + /// Rotate around (1,1,1) + rot_vec.at(0,0) += CV_PI * 0.01f; + rot_vec.at(0,1) += CV_PI * 0.01f; + rot_vec.at(0,2) += CV_PI * 0.01f; + + ... + + Mat rot_mat; + Rodrigues(rot_vec, rot_mat); + +* Use Affine3f to set pose of the cube. + +.. code-block:: cpp + + /// Construct pose + Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); + myWindow.setWidgetPose("Cube Widget", pose); + +* Animate the rotation using wasStopped and spinOnce + +.. code-block:: cpp + + while(!myWindow.wasStopped()) + { + ... + + myWindow.spinOnce(1, true); + } + +Results +======= + +Here is the result of the program. + +.. raw:: html + +
+ +
diff --git a/modules/contrib/src/rgbdodometry.cpp b/modules/contrib/src/rgbdodometry.cpp index 4e9d8c4df9..0b2b9518c4 100644 --- a/modules/contrib/src/rgbdodometry.cpp +++ b/modules/contrib/src/rgbdodometry.cpp @@ -115,7 +115,7 @@ void computeProjectiveMatrix( const Mat& ksi, Mat& Rt ) { CV_Assert( ksi.size() == Size(1,6) && ksi.type() == CV_64FC1 ); -#if defined(HAVE_EIGEN) && EIGEN_WORLD_VERSION == 3 +#if defined(HAVE_EIGEN) && EIGEN_WORLD_VERSION == 3 && (!defined _MSC_VER || !defined _M_X64 || _MSC_VER > 1500) const double* ksi_ptr = reinterpret_cast(ksi.ptr(0)); Eigen::Matrix twist, g; twist << 0., -ksi_ptr[2], ksi_ptr[1], ksi_ptr[3], diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index fe3eff33ab..d9de52da2f 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -25,7 +25,7 @@ endif() if(HAVE_CUDA) ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/include") - ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef) + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wshadow) endif() file(GLOB lib_cuda_hdrs "include/opencv2/${name}/cuda/*.hpp" "include/opencv2/${name}/cuda/*.h") diff --git a/modules/core/doc/basic_structures.rst b/modules/core/doc/basic_structures.rst index 6f9c10e1db..54a1f4261d 100644 --- a/modules/core/doc/basic_structures.rst +++ b/modules/core/doc/basic_structures.rst @@ -1355,7 +1355,7 @@ The method copies the matrix data to another matrix. Before copying the data, th so that the destination matrix is reallocated if needed. While ``m.copyTo(m);`` works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices. -When the operation mask is specified, and the ``Mat::create`` call shown above reallocated the matrix, the newly allocated matrix is initialized with all zeros before copying the data. +When the operation mask is specified, if the ``Mat::create`` call shown above reallocates the matrix, the newly allocated matrix is initialized with all zeros before copying the data. .. _Mat::convertTo: diff --git a/modules/core/include/opencv2/core/affine.hpp b/modules/core/include/opencv2/core/affine.hpp new file mode 100644 index 0000000000..827d044b87 --- /dev/null +++ b/modules/core/include/opencv2/core/affine.hpp @@ -0,0 +1,509 @@ +/*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) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, 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_CORE_AFFINE3_HPP__ +#define __OPENCV_CORE_AFFINE3_HPP__ + +#ifdef __cplusplus + +#include + +namespace cv +{ + template + class Affine3 + { + public: + typedef T float_type; + typedef Matx Mat3; + typedef Matx Mat4; + typedef Vec Vec3; + + Affine3(); + + //Augmented affine matrix + Affine3(const Mat4& affine); + + //Rotation matrix + Affine3(const Mat3& R, const Vec3& t = Vec3::all(0)); + + //Rodrigues vector + Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0)); + + //Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix + explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0)); + + //From 16th element array + explicit Affine3(const float_type* vals); + + static Affine3 Identity(); + + //Rotation matrix + void rotation(const Mat3& R); + + //Rodrigues vector + void rotation(const Vec3& rvec); + + //Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix; + void rotation(const Mat& data); + + void linear(const Mat3& L); + void translation(const Vec3& t); + + Mat3 rotation() const; + Mat3 linear() const; + Vec3 translation() const; + + //Rodrigues vector + Vec3 rvec() const; + + Affine3 inv(int method = cv::DECOMP_SVD) const; + + // a.rotate(R) is equivalent to Affine(R, 0) * a; + Affine3 rotate(const Mat3& R) const; + + // a.rotate(R) is equivalent to Affine(rvec, 0) * a; + Affine3 rotate(const Vec3& rvec) const; + + // a.translate(t) is equivalent to Affine(E, t) * a; + Affine3 translate(const Vec3& t) const; + + // a.concatenate(affine) is equivalent to affine * a; + Affine3 concatenate(const Affine3& affine) const; + + template operator Affine3() const; + + template Affine3 cast() const; + + Mat4 matrix; + +#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H + Affine3(const Eigen::Transform& affine); + Affine3(const Eigen::Transform& affine); + operator Eigen::Transform() const; + operator Eigen::Transform() const; +#endif + }; + + template static + Affine3 operator*(const Affine3& affine1, const Affine3& affine2); + + template static + V operator*(const Affine3& affine, const V& vector); + + typedef Affine3 Affine3f; + typedef Affine3 Affine3d; + + static Vec3f operator*(const Affine3f& affine, const Vec3f& vector); + static Vec3d operator*(const Affine3d& affine, const Vec3d& vector); + + template class DataType< Affine3<_Tp> > + { + public: + typedef Affine3<_Tp> value_type; + typedef Affine3::work_type> work_type; + typedef _Tp channel_type; + + enum { generic_type = 0, + depth = DataType::depth, + channels = 16, + fmt = DataType::fmt + ((channels - 1) << 8), + type = CV_MAKETYPE(depth, channels) + }; + + typedef Vec vec_type; + }; +} + + +/////////////////////////////////////////////////////////////////////////////////// +/// Implementaiton + +template inline +cv::Affine3::Affine3() + : matrix(Mat4::eye()) +{} + +template inline +cv::Affine3::Affine3(const Mat4& affine) + : matrix(affine) +{} + +template inline +cv::Affine3::Affine3(const Mat3& R, const Vec3& t) +{ + rotation(R); + translation(t); + matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; + matrix.val[15] = 1; +} + +template inline +cv::Affine3::Affine3(const Vec3& _rvec, const Vec3& t) +{ + rotation(_rvec); + translation(t); + matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; + matrix.val[15] = 1; +} + +template inline +cv::Affine3::Affine3(const cv::Mat& data, const Vec3& t) +{ + CV_Assert(data.type() == cv::DataType::type); + + if (data.cols == 4 && data.rows == 4) + { + data.copyTo(matrix); + return; + } + else if (data.cols == 4 && data.rows == 3) + { + rotation(data(Rect(0, 0, 3, 3))); + translation(data(Rect(3, 0, 1, 3))); + return; + } + + rotation(data); + translation(t); + matrix.val[12] = matrix.val[13] = matrix.val[14] = 0; + matrix.val[15] = 1; +} + +template inline +cv::Affine3::Affine3(const float_type* vals) : matrix(vals) +{} + +template inline +cv::Affine3 cv::Affine3::Identity() +{ + return Affine3(cv::Affine3::Mat4::eye()); +} + +template inline +void cv::Affine3::rotation(const Mat3& R) +{ + linear(R); +} + +template inline +void cv::Affine3::rotation(const Vec3& _rvec) +{ + double rx = _rvec[0], ry = _rvec[1], rz = _rvec[2]; + double theta = std::sqrt(rx*rx + ry*ry + rz*rz); + + if (theta < DBL_EPSILON) + rotation(Mat3::eye()); + else + { + const double I[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; + + double c = std::cos(theta); + double s = std::sin(theta); + double c1 = 1. - c; + double itheta = theta ? 1./theta : 0.; + + rx *= itheta; ry *= itheta; rz *= itheta; + + double rrt[] = { rx*rx, rx*ry, rx*rz, rx*ry, ry*ry, ry*rz, rx*rz, ry*rz, rz*rz }; + double _r_x_[] = { 0, -rz, ry, rz, 0, -rx, -ry, rx, 0 }; + Mat3 R; + + // R = cos(theta)*I + (1 - cos(theta))*r*rT + sin(theta)*[r_x] + // where [r_x] is [0 -rz ry; rz 0 -rx; -ry rx 0] + for(int k = 0; k < 9; ++k) + R.val[k] = static_cast(c*I[k] + c1*rrt[k] + s*_r_x_[k]); + + rotation(R); + } +} + +//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix; +template inline +void cv::Affine3::rotation(const cv::Mat& data) +{ + CV_Assert(data.type() == cv::DataType::type); + + if (data.cols == 3 && data.rows == 3) + { + Mat3 R; + data.copyTo(R); + rotation(R); + } + else if ((data.cols == 3 && data.rows == 1) || (data.cols == 1 && data.rows == 3)) + { + Vec3 _rvec; + data.reshape(1, 3).copyTo(_rvec); + rotation(_rvec); + } + else + CV_Assert(!"Input marix can be 3x3, 1x3 or 3x1"); +} + +template inline +void cv::Affine3::linear(const Mat3& L) +{ + matrix.val[0] = L.val[0]; matrix.val[1] = L.val[1]; matrix.val[ 2] = L.val[2]; + matrix.val[4] = L.val[3]; matrix.val[5] = L.val[4]; matrix.val[ 6] = L.val[5]; + matrix.val[8] = L.val[6]; matrix.val[9] = L.val[7]; matrix.val[10] = L.val[8]; +} + +template inline +void cv::Affine3::translation(const Vec3& t) +{ + matrix.val[3] = t[0]; matrix.val[7] = t[1]; matrix.val[11] = t[2]; +} + +template inline +typename cv::Affine3::Mat3 cv::Affine3::rotation() const +{ + return linear(); +} + +template inline +typename cv::Affine3::Mat3 cv::Affine3::linear() const +{ + typename cv::Affine3::Mat3 R; + R.val[0] = matrix.val[0]; R.val[1] = matrix.val[1]; R.val[2] = matrix.val[ 2]; + R.val[3] = matrix.val[4]; R.val[4] = matrix.val[5]; R.val[5] = matrix.val[ 6]; + R.val[6] = matrix.val[8]; R.val[7] = matrix.val[9]; R.val[8] = matrix.val[10]; + return R; +} + +template inline +typename cv::Affine3::Vec3 cv::Affine3::translation() const +{ + return Vec3(matrix.val[3], matrix.val[7], matrix.val[11]); +} + +template inline +typename cv::Affine3::Vec3 cv::Affine3::rvec() const +{ + cv::Vec3d w; + cv::Matx33d u, vt, R = rotation(); + cv::SVD::compute(R, w, u, vt, cv::SVD::FULL_UV + cv::SVD::MODIFY_A); + R = u * vt; + + double rx = R.val[7] - R.val[5]; + double ry = R.val[2] - R.val[6]; + double rz = R.val[3] - R.val[1]; + + double s = std::sqrt((rx*rx + ry*ry + rz*rz)*0.25); + double c = (R.val[0] + R.val[4] + R.val[8] - 1) * 0.5; + c = c > 1.0 ? 1.0 : c < -1.0 ? -1.0 : c; + double theta = acos(c); + + if( s < 1e-5 ) + { + if( c > 0 ) + rx = ry = rz = 0; + else + { + double t; + t = (R.val[0] + 1) * 0.5; + rx = std::sqrt(std::max(t, 0.0)); + t = (R.val[4] + 1) * 0.5; + ry = std::sqrt(std::max(t, 0.0)) * (R.val[1] < 0 ? -1.0 : 1.0); + t = (R.val[8] + 1) * 0.5; + rz = std::sqrt(std::max(t, 0.0)) * (R.val[2] < 0 ? -1.0 : 1.0); + + if( fabs(rx) < fabs(ry) && fabs(rx) < fabs(rz) && (R.val[5] > 0) != (ry*rz > 0) ) + rz = -rz; + theta /= std::sqrt(rx*rx + ry*ry + rz*rz); + rx *= theta; + ry *= theta; + rz *= theta; + } + } + else + { + double vth = 1/(2*s); + vth *= theta; + rx *= vth; ry *= vth; rz *= vth; + } + + return cv::Vec3d(rx, ry, rz); +} + +template inline +cv::Affine3 cv::Affine3::inv(int method) const +{ + return matrix.inv(method); +} + +template inline +cv::Affine3 cv::Affine3::rotate(const Mat3& R) const +{ + Mat3 Lc = linear(); + Vec3 tc = translation(); + Mat4 result; + result.val[12] = result.val[13] = result.val[14] = 0; + result.val[15] = 1; + + for(int j = 0; j < 3; ++j) + { + for(int i = 0; i < 3; ++i) + { + float_type value = 0; + for(int k = 0; k < 3; ++k) + value += R(j, k) * Lc(k, i); + result(j, i) = value; + } + + result(j, 3) = R.row(j).dot(tc.t()); + } + return result; +} + +template inline +cv::Affine3 cv::Affine3::rotate(const Vec3& _rvec) const +{ + return rotate(Affine3f(_rvec).rotation()); +} + +template inline +cv::Affine3 cv::Affine3::translate(const Vec3& t) const +{ + Mat4 m = matrix; + m.val[ 3] += t[0]; + m.val[ 7] += t[1]; + m.val[11] += t[2]; + return m; +} + +template inline +cv::Affine3 cv::Affine3::concatenate(const Affine3& affine) const +{ + return (*this).rotate(affine.rotation()).translate(affine.translation()); +} + +template template inline +cv::Affine3::operator Affine3() const +{ + return Affine3(matrix); +} + +template template inline +cv::Affine3 cv::Affine3::cast() const +{ + return Affine3(matrix); +} + +template inline +cv::Affine3 cv::operator*(const cv::Affine3& affine1, const cv::Affine3& affine2) +{ + return affine2.concatenate(affine1); +} + +template inline +V cv::operator*(const cv::Affine3& affine, const V& v) +{ + const typename Affine3::Mat4& m = affine.matrix; + + V r; + r.x = m.val[0] * v.x + m.val[1] * v.y + m.val[ 2] * v.z + m.val[ 3]; + r.y = m.val[4] * v.x + m.val[5] * v.y + m.val[ 6] * v.z + m.val[ 7]; + r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11]; + return r; +} + +static inline +cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v) +{ + const cv::Matx44f& m = affine.matrix; + cv::Vec3f r; + r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3]; + r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7]; + r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11]; + return r; +} + +static inline +cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v) +{ + const cv::Matx44d& m = affine.matrix; + cv::Vec3d r; + r.val[0] = m.val[0] * v[0] + m.val[1] * v[1] + m.val[ 2] * v[2] + m.val[ 3]; + r.val[1] = m.val[4] * v[0] + m.val[5] * v[1] + m.val[ 6] * v[2] + m.val[ 7]; + r.val[2] = m.val[8] * v[0] + m.val[9] * v[1] + m.val[10] * v[2] + m.val[11]; + return r; +} + + + +#if defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H + +template inline +cv::Affine3::Affine3(const Eigen::Transform& affine) +{ + cv::Mat(4, 4, cv::DataType::type, affine.matrix().data()).copyTo(matrix); +} + +template inline +cv::Affine3::Affine3(const Eigen::Transform& affine) +{ + Eigen::Transform a = affine; + cv::Mat(4, 4, cv::DataType::type, a.matrix().data()).copyTo(matrix); +} + +template inline +cv::Affine3::operator Eigen::Transform() const +{ + Eigen::Transform r; + cv::Mat hdr(4, 4, cv::DataType::type, r.matrix().data()); + cv::Mat(matrix, false).copyTo(hdr); + return r; +} + +template inline +cv::Affine3::operator Eigen::Transform() const +{ + return this->operator Eigen::Transform(); +} + +#endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */ + + +#endif /* __cplusplus */ + +#endif /* __OPENCV_CORE_AFFINE3_HPP__ */ diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index cafba0f8f3..2ecb70c713 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -892,6 +892,7 @@ public: typedef Point_ Point2i; typedef Point2i Point; typedef Size_ Size2i; +typedef Size_ Size2d; typedef Size2i Size; typedef Rect_ Rect; typedef Point_ Point2f; diff --git a/modules/core/include/opencv2/core/types_c.h b/modules/core/include/opencv2/core/types_c.h index 3e5d5b0334..99ac0d2575 100644 --- a/modules/core/include/opencv2/core/types_c.h +++ b/modules/core/include/opencv2/core/types_c.h @@ -245,7 +245,7 @@ enum { CV_StsVecLengthErr= -28, /* incorrect vector length */ CV_StsFilterStructContentErr= -29, /* incorr. filter structure content */ CV_StsKernelStructContentErr= -30, /* incorr. transform kernel content */ - CV_StsFilterOffsetErr= -31, /* incorrect filter ofset value */ + CV_StsFilterOffsetErr= -31, /* incorrect filter offset value */ CV_StsBadSize= -201, /* the input/output structure size is incorrect */ CV_StsDivByZero= -202, /* division by zero */ CV_StsInplaceNotSupported= -203, /* in-place operation is not supported */ diff --git a/modules/core/src/gl_core_3_1.cpp b/modules/core/src/gl_core_3_1.cpp index bd1eb7ddd3..4a83ba0ca0 100644 --- a/modules/core/src/gl_core_3_1.cpp +++ b/modules/core/src/gl_core_3_1.cpp @@ -47,22 +47,27 @@ #include "gl_core_3_1.hpp" #ifdef HAVE_OPENGL - #if defined(__APPLE__) - #include + + #ifdef __APPLE__ + #include static void* AppleGLGetProcAddress (const char* name) { - static const struct mach_header* image = 0; - if (!image) - image = NSAddImage("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", NSADDIMAGE_OPTION_RETURN_ON_ERROR); - - // prepend a '_' for the Unix C symbol mangling convention - std::string symbolName = "_"; - symbolName += std::string(name); - - NSSymbol symbol = image ? NSLookupSymbolInImage(image, &symbolName[0], NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) : 0; - - return symbol ? NSAddressOfSymbol(symbol) : 0; + static bool initialized = false; + static void * handle = NULL; + if (!handle) + { + if (!initialized) + { + initialized = true; + const char * const path = "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"; + + handle = dlopen(path, RTLD_LAZY | RTLD_GLOBAL); + } + if (!handle) + return NULL; + } + return dlsym(handle, name); } #endif // __APPLE__ diff --git a/modules/core/test/test_math.cpp b/modules/core/test/test_math.cpp index 3847afce6e..a572cd0d92 100644 --- a/modules/core/test/test_math.cpp +++ b/modules/core/test/test_math.cpp @@ -2392,16 +2392,14 @@ TYPED_TEST_P(Core_CheckRange, Negative) double min_bound = 4.5; double max_bound = 16.0; - TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14}; + TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14}; cv::Mat src = cv::Mat(3,3, cv::DataDepth::value, data); - cv::Point* bad_pt = new cv::Point(0, 0); + cv::Point bad_pt(0, 0); - ASSERT_FALSE(checkRange(src, true, bad_pt, min_bound, max_bound)); - ASSERT_EQ(bad_pt->x,0); - ASSERT_EQ(bad_pt->y,1); - - delete bad_pt; + ASSERT_FALSE(checkRange(src, true, &bad_pt, min_bound, max_bound)); + ASSERT_EQ(bad_pt.x, 0); + ASSERT_EQ(bad_pt.y, 1); } TYPED_TEST_P(Core_CheckRange, Positive) @@ -2409,16 +2407,14 @@ TYPED_TEST_P(Core_CheckRange, Positive) double min_bound = -1; double max_bound = 16.0; - TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14}; + TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14}; cv::Mat src = cv::Mat(3,3, cv::DataDepth::value, data); - cv::Point* bad_pt = new cv::Point(0, 0); - - ASSERT_TRUE(checkRange(src, true, bad_pt, min_bound, max_bound)); - ASSERT_EQ(bad_pt->x,0); - ASSERT_EQ(bad_pt->y,0); + cv::Point bad_pt(0, 0); - delete bad_pt; + ASSERT_TRUE(checkRange(src, true, &bad_pt, min_bound, max_bound)); + ASSERT_EQ(bad_pt.x, 0); + ASSERT_EQ(bad_pt.y, 0); } TYPED_TEST_P(Core_CheckRange, Bounds) @@ -2426,16 +2422,14 @@ TYPED_TEST_P(Core_CheckRange, Bounds) double min_bound = 24.5; double max_bound = 1.0; - TypeParam data[] = {5, 10, 15, 4, 10 ,2, 8, 12, 14}; + TypeParam data[] = {5, 10, 15, 4, 10, 2, 8, 12, 14}; cv::Mat src = cv::Mat(3,3, cv::DataDepth::value, data); - cv::Point* bad_pt = new cv::Point(0, 0); - - ASSERT_FALSE(checkRange(src, true, bad_pt, min_bound, max_bound)); - ASSERT_EQ(bad_pt->x,0); - ASSERT_EQ(bad_pt->y,0); + cv::Point bad_pt(0, 0); - delete bad_pt; + ASSERT_FALSE(checkRange(src, true, &bad_pt, min_bound, max_bound)); + ASSERT_EQ(bad_pt.x, 0); + ASSERT_EQ(bad_pt.y, 0); } TYPED_TEST_P(Core_CheckRange, Zero) diff --git a/modules/dynamicuda/include/opencv2/dynamicuda/dynamicuda.hpp b/modules/dynamicuda/include/opencv2/dynamicuda/dynamicuda.hpp index d4d0220e00..00f0873030 100644 --- a/modules/dynamicuda/include/opencv2/dynamicuda/dynamicuda.hpp +++ b/modules/dynamicuda/include/opencv2/dynamicuda/dynamicuda.hpp @@ -129,15 +129,20 @@ public: #if defined(USE_CUDA) -#define cudaSafeCall(expr) ___cudaSafeCall(expr, __FILE__, __LINE__, CV_Func) -#define nppSafeCall(expr) ___nppSafeCall(expr, __FILE__, __LINE__, CV_Func) +// Disable NPP for this file +//#define USE_NPP +#undef USE_NPP +#define cudaSafeCall(expr) ___cudaSafeCall(expr, __FILE__, __LINE__, CV_Func) inline void ___cudaSafeCall(cudaError_t err, const char *file, const int line, const char *func = "") { if (cudaSuccess != err) cv::gpu::error(cudaGetErrorString(err), file, line, func); } +#ifdef USE_NPP + +#define nppSafeCall(expr) ___nppSafeCall(expr, __FILE__, __LINE__, CV_Func) inline void ___nppSafeCall(int err, const char *file, const int line, const char *func = "") { if (err < 0) @@ -148,6 +153,8 @@ inline void ___nppSafeCall(int err, const char *file, const int line, const char } } +#endif + namespace cv { namespace gpu { namespace device { void copyToWithMask_gpu(PtrStepSzb src, PtrStepSzb dst, size_t elemSize1, int cn, PtrStepSzb mask, bool colorMask, cudaStream_t stream); @@ -173,6 +180,8 @@ template void kernelSetCaller(GpuMat& src, Scalar s, const GpuMat& cv::gpu::device::set_to_gpu(src, sf.val, mask, src.channels(), stream); } +#ifdef USE_NPP + template struct NPPTypeTraits; template<> struct NPPTypeTraits { typedef Npp8u npp_type; }; template<> struct NPPTypeTraits { typedef Npp8s npp_type; }; @@ -182,9 +191,13 @@ template<> struct NPPTypeTraits { typedef Npp32s npp_type; }; template<> struct NPPTypeTraits { typedef Npp32f npp_type; }; template<> struct NPPTypeTraits { typedef Npp64f npp_type; }; +#endif + ////////////////////////////////////////////////////////////////////////// // Convert +#ifdef USE_NPP + template struct NppConvertFunc { typedef typename NPPTypeTraits::npp_type src_t; @@ -232,9 +245,13 @@ template::func_ptr func> str } }; +#endif + ////////////////////////////////////////////////////////////////////////// // Set +#ifdef USE_NPP + template struct NppSetFunc { typedef typename NPPTypeTraits::npp_type src_t; @@ -339,9 +356,13 @@ template::func_ptr func> struct N } }; +#endif + ////////////////////////////////////////////////////////////////////////// // CopyMasked +#ifdef USE_NPP + template struct NppCopyMaskedFunc { typedef typename NPPTypeTraits::npp_type src_t; @@ -365,6 +386,8 @@ template::func_ptr func> struct N } }; +#endif + template static inline bool isAligned(const T* ptr, size_t size) { return reinterpret_cast(ptr) % size == 0; @@ -877,6 +900,8 @@ public: } typedef void (*func_t)(const GpuMat& src, GpuMat& dst, const GpuMat& mask, cudaStream_t stream); + +#ifdef USE_NPP static const func_t funcs[7][4] = { /* 8U */ {NppCopyMasked::call, cv::gpu::device::copyWithMask, NppCopyMasked::call, NppCopyMasked::call}, @@ -889,6 +914,9 @@ public: }; const func_t func = mask.channels() == src.channels() ? funcs[src.depth()][src.channels() - 1] : cv::gpu::device::copyWithMask; +#else + const func_t func = cv::gpu::device::copyWithMask; +#endif func(src, dst, mask, 0); } @@ -896,6 +924,8 @@ public: void convert(const GpuMat& src, GpuMat& dst) const { typedef void (*func_t)(const GpuMat& src, GpuMat& dst); + +#ifdef USE_NPP static const func_t funcs[7][7][4] = { { @@ -962,6 +992,7 @@ public: /* 64F -> 64F */ {0,0,0,0} } }; +#endif CV_Assert(src.depth() <= CV_64F && src.channels() <= 4); CV_Assert(dst.depth() <= CV_64F); @@ -980,8 +1011,12 @@ public: return; } +#ifdef USE_NPP const func_t func = funcs[src.depth()][dst.depth()][src.channels() - 1]; CV_DbgAssert(func != 0); +#else + const func_t func = cv::gpu::device::convertTo; +#endif func(src, dst); } @@ -1023,6 +1058,8 @@ public: } typedef void (*func_t)(GpuMat& src, Scalar s); + +#ifdef USE_NPP static const func_t funcs[7][4] = { {NppSet::call, cv::gpu::device::setTo , cv::gpu::device::setTo , NppSet::call}, @@ -1033,6 +1070,7 @@ public: {NppSet::call, cv::gpu::device::setTo , cv::gpu::device::setTo , NppSet::call}, {cv::gpu::device::setTo , cv::gpu::device::setTo , cv::gpu::device::setTo , cv::gpu::device::setTo } }; +#endif CV_Assert(m.depth() <= CV_64F && m.channels() <= 4); @@ -1042,14 +1080,22 @@ public: CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double"); } +#ifdef USE_NPP + const func_t func = funcs[m.depth()][m.channels() - 1]; +#else + const func_t func = cv::gpu::device::setTo; +#endif + if (stream) cv::gpu::device::setTo(m, s, stream); else - funcs[m.depth()][m.channels() - 1](m, s); + func(m, s); } else { typedef void (*func_t)(GpuMat& src, Scalar s, const GpuMat& mask); + +#ifdef USE_NPP static const func_t funcs[7][4] = { {NppSetMask::call, cv::gpu::device::setTo, cv::gpu::device::setTo, NppSetMask::call}, @@ -1060,6 +1106,7 @@ public: {NppSetMask::call, cv::gpu::device::setTo, cv::gpu::device::setTo, NppSetMask::call}, {cv::gpu::device::setTo , cv::gpu::device::setTo, cv::gpu::device::setTo, cv::gpu::device::setTo } }; +#endif CV_Assert(m.depth() <= CV_64F && m.channels() <= 4); @@ -1069,10 +1116,16 @@ public: CV_Error(CV_StsUnsupportedFormat, "The device doesn't support double"); } +#ifdef USE_NPP + const func_t func = funcs[m.depth()][m.channels() - 1]; +#else + const func_t func = cv::gpu::device::setTo; +#endif + if (stream) cv::gpu::device::setTo(m, s, mask, stream); else - funcs[m.depth()][m.channels() - 1](m, s, mask); + func(m, s, mask); } } diff --git a/modules/gpu/perf/perf_calib3d.cpp b/modules/gpu/perf/perf_calib3d.cpp index 91800649c2..4a67405980 100644 --- a/modules/gpu/perf/perf_calib3d.cpp +++ b/modules/gpu/perf/perf_calib3d.cpp @@ -93,7 +93,7 @@ PERF_TEST_P(ImagePair, Calib3D_StereoBM, ////////////////////////////////////////////////////////////////////// // StereoBeliefPropagation -PERF_TEST_P(ImagePair, Calib3D_StereoBeliefPropagation, +PERF_TEST_P(ImagePair, DISABLED_Calib3D_StereoBeliefPropagation, Values(pair_string("gpu/stereobp/aloe-L.png", "gpu/stereobp/aloe-R.png"))) { declare.time(300.0); diff --git a/modules/gpu/perf/perf_imgproc.cpp b/modules/gpu/perf/perf_imgproc.cpp index 4093b16e73..be0e312a02 100644 --- a/modules/gpu/perf/perf_imgproc.cpp +++ b/modules/gpu/perf/perf_imgproc.cpp @@ -851,6 +851,8 @@ PERF_TEST_P(Sz_Depth_Cn, ImgProc_BlendLinear, } } +#ifdef HAVE_CUFFT + ////////////////////////////////////////////////////////////////////// // Convolve @@ -1085,6 +1087,8 @@ PERF_TEST_P(Sz_Flags, ImgProc_Dft, } } +#endif + ////////////////////////////////////////////////////////////////////// // CornerHarris @@ -1538,7 +1542,7 @@ CV_ENUM(AlphaOp, ALPHA_OVER, ALPHA_IN, ALPHA_OUT, ALPHA_ATOP, ALPHA_XOR, ALPHA_P DEF_PARAM_TEST(Sz_Type_Op, cv::Size, MatType, AlphaOp); -PERF_TEST_P(Sz_Type_Op, ImgProc_AlphaComp, +PERF_TEST_P(Sz_Type_Op, DISABLED_ImgProc_AlphaComp, Combine(GPU_TYPICAL_MAT_SIZES, Values(CV_8UC4, CV_16UC4, CV_32SC4, CV_32FC4), AlphaOp::all())) @@ -1559,7 +1563,14 @@ PERF_TEST_P(Sz_Type_Op, ImgProc_AlphaComp, TEST_CYCLE() cv::gpu::alphaComp(d_img1, d_img2, dst, alpha_op); - GPU_SANITY_CHECK(dst, 1e-3, ERROR_RELATIVE); + if (CV_MAT_DEPTH(type) < CV_32F) + { + GPU_SANITY_CHECK(dst, 1); + } + else + { + GPU_SANITY_CHECK(dst, 1e-3, ERROR_RELATIVE); + } } else { @@ -1825,7 +1836,7 @@ CV_FLAGS(GHMethod, GHT_POSITION, GHT_SCALE, GHT_ROTATION) DEF_PARAM_TEST(Method_Sz, GHMethod, cv::Size); -PERF_TEST_P(Method_Sz, ImgProc_GeneralizedHough, +PERF_TEST_P(Method_Sz, DISABLED_ImgProc_GeneralizedHough, Combine(Values(GHMethod(cv::GHT_POSITION), GHMethod(cv::GHT_POSITION | cv::GHT_SCALE), GHMethod(cv::GHT_POSITION | cv::GHT_ROTATION), GHMethod(cv::GHT_POSITION | cv::GHT_SCALE | cv::GHT_ROTATION)), GPU_TYPICAL_MAT_SIZES)) { diff --git a/modules/gpu/src/cuda/canny.cu b/modules/gpu/src/cuda/canny.cu index aab922f22c..468eec4172 100644 --- a/modules/gpu/src/cuda/canny.cu +++ b/modules/gpu/src/cuda/canny.cu @@ -42,8 +42,6 @@ #if !defined CUDA_DISABLER -#include -#include //std::swap #include "opencv2/gpu/device/common.hpp" #include "opencv2/gpu/device/emulation.hpp" #include "opencv2/gpu/device/transform.hpp" @@ -239,30 +237,35 @@ namespace canny { __device__ int counter = 0; - __global__ void edgesHysteresisLocalKernel(PtrStepSzi map, ushort2* st) + __device__ __forceinline__ bool checkIdx(int y, int x, int rows, int cols) + { + return (y >= 0) && (y < rows) && (x >= 0) && (x < cols); + } + + __global__ void edgesHysteresisLocalKernel(PtrStepSzi map, short2* st) { __shared__ volatile int smem[18][18]; const int x = blockIdx.x * blockDim.x + threadIdx.x; const int y = blockIdx.y * blockDim.y + threadIdx.y; - smem[threadIdx.y + 1][threadIdx.x + 1] = x < map.cols && y < map.rows ? map(y, x) : 0; + smem[threadIdx.y + 1][threadIdx.x + 1] = checkIdx(y, x, map.rows, map.cols) ? map(y, x) : 0; if (threadIdx.y == 0) - smem[0][threadIdx.x + 1] = y > 0 ? map(y - 1, x) : 0; + smem[0][threadIdx.x + 1] = checkIdx(y - 1, x, map.rows, map.cols) ? map(y - 1, x) : 0; if (threadIdx.y == blockDim.y - 1) - smem[blockDim.y + 1][threadIdx.x + 1] = y + 1 < map.rows ? map(y + 1, x) : 0; + smem[blockDim.y + 1][threadIdx.x + 1] = checkIdx(y + 1, x, map.rows, map.cols) ? map(y + 1, x) : 0; if (threadIdx.x == 0) - smem[threadIdx.y + 1][0] = x > 0 ? map(y, x - 1) : 0; + smem[threadIdx.y + 1][0] = checkIdx(y, x - 1, map.rows, map.cols) ? map(y, x - 1) : 0; if (threadIdx.x == blockDim.x - 1) - smem[threadIdx.y + 1][blockDim.x + 1] = x + 1 < map.cols ? map(y, x + 1) : 0; + smem[threadIdx.y + 1][blockDim.x + 1] = checkIdx(y, x + 1, map.rows, map.cols) ? map(y, x + 1) : 0; if (threadIdx.x == 0 && threadIdx.y == 0) - smem[0][0] = y > 0 && x > 0 ? map(y - 1, x - 1) : 0; + smem[0][0] = checkIdx(y - 1, x - 1, map.rows, map.cols) ? map(y - 1, x - 1) : 0; if (threadIdx.x == blockDim.x - 1 && threadIdx.y == 0) - smem[0][blockDim.x + 1] = y > 0 && x + 1 < map.cols ? map(y - 1, x + 1) : 0; + smem[0][blockDim.x + 1] = checkIdx(y - 1, x + 1, map.rows, map.cols) ? map(y - 1, x + 1) : 0; if (threadIdx.x == 0 && threadIdx.y == blockDim.y - 1) - smem[blockDim.y + 1][0] = y + 1 < map.rows && x > 0 ? map(y + 1, x - 1) : 0; + smem[blockDim.y + 1][0] = checkIdx(y + 1, x - 1, map.rows, map.cols) ? map(y + 1, x - 1) : 0; if (threadIdx.x == blockDim.x - 1 && threadIdx.y == blockDim.y - 1) - smem[blockDim.y + 1][blockDim.x + 1] = y + 1 < map.rows && x + 1 < map.cols ? map(y + 1, x + 1) : 0; + smem[blockDim.y + 1][blockDim.x + 1] = checkIdx(y + 1, x + 1, map.rows, map.cols) ? map(y + 1, x + 1) : 0; __syncthreads(); @@ -290,8 +293,12 @@ namespace canny n += smem[threadIdx.y + 2][threadIdx.x + 2] == 2; } + __syncthreads(); + if (n > 0) smem[threadIdx.y + 1][threadIdx.x + 1] = 2; + + __syncthreads(); } const int e = smem[threadIdx.y + 1][threadIdx.x + 1]; @@ -317,11 +324,11 @@ namespace canny if (n > 0) { const int ind = ::atomicAdd(&counter, 1); - st[ind] = make_ushort2(x, y); + st[ind] = make_short2(x, y); } } - void edgesHysteresisLocal(PtrStepSzi map, ushort2* st1) + void edgesHysteresisLocal(PtrStepSzi map, short2* st1) { void* counter_ptr; cudaSafeCall( cudaGetSymbolAddress(&counter_ptr, counter) ); @@ -345,13 +352,13 @@ namespace canny __constant__ int c_dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; __constant__ int c_dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; - __global__ void edgesHysteresisGlobalKernel(PtrStepSzi map, ushort2* st1, ushort2* st2, const int count) + __global__ void edgesHysteresisGlobalKernel(PtrStepSzi map, short2* st1, short2* st2, const int count) { const int stack_size = 512; __shared__ int s_counter; __shared__ int s_ind; - __shared__ ushort2 s_st[stack_size]; + __shared__ short2 s_st[stack_size]; if (threadIdx.x == 0) s_counter = 0; @@ -363,14 +370,14 @@ namespace canny if (ind >= count) return; - ushort2 pos = st1[ind]; + short2 pos = st1[ind]; if (threadIdx.x < 8) { pos.x += c_dx[threadIdx.x]; pos.y += c_dy[threadIdx.x]; - if (pos.x > 0 && pos.x < map.cols && pos.y > 0 && pos.y < map.rows && map(pos.y, pos.x) == 1) + if (pos.x > 0 && pos.x < map.cols - 1 && pos.y > 0 && pos.y < map.rows - 1 && map(pos.y, pos.x) == 1) { map(pos.y, pos.x) = 2; @@ -402,7 +409,7 @@ namespace canny pos.x += c_dx[threadIdx.x & 7]; pos.y += c_dy[threadIdx.x & 7]; - if (pos.x > 0 && pos.x < map.cols && pos.y > 0 && pos.y < map.rows && map(pos.y, pos.x) == 1) + if (pos.x > 0 && pos.x < map.cols - 1 && pos.y > 0 && pos.y < map.rows - 1 && map(pos.y, pos.x) == 1) { map(pos.y, pos.x) = 2; @@ -419,8 +426,10 @@ namespace canny { if (threadIdx.x == 0) { - ind = ::atomicAdd(&counter, s_counter); - s_ind = ind - s_counter; + s_ind = ::atomicAdd(&counter, s_counter); + + if (s_ind + s_counter > map.cols * map.rows) + s_counter = 0; } __syncthreads(); @@ -432,7 +441,7 @@ namespace canny } } - void edgesHysteresisGlobal(PtrStepSzi map, ushort2* st1, ushort2* st2) + void edgesHysteresisGlobal(PtrStepSzi map, short2* st1, short2* st2) { void* counter_ptr; cudaSafeCall( cudaGetSymbolAddress(&counter_ptr, canny::counter) ); @@ -454,7 +463,12 @@ namespace canny cudaSafeCall( cudaMemcpy(&count, counter_ptr, sizeof(int), cudaMemcpyDeviceToHost) ); - std::swap(st1, st2); + count = min(count, map.cols * map.rows); + + //std::swap(st1, st2); + short2* tmp = st1; + st1 = st2; + st2 = tmp; } } } diff --git a/modules/gpu/src/cuda/generalized_hough.cu b/modules/gpu/src/cuda/generalized_hough.cu index 35451e7e23..5e2041eae4 100644 --- a/modules/gpu/src/cuda/generalized_hough.cu +++ b/modules/gpu/src/cuda/generalized_hough.cu @@ -40,8 +40,6 @@ // //M*/ -#define CUDA_DISABLER - #if !defined CUDA_DISABLER #include diff --git a/modules/gpu/src/cuda/nlm.cu b/modules/gpu/src/cuda/nlm.cu index 922cba7e5a..8789a4cf6b 100644 --- a/modules/gpu/src/cuda/nlm.cu +++ b/modules/gpu/src/cuda/nlm.cu @@ -266,7 +266,7 @@ namespace cv { namespace gpu { namespace device __device__ __forceinline__ int calcDist(const uchar2& a, const uchar2& b) { return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y); } __device__ __forceinline__ int calcDist(const uchar3& a, const uchar3& b) { return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) + (a.z-b.z)*(a.z-b.z); } - template struct FastNonLocalMenas + template struct FastNonLocalMeans { enum { @@ -290,7 +290,7 @@ namespace cv { namespace gpu { namespace device int block_window; float minus_h2_inv; - FastNonLocalMenas(int search_window_, int block_window_, float h) : search_radius(search_window_/2), block_radius(block_window_/2), + FastNonLocalMeans(int search_window_, int block_window_, float h) : search_radius(search_window_/2), block_radius(block_window_/2), search_window(search_window_), block_window(block_window_), minus_h2_inv(-1.f/(h * h * VecTraits::cn)) {} PtrStep src; @@ -394,7 +394,7 @@ namespace cv { namespace gpu { namespace device } } - __device__ __forceinline__ void convolve_window(int i, int j, const int* dist_sums, PtrStepi& col_sums, PtrStepi& up_col_sums, T& dst) const + __device__ __forceinline__ void convolve_window(int i, int j, const int* dist_sums, T& dst) const { typedef typename TypeVec::cn>::vec_type sum_type; @@ -471,18 +471,18 @@ namespace cv { namespace gpu { namespace device __syncthreads(); - convolve_window(i, j, dist_sums, col_sums, up_col_sums, dst(i, j)); + convolve_window(i, j, dist_sums, dst(i, j)); } } }; template - __global__ void fast_nlm_kernel(const FastNonLocalMenas fnlm, PtrStepSz dst) { fnlm(dst); } + __global__ void fast_nlm_kernel(const FastNonLocalMeans fnlm, PtrStepSz dst) { fnlm(dst); } void nln_fast_get_buffer_size(const PtrStepSzb& src, int search_window, int block_window, int& buffer_cols, int& buffer_rows) { - typedef FastNonLocalMenas FNLM; + typedef FastNonLocalMeans FNLM; dim3 grid(divUp(src.cols, FNLM::TILE_COLS), divUp(src.rows, FNLM::TILE_ROWS)); buffer_cols = search_window * search_window * grid.y; @@ -493,7 +493,7 @@ namespace cv { namespace gpu { namespace device void nlm_fast_gpu(const PtrStepSzb& src, PtrStepSzb dst, PtrStepi buffer, int search_window, int block_window, float h, cudaStream_t stream) { - typedef FastNonLocalMenas FNLM; + typedef FastNonLocalMeans FNLM; FNLM fnlm(search_window, block_window, h); fnlm.src = (PtrStepSz)src; diff --git a/modules/gpu/src/generalized_hough.cpp b/modules/gpu/src/generalized_hough.cpp index 867ba7ee71..a92c37d1a5 100644 --- a/modules/gpu/src/generalized_hough.cpp +++ b/modules/gpu/src/generalized_hough.cpp @@ -40,8 +40,6 @@ // //M*/ -#define CUDA_DISABLER - #include "precomp.hpp" using namespace std; diff --git a/modules/gpu/src/imgproc.cpp b/modules/gpu/src/imgproc.cpp index 1904b6aad6..66f838f77a 100644 --- a/modules/gpu/src/imgproc.cpp +++ b/modules/gpu/src/imgproc.cpp @@ -244,6 +244,10 @@ void cv::gpu::reprojectImageTo3D(const GpuMat& disp, GpuMat& xyz, const Mat& Q, //////////////////////////////////////////////////////////////////////// // copyMakeBorder +// Disable NPP for this file +//#define USE_NPP +#undef USE_NPP + namespace cv { namespace gpu { namespace device { namespace imgproc @@ -279,6 +283,7 @@ void cv::gpu::copyMakeBorder(const GpuMat& src, GpuMat& dst, int top, int bottom cudaStream_t stream = StreamAccessor::getStream(s); +#ifdef USE_NPP if (borderType == BORDER_CONSTANT && (src.type() == CV_8UC1 || src.type() == CV_8UC4 || src.type() == CV_32SC1 || src.type() == CV_32FC1)) { NppiSize srcsz; @@ -328,6 +333,7 @@ void cv::gpu::copyMakeBorder(const GpuMat& src, GpuMat& dst, int top, int bottom cudaSafeCall( cudaDeviceSynchronize() ); } else +#endif { typedef void (*caller_t)(const PtrStepSzb& src, const PtrStepSzb& dst, int top, int left, int borderType, const Scalar& value, cudaStream_t stream); static const caller_t callers[6][4] = @@ -1485,6 +1491,8 @@ void cv::gpu::convolve(const GpuMat& image, const GpuMat& templ, GpuMat& result, void cv::gpu::CannyBuf::create(const Size& image_size, int apperture_size) { + CV_Assert(image_size.width < std::numeric_limits::max() && image_size.height < std::numeric_limits::max()); + if (apperture_size > 0) { ensureSizeIsEnough(image_size, CV_32SC1, dx); @@ -1500,8 +1508,8 @@ void cv::gpu::CannyBuf::create(const Size& image_size, int apperture_size) ensureSizeIsEnough(image_size, CV_32FC1, mag); ensureSizeIsEnough(image_size, CV_32SC1, map); - ensureSizeIsEnough(1, image_size.area(), CV_16UC2, st1); - ensureSizeIsEnough(1, image_size.area(), CV_16UC2, st2); + ensureSizeIsEnough(1, image_size.area(), CV_16SC2, st1); + ensureSizeIsEnough(1, image_size.area(), CV_16SC2, st2); } void cv::gpu::CannyBuf::release() @@ -1521,9 +1529,9 @@ namespace canny void calcMap(PtrStepSzi dx, PtrStepSzi dy, PtrStepSzf mag, PtrStepSzi map, float low_thresh, float high_thresh); - void edgesHysteresisLocal(PtrStepSzi map, ushort2* st1); + void edgesHysteresisLocal(PtrStepSzi map, short2* st1); - void edgesHysteresisGlobal(PtrStepSzi map, ushort2* st1, ushort2* st2); + void edgesHysteresisGlobal(PtrStepSzi map, short2* st1, short2* st2); void getEdges(PtrStepSzi map, PtrStepSzb dst); } @@ -1537,9 +1545,9 @@ namespace buf.map.setTo(Scalar::all(0)); calcMap(dx, dy, buf.mag, buf.map, low_thresh, high_thresh); - edgesHysteresisLocal(buf.map, buf.st1.ptr()); + edgesHysteresisLocal(buf.map, buf.st1.ptr()); - edgesHysteresisGlobal(buf.map, buf.st1.ptr(), buf.st2.ptr()); + edgesHysteresisGlobal(buf.map, buf.st1.ptr(), buf.st2.ptr()); getEdges(buf.map, dst); } diff --git a/modules/gpu/test/nvidia/TestHaarCascadeLoader.cpp b/modules/gpu/test/nvidia/TestHaarCascadeLoader.cpp index 42552295d2..1c0e691ba2 100644 --- a/modules/gpu/test/nvidia/TestHaarCascadeLoader.cpp +++ b/modules/gpu/test/nvidia/TestHaarCascadeLoader.cpp @@ -98,7 +98,7 @@ bool TestHaarCascadeLoader::process() NCV_SET_SKIP_COND(this->allocatorGPU.get()->isCounting()); NCV_SKIP_COND_BEGIN - const std::string testNvbinName = "test.nvbin"; + const std::string testNvbinName = cv::tempfile("test.nvbin"); ncvStat = ncvHaarLoadFromFile_host(this->cascadeName, haar, h_HaarStages, h_HaarNodes, h_HaarFeatures); ncvAssertReturn(ncvStat == NCV_SUCCESS, false); diff --git a/modules/gpu/test/test_color.cpp b/modules/gpu/test/test_color.cpp index 3b4b326e4d..321785ffe0 100644 --- a/modules/gpu/test/test_color.cpp +++ b/modules/gpu/test/test_color.cpp @@ -715,7 +715,7 @@ GPU_TEST_P(CvtColor, BGR2YCrCb) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_BGR2YCrCb); - EXPECT_MAT_NEAR(dst_gold, dst, 1.0); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_32F ? 1e-2 : 1); } GPU_TEST_P(CvtColor, RGB2YCrCb) @@ -728,7 +728,7 @@ GPU_TEST_P(CvtColor, RGB2YCrCb) cv::Mat dst_gold; cv::cvtColor(src, dst_gold, cv::COLOR_RGB2YCrCb); - EXPECT_MAT_NEAR(dst_gold, dst, 1.0); + EXPECT_MAT_NEAR(dst_gold, dst, depth == CV_32F ? 1e-2 : 1); } GPU_TEST_P(CvtColor, BGR2YCrCb4) @@ -749,7 +749,7 @@ GPU_TEST_P(CvtColor, BGR2YCrCb4) cv::split(h_dst, channels); cv::merge(channels, 3, h_dst); - EXPECT_MAT_NEAR(dst_gold, h_dst, 1.0); + EXPECT_MAT_NEAR(dst_gold, h_dst, depth == CV_32F ? 1e-2 : 1); } GPU_TEST_P(CvtColor, RGBA2YCrCb4) @@ -771,7 +771,7 @@ GPU_TEST_P(CvtColor, RGBA2YCrCb4) cv::split(h_dst, channels); cv::merge(channels, 3, h_dst); - EXPECT_MAT_NEAR(dst_gold, h_dst, 1.0); + EXPECT_MAT_NEAR(dst_gold, h_dst, depth == CV_32F ? 1e-2 : 1); } GPU_TEST_P(CvtColor, YCrCb2BGR) diff --git a/modules/gpu/test/test_core.cpp b/modules/gpu/test/test_core.cpp index 1edc69b971..7ceeaedf08 100644 --- a/modules/gpu/test/test_core.cpp +++ b/modules/gpu/test/test_core.cpp @@ -3582,7 +3582,7 @@ GPU_TEST_P(Normalize, WithOutMask) cv::Mat dst_gold; cv::normalize(src, dst_gold, alpha, beta, norm_type, type); - EXPECT_MAT_NEAR(dst_gold, dst, 1.0); + EXPECT_MAT_NEAR(dst_gold, dst, type < CV_32F ? 1.0 : 1e-4); } GPU_TEST_P(Normalize, WithMask) @@ -3598,7 +3598,7 @@ GPU_TEST_P(Normalize, WithMask) dst_gold.setTo(cv::Scalar::all(0)); cv::normalize(src, dst_gold, alpha, beta, norm_type, type, mask); - EXPECT_MAT_NEAR(dst_gold, dst, 1.0); + EXPECT_MAT_NEAR(dst_gold, dst, type < CV_32F ? 1.0 : 1e-4); } INSTANTIATE_TEST_CASE_P(GPU_Core, Normalize, testing::Combine( diff --git a/modules/gpu/test/test_denoising.cpp b/modules/gpu/test/test_denoising.cpp index e480cf4680..e416e92597 100644 --- a/modules/gpu/test/test_denoising.cpp +++ b/modules/gpu/test/test_denoising.cpp @@ -114,6 +114,7 @@ GPU_TEST_P(BruteForceNonLocalMeans, Regression) cv::Mat bgr = readImage("denoising/lena_noised_gaussian_sigma=20_multi_0.png", cv::IMREAD_COLOR); ASSERT_FALSE(bgr.empty()); + cv::resize(bgr, bgr, cv::Size(256, 256)); cv::Mat gray; cv::cvtColor(bgr, gray, CV_BGR2GRAY); @@ -130,6 +131,8 @@ GPU_TEST_P(BruteForceNonLocalMeans, Regression) cv::Mat bgr_gold = readImage("denoising/nlm_denoised_lena_bgr.png", cv::IMREAD_COLOR); cv::Mat gray_gold = readImage("denoising/nlm_denoised_lena_gray.png", cv::IMREAD_GRAYSCALE); ASSERT_FALSE(bgr_gold.empty() || gray_gold.empty()); + cv::resize(bgr_gold, bgr_gold, cv::Size(256, 256)); + cv::resize(gray_gold, gray_gold, cv::Size(256, 256)); EXPECT_MAT_NEAR(bgr_gold, dbgr, 1e-4); EXPECT_MAT_NEAR(gray_gold, dgray, 1e-4); diff --git a/modules/gpu/test/test_gpumat.cpp b/modules/gpu/test/test_gpumat.cpp index 210b6a4415..fee264341b 100644 --- a/modules/gpu/test/test_gpumat.cpp +++ b/modules/gpu/test/test_gpumat.cpp @@ -281,7 +281,7 @@ GPU_TEST_P(ConvertTo, WithOutScaling) cv::Mat dst_gold; src.convertTo(dst_gold, depth2); - EXPECT_MAT_NEAR(dst_gold, dst, 1.0); + EXPECT_MAT_NEAR(dst_gold, dst, depth2 < CV_32F ? 1.0 : 1e-4); } } diff --git a/modules/gpu/test/test_hough.cpp b/modules/gpu/test/test_hough.cpp index 6441fc69ab..f876a7a2b0 100644 --- a/modules/gpu/test/test_hough.cpp +++ b/modules/gpu/test/test_hough.cpp @@ -189,7 +189,7 @@ PARAM_TEST_CASE(GeneralizedHough, cv::gpu::DeviceInfo, UseRoi) { }; -GPU_TEST_P(GeneralizedHough, DISABLED_POSITION) +GPU_TEST_P(GeneralizedHough, POSITION) { const cv::gpu::DeviceInfo devInfo = GET_PARAM(0); cv::gpu::setDevice(devInfo.deviceID()); diff --git a/modules/gpu/test/test_imgproc.cpp b/modules/gpu/test/test_imgproc.cpp index 811d1294cf..9ce32d12b8 100644 --- a/modules/gpu/test/test_imgproc.cpp +++ b/modules/gpu/test/test_imgproc.cpp @@ -563,6 +563,8 @@ INSTANTIATE_TEST_CASE_P(GPU_ImgProc, Blend, testing::Combine( testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_8UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)), WHOLE_SUBMAT)); +#ifdef HAVE_CUFFT + //////////////////////////////////////////////////////// // Convolve @@ -1090,6 +1092,8 @@ GPU_TEST_P(Dft, R2CThenC2R) INSTANTIATE_TEST_CASE_P(GPU_ImgProc, Dft, ALL_DEVICES); +#endif + /////////////////////////////////////////////////////////////////////////////////////////////////////// // CornerHarris diff --git a/modules/gpu/test/test_optflow.cpp b/modules/gpu/test/test_optflow.cpp index 53b93a096b..571403d2a7 100644 --- a/modules/gpu/test/test_optflow.cpp +++ b/modules/gpu/test/test_optflow.cpp @@ -483,13 +483,15 @@ GPU_TEST_P(OpticalFlowBM, Accuracy) cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE); ASSERT_FALSE(frame0.empty()); + cv::resize(frame0, frame0, cv::Size(), 0.5, 0.5); cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE); ASSERT_FALSE(frame1.empty()); + cv::resize(frame1, frame1, cv::Size(), 0.5, 0.5); - cv::Size block_size(16, 16); + cv::Size block_size(8, 8); cv::Size shift_size(1, 1); - cv::Size max_range(16, 16); + cv::Size max_range(8, 8); cv::gpu::GpuMat d_velx, d_vely, buf; cv::gpu::calcOpticalFlowBM(loadMat(frame0), loadMat(frame1), diff --git a/modules/highgui/src/cap_ios_abstract_camera.mm b/modules/highgui/src/cap_ios_abstract_camera.mm index a77e200a82..b40b3648de 100644 --- a/modules/highgui/src/cap_ios_abstract_camera.mm +++ b/modules/highgui/src/cap_ios_abstract_camera.mm @@ -278,8 +278,20 @@ { self.captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession]; - if ([self.captureVideoPreviewLayer isOrientationSupported]) { - [self.captureVideoPreviewLayer setOrientation:self.defaultAVCaptureVideoOrientation]; + if ([self.captureVideoPreviewLayer respondsToSelector:@selector(connection)]) + { + if ([self.captureVideoPreviewLayer.connection isVideoOrientationSupported]) + { + [self.captureVideoPreviewLayer.connection setVideoOrientation:self.defaultAVCaptureVideoOrientation]; + } + } + else + { + // Deprecated in 6.0; here for backward compatibility + if ([self.captureVideoPreviewLayer isOrientationSupported]) + { + [self.captureVideoPreviewLayer setOrientation:self.defaultAVCaptureVideoOrientation]; + } } if (parentView != nil) { @@ -290,9 +302,6 @@ NSLog(@"[Camera] created AVCaptureVideoPreviewLayer"); } - - - - (void)setDesiredCameraPosition:(AVCaptureDevicePosition)desiredPosition; { for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { diff --git a/modules/highgui/src/grfmt_tiff.cpp b/modules/highgui/src/grfmt_tiff.cpp index 614d001231..f40699f83a 100644 --- a/modules/highgui/src/grfmt_tiff.cpp +++ b/modules/highgui/src/grfmt_tiff.cpp @@ -111,18 +111,21 @@ bool TiffDecoder::readHeader() bool result = false; close(); - TIFF* tif = TIFFOpen( m_filename.c_str(), "rb" ); + // TIFFOpen() mode flags are different to fopen(). A 'b' in mode "rb" has no effect when reading. + // http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html + TIFF* tif = TIFFOpen( m_filename.c_str(), "r" ); if( tif ) { - int wdth = 0, hght = 0, photometric = 0; + uint32 wdth = 0, hght = 0; + uint16 photometric = 0; m_tif = tif; if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &wdth ) && TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &hght ) && TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric )) { - int bpp=8, ncn = photometric > 1 ? 3 : 1; + uint16 bpp=8, ncn = photometric > 1 ? 3 : 1; TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp ); TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn ); @@ -175,12 +178,12 @@ bool TiffDecoder::readData( Mat& img ) if( m_tif && m_width && m_height ) { TIFF* tif = (TIFF*)m_tif; - int tile_width0 = m_width, tile_height0 = 0; + uint32 tile_width0 = m_width, tile_height0 = 0; int x, y, i; int is_tiled = TIFFIsTiled(tif); - int photometric; + uint16 photometric; TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ); - int bpp = 8, ncn = photometric > 1 ? 3 : 1; + uint16 bpp = 8, ncn = photometric > 1 ? 3 : 1; TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp ); TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn ); const int bitsPerByte = 8; diff --git a/modules/highgui/test/test_ffmpeg.cpp b/modules/highgui/test/test_ffmpeg.cpp index 30410eaab8..55bf952213 100644 --- a/modules/highgui/test/test_ffmpeg.cpp +++ b/modules/highgui/test/test_ffmpeg.cpp @@ -88,7 +88,7 @@ public: stringstream s; s << tag; - const string filename = "output_"+s.str()+".avi"; + const string filename = tempfile((s.str()+".avi").c_str()); try { diff --git a/modules/highgui/test/test_grfmt.cpp b/modules/highgui/test/test_grfmt.cpp index 1fdf2c515a..bd9e79ad02 100644 --- a/modules/highgui/test/test_grfmt.cpp +++ b/modules/highgui/test/test_grfmt.cpp @@ -408,8 +408,8 @@ TEST(Highgui_Tiff, decode_tile16384x16384) try { - cv::imread(file3); - EXPECT_NO_THROW(cv::imread(file4)); + cv::imread(file3, CV_LOAD_IMAGE_UNCHANGED); + EXPECT_NO_THROW(cv::imread(file4, CV_LOAD_IMAGE_UNCHANGED)); } catch(const std::bad_alloc&) { @@ -420,6 +420,53 @@ TEST(Highgui_Tiff, decode_tile16384x16384) remove(file4.c_str()); } +class CV_GrfmtReadTifTiledWithNotFullTiles: public cvtest::BaseTest +{ + // see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness" + + // Setup data for two minimal 16-bit grayscale TIFF files in both endian formats + uchar tiff_sample_data[2][86] = { { + // Little endian + 0x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01, + 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, + 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, { + // Big endian + 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, + 0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x04 } + }; + + // Test imread() for both a little endian TIFF and big endian TIFF + for (int i = 0; i < 2; i++) + { + string filename = cv::tempfile(".tiff"); + + // Write sample TIFF file + FILE* fp = fopen(filename.c_str(), "wb"); + ASSERT_TRUE(fp != NULL); + ASSERT_EQ((size_t)1, fwrite(tiff_sample_data, 86, 1, fp)); + fclose(fp); + + Mat img = imread(filename, CV_LOAD_IMAGE_UNCHANGED); + + EXPECT_EQ(1, img.rows); + EXPECT_EQ(2, img.cols); + EXPECT_EQ(CV_16U, img.type()); + EXPECT_EQ(sizeof(ushort), img.elemSize()); + EXPECT_EQ(1, img.channels()); + EXPECT_EQ(0xDEAD, img.at(0,0)); + EXPECT_EQ(0xBEEF, img.at(0,1)); + + remove(filename.c_str()); + } +} + class CV_GrfmtReadTifTiledWithNotFullTiles: public cvtest::BaseTest { public: diff --git a/modules/highgui/test/test_video_io.cpp b/modules/highgui/test/test_video_io.cpp index cf47b73a6f..755bcd0677 100644 --- a/modules/highgui/test/test_video_io.cpp +++ b/modules/highgui/test/test_video_io.cpp @@ -332,9 +332,7 @@ void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt } } - printf("Before saved release for %s\n", tmp_name.c_str()); cvReleaseCapture( &saved ); - printf("After release\n"); ts->printf(ts->LOG, "end test function : ImagesVideo \n"); } diff --git a/modules/imgproc/src/clahe.cpp b/modules/imgproc/src/clahe.cpp index 4ce479713e..9ecf792daf 100644 --- a/modules/imgproc/src/clahe.cpp +++ b/modules/imgproc/src/clahe.cpp @@ -49,8 +49,8 @@ namespace class CLAHE_CalcLut_Body : public cv::ParallelLoopBody { public: - CLAHE_CalcLut_Body(const cv::Mat& src, cv::Mat& lut, cv::Size tileSize, int tilesX, int tilesY, int clipLimit, float lutScale) : - src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), tilesY_(tilesY), clipLimit_(clipLimit), lutScale_(lutScale) + CLAHE_CalcLut_Body(const cv::Mat& src, cv::Mat& lut, cv::Size tileSize, int tilesX, int clipLimit, float lutScale) : + src_(src), lut_(lut), tileSize_(tileSize), tilesX_(tilesX), clipLimit_(clipLimit), lutScale_(lutScale) { } @@ -62,7 +62,6 @@ namespace cv::Size tileSize_; int tilesX_; - int tilesY_; int clipLimit_; float lutScale_; }; @@ -293,7 +292,7 @@ namespace clipLimit = std::max(clipLimit, 1); } - CLAHE_CalcLut_Body calcLutBody(srcForLut, lut_, tileSize, tilesX_, tilesY_, clipLimit, lutScale); + CLAHE_CalcLut_Body calcLutBody(srcForLut, lut_, tileSize, tilesX_, clipLimit, lutScale); cv::parallel_for_(cv::Range(0, tilesX_ * tilesY_), calcLutBody); CLAHE_Interpolation_Body interpolationBody(src, dst, lut_, tileSize, tilesX_, tilesY_); diff --git a/modules/imgproc/src/color.cpp b/modules/imgproc/src/color.cpp index 15c214ef91..08f27aef97 100644 --- a/modules/imgproc/src/color.cpp +++ b/modules/imgproc/src/color.cpp @@ -3214,7 +3214,7 @@ struct YUV420p2RGB888Invoker : ParallelLoopBody const int rangeBegin = range.start * 2; const int rangeEnd = range.end * 2; - size_t uvsteps[2] = {width/2, stride - width/2}; + int uvsteps[2] = {width/2, stride - width/2}; int usIdx = ustepIdx, vsIdx = vstepIdx; const uchar* y1 = my1 + rangeBegin * stride; @@ -3282,7 +3282,7 @@ struct YUV420p2RGBA8888Invoker : ParallelLoopBody int rangeBegin = range.start * 2; int rangeEnd = range.end * 2; - size_t uvsteps[2] = {width/2, stride - width/2}; + int uvsteps[2] = {width/2, stride - width/2}; int usIdx = ustepIdx, vsIdx = vstepIdx; const uchar* y1 = my1 + rangeBegin * stride; diff --git a/modules/imgproc/src/floodfill.cpp b/modules/imgproc/src/floodfill.cpp index 74047676e4..db2563ddea 100644 --- a/modules/imgproc/src/floodfill.cpp +++ b/modules/imgproc/src/floodfill.cpp @@ -41,7 +41,7 @@ #include "precomp.hpp" -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic ignored "-Warray-bounds" #endif diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 4748af2cee..6cbb416c9e 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -1217,8 +1217,13 @@ public: alpha(_alpha), _beta(__beta), ssize(_ssize), dsize(_dsize), ksize(_ksize), xmin(_xmin), xmax(_xmax) { + CV_Assert(ksize <= MAX_ESIZE); } +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +#endif virtual void operator() (const Range& range) const { int dy, cn = src.channels(); @@ -1267,6 +1272,9 @@ public: vresize( (const WT**)rows, (T*)(dst.data + dst.step*dy), beta, dsize.width ); } } +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +# pragma GCC diagnostic pop +#endif private: Mat src; @@ -1274,7 +1282,9 @@ private: const int* xofs, *yofs; const AT* alpha, *_beta; Size ssize, dsize; - int ksize, xmin, xmax; + const int ksize, xmin, xmax; + + resizeGeneric_Invoker& operator = (const resizeGeneric_Invoker&); }; template diff --git a/modules/imgproc/src/moments.cpp b/modules/imgproc/src/moments.cpp index 784a61b8df..2fca862bca 100644 --- a/modules/imgproc/src/moments.cpp +++ b/modules/imgproc/src/moments.cpp @@ -197,6 +197,10 @@ static void icvContourMoments( CvSeq* contour, CvMoments* moments ) \****************************************************************************************/ template +#if defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 9 +// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60196 +__attribute__((optimize("no-tree-vectorize"))) +#endif static void momentsInTile( const cv::Mat& img, double* moments ) { cv::Size size = img.size(); diff --git a/modules/imgproc/src/smooth.cpp b/modules/imgproc/src/smooth.cpp index bbce3deedf..ae14ca9e11 100644 --- a/modules/imgproc/src/smooth.cpp +++ b/modules/imgproc/src/smooth.cpp @@ -718,7 +718,7 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth, ddepth = sdepth; _dst.create( src.size(), CV_MAKETYPE(ddepth, cn) ); Mat dst = _dst.getMat(); - if( borderType != BORDER_CONSTANT && normalize ) + if( borderType != BORDER_CONSTANT && normalize && (borderType & BORDER_ISOLATED) != 0 ) { if( src.rows == 1 ) ksize.height = 1; diff --git a/modules/imgproc/test/test_convhull.cpp b/modules/imgproc/test/test_convhull.cpp index e20b1a2076..75fddfd04f 100644 --- a/modules/imgproc/test/test_convhull.cpp +++ b/modules/imgproc/test/test_convhull.cpp @@ -1225,7 +1225,7 @@ CV_FitLineTest::CV_FitLineTest() max_noise = 0.05; } -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Warray-bounds" #endif @@ -1301,7 +1301,7 @@ void CV_FitLineTest::generate_point_set( void* pointsSet ) } } -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic pop #endif @@ -1329,7 +1329,7 @@ void CV_FitLineTest::run_func() cv::fitLine(cv::cvarrToMat(points), (cv::Vec6f&)line[0], dist_type, 0, reps, aeps); } -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Warray-bounds" #endif @@ -1412,7 +1412,7 @@ _exit_: return code; } -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic pop #endif diff --git a/modules/imgproc/test/test_filter.cpp b/modules/imgproc/test/test_filter.cpp index efbad99749..c860a6f114 100644 --- a/modules/imgproc/test/test_filter.cpp +++ b/modules/imgproc/test/test_filter.cpp @@ -1886,3 +1886,35 @@ protected: }; TEST(Imgproc_Filtering, supportedFormats) { CV_FilterSupportedFormatsTest test; test.safe_run(); } + +TEST(Imgproc_Blur, borderTypes) +{ + Size kernelSize(3, 3); + + /// ksize > src_roi.size() + Mat src(3, 3, CV_8UC1, cv::Scalar::all(255)), dst; + Mat src_roi = src(Rect(1, 1, 1, 1)); + src_roi.setTo(cv::Scalar::all(0)); + + // should work like !BORDER_ISOLATED + blur(src_roi, dst, kernelSize, Point(-1, -1), BORDER_REPLICATE); + EXPECT_EQ(227, dst.at(0, 0)); + + // should work like BORDER_ISOLATED + blur(src_roi, dst, kernelSize, Point(-1, -1), BORDER_REPLICATE | BORDER_ISOLATED); + EXPECT_EQ(0, dst.at(0, 0)); + + /// ksize <= src_roi.size() + src = Mat(5, 5, CV_8UC1, cv::Scalar(255)); + src_roi = src(Rect(1, 1, 3, 3)); + src_roi.setTo(0); + src.at(2, 2) = 255; + + // should work like !BORDER_ISOLATED + blur(src_roi, dst, kernelSize, Point(-1, -1), BORDER_REPLICATE); + Mat expected_dst = + (Mat_(3, 3) << 170, 113, 170, 113, 28, 113, 170, 113, 170); + EXPECT_EQ(expected_dst.type(), dst.type()); + EXPECT_EQ(expected_dst.size(), dst.size()); + EXPECT_DOUBLE_EQ(0.0, cvtest::norm(expected_dst, dst, NORM_INF)); +} diff --git a/modules/java/CMakeLists.txt b/modules/java/CMakeLists.txt index 198048ebe2..1ef2a1208e 100644 --- a/modules/java/CMakeLists.txt +++ b/modules/java/CMakeLists.txt @@ -266,7 +266,7 @@ if(ANDROID) else(ANDROID) set(JAR_NAME opencv-${LIB_NAME_SUFIX}.jar) set(JAR_FILE "${OpenCV_BINARY_DIR}/bin/${JAR_NAME}") - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build.xml.in" "${OpenCV_BINARY_DIR}/build.xml" IMMEDIATE @ONLY) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build.xml.in" "${OpenCV_BINARY_DIR}/build.xml" @ONLY) list(APPEND step3_depends "${OpenCV_BINARY_DIR}/build.xml") add_custom_command(OUTPUT "${JAR_FILE}" "${JAR_FILE}.dephelper" diff --git a/modules/java/generator/src/cpp/VideoCapture.cpp b/modules/java/generator/src/cpp/VideoCapture.cpp index a9d0a56c1c..e4a8bc25a9 100644 --- a/modules/java/generator/src/cpp/VideoCapture.cpp +++ b/modules/java/generator/src/cpp/VideoCapture.cpp @@ -329,7 +329,10 @@ JNIEXPORT jstring JNICALL Java_org_opencv_highgui_VideoCapture_n_1getSupportedPr VideoCapture* me = (VideoCapture*) self; //TODO: check for NULL union {double prop; const char* name;} u; u.prop = me->get(CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING); - return env->NewStringUTF(u.name); + // VideoCapture::get can return 0.0 or -1.0 if it doesn't support + // CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING + if (u.prop != 0.0 && u.prop != -1.0) + return env->NewStringUTF(u.name); } catch(const std::exception &e) { throwJavaException(env, &e, method_name); } catch (...) { diff --git a/modules/java/generator/src/java/android+OpenCVLoader.java b/modules/java/generator/src/java/android+OpenCVLoader.java index 46e62eb347..0892e3af3c 100644 --- a/modules/java/generator/src/java/android+OpenCVLoader.java +++ b/modules/java/generator/src/java/android+OpenCVLoader.java @@ -48,7 +48,17 @@ public class OpenCVLoader */ public static boolean initDebug() { - return StaticHelper.initOpenCV(); + return StaticHelper.initOpenCV(false); + } + + /** + * Loads and initializes OpenCV library from current application package. Roughly, it's an analog of system.loadLibrary("opencv_java"). + * @param InitCuda load and initialize CUDA runtime libraries. + * @return Returns true is initialization of OpenCV was successful. + */ + public static boolean initDebug(boolean InitCuda) + { + return StaticHelper.initOpenCV(InitCuda); } /** diff --git a/modules/java/generator/src/java/android+StaticHelper.java b/modules/java/generator/src/java/android+StaticHelper.java index 8d0629c8d3..10442c904d 100644 --- a/modules/java/generator/src/java/android+StaticHelper.java +++ b/modules/java/generator/src/java/android+StaticHelper.java @@ -7,11 +7,21 @@ import android.util.Log; class StaticHelper { - public static boolean initOpenCV() + public static boolean initOpenCV(boolean InitCuda) { boolean result; String libs = ""; + if(InitCuda) + { + loadLibrary("cudart"); + loadLibrary("nppc"); + loadLibrary("nppi"); + loadLibrary("npps"); + loadLibrary("cufft"); + loadLibrary("cublas"); + } + Log.d(TAG, "Trying to get library list"); try @@ -52,7 +62,7 @@ class StaticHelper { try { System.loadLibrary(Name); - Log.d(TAG, "OpenCV libs init was ok!"); + Log.d(TAG, "Library " + Name + " loaded"); } catch(UnsatisfiedLinkError e) { diff --git a/modules/java/generator/src/java/core+TermCriteria.java b/modules/java/generator/src/java/core+TermCriteria.java index 98a5e3c394..c67e51ea8d 100644 --- a/modules/java/generator/src/java/core+TermCriteria.java +++ b/modules/java/generator/src/java/core+TermCriteria.java @@ -87,7 +87,6 @@ public class TermCriteria { @Override public String toString() { - if (this == null) return "null"; return "{ type: " + type + ", maxCount: " + maxCount + ", epsilon: " + epsilon + "}"; } } diff --git a/modules/legacy/src/bgfg_gaussmix.cpp b/modules/legacy/src/bgfg_gaussmix.cpp index 3cb7a5af9f..829e4fa14c 100644 --- a/modules/legacy/src/bgfg_gaussmix.cpp +++ b/modules/legacy/src/bgfg_gaussmix.cpp @@ -415,7 +415,7 @@ CV_INLINE int _icvRemoveShadowGMM(float* data, int nD, //IEEE Trans. on Pattern Analysis and Machine Intelligence, vol.26, no.5, pages 651-656, 2004 //http://www.zoranz.net/Publications/zivkovic2004PAMI.pdf -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif @@ -608,7 +608,7 @@ CV_INLINE int _icvUpdateGMM(float* data, int nD, return bBackground; } -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic pop #endif diff --git a/modules/legacy/src/face.cpp b/modules/legacy/src/face.cpp index b188a10def..2132ea8f95 100644 --- a/modules/legacy/src/face.cpp +++ b/modules/legacy/src/face.cpp @@ -200,6 +200,7 @@ void RFace::CalculateError(FaceData * lpFaceData) void RFace::CreateFace(void * lpData) { FaceData Data; + memset(&Data, 0, sizeof(FaceData)); double Error = MAX_ERROR; double CurError = MAX_ERROR; diff --git a/modules/legacy/src/lmeds.cpp b/modules/legacy/src/lmeds.cpp index 33b57a7597..d1bb298ec1 100644 --- a/modules/legacy/src/lmeds.cpp +++ b/modules/legacy/src/lmeds.cpp @@ -163,7 +163,7 @@ icvLMedS( int *points1, int *points2, int numPoints, CvMatrix3 * fundamentalMatr /*===========================================================================*/ /*===========================================================================*/ -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Warray-bounds" #endif @@ -328,7 +328,7 @@ icvCubic( double a2, double a1, double a0, double *squares ) return CV_NO_ERR; } /* icvCubic */ -#if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) # pragma GCC diagnostic pop #endif diff --git a/modules/nonfree/CMakeLists.txt b/modules/nonfree/CMakeLists.txt index d5c5562eca..b43273bc80 100644 --- a/modules/nonfree/CMakeLists.txt +++ b/modules/nonfree/CMakeLists.txt @@ -3,10 +3,10 @@ if(BUILD_ANDROID_PACKAGE) endif() set(the_description "Functionality with possible limitations on the use") -ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef) -if (ENABLE_DYNAMIC_CUDA) - set(HAVE_CUDA FALSE) +ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wshadow) +if(ENABLE_DYNAMIC_CUDA) + add_definitions(-DDYNAMIC_CUDA_SUPPORT) ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_ocl) else() ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_gpu opencv_ocl) -endif() \ No newline at end of file +endif() diff --git a/modules/nonfree/include/opencv2/nonfree/gpu.hpp b/modules/nonfree/include/opencv2/nonfree/gpu.hpp index c8730fb3b9..722ef26a25 100644 --- a/modules/nonfree/include/opencv2/nonfree/gpu.hpp +++ b/modules/nonfree/include/opencv2/nonfree/gpu.hpp @@ -43,11 +43,7 @@ #ifndef __OPENCV_NONFREE_GPU_HPP__ #define __OPENCV_NONFREE_GPU_HPP__ -#include "opencv2/opencv_modules.hpp" - -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) - -#include "opencv2/gpu/gpu.hpp" +#include "opencv2/core/gpumat.hpp" namespace cv { namespace gpu { @@ -129,6 +125,4 @@ public: } // namespace cv -#endif // defined(HAVE_OPENCV_GPU) - #endif // __OPENCV_NONFREE_GPU_HPP__ diff --git a/modules/nonfree/perf/perf_gpu.cpp b/modules/nonfree/perf/perf_gpu.cpp index 9f451deaba..e29eeb2fa8 100644 --- a/modules/nonfree/perf/perf_gpu.cpp +++ b/modules/nonfree/perf/perf_gpu.cpp @@ -42,7 +42,9 @@ #include "perf_precomp.hpp" -#if defined(HAVE_OPENCV_GPU) && defined(HAVE_CUDA) +#include "cvconfig.h" + +#if defined(HAVE_OPENCV_GPU) && defined(HAVE_CUDA) && !defined(DYNAMIC_CUDA_SUPPORT) #include "opencv2/ts/gpu_perf.hpp" diff --git a/modules/nonfree/perf/perf_main.cpp b/modules/nonfree/perf/perf_main.cpp index d5f4a1a512..03f9b71852 100644 --- a/modules/nonfree/perf/perf_main.cpp +++ b/modules/nonfree/perf/perf_main.cpp @@ -4,6 +4,9 @@ static const char * impls[] = { #ifdef HAVE_CUDA "cuda", +#endif +#ifdef HAVE_OPENCL + "ocl", #endif "plain" }; diff --git a/modules/nonfree/perf/perf_surf.ocl.cpp b/modules/nonfree/perf/perf_surf_ocl.cpp similarity index 66% rename from modules/nonfree/perf/perf_surf.ocl.cpp rename to modules/nonfree/perf/perf_surf_ocl.cpp index cc48aa28c5..4528b79268 100644 --- a/modules/nonfree/perf/perf_surf.ocl.cpp +++ b/modules/nonfree/perf/perf_surf_ocl.cpp @@ -57,55 +57,68 @@ typedef perf::TestBaseWithParam OCL_SURF; "cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\ "stitching/a3.png" -PERF_TEST_P(OCL_SURF, DISABLED_with_data_transfer, testing::Values(SURF_IMAGES)) +#define OCL_TEST_CYCLE() for( ; startTimer(), next(); cv::ocl::finish(), stopTimer()) + +PERF_TEST_P(OCL_SURF, with_data_transfer, testing::Values(SURF_IMAGES)) { string filename = getDataPath(GetParam()); - Mat img = imread(filename, IMREAD_GRAYSCALE); - ASSERT_FALSE(img.empty()); - - SURF_OCL d_surf; - oclMat d_keypoints; - oclMat d_descriptors; - Mat cpu_kp; - Mat cpu_dp; + Mat src = imread(filename, IMREAD_GRAYSCALE); + ASSERT_FALSE(src.empty()); + Mat cpu_kp, cpu_dp; declare.time(60); - TEST_CYCLE() + if (getSelectedImpl() == "ocl") { - oclMat d_src(img); + SURF_OCL d_surf; + oclMat d_keypoints, d_descriptors; - d_surf(d_src, oclMat(), d_keypoints, d_descriptors); + OCL_TEST_CYCLE() + { + oclMat d_src(src); - d_keypoints.download(cpu_kp); - d_descriptors.download(cpu_dp); + d_surf(d_src, oclMat(), d_keypoints, d_descriptors); + + d_keypoints.download(cpu_kp); + d_descriptors.download(cpu_dp); + } } + else if (getSelectedImpl() == "plain") + { + cv::SURF surf; + std::vector kp; - SANITY_CHECK(cpu_kp, 1); - SANITY_CHECK(cpu_dp, 1); + TEST_CYCLE() surf(src, Mat(), kp, cpu_dp); + } + + SANITY_CHECK_NOTHING(); } -PERF_TEST_P(OCL_SURF, DISABLED_without_data_transfer, testing::Values(SURF_IMAGES)) +PERF_TEST_P(OCL_SURF, without_data_transfer, testing::Values(SURF_IMAGES)) { string filename = getDataPath(GetParam()); - Mat img = imread(filename, IMREAD_GRAYSCALE); - ASSERT_FALSE(img.empty()); - - SURF_OCL d_surf; - oclMat d_keypoints; - oclMat d_descriptors; - oclMat d_src(img); + Mat src = imread(filename, IMREAD_GRAYSCALE); + ASSERT_FALSE(src.empty()); + Mat cpu_kp, cpu_dp; declare.time(60); - TEST_CYCLE() d_surf(d_src, oclMat(), d_keypoints, d_descriptors); + if (getSelectedImpl() == "ocl") + { + SURF_OCL d_surf; + oclMat d_keypoints, d_descriptors, d_src(src); + + OCL_TEST_CYCLE() d_surf(d_src, oclMat(), d_keypoints, d_descriptors); + } + else if (getSelectedImpl() == "plain") + { + cv::SURF surf; + std::vector kp; + + TEST_CYCLE() surf(src, Mat(), kp, cpu_dp); + } - Mat cpu_kp; - Mat cpu_dp; - d_keypoints.download(cpu_kp); - d_descriptors.download(cpu_dp); - SANITY_CHECK(cpu_kp, 1); - SANITY_CHECK(cpu_dp, 1); + SANITY_CHECK_NOTHING(); } #endif // HAVE_OPENCV_OCL diff --git a/modules/nonfree/src/cuda/surf.cu b/modules/nonfree/src/cuda/surf.cu index df5905d31d..65345a363d 100644 --- a/modules/nonfree/src/cuda/surf.cu +++ b/modules/nonfree/src/cuda/surf.cu @@ -42,7 +42,7 @@ #include "opencv2/opencv_modules.hpp" -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) #include "opencv2/gpu/device/common.hpp" #include "opencv2/gpu/device/limits.hpp" diff --git a/modules/nonfree/src/precomp.hpp b/modules/nonfree/src/precomp.hpp index 0d2e180fc5..6311ee2aa9 100644 --- a/modules/nonfree/src/precomp.hpp +++ b/modules/nonfree/src/precomp.hpp @@ -51,17 +51,14 @@ #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/core/internal.hpp" -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) - #include "opencv2/nonfree/gpu.hpp" +#include "opencv2/nonfree/gpu.hpp" - #if defined(HAVE_CUDA) - #include "opencv2/gpu/stream_accessor.hpp" - #include "opencv2/gpu/device/common.hpp" - - static inline void throw_nogpu() { CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform"); } - #else - static inline void throw_nogpu() { CV_Error(CV_GpuNotSupported, "The library is compiled without GPU support"); } - #endif +#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) + #include "opencv2/gpu/stream_accessor.hpp" + #include "opencv2/gpu/device/common.hpp" + static inline void throw_nogpu() { CV_Error(CV_StsNotImplemented, "The called functionality is disabled for current build or platform"); } +#else + static inline void throw_nogpu() { CV_Error(CV_GpuNotSupported, "The library is compiled without GPU support"); } #endif #ifdef HAVE_OPENCV_OCL diff --git a/modules/nonfree/src/surf_gpu.cpp b/modules/nonfree/src/surf_gpu.cpp index e0cf6ff517..b3c2ce22b2 100644 --- a/modules/nonfree/src/surf_gpu.cpp +++ b/modules/nonfree/src/surf_gpu.cpp @@ -42,12 +42,10 @@ #include "precomp.hpp" -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) - using namespace cv; using namespace cv::gpu; -#if !defined (HAVE_CUDA) +#if !defined (HAVE_CUDA) || !defined(HAVE_OPENCV_GPU) || defined(DYNAMIC_CUDA_SUPPORT) cv::gpu::SURF_GPU::SURF_GPU() { throw_nogpu(); } cv::gpu::SURF_GPU::SURF_GPU(double, int, int, bool, float, bool) { throw_nogpu(); } @@ -421,5 +419,3 @@ void cv::gpu::SURF_GPU::releaseMemory() } #endif // !defined (HAVE_CUDA) - -#endif // defined(HAVE_OPENCV_GPU) && !defined(ANDROID) diff --git a/modules/nonfree/src/surf.ocl.cpp b/modules/nonfree/src/surf_ocl.cpp similarity index 100% rename from modules/nonfree/src/surf.ocl.cpp rename to modules/nonfree/src/surf_ocl.cpp diff --git a/modules/nonfree/test/test_gpu.cpp b/modules/nonfree/test/test_gpu.cpp index 3f63eeddf2..938bc1d328 100644 --- a/modules/nonfree/test/test_gpu.cpp +++ b/modules/nonfree/test/test_gpu.cpp @@ -42,7 +42,9 @@ #include "test_precomp.hpp" -#if defined(HAVE_OPENCV_GPU) && defined(HAVE_CUDA) +#include "cvconfig.h" + +#if defined(HAVE_OPENCV_GPU) && defined(HAVE_CUDA) && !defined(DYNAMIC_CUDA_SUPPORT) using namespace cvtest; diff --git a/modules/nonfree/test/test_surf.ocl.cpp b/modules/nonfree/test/test_surf_ocl.cpp similarity index 100% rename from modules/nonfree/test/test_surf.ocl.cpp rename to modules/nonfree/test/test_surf_ocl.cpp diff --git a/modules/ocl/perf/perf_haar.cpp b/modules/ocl/perf/perf_haar.cpp index 86890a8911..1a97e908c1 100644 --- a/modules/ocl/perf/perf_haar.cpp +++ b/modules/ocl/perf/perf_haar.cpp @@ -95,10 +95,11 @@ typedef perf::TestBaseWithParam OCL_Cascade_Image_M PERF_TEST_P( OCL_Cascade_Image_MinSize, CascadeClassifier, testing::Combine( - testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml") ), + testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml"), + string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt2.xml") ), testing::Values( string("cv/shared/lena.png"), - string("cv/cascadeandhog/images/bttf301.png"), - string("cv/cascadeandhog/images/class57.png") ), + string("cv/cascadeandhog/images/bttf301.png")/*, + string("cv/cascadeandhog/images/class57.png")*/ ), testing::Values(30, 64, 90) ) ) { const string cascasePath = get<0>(GetParam()); diff --git a/modules/ocl/perf/perf_ml.cpp b/modules/ocl/perf/perf_ml.cpp index db45eceb8f..13dcaa18f0 100644 --- a/modules/ocl/perf/perf_ml.cpp +++ b/modules/ocl/perf/perf_ml.cpp @@ -106,4 +106,108 @@ PERF_TEST_P(KNNFixture, KNN, }else OCL_PERF_ELSE SANITY_CHECK(best_label); -} \ No newline at end of file +} + + +typedef TestBaseWithParam > SVMFixture; + +// code is based on: samples\cpp\tutorial_code\ml\non_linear_svms\non_linear_svms.cpp +PERF_TEST_P(SVMFixture, DISABLED_SVM, + testing::Values(50, 100)) +{ + + const int NTRAINING_SAMPLES = get<0>(GetParam()); // Number of training samples per class + + #define FRAC_LINEAR_SEP 0.9f // Fraction of samples which compose the linear separable part + + const int WIDTH = 512, HEIGHT = 512; + + Mat trainData(2*NTRAINING_SAMPLES, 2, CV_32FC1); + Mat labels (2*NTRAINING_SAMPLES, 1, CV_32FC1); + + RNG rng(100); // Random value generation class + + // Set up the linearly separable part of the training data + int nLinearSamples = (int) (FRAC_LINEAR_SEP * NTRAINING_SAMPLES); + + // Generate random points for the class 1 + Mat trainClass = trainData.rowRange(0, nLinearSamples); + // The x coordinate of the points is in [0, 0.4) + Mat c = trainClass.colRange(0, 1); + rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(0.4 * WIDTH)); + // The y coordinate of the points is in [0, 1) + c = trainClass.colRange(1,2); + rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT)); + + // Generate random points for the class 2 + trainClass = trainData.rowRange(2*NTRAINING_SAMPLES-nLinearSamples, 2*NTRAINING_SAMPLES); + // The x coordinate of the points is in [0.6, 1] + c = trainClass.colRange(0 , 1); + rng.fill(c, RNG::UNIFORM, Scalar(0.6*WIDTH), Scalar(WIDTH)); + // The y coordinate of the points is in [0, 1) + c = trainClass.colRange(1,2); + rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT)); + + //------------------ Set up the non-linearly separable part of the training data --------------- + + // Generate random points for the classes 1 and 2 + trainClass = trainData.rowRange( nLinearSamples, 2*NTRAINING_SAMPLES-nLinearSamples); + // The x coordinate of the points is in [0.4, 0.6) + c = trainClass.colRange(0,1); + rng.fill(c, RNG::UNIFORM, Scalar(0.4*WIDTH), Scalar(0.6*WIDTH)); + // The y coordinate of the points is in [0, 1) + c = trainClass.colRange(1,2); + rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT)); + + //------------------------- Set up the labels for the classes --------------------------------- + labels.rowRange( 0, NTRAINING_SAMPLES).setTo(1); // Class 1 + labels.rowRange(NTRAINING_SAMPLES, 2*NTRAINING_SAMPLES).setTo(2); // Class 2 + + //------------------------ Set up the support vector machines parameters -------------------- + CvSVMParams params; + params.svm_type = SVM::C_SVC; + params.C = 0.1; + params.kernel_type = SVM::LINEAR; + params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6); + + Mat dst = Mat::zeros(HEIGHT, WIDTH, CV_8UC1); + + Mat samples(WIDTH*HEIGHT, 2, CV_32FC1); + int k = 0; + for (int i = 0; i < HEIGHT; ++i) + { + for (int j = 0; j < WIDTH; ++j) + { + samples.at(k, 0) = (float)i; + samples.at(k, 0) = (float)j; + k++; + } + } + Mat results(WIDTH*HEIGHT, 1, CV_32FC1); + + CvMat samples_ = samples; + CvMat results_ = results; + + if(RUN_PLAIN_IMPL) + { + CvSVM svm; + svm.train(trainData, labels, Mat(), Mat(), params); + TEST_CYCLE() + { + svm.predict(&samples_, &results_); + } + } + else if(RUN_OCL_IMPL) + { + CvSVM_OCL svm; + svm.train(trainData, labels, Mat(), Mat(), params); + OCL_TEST_CYCLE() + { + svm.predict(&samples_, &results_); + } + } + else + OCL_PERF_ELSE + + SANITY_CHECK_NOTHING(); +} diff --git a/modules/ocl/src/opencl/arithm_pow.cl b/modules/ocl/src/opencl/arithm_pow.cl index 385e4cc15a..fe24553e97 100644 --- a/modules/ocl/src/opencl/arithm_pow.cl +++ b/modules/ocl/src/opencl/arithm_pow.cl @@ -66,7 +66,7 @@ __kernel void arithm_pow(__global VT * src, int src_step, int src_offset, int dst_index = mad24(y, dst_step, x + dst_offset); VT src_data = src[src_index]; - VT tmp = src_data > 0 ? exp(p * log(src_data)) : (src_data == 0 ? 0 : exp(p * log(fabs(src_data)))); + VT tmp = src_data > (VT)0 ? (VT)exp(p * log(src_data)) : (src_data == (VT)0 ? (VT)0 : (VT)exp(p * log(fabs(src_data)))); dst[dst_index] = tmp; } diff --git a/modules/ocl/src/opencl/imgproc_resize.cl b/modules/ocl/src/opencl/imgproc_resize.cl index ebf8c712b7..100d687739 100644 --- a/modules/ocl/src/opencl/imgproc_resize.cl +++ b/modules/ocl/src/opencl/imgproc_resize.cl @@ -83,10 +83,10 @@ __kernel void resizeLN_C1_D0(__global uchar * dst, __global uchar const * restri int y = floor(sy); float v = sy - y; - u = x < 0 ? 0 : u; - u = (x >= src_cols) ? 0 : u; - x = x < 0 ? 0 : x; - x = (x >= src_cols) ? src_cols-1 : x; + u = x < (int4)0 ? (float4)0 : u; + u = (x >= (int4)src_cols) ? (float4)0 : u; + x = x < (int4)0 ? (int4)0 : x; + x = (x >= (int4)src_cols) ? (int4)(src_cols-1) : x; y<0 ? y=0,v=0 : y; y>=src_rows ? y=src_rows-1,v=0 : y; diff --git a/modules/stitching/CMakeLists.txt b/modules/stitching/CMakeLists.txt index 6e9a35ba73..fc8b2fcf96 100644 --- a/modules/stitching/CMakeLists.txt +++ b/modules/stitching/CMakeLists.txt @@ -1,6 +1,7 @@ set(the_description "Images stitching") -if (ENABLE_DYNAMIC_CUDA) +if(ENABLE_DYNAMIC_CUDA) + add_definitions(-DDYNAMIC_CUDA_SUPPORT) ocv_define_module(stitching opencv_imgproc opencv_features2d opencv_calib3d opencv_objdetect OPTIONAL opencv_nonfree) else() ocv_define_module(stitching opencv_imgproc opencv_features2d opencv_calib3d opencv_objdetect OPTIONAL opencv_gpu opencv_nonfree) -endif() \ No newline at end of file +endif() diff --git a/modules/stitching/include/opencv2/stitching/detail/matchers.hpp b/modules/stitching/include/opencv2/stitching/detail/matchers.hpp index 36f80f481c..af7439fba2 100644 --- a/modules/stitching/include/opencv2/stitching/detail/matchers.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/matchers.hpp @@ -44,11 +44,12 @@ #define __OPENCV_STITCHING_MATCHERS_HPP__ #include "opencv2/core/core.hpp" +#include "opencv2/core/gpumat.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/opencv_modules.hpp" -#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_NONFREE) #include "opencv2/nonfree/gpu.hpp" #endif @@ -104,7 +105,7 @@ private: }; -#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_NONFREE) class CV_EXPORTS SurfFeaturesFinderGpu : public FeaturesFinder { public: diff --git a/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp b/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp index 9301dc5ebe..5034c80043 100644 --- a/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/seam_finders.hpp @@ -45,7 +45,7 @@ #include #include "opencv2/core/core.hpp" -#include "opencv2/opencv_modules.hpp" +#include "opencv2/core/gpumat.hpp" namespace cv { namespace detail { @@ -227,7 +227,6 @@ private: }; -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder { public: @@ -251,7 +250,6 @@ private: float terminal_cost_; float bad_region_penalty_; }; -#endif } // namespace detail } // namespace cv diff --git a/modules/stitching/include/opencv2/stitching/detail/warpers.hpp b/modules/stitching/include/opencv2/stitching/detail/warpers.hpp index d44bfe69eb..60d5e54188 100644 --- a/modules/stitching/include/opencv2/stitching/detail/warpers.hpp +++ b/modules/stitching/include/opencv2/stitching/detail/warpers.hpp @@ -44,11 +44,8 @@ #define __OPENCV_STITCHING_WARPERS_HPP__ #include "opencv2/core/core.hpp" +#include "opencv2/core/gpumat.hpp" #include "opencv2/imgproc/imgproc.hpp" -#include "opencv2/opencv_modules.hpp" -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) -# include "opencv2/gpu/gpu.hpp" -#endif namespace cv { namespace detail { @@ -331,7 +328,6 @@ public: }; -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) class CV_EXPORTS PlaneWarperGpu : public PlaneWarper { public: @@ -448,7 +444,6 @@ public: private: gpu::GpuMat d_xmap_, d_ymap_, d_src_, d_dst_; }; -#endif struct SphericalPortraitProjector : ProjectorBase diff --git a/modules/stitching/include/opencv2/stitching/warpers.hpp b/modules/stitching/include/opencv2/stitching/warpers.hpp index 87efa7e80a..11e012ff09 100644 --- a/modules/stitching/include/opencv2/stitching/warpers.hpp +++ b/modules/stitching/include/opencv2/stitching/warpers.hpp @@ -145,7 +145,6 @@ public: -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) class PlaneWarperGpu: public WarperCreator { public: @@ -165,7 +164,6 @@ class SphericalWarperGpu: public WarperCreator public: Ptr create(float scale) const { return new detail::SphericalWarperGpu(scale); } }; -#endif } // namespace cv diff --git a/modules/stitching/src/blenders.cpp b/modules/stitching/src/blenders.cpp index fb3c0d666b..316263e998 100644 --- a/modules/stitching/src/blenders.cpp +++ b/modules/stitching/src/blenders.cpp @@ -189,7 +189,7 @@ Rect FeatherBlender::createWeightMaps(const vector &masks, const vector &pyr) void createLaplacePyrGpu(const Mat &img, int num_levels, vector &pyr) { -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) pyr.resize(num_levels + 1); vector gpu_pyr(num_levels + 1); @@ -512,6 +512,7 @@ void createLaplacePyrGpu(const Mat &img, int num_levels, vector &pyr) (void)img; (void)num_levels; (void)pyr; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); #endif } @@ -531,7 +532,7 @@ void restoreImageFromLaplacePyr(vector &pyr) void restoreImageFromLaplacePyrGpu(vector &pyr) { -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) if (pyr.empty()) return; @@ -549,6 +550,7 @@ void restoreImageFromLaplacePyrGpu(vector &pyr) gpu_pyr[0].download(pyr[0]); #else (void)pyr; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); #endif } diff --git a/modules/stitching/src/matchers.cpp b/modules/stitching/src/matchers.cpp index d86206233f..ac29d7ca2b 100644 --- a/modules/stitching/src/matchers.cpp +++ b/modules/stitching/src/matchers.cpp @@ -45,10 +45,7 @@ using namespace std; using namespace cv; using namespace cv::detail; - -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) using namespace cv::gpu; -#endif #ifdef HAVE_OPENCV_NONFREE #include "opencv2/nonfree/nonfree.hpp" @@ -129,7 +126,7 @@ private: float match_conf_; }; -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) class GpuMatcher : public FeaturesMatcher { public: @@ -204,7 +201,7 @@ void CpuMatcher::match(const ImageFeatures &features1, const ImageFeatures &feat LOG("1->2 & 2->1 matches: " << matches_info.matches.size() << endl); } -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) void GpuMatcher::match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo& matches_info) { matches_info.matches.clear(); @@ -432,7 +429,7 @@ void OrbFeaturesFinder::find(const Mat &image, ImageFeatures &features) } } -#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) SurfFeaturesFinderGpu::SurfFeaturesFinderGpu(double hess_thresh, int num_octaves, int num_layers, int num_octaves_descr, int num_layers_descr) { @@ -478,6 +475,29 @@ void SurfFeaturesFinderGpu::collectGarbage() keypoints_.release(); descriptors_.release(); } +#elif defined(HAVE_OPENCV_NONFREE) +SurfFeaturesFinderGpu::SurfFeaturesFinderGpu(double hess_thresh, int num_octaves, int num_layers, + int num_octaves_descr, int num_layers_descr) +{ + (void)hess_thresh; + (void)num_octaves; + (void)num_layers; + (void)num_octaves_descr; + (void)num_layers_descr; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); +} + + +void SurfFeaturesFinderGpu::find(const Mat &image, ImageFeatures &features) +{ + (void)image; + (void)features; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); +} + +void SurfFeaturesFinderGpu::collectGarbage() +{ +} #endif @@ -533,7 +553,7 @@ void FeaturesMatcher::operator ()(const vector &features, vector< BestOf2NearestMatcher::BestOf2NearestMatcher(bool try_use_gpu, float match_conf, int num_matches_thresh1, int num_matches_thresh2) { -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) if (try_use_gpu && getCudaEnabledDeviceCount() > 0) impl_ = new GpuMatcher(match_conf); else diff --git a/modules/stitching/src/precomp.hpp b/modules/stitching/src/precomp.hpp index 54b6721437..699f19c38c 100644 --- a/modules/stitching/src/precomp.hpp +++ b/modules/stitching/src/precomp.hpp @@ -68,7 +68,7 @@ #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/calib3d/calib3d.hpp" -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) #include "opencv2/gpu/gpu.hpp" #ifdef HAVE_OPENCV_NONFREE diff --git a/modules/stitching/src/seam_finders.cpp b/modules/stitching/src/seam_finders.cpp index a198c1ebb4..234f2047e6 100644 --- a/modules/stitching/src/seam_finders.cpp +++ b/modules/stitching/src/seam_finders.cpp @@ -1318,7 +1318,7 @@ void GraphCutSeamFinder::find(const vector &src, const vector &corne } -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) void GraphCutSeamFinderGpu::find(const vector &src, const vector &corners, vector &masks) { @@ -1642,6 +1642,62 @@ void GraphCutSeamFinderGpu::setGraphWeightsColorGrad( } } } +#else +void GraphCutSeamFinderGpu::find(const vector &src, const vector &corners, + vector &masks) +{ + (void)src; + (void)corners; + (void)masks; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); +} + + +void GraphCutSeamFinderGpu::findInPair(size_t first, size_t second, Rect roi) +{ + (void)first; + (void)second; + (void)roi; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); +} + + +void GraphCutSeamFinderGpu::setGraphWeightsColor(const Mat &img1, const Mat &img2, const Mat &mask1, const Mat &mask2, + Mat &terminals, Mat &leftT, Mat &rightT, Mat &top, Mat &bottom) +{ + (void)img1; + (void)img2; + (void)mask1; + (void)mask2; + (void)terminals; + (void)leftT; + (void)rightT; + (void)top; + (void)bottom; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); +} + + +void GraphCutSeamFinderGpu::setGraphWeightsColorGrad( + const Mat &img1, const Mat &img2, const Mat &dx1, const Mat &dx2, + const Mat &dy1, const Mat &dy2, const Mat &mask1, const Mat &mask2, + Mat &terminals, Mat &leftT, Mat &rightT, Mat &top, Mat &bottom) +{ + (void)img1; + (void)img2; + (void)dx1; + (void)dx2; + (void)dy1; + (void)dy2; + (void)mask1; + (void)mask2; + (void)terminals; + (void)leftT; + (void)rightT; + (void)top; + (void)bottom; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); +} #endif } // namespace detail diff --git a/modules/stitching/src/stitcher.cpp b/modules/stitching/src/stitcher.cpp index 4a36ab0a45..83ea60954e 100644 --- a/modules/stitching/src/stitcher.cpp +++ b/modules/stitching/src/stitcher.cpp @@ -58,7 +58,7 @@ Stitcher Stitcher::createDefault(bool try_use_gpu) stitcher.setFeaturesMatcher(new detail::BestOf2NearestMatcher(try_use_gpu)); stitcher.setBundleAdjuster(new detail::BundleAdjusterRay()); -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) if (try_use_gpu && gpu::getCudaEnabledDeviceCount() > 0) { #if defined(HAVE_OPENCV_NONFREE) diff --git a/modules/stitching/src/warpers.cpp b/modules/stitching/src/warpers.cpp index 935831950f..3b1d9c2287 100644 --- a/modules/stitching/src/warpers.cpp +++ b/modules/stitching/src/warpers.cpp @@ -212,7 +212,7 @@ void SphericalWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_b } -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) && !defined(DYNAMIC_CUDA_SUPPORT) Rect PlaneWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap) { return buildMaps(src_size, K, R, Mat::zeros(3, 1, CV_32F), xmap, ymap); @@ -294,6 +294,96 @@ Point CylindricalWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat gpu::remap(src, dst, d_xmap_, d_ymap_, interp_mode, border_mode); return dst_roi.tl(); } +#else +Rect PlaneWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap) +{ + return buildMaps(src_size, K, R, Mat::zeros(3, 1, CV_32F), xmap, ymap); +} + +Rect PlaneWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, gpu::GpuMat &xmap, gpu::GpuMat &ymap) +{ + (void)src_size; + (void)K; + (void)R; + (void)T; + (void)xmap; + (void)ymap; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); + return Rect(); +} + +Point PlaneWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode, + gpu::GpuMat &dst) +{ + return warp(src, K, R, Mat::zeros(3, 1, CV_32F), interp_mode, border_mode, dst); +} + + +Point PlaneWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode, + gpu::GpuMat &dst) +{ + (void)src; + (void)K; + (void)R; + (void)T; + (void)interp_mode; + (void)border_mode; + (void)dst; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); + return Point(); +} + + +Rect SphericalWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap) +{ + (void)src_size; + (void)K; + (void)R; + (void)xmap; + (void)ymap; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); + return Rect(); +} + + +Point SphericalWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode, + gpu::GpuMat &dst) +{ + (void)src; + (void)K; + (void)R; + (void)interp_mode; + (void)border_mode; + (void)dst; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); + return Point(); +} + + +Rect CylindricalWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap) +{ + (void)src_size; + (void)K; + (void)R; + (void)xmap; + (void)ymap; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); + return Rect(); +} + + +Point CylindricalWarperGpu::warp(const gpu::GpuMat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode, + gpu::GpuMat &dst) +{ + (void)src; + (void)K; + (void)R; + (void)interp_mode; + (void)border_mode; + (void)dst; + CV_Error(CV_StsNotImplemented, "CUDA optimization is unavailable"); + return Point(); +} #endif void SphericalPortraitWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br) diff --git a/modules/superres/CMakeLists.txt b/modules/superres/CMakeLists.txt index 3da8dc2c6e..82c61cccb4 100644 --- a/modules/superres/CMakeLists.txt +++ b/modules/superres/CMakeLists.txt @@ -3,5 +3,5 @@ if(ANDROID OR IOS) endif() set(the_description "Super Resolution") -ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 -Wundef) +ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 -Wundef -Wshadow) ocv_define_module(superres opencv_imgproc opencv_video OPTIONAL opencv_gpu opencv_highgui opencv_ocl ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY}) diff --git a/modules/ts/misc/xls-report.py b/modules/ts/misc/xls-report.py index e71a7f66c7..6b90b59247 100755 --- a/modules/ts/misc/xls-report.py +++ b/modules/ts/misc/xls-report.py @@ -97,6 +97,9 @@ re_data_type = re.compile(r'^ (?: 8 | 16 | 32 | 64 ) [USF] C [1234] $', re.VERBO time_style = xlwt.easyxf(num_format_str='#0.00') no_time_style = xlwt.easyxf('pattern: pattern solid, fore_color gray25') +failed_style = xlwt.easyxf('pattern: pattern solid, fore_color red') +noimpl_style = xlwt.easyxf('pattern: pattern solid, fore_color orange') +style_dict = {"failed": failed_style, "noimpl":noimpl_style} speedup_style = time_style good_speedup_style = xlwt.easyxf('font: color green', num_format_str='#0.00') @@ -328,7 +331,7 @@ def main(): for c in config_names: if c in configs: - sheet.write(row, col, configs[c], time_style) + sheet.write(row, col, configs[c], style_dict.get(configs[c], time_style)) else: sheet.write(row, col, None, no_time_style) col += 1 diff --git a/modules/ts/src/ts_arrtest.cpp b/modules/ts/src/ts_arrtest.cpp index ec3f18330d..cdfbe23b37 100644 --- a/modules/ts/src/ts_arrtest.cpp +++ b/modules/ts/src/ts_arrtest.cpp @@ -122,7 +122,7 @@ void ArrayTest::get_test_array_types_and_sizes( int /*test_case_idx*/, vector& v) + + :param v: return true if **any** of the elements of the vector is *nan*. + +Checks **point** for nan + + .. ocv:function:: bool isNan(const Point3_<_Tp>& p) + + :param p: return true if **any** of the elements of the point is *nan*. + +viz::Viz3d +---------- +.. ocv:class:: Viz3d + +The Viz3d class represents a 3D visualizer window. This class is implicitly shared. :: + + class CV_EXPORTS Viz3d + { + public: + typedef cv::Ptr Ptr; + typedef void (*KeyboardCallback)(const KeyboardEvent&, void*); + typedef void (*MouseCallback)(const MouseEvent&, void*); + + Viz3d(const String& window_name = String()); + Viz3d(const Viz3d&); + Viz3d& operator=(const Viz3d&); + ~Viz3d(); + + void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity()); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; + void removeAllWidgets(); + + void setWidgetPose(const String &id, const Affine3d &pose); + void updateWidgetPose(const String &id, const Affine3d &pose); + Affine3d getWidgetPose(const String &id) const; + + void showImage(InputArray image, const Size& window_size = Size(-1, -1)); + + void setCamera(const Camera &camera); + Camera getCamera() const; + Affine3d getViewerPose(); + void setViewerPose(const Affine3d &pose); + + void resetCameraViewpoint (const String &id); + void resetCamera(); + + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); + + Size getWindowSize() const; + void setWindowSize(const Size &window_size); + String getWindowName() const; + void saveScreenshot (const String &file); + void setWindowPosition (int x, int y); + void setFullScreen (bool mode); + void setBackgroundColor(const Color& color = Color::black()); + + void spin(); + void spinOnce(int time = 1, bool force_redraw = false); + bool wasStopped() const; + + void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); + void registerMouseCallback(MouseCallback callback, void* cookie = 0); + + void setRenderingProperty(const String &id, int property, double value); + double getRenderingProperty(const String &id, int property); + + + void setRepresentation(int representation); + private: + /* hidden */ + }; + +viz::Viz3d::Viz3d +----------------- +The constructors. + +.. ocv:function:: Viz3d::Viz3d(const String& window_name = String()) + + :param window_name: Name of the window. + +viz::Viz3d::showWidget +---------------------- +Shows a widget in the window. + +.. ocv:function:: void Viz3d::showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity()) + + :param id: A unique id for the widget. + :param widget: The widget to be displayed in the window. + :param pose: Pose of the widget. + +viz::Viz3d::removeWidget +------------------------ +Removes a widget from the window. + +.. ocv:function:: void removeWidget(const String &id) + + :param id: The id of the widget that will be removed. + +viz::Viz3d::getWidget +--------------------- +Retrieves a widget from the window. A widget is implicitly shared; +that is, if the returned widget is modified, the changes will be +immediately visible in the window. + +.. ocv:function:: Widget getWidget(const String &id) const + + :param id: The id of the widget that will be returned. + +viz::Viz3d::removeAllWidgets +---------------------------- +Removes all widgets from the window. + +.. ocv:function:: void removeAllWidgets() + +viz::Viz3d::showImage +--------------------- +Removed all widgets and displays image scaled to whole window area. + +.. ocv:function:: void showImage(InputArray image, const Size& window_size = Size(-1, -1)) + + :param image: Image to be displayed. + :param size: Size of Viz3d window. Default value means no change. + +viz::Viz3d::setWidgetPose +------------------------- +Sets pose of a widget in the window. + +.. ocv:function:: void setWidgetPose(const String &id, const Affine3d &pose) + + :param id: The id of the widget whose pose will be set. + :param pose: The new pose of the widget. + +viz::Viz3d::updateWidgetPose +---------------------------- +Updates pose of a widget in the window by pre-multiplying its current pose. + +.. ocv:function:: void updateWidgetPose(const String &id, const Affine3d &pose) + + :param id: The id of the widget whose pose will be updated. + :param pose: The pose that the current pose of the widget will be pre-multiplied by. + +viz::Viz3d::getWidgetPose +------------------------- +Returns the current pose of a widget in the window. + +.. ocv:function:: Affine3d getWidgetPose(const String &id) const + + :param id: The id of the widget whose pose will be returned. + +viz::Viz3d::setCamera +--------------------- +Sets the intrinsic parameters of the viewer using Camera. + +.. ocv:function:: void setCamera(const Camera &camera) + + :param camera: Camera object wrapping intrinsinc parameters. + +viz::Viz3d::getCamera +--------------------- +Returns a camera object that contains intrinsic parameters of the current viewer. + +.. ocv:function:: Camera getCamera() const + +viz::Viz3d::getViewerPose +------------------------- +Returns the current pose of the viewer. + +..ocv:function:: Affine3d getViewerPose() + +viz::Viz3d::setViewerPose +------------------------- +Sets pose of the viewer. + +.. ocv:function:: void setViewerPose(const Affine3d &pose) + + :param pose: The new pose of the viewer. + +viz::Viz3d::resetCameraViewpoint +-------------------------------- +Resets camera viewpoint to a 3D widget in the scene. + +.. ocv:function:: void resetCameraViewpoint (const String &id) + + :param pose: Id of a 3D widget. + +viz::Viz3d::resetCamera +----------------------- +Resets camera. + +.. ocv:function:: void resetCamera() + +viz::Viz3d::convertToWindowCoordinates +-------------------------------------- +Transforms a point in world coordinate system to window coordinate system. + +.. ocv:function:: void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) + + :param pt: Point in world coordinate system. + :param window_coord: Output point in window coordinate system. + +viz::Viz3d::converTo3DRay +------------------------- +Transforms a point in window coordinate system to a 3D ray in world coordinate system. + +.. ocv:function:: void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) + + :param window_coord: Point in window coordinate system. + :param origin: Output origin of the ray. + :param direction: Output direction of the ray. + +viz::Viz3d::getWindowSize +------------------------- +Returns the current size of the window. + +.. ocv:function:: Size getWindowSize() const + +viz::Viz3d::setWindowSize +------------------------- +Sets the size of the window. + +.. ocv:function:: void setWindowSize(const Size &window_size) + + :param window_size: New size of the window. + +viz::Viz3d::getWindowName +------------------------- +Returns the name of the window which has been set in the constructor. + +.. ocv:function:: String getWindowName() const + +viz::Viz3d::saveScreenshot +-------------------------- +Saves screenshot of the current scene. + +.. ocv:function:: void saveScreenshot(const String &file) + + :param file: Name of the file. + +viz::Viz3d::setWindowPosition +----------------------------- +Sets the position of the window in the screen. + +.. ocv:function:: void setWindowPosition(int x, int y) + + :param x: x coordinate of the window + :param y: y coordinate of the window + +viz::Viz3d::setFullScreen +------------------------- +Sets or unsets full-screen rendering mode. + +.. ocv:function:: void setFullScreen(bool mode) + + :param mode: If true, window will use full-screen mode. + +viz::Viz3d::setBackgroundColor +------------------------------ +Sets background color. + +.. ocv:function:: void setBackgroundColor(const Color& color = Color::black()) + +viz::Viz3d::spin +---------------- +The window renders and starts the event loop. + +.. ocv:function:: void spin() + +viz::Viz3d::spinOnce +-------------------- +Starts the event loop for a given time. + +.. ocv:function:: void spinOnce(int time = 1, bool force_redraw = false) + + :param time: Amount of time in milliseconds for the event loop to keep running. + :param force_draw: If true, window renders. + +viz::Viz3d::wasStopped +---------------------- +Returns whether the event loop has been stopped. + +.. ocv:function:: bool wasStopped() + +viz::Viz3d::registerKeyboardCallback +------------------------------------ +Sets keyboard handler. + +.. ocv:function:: void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0) + + :param callback: Keyboard callback ``(void (*KeyboardCallbackFunction(const KeyboardEvent&, void*))``. + :param cookie: The optional parameter passed to the callback. + +viz::Viz3d::registerMouseCallback +--------------------------------- +Sets mouse handler. + +.. ocv:function:: void registerMouseCallback(MouseCallback callback, void* cookie = 0) + + :param callback: Mouse callback ``(void (*MouseCallback)(const MouseEvent&, void*))``. + :param cookie: The optional parameter passed to the callback. + +viz::Viz3d::setRenderingProperty +-------------------------------- +Sets rendering property of a widget. + +.. ocv:function:: void setRenderingProperty(const String &id, int property, double value) + + :param id: Id of the widget. + :param property: Property that will be modified. + :param value: The new value of the property. + + **Rendering property** can be one of the following: + + * **POINT_SIZE** + * **OPACITY** + * **LINE_WIDTH** + * **FONT_SIZE** + * **REPRESENTATION**: Expected values are + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + * **IMMEDIATE_RENDERING**: + * Turn on immediate rendering by setting the value to ``1``. + * Turn off immediate rendering by setting the value to ``0``. + * **SHADING**: Expected values are + * **SHADING_FLAT** + * **SHADING_GOURAUD** + * **SHADING_PHONG** + +viz::Viz3d::getRenderingProperty +-------------------------------- +Returns rendering property of a widget. + +.. ocv:function:: double getRenderingProperty(const String &id, int property) + + :param id: Id of the widget. + :param property: Property. + + **Rendering property** can be one of the following: + + * **POINT_SIZE** + * **OPACITY** + * **LINE_WIDTH** + * **FONT_SIZE** + * **REPRESENTATION**: Expected values are + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + * **IMMEDIATE_RENDERING**: + * Turn on immediate rendering by setting the value to ``1``. + * Turn off immediate rendering by setting the value to ``0``. + * **SHADING**: Expected values are + * **SHADING_FLAT** + * **SHADING_GOURAUD** + * **SHADING_PHONG** + +viz::Viz3d::setRepresentation +----------------------------- +Sets geometry representation of the widgets to surface, wireframe or points. + +.. ocv:function:: void setRepresentation(int representation) + + :param representation: Geometry representation which can be one of the following: + + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + +viz::Color +---------- +.. ocv:class:: Color + +This class a represents BGR color. :: + + class CV_EXPORTS Color : public Scalar + { + public: + Color(); + Color(double gray); + Color(double blue, double green, double red); + + Color(const Scalar& color); + + static Color black(); + static Color blue(); + static Color green(); + static Color cyan(); + + static Color red(); + static Color magenta(); + static Color yellow(); + static Color white(); + + static Color gray(); + }; + +viz::Mesh +----------- +.. ocv:class:: Mesh + +This class wraps mesh attributes, and it can load a mesh from a ``ply`` file. :: + + class CV_EXPORTS Mesh + { + public: + + Mat cloud, colors, normals; + + //! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...) + //! where n is the number of points in the poligon, and id is a zero-offset index into an associated cloud. + Mat polygons; + + //! Loads mesh from a given ply file + static Mesh load(const String& file); + }; + +viz::Mesh::load +--------------------- +Loads a mesh from a ``ply`` file. + +.. ocv:function:: static Mesh load(const String& file) + + :param file: File name (for no only PLY is supported) + + +viz::KeyboardEvent +------------------ +.. ocv:class:: KeyboardEvent + +This class represents a keyboard event. :: + + class CV_EXPORTS KeyboardEvent + { + public: + enum { ALT = 1, CTRL = 2, SHIFT = 4 }; + enum Action { KEY_UP = 0, KEY_DOWN = 1 }; + + KeyboardEvent(Action action, const String& symbol, unsigned char code, int modifiers); + + Action action; + String symbol; + unsigned char code; + int modifiers; + }; + +viz::KeyboardEvent::KeyboardEvent +--------------------------------- +Constructs a KeyboardEvent. + +.. ocv:function:: KeyboardEvent (Action action, const String& symbol, unsigned char code, Modifiers modifiers) + + :param action: Signals if key is pressed or released. + :param symbol: Name of the key. + :param code: Code of the key. + :param modifiers: Signals if ``alt``, ``ctrl`` or ``shift`` are pressed or their combination. + + +viz::MouseEvent +--------------- +.. ocv:class:: MouseEvent + +This class represents a mouse event. :: + + class CV_EXPORTS MouseEvent + { + public: + enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ; + enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ; + + MouseEvent(const Type& type, const MouseButton& button, const Point& pointer, int modifiers); + + Type type; + MouseButton button; + Point pointer; + int modifiers; + }; + +viz::MouseEvent::MouseEvent +--------------------------- +Constructs a MouseEvent. + +.. ocv:function:: MouseEvent (const Type& type, const MouseButton& button, const Point& p, Modifiers modifiers) + + :param type: Type of the event. This can be **MouseMove**, **MouseButtonPress**, **MouseButtonRelease**, **MouseScrollDown**, **MouseScrollUp**, **MouseDblClick**. + :param button: Mouse button. This can be **NoButton**, **LeftButton**, **MiddleButton**, **RightButton**, **VScroll**. + :param p: Position of the event. + :param modifiers: Signals if ``alt``, ``ctrl`` or ``shift`` are pressed or their combination. + +viz::Camera +----------- +.. ocv:class:: Camera + +This class wraps intrinsic parameters of a camera. It provides several constructors +that can extract the intrinsic parameters from ``field of view``, ``intrinsic matrix`` and +``projection matrix``. :: + + class CV_EXPORTS Camera + { + public: + Camera(double f_x, double f_y, double c_x, double c_y, const Size &window_size); + Camera(const Vec2d &fov, const Size &window_size); + Camera(const Matx33d &K, const Size &window_size); + Camera(const Matx44d &proj, const Size &window_size); + + inline const Vec2d & getClip() const; + inline void setClip(const Vec2d &clip); + + inline const Size & getWindowSize() const; + void setWindowSize(const Size &window_size); + + inline const Vec2d & getFov() const; + inline void setFov(const Vec2d & fov); + + inline const Vec2d & getPrincipalPoint() const; + inline const Vec2d & getFocalLength() const; + + void computeProjectionMatrix(Matx44d &proj) const; + + static Camera KinectCamera(const Size &window_size); + + private: + /* hidden */ + }; + +viz::Camera::Camera +------------------- +Constructs a Camera. + +.. ocv:function:: Camera(double f_x, double f_y, double c_x, double c_y, const Size &window_size) + + :param f_x: Horizontal focal length. + :param f_y: Vertical focal length. + :param c_x: x coordinate of the principal point. + :param c_y: y coordinate of the principal point. + :param window_size: Size of the window. This together with focal length and principal point determines the field of view. + +.. ocv:function:: Camera(const Vec2d &fov, const Size &window_size) + + :param fov: Field of view (horizontal, vertical) + :param window_size: Size of the window. + + Principal point is at the center of the window by default. + +.. ocv:function:: Camera(const Matx33d &K, const Size &window_size) + + :param K: Intrinsic matrix of the camera. + :param window_size: Size of the window. This together with intrinsic matrix determines the field of view. + +.. ocv:function:: Camera(const Matx44d &proj, const Size &window_size) + + :param proj: Projection matrix of the camera. + :param window_size: Size of the window. This together with projection matrix determines the field of view. + +viz::Camera::computeProjectionMatrix +------------------------------------ +Computes projection matrix using intrinsic parameters of the camera. + +.. ocv:function:: void computeProjectionMatrix(Matx44d &proj) const + + :param proj: Output projection matrix. + +viz::Camera::KinectCamera +------------------------- +Creates a Kinect Camera. + +.. ocv:function:: static Camera KinectCamera(const Size &window_size) + + :param window_size: Size of the window. This together with intrinsic matrix of a Kinect Camera determines the field of view. diff --git a/modules/viz/doc/widget.rst b/modules/viz/doc/widget.rst new file mode 100644 index 0000000000..008e0e68a5 --- /dev/null +++ b/modules/viz/doc/widget.rst @@ -0,0 +1,1019 @@ +Widget +====== + +.. highlight:: cpp + +In this section, the widget framework is explained. Widgets represent +2D or 3D objects, varying from simple ones such as lines to complex one such as +point clouds and meshes. + +Widgets are **implicitly shared**. Therefore, one can add a widget to the scene, +and modify the widget without re-adding the widget. + +.. code-block:: cpp + + ... + /// Create a cloud widget + viz::WCloud cw(cloud, viz::Color::red()); + /// Display it in a window + myWindow.showWidget("CloudWidget1", cw); + /// Modify it, and it will be modified in the window. + cw.setColor(viz::Color::yellow()); + ... + +viz::Widget +----------- +.. ocv:class:: Widget + +Base class of all widgets. Widget is implicitly shared. :: + + class CV_EXPORTS Widget + { + public: + Widget(); + Widget(const Widget& other); + Widget& operator=(const Widget& other); + ~Widget(); + + //! Create a widget directly from ply file + static Widget fromPlyFile(const String &file_name); + + //! Rendering properties of this particular widget + void setRenderingProperty(int property, double value); + double getRenderingProperty(int property) const; + + //! Casting between widgets + template _W cast(); + private: + /* hidden */ + }; + +viz::Widget::fromPlyFile +------------------------ +Creates a widget from ply file. + +.. ocv:function:: static Widget fromPlyFile(const String &file_name) + + :param file_name: Ply file name. + +viz::Widget::setRenderingProperty +--------------------------------- +Sets rendering property of the widget. + +.. ocv:function:: void setRenderingProperty(int property, double value) + + :param property: Property that will be modified. + :param value: The new value of the property. + + **Rendering property** can be one of the following: + + * **POINT_SIZE** + * **OPACITY** + * **LINE_WIDTH** + * **FONT_SIZE** + * **REPRESENTATION**: Expected values are + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + * **IMMEDIATE_RENDERING**: + * Turn on immediate rendering by setting the value to ``1``. + * Turn off immediate rendering by setting the value to ``0``. + * **SHADING**: Expected values are + * **SHADING_FLAT** + * **SHADING_GOURAUD** + * **SHADING_PHONG** + +viz::Widget::getRenderingProperty +--------------------------------- +Returns rendering property of the widget. + +.. ocv:function:: double getRenderingProperty(int property) const + + :param property: Property. + + **Rendering property** can be one of the following: + + * **POINT_SIZE** + * **OPACITY** + * **LINE_WIDTH** + * **FONT_SIZE** + * **REPRESENTATION**: Expected values are + * **REPRESENTATION_POINTS** + * **REPRESENTATION_WIREFRAME** + * **REPRESENTATION_SURFACE** + * **IMMEDIATE_RENDERING**: + * Turn on immediate rendering by setting the value to ``1``. + * Turn off immediate rendering by setting the value to ``0``. + * **SHADING**: Expected values are + * **SHADING_FLAT** + * **SHADING_GOURAUD** + * **SHADING_PHONG** + +viz::Widget::cast +----------------- +Casts a widget to another. + +.. ocv:function:: template _W cast() + +.. code-block:: cpp + + // Create a sphere widget + viz::WSphere sw(Point3f(0.0f,0.0f,0.0f), 0.5f); + // Cast sphere widget to cloud widget + viz::WCloud cw = sw.cast(); + +.. note:: 3D Widgets can only be cast to 3D Widgets. 2D Widgets can only be cast to 2D Widgets. + +viz::WidgetAccessor +------------------- +.. ocv:class:: WidgetAccessor + +This class is for users who want to develop their own widgets using VTK library API. :: + + struct CV_EXPORTS WidgetAccessor + { + static vtkSmartPointer getProp(const Widget &widget); + static void setProp(Widget &widget, vtkSmartPointer prop); + }; + +viz::WidgetAccessor::getProp +---------------------------- +Returns ``vtkProp`` of a given widget. + +.. ocv:function:: static vtkSmartPointer getProp(const Widget &widget) + + :param widget: Widget whose ``vtkProp`` is to be returned. + +.. note:: vtkProp has to be down cast appropriately to be modified. + + .. code-block:: cpp + + vtkActor * actor = vtkActor::SafeDownCast(viz::WidgetAccessor::getProp(widget)); + +viz::WidgetAccessor::setProp +---------------------------- +Sets ``vtkProp`` of a given widget. + +.. ocv:function:: static void setProp(Widget &widget, vtkSmartPointer prop) + + :param widget: Widget whose ``vtkProp`` is to be set. + :param prop: A ``vtkProp``. + +viz::Widget3D +------------- +.. ocv:class:: Widget3D + +Base class of all 3D widgets. :: + + class CV_EXPORTS Widget3D : public Widget + { + public: + Widget3D() {} + + //! widget position manipulation, i.e. place where it is rendered. + void setPose(const Affine3d &pose); + void updatePose(const Affine3d &pose); + Affine3d getPose() const; + + //! updates internal widget data, i.e. points, normals, etc. + void applyTransform(const Affine3d &transform); + + void setColor(const Color &color); + + }; + +viz::Widget3D::setPose +---------------------- +Sets pose of the widget. + +.. ocv:function:: void setPose(const Affine3d &pose) + + :param pose: The new pose of the widget. + +viz::Widget3D::updateWidgetPose +------------------------------- +Updates pose of the widget by pre-multiplying its current pose. + +.. ocv:function:: void updateWidgetPose(const Affine3d &pose) + + :param pose: The pose that the current pose of the widget will be pre-multiplied by. + +viz::Widget3D::getPose +---------------------- +Returns the current pose of the widget. + +.. ocv:function:: Affine3d getWidgetPose() const + + +viz::Widget3D::applyTransform +------------------------------- +Transforms internal widget data (i.e. points, normals) using the given transform. + +.. ocv:function:: void applyTransform(const Affine3d &transform) + + :param transform: Specified transformation to apply. + +viz::Widget3D::setColor +----------------------- +Sets the color of the widget. + +.. ocv:function:: void setColor(const Color &color) + + :param color: color of type :ocv:class:`Color` + +viz::Widget2D +------------- +.. ocv:class:: Widget2D + +Base class of all 2D widgets. :: + + class CV_EXPORTS Widget2D : public Widget + { + public: + Widget2D() {} + + void setColor(const Color &color); + }; + +viz::Widget2D::setColor +----------------------- +Sets the color of the widget. + +.. ocv:function:: void setColor(const Color &color) + + :param color: color of type :ocv:class:`Color` + +viz::WLine +---------- +.. ocv:class:: WLine + +This 3D Widget defines a finite line. :: + + class CV_EXPORTS WLine : public Widget3D + { + public: + WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()); + }; + +viz::WLine::WLine +----------------- +Constructs a WLine. + +.. ocv:function:: WLine(const Point3f &pt1, const Point3f &pt2, const Color &color = Color::white()) + + :param pt1: Start point of the line. + :param pt2: End point of the line. + :param color: :ocv:class:`Color` of the line. + +viz::WPlane +----------- +.. ocv:class:: WPlane + +This 3D Widget defines a finite plane. :: + + class CV_EXPORTS WPlane : public Widget3D + { + public: + //! created default plane with center point at origin and normal oriented along z-axis + WPlane(const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); + + //! repositioned plane + WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_plane_yaxis,const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); + }; + +viz::WPlane::WPlane +------------------- +Constructs a default plane with center point at origin and normal oriented along z-axis. + +.. ocv:function:: WPlane(const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()) + + :param size: Size of the plane + :param color: :ocv:class:`Color` of the plane. + +viz::WPlane::WPlane +------------------- +Constructs a repositioned plane + +.. ocv:function:: WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis,const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()) + + :param center: Center of the plane + :param normal: Plane normal orientation + :param new_yaxis: Up-vector. New orientation of plane y-axis. + :param color: :ocv:class:`Color` of the plane. + +viz::WSphere +------------ +.. ocv:class:: WSphere + +This 3D Widget defines a sphere. :: + + class CV_EXPORTS WSphere : public Widget3D + { + public: + WSphere(const cv::Point3f ¢er, double radius, int sphere_resolution = 10, const Color &color = Color::white()) + }; + +viz::WSphere::WSphere +--------------------- +Constructs a WSphere. + +.. ocv:function:: WSphere(const cv::Point3f ¢er, double radius, int sphere_resolution = 10, const Color &color = Color::white()) + + :param center: Center of the sphere. + :param radius: Radius of the sphere. + :param sphere_resolution: Resolution of the sphere. + :param color: :ocv:class:`Color` of the sphere. + +viz::WArrow +---------------- +.. ocv:class:: WArrow + +This 3D Widget defines an arrow. :: + + class CV_EXPORTS WArrow : public Widget3D + { + public: + WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()); + }; + +viz::WArrow::WArrow +----------------------------- +Constructs an WArrow. + +.. ocv:function:: WArrow(const Point3f& pt1, const Point3f& pt2, double thickness = 0.03, const Color &color = Color::white()) + + :param pt1: Start point of the arrow. + :param pt2: End point of the arrow. + :param thickness: Thickness of the arrow. Thickness of arrow head is also adjusted accordingly. + :param color: :ocv:class:`Color` of the arrow. + +Arrow head is located at the end point of the arrow. + +viz::WCircle +----------------- +.. ocv:class:: WCircle + +This 3D Widget defines a circle. :: + + class CV_EXPORTS WCircle : public Widget3D + { + public: + //! creates default planar circle centred at origin with plane normal along z-axis + WCircle(double radius, double thickness = 0.01, const Color &color = Color::white()); + + //! creates repositioned circle + WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness = 0.01, const Color &color = Color::white()); + }; + +viz::WCircle::WCircle +------------------------------- +Constructs default planar circle centred at origin with plane normal along z-axis + +.. ocv:function:: WCircle(double radius, double thickness = 0.01, const Color &color = Color::white()) + + :param radius: Radius of the circle. + :param thickness: Thickness of the circle. + :param color: :ocv:class:`Color` of the circle. + +viz::WCircle::WCircle +------------------------------- +Constructs repositioned planar circle. + +.. ocv:function:: WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness = 0.01, const Color &color = Color::white()) + + :param radius: Radius of the circle. + :param center: Center of the circle. + :param normal: Normal of the plane in which the circle lies. + :param thickness: Thickness of the circle. + :param color: :ocv:class:`Color` of the circle. + +viz::WCone +------------------------------- +.. ocv:class:: WCone + +This 3D Widget defines a cone. :: + + class CV_EXPORTS WCone : public Widget3D + { + public: + //! create default cone, oriented along x-axis with center of its base located at origin + WCone(double lenght, double radius, int resolution = 6.0, const Color &color = Color::white()); + + //! creates repositioned cone + WCone(double radius, const Point3d& center, const Point3d& tip, int resolution = 6.0, const Color &color = Color::white()); + }; + +viz::WCone::WCone +------------------------------- +Constructs default cone oriented along x-axis with center of its base located at origin + +.. ocv:function:: WCone(double length, double radius, int resolution = 6.0, const Color &color = Color::white()) + + :param length: Length of the cone. + :param radius: Radius of the cone. + :param resolution: Resolution of the cone. + :param color: :ocv:class:`Color` of the cone. + +viz::WCone::WCone +------------------------------- +Constructs repositioned planar cone. + +.. ocv:function:: WCone(double radius, const Point3d& center, const Point3d& tip, int resolution = 6.0, const Color &color = Color::white()) + + :param radius: Radius of the cone. + :param center: Center of the cone base. + :param tip: Tip of the cone. + :param resolution: Resolution of the cone. + :param color: :ocv:class:`Color` of the cone. + +viz::WCylinder +-------------- +.. ocv:class:: WCylinder + +This 3D Widget defines a cylinder. :: + + class CV_EXPORTS WCylinder : public Widget3D + { + public: + WCylinder(const Point3d& axis_point1, const Point3d& axis_point2, double radius, int numsides = 30, const Color &color = Color::white()); + }; + +viz::WCylinder::WCylinder +----------------------------------- +Constructs a WCylinder. + +.. ocv:function:: WCylinder(const Point3f& pt_on_axis, const Point3f& axis_direction, double radius, int numsides = 30, const Color &color = Color::white()) + + :param axis_point1: A point1 on the axis of the cylinder. + :param axis_point2: A point2 on the axis of the cylinder. + :param radius: Radius of the cylinder. + :param numsides: Resolution of the cylinder. + :param color: :ocv:class:`Color` of the cylinder. + +viz::WCube +---------- +.. ocv:class:: WCube + +This 3D Widget defines a cube. :: + + class CV_EXPORTS WCube : public Widget3D + { + public: + WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()); + }; + +viz::WCube::WCube +--------------------------- +Constructs a WCube. + +.. ocv:function:: WCube(const Point3f& pt_min, const Point3f& pt_max, bool wire_frame = true, const Color &color = Color::white()) + + :param pt_min: Specifies minimum point of the bounding box. + :param pt_max: Specifies maximum point of the bounding box. + :param wire_frame: If true, cube is represented as wireframe. + :param color: :ocv:class:`Color` of the cube. + +.. image:: images/cube_widget.png + :alt: Cube Widget + :align: center + +viz::WCoordinateSystem +---------------------- +.. ocv:class:: WCoordinateSystem + +This 3D Widget represents a coordinate system. :: + + class CV_EXPORTS WCoordinateSystem : public Widget3D + { + public: + WCoordinateSystem(double scale = 1.0); + }; + +viz::WCoordinateSystem::WCoordinateSystem +--------------------------------------------------- +Constructs a WCoordinateSystem. + +.. ocv:function:: WCoordinateSystem(double scale = 1.0) + + :param scale: Determines the size of the axes. + +viz::WPolyLine +-------------- +.. ocv:class:: WPolyLine + +This 3D Widget defines a poly line. :: + + class CV_EXPORTS WPolyLine : public Widget3D + { + public: + WPolyLine(InputArray points, const Color &color = Color::white()); + }; + +viz::WPolyLine::WPolyLine +----------------------------------- +Constructs a WPolyLine. + +.. ocv:function:: WPolyLine(InputArray points, const Color &color = Color::white()) + + :param points: Point set. + :param color: :ocv:class:`Color` of the poly line. + +viz::WGrid +---------- +.. ocv:class:: WGrid + +This 3D Widget defines a grid. :: + + class CV_EXPORTS WGrid : public Widget3D + { + public: + //! Creates grid at the origin and normal oriented along z-axis + WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); + + //! Creates repositioned grid + WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, + const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); + }; + +viz::WGrid::WGrid +--------------------------- +Constructs a WGrid. + +.. ocv:function:: WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()) + + :param cells: Number of cell columns and rows, respectively. + :param cells_spacing: Size of each cell, respectively. + :param color: :ocv:class:`Color` of the grid. + +.. ocv:function: WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, Vec2i &cells, const Vec2d &cells_spacing, const Color &color; + + :param center: Center of the grid + :param normal: Grid normal orientation + :param new_yaxis: Up-vector. New orientation of grid y-axis. + :param cells: Number of cell columns and rows, respectively. + :param cells_spacing: Size of each cell, respectively. + :param color: :ocv:class:`Color` of the grid.. + +viz::WText3D +------------ +.. ocv:class:: WText3D + +This 3D Widget represents 3D text. The text always faces the camera. :: + + class CV_EXPORTS WText3D : public Widget3D + { + public: + WText3D(const String &text, const Point3f &position, double text_scale = 1.0, bool face_camera = true, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + +viz::WText3D::WText3D +------------------------------- +Constructs a WText3D. + +.. ocv:function:: WText3D(const String &text, const Point3f &position, double text_scale = 1.0, bool face_camera = true, const Color &color = Color::white()) + + :param text: Text content of the widget. + :param position: Position of the text. + :param text_scale: Size of the text. + :param face_camera: If true, text always faces the camera. + :param color: :ocv:class:`Color` of the text. + +viz::WText3D::setText +--------------------- +Sets the text content of the widget. + +.. ocv:function:: void setText(const String &text) + + :param text: Text content of the widget. + +viz::WText3D::getText +--------------------- +Returns the current text content of the widget. + +.. ocv:function:: String getText() const + +viz::WText +---------- +.. ocv:class:: WText + +This 2D Widget represents text overlay. :: + + class CV_EXPORTS WText : public Widget2D + { + public: + WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + +viz::WText::WText +----------------- +Constructs a WText. + +.. ocv:function:: WText(const String &text, const Point2i &pos, int font_size = 10, const Color &color = Color::white()) + + :param text: Text content of the widget. + :param pos: Position of the text. + :param font_size: Font size. + :param color: :ocv:class:`Color` of the text. + +viz::WText::setText +------------------- +Sets the text content of the widget. + +.. ocv:function:: void setText(const String &text) + + :param text: Text content of the widget. + +viz::WText::getText +------------------- +Returns the current text content of the widget. + +.. ocv:function:: String getText() const + +viz::WImageOverlay +------------------ +.. ocv:class:: WImageOverlay + +This 2D Widget represents an image overlay. :: + + class CV_EXPORTS WImageOverlay : public Widget2D + { + public: + WImageOverlay(InputArray image, const Rect &rect); + + void setImage(InputArray image); + }; + +viz::WImageOverlay::WImageOverlay +--------------------------------- +Constructs an WImageOverlay. + +.. ocv:function:: WImageOverlay(InputArray image, const Rect &rect) + + :param image: BGR or Gray-Scale image. + :param rect: Image is scaled and positioned based on rect. + +viz::WImageOverlay::setImage +---------------------------- +Sets the image content of the widget. + +.. ocv:function:: void setImage(InputArray image) + + :param image: BGR or Gray-Scale image. + +viz::WImage3D +------------- +.. ocv:class:: WImage3D + +This 3D Widget represents an image in 3D space. :: + + class CV_EXPORTS WImage3D : public Widget3D + { + public: + //! Creates 3D image at the origin + WImage3D(InputArray image, const Size2d &size); + //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation + WImage3D(InputArray image, const Size2d &size, const Vec3d &position, const Vec3d &normal, const Vec3d &up_vector); + + void setImage(InputArray image); + }; + +viz::WImage3D::WImage3D +----------------------- +Constructs an WImage3D. + +.. ocv:function:: WImage3D(InputArray image, const Size2d &size) + + :param image: BGR or Gray-Scale image. + :param size: Size of the image. + +.. ocv:function:: WImage3D(InputArray image, const Size2d &size, const Vec3d &position, const Vec3d &normal, const Vec3d &up_vector) + + :param position: Position of the image. + :param normal: Normal of the plane that represents the image. + :param up_vector: Determines orientation of the image. + :param image: BGR or Gray-Scale image. + :param size: Size of the image. + +viz::WImage3D::setImage +----------------------- +Sets the image content of the widget. + +.. ocv:function:: void setImage(InputArray image) + + :param image: BGR or Gray-Scale image. + +viz::WCameraPosition +-------------------- +.. ocv:class:: WCameraPosition + +This 3D Widget represents camera position in a scene by its axes or viewing frustum. :: + + class CV_EXPORTS WCameraPosition : public Widget3D + { + public: + //! Creates camera coordinate frame (axes) at the origin + WCameraPosition(double scale = 1.0); + //! Creates frustum based on the intrinsic marix K at the origin + WCameraPosition(const Matx33d &K, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum based on the field of view at the origin + WCameraPosition(const Vec2d &fov, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane + WCameraPosition(const Matx33d &K, InputArray image, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane + WCameraPosition(const Vec2d &fov, InputArray image, double scale = 1.0, const Color &color = Color::white()); + }; + +viz::WCameraPosition::WCameraPosition +------------------------------------- +Constructs a WCameraPosition. + +- **Display camera coordinate frame.** + + .. ocv:function:: WCameraPosition(double scale = 1.0) + + Creates camera coordinate frame at the origin. + + .. image:: images/cpw1.png + :alt: Camera coordinate frame + :align: center + +- **Display the viewing frustum.** + + .. ocv:function:: WCameraPosition(const Matx33d &K, double scale = 1.0, const Color &color = Color::white()) + + :param K: Intrinsic matrix of the camera. + :param scale: Scale of the frustum. + :param color: :ocv:class:`Color` of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K. + + .. ocv:function:: WCameraPosition(const Vec2d &fov, double scale = 1.0, const Color &color = Color::white()) + + :param fov: Field of view of the camera (horizontal, vertical). + :param scale: Scale of the frustum. + :param color: :ocv:class:`Color` of the frustum. + + Creates viewing frustum of the camera based on its field of view fov. + + .. image:: images/cpw2.png + :alt: Camera viewing frustum + :align: center + +- **Display image on the far plane of the viewing frustum.** + + .. ocv:function:: WCameraPosition(const Matx33d &K, InputArray image, double scale = 1.0, const Color &color = Color::white()) + + :param K: Intrinsic matrix of the camera. + :param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum. + :param scale: Scale of the frustum and image. + :param color: :ocv:class:`Color` of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. + + .. ocv:function:: WCameraPosition(const Vec2d &fov, InputArray image, double scale = 1.0, const Color &color = Color::white()) + + :param fov: Field of view of the camera (horizontal, vertical). + :param img: BGR or Gray-Scale image that is going to be displayed on the far plane of the frustum. + :param scale: Scale of the frustum and image. + :param color: :ocv:class:`Color` of the frustum. + + Creates viewing frustum of the camera based on its intrinsic matrix K, and displays image on the far end plane. + + .. image:: images/cpw3.png + :alt: Camera viewing frustum with image + :align: center + +viz::WTrajectory +---------------- +.. ocv:class:: WTrajectory + +This 3D Widget represents a trajectory. :: + + class CV_EXPORTS WTrajectory : public Widget3D + { + public: + enum {FRAMES = 1, PATH = 2, BOTH = FRAMES + PATH}; + + //! Displays trajectory of the given path either by coordinate frames or polyline + WTrajectory(InputArray path, int display_mode = WTrajectory::PATH, double scale = 1.0, const Color &color = Color::white(),; + }; + +viz::WTrajectory::WTrajectory +----------------------------- +Constructs a WTrajectory. + +.. ocv:function:: WTrajectory(InputArray path, int display_mode = WTrajectory::PATH, double scale = 1.0, const Color &color = Color::white()) + + :param path: List of poses on a trajectory. Takes std::vector> with T == [float | double] + :param display_mode: Display mode. This can be PATH, FRAMES, and BOTH. + :param scale: Scale of the frames. Polyline is not affected. + :param color: :ocv:class:`Color` of the polyline that represents path. Frames are not affected. + + Displays trajectory of the given path as follows: + + * PATH : Displays a poly line that represents the path. + * FRAMES : Displays coordinate frames at each pose. + * PATH & FRAMES : Displays both poly line and coordinate frames. + +viz::WTrajectoryFrustums +------------------------ +.. ocv:class:: WTrajectoryFrustums + +This 3D Widget represents a trajectory. :: + + class CV_EXPORTS WTrajectoryFrustums : public Widget3D + { + public: + //! Displays trajectory of the given path by frustums + WTrajectoryFrustums(InputArray path, const Matx33d &K, double scale = 1.0, const Color &color = Color::white()); + //! Displays trajectory of the given path by frustums + WTrajectoryFrustums(InputArray path, const Vec2d &fov, double scale = 1.0, const Color &color = Color::white()); + }; + +viz::WTrajectoryFrustums::WTrajectoryFrustums +--------------------------------------------- +Constructs a WTrajectoryFrustums. + +.. ocv:function:: WTrajectoryFrustums(const std::vector &path, const Matx33d &K, double scale = 1.0, const Color &color = Color::white()) + + :param path: List of poses on a trajectory. Takes std::vector> with T == [float | double] + :param K: Intrinsic matrix of the camera. + :param scale: Scale of the frustums. + :param color: :ocv:class:`Color` of the frustums. + + Displays frustums at each pose of the trajectory. + +.. ocv:function:: WTrajectoryFrustums(const std::vector &path, const Vec2d &fov, double scale = 1.0, const Color &color = Color::white()) + + :param path: List of poses on a trajectory. Takes std::vector> with T == [float | double] + :param fov: Field of view of the camera (horizontal, vertical). + :param scale: Scale of the frustums. + :param color: :ocv:class:`Color` of the frustums. + + Displays frustums at each pose of the trajectory. + +viz::WTrajectorySpheres +----------------------- +.. ocv:class:: WTrajectorySpheres + +This 3D Widget represents a trajectory using spheres and lines, where spheres represent the positions of the camera, and lines +represent the direction from previous position to the current. :: + + class CV_EXPORTS WTrajectorySpheres : public Widget3D + { + public: + WTrajectorySpheres(InputArray path, double line_length = 0.05, double radius = 0.007, + const Color &from = Color::red(), const Color &to = Color::white()); + }; + +viz::WTrajectorySpheres::WTrajectorySpheres +------------------------------------------- +Constructs a WTrajectorySpheres. + +.. ocv:function:: WTrajectorySpheres(InputArray path, double line_length = 0.05, double radius = 0.007, const Color &from = Color::red(), const Color &to = Color::white()) + + :param path: List of poses on a trajectory. Takes std::vector> with T == [float | double] + :param line_length: Max length of the lines which point to previous position + :param sphere_radius: Radius of the spheres. + :param from: :ocv:class:`Color` for first sphere. + :param to: :ocv:class:`Color` for last sphere. Intermediate spheres will have interpolated color. + +viz::WCloud +----------- +.. ocv:class:: WCloud + +This 3D Widget defines a point cloud. :: + + class CV_EXPORTS WCloud : public Widget3D + { + public: + //! Each point in cloud is mapped to a color in colors + WCloud(InputArray cloud, InputArray colors); + //! All points in cloud have the same color + WCloud(InputArray cloud, const Color &color = Color::white()); + }; + +viz::WCloud::WCloud +------------------- +Constructs a WCloud. + +.. ocv:function:: WCloud(InputArray cloud, InputArray colors) + + :param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. + :param colors: Set of colors. It has to be of the same size with cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +.. ocv:function:: WCloud(InputArray cloud, const Color &color = Color::white()) + + :param cloud: Set of points which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. + :param color: A single :ocv:class:`Color` for the whole cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +.. note:: In case there are four channels in the cloud, fourth channel is ignored. + +viz::WCloudCollection +--------------------- +.. ocv:class:: WCloudCollection + +This 3D Widget defines a collection of clouds. :: + + class CV_EXPORTS WCloudCollection : public Widget3D + { + public: + WCloudCollection(); + + //! Each point in cloud is mapped to a color in colors + void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()); + //! All points in cloud have the same color + void addCloud(InputArray cloud, const Color &color = Color::white(), Affine3d &pose = Affine3d::Identity()); + }; + +viz::WCloudCollection::WCloudCollection +--------------------------------------- +Constructs a WCloudCollection. + +.. ocv:function:: WCloudCollection() + +viz::WCloudCollection::addCloud +------------------------------- +Adds a cloud to the collection. + +.. ocv:function:: void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()) + + :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. + :param colors: Set of colors. It has to be of the same size with cloud. + :param pose: Pose of the cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +.. ocv:function:: void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity()) + + :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. + :param colors: A single :ocv:class:`Color` for the whole cloud. + :param pose: Pose of the cloud. + + Points in the cloud belong to mask when they are set to (NaN, NaN, NaN). + +.. note:: In case there are four channels in the cloud, fourth channel is ignored. + +viz::WCloudNormals +------------------ +.. ocv:class:: WCloudNormals + +This 3D Widget represents normals of a point cloud. :: + + class CV_EXPORTS WCloudNormals : public Widget3D + { + public: + WCloudNormals(InputArray cloud, InputArray normals, int level = 100, double scale = 0.02f, const Color &color = Color::white()); + }; + +viz::WCloudNormals::WCloudNormals +--------------------------------- +Constructs a WCloudNormals. + +.. ocv:function:: WCloudNormals(InputArray cloud, InputArray normals, int level = 100, double scale = 0.02f, const Color &color = Color::white()) + + :param cloud: Point set which can be of type: ``CV_32FC3``, ``CV_32FC4``, ``CV_64FC3``, ``CV_64FC4``. + :param normals: A set of normals that has to be of same type with cloud. + :param level: Display only every ``level`` th normal. + :param scale: Scale of the arrows that represent normals. + :param color: :ocv:class:`Color` of the arrows that represent normals. + +.. note:: In case there are four channels in the cloud, fourth channel is ignored. + +viz::WMesh +---------- +.. ocv:class:: WMesh + +This 3D Widget defines a mesh. :: + + class CV_EXPORTS WMesh : public Widget3D + { + public: + WMesh(const Mesh &mesh); + WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray()); + }; + +viz::WMesh::WMesh +----------------- +Constructs a WMesh. + +.. ocv:function:: WMesh(const Mesh &mesh) + + :param mesh: :ocv:class:`Mesh` object that will be displayed. + +.. ocv:function:: WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray()) + + :param cloud: Points of the mesh object. + :param polygons: Points of the mesh object. + :param colors: Point colors. + :param normals: Point normals. diff --git a/modules/viz/include/opencv2/viz/types.hpp b/modules/viz/include/opencv2/viz/types.hpp new file mode 100644 index 0000000000..acbece2edf --- /dev/null +++ b/modules/viz/include/opencv2/viz/types.hpp @@ -0,0 +1,236 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __OPENCV_VIZ_TYPES_HPP__ +#define __OPENCV_VIZ_TYPES_HPP__ + +#include +#include +#include + +namespace cv +{ + namespace viz + { + class Color : public Scalar + { + public: + Color(); + Color(double gray); + Color(double blue, double green, double red); + + Color(const Scalar& color); + + static Color black(); + static Color blue(); + static Color green(); + static Color cyan(); + + static Color red(); + static Color magenta(); + static Color yellow(); + static Color white(); + + static Color gray(); + + static Color mlab(); + + static Color navy(); + static Color olive(); + static Color maroon(); + static Color teal(); + static Color rose(); + static Color azure(); + static Color lime(); + static Color gold(); + static Color brown(); + static Color orange(); + static Color chartreuse(); + static Color orange_red(); + static Color purple(); + static Color indigo(); + + static Color pink(); + static Color cherry(); + static Color bluberry(); + static Color raspberry(); + static Color silver(); + static Color violet(); + static Color apricot(); + static Color turquoise(); + static Color celestial_blue(); + static Color amethyst(); + + static Color not_set(); + }; + + class CV_EXPORTS Mesh + { + public: + Mat cloud, colors, normals; + + //! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...) + //! where n is the number of points in the poligon, and id is a zero-offset index into an associated cloud. + Mat polygons; + + Mat texture, tcoords; + + //! Loads mesh from a given ply file (no texture load support for now) + static Mesh load(const String& file); + }; + + class CV_EXPORTS Camera + { + public: + Camera(double fx, double fy, double cx, double cy, const Size &window_size); + explicit Camera(const Vec2d &fov, const Size &window_size); + explicit Camera(const Matx33d &K, const Size &window_size); + explicit Camera(const Matx44d &proj, const Size &window_size); + + const Vec2d & getClip() const { return clip_; } + void setClip(const Vec2d &clip) { clip_ = clip; } + + const Size & getWindowSize() const { return window_size_; } + void setWindowSize(const Size &window_size); + + const Vec2d& getFov() const { return fov_; } + void setFov(const Vec2d& fov) { fov_ = fov; } + + const Vec2d& getPrincipalPoint() const { return principal_point_; } + const Vec2d& getFocalLength() const { return focal_; } + + void computeProjectionMatrix(Matx44d &proj) const; + + static Camera KinectCamera(const Size &window_size); + + private: + void init(double fx, double fy, double cx, double cy, const Size &window_size); + + Vec2d clip_; + Vec2d fov_; + Size window_size_; + Vec2d principal_point_; + Vec2d focal_; + }; + + class CV_EXPORTS KeyboardEvent + { + public: + enum { NONE = 0, ALT = 1, CTRL = 2, SHIFT = 4 }; + enum Action { KEY_UP = 0, KEY_DOWN = 1 }; + + KeyboardEvent(Action action, const String& symbol, unsigned char code, int modifiers); + + Action action; + String symbol; + unsigned char code; + int modifiers; + }; + + class CV_EXPORTS MouseEvent + { + public: + enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ; + enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ; + + MouseEvent(const Type& type, const MouseButton& button, const Point& pointer, int modifiers); + + Type type; + MouseButton button; + Point pointer; + int modifiers; + }; + } /* namespace viz */ +} /* namespace cv */ + +////////////////////////////////////////////////////////////////////////////////////////////////////// +/// cv::viz::Color + +inline cv::viz::Color::Color() : Scalar(0, 0, 0) {} +inline cv::viz::Color::Color(double _gray) : Scalar(_gray, _gray, _gray) {} +inline cv::viz::Color::Color(double _blue, double _green, double _red) : Scalar(_blue, _green, _red) {} +inline cv::viz::Color::Color(const Scalar& color) : Scalar(color) {} + +inline cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); } +inline cv::viz::Color cv::viz::Color::green() { return Color( 0, 255, 0); } +inline cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); } +inline cv::viz::Color cv::viz::Color::cyan() { return Color(255, 255, 0); } +inline cv::viz::Color cv::viz::Color::red() { return Color( 0, 0, 255); } +inline cv::viz::Color cv::viz::Color::yellow() { return Color( 0, 255, 255); } +inline cv::viz::Color cv::viz::Color::magenta() { return Color(255, 0, 255); } +inline cv::viz::Color cv::viz::Color::white() { return Color(255, 255, 255); } +inline cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); } + +inline cv::viz::Color cv::viz::Color::mlab() { return Color(255, 128, 128); } + +inline cv::viz::Color cv::viz::Color::navy() { return Color(0, 0, 128); } +inline cv::viz::Color cv::viz::Color::olive() { return Color(0, 128, 128); } +inline cv::viz::Color cv::viz::Color::maroon() { return Color(0, 0, 128); } +inline cv::viz::Color cv::viz::Color::teal() { return Color(128, 128, 0); } +inline cv::viz::Color cv::viz::Color::rose() { return Color(128, 0, 255); } +inline cv::viz::Color cv::viz::Color::azure() { return Color(255, 128, 0); } +inline cv::viz::Color cv::viz::Color::lime() { return Color(0, 255, 191); } +inline cv::viz::Color cv::viz::Color::gold() { return Color(0, 215, 255); } +inline cv::viz::Color cv::viz::Color::brown() { return Color(0, 75, 150); } +inline cv::viz::Color cv::viz::Color::orange() { return Color(0, 165, 255); } +inline cv::viz::Color cv::viz::Color::chartreuse() { return Color(0, 255, 128); } +inline cv::viz::Color cv::viz::Color::orange_red() { return Color(0, 69, 255); } +inline cv::viz::Color cv::viz::Color::purple() { return Color(128, 0, 128); } +inline cv::viz::Color cv::viz::Color::indigo() { return Color(130, 0, 75); } + +inline cv::viz::Color cv::viz::Color::pink() { return Color(203, 192, 255); } +inline cv::viz::Color cv::viz::Color::cherry() { return Color( 99, 29, 222); } +inline cv::viz::Color cv::viz::Color::bluberry() { return Color(247, 134, 79); } +inline cv::viz::Color cv::viz::Color::raspberry() { return Color( 92, 11, 227); } +inline cv::viz::Color cv::viz::Color::silver() { return Color(192, 192, 192); } +inline cv::viz::Color cv::viz::Color::violet() { return Color(226, 43, 138); } +inline cv::viz::Color cv::viz::Color::apricot() { return Color(177, 206, 251); } +inline cv::viz::Color cv::viz::Color::turquoise() { return Color(208, 224, 64); } +inline cv::viz::Color cv::viz::Color::celestial_blue() { return Color(208, 151, 73); } +inline cv::viz::Color cv::viz::Color::amethyst() { return Color(204, 102, 153); } + +inline cv::viz::Color cv::viz::Color::not_set() { return Color(-1, -1, -1); } + +#endif diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp new file mode 100644 index 0000000000..1a137bcfb3 --- /dev/null +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -0,0 +1,131 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __OPENCV_VIZ_VIZ3D_HPP__ +#define __OPENCV_VIZ_VIZ3D_HPP__ + +#if !defined YES_I_AGREE_THAT_VIZ_API_IS_NOT_STABLE_NOW_AND_BINARY_COMPARTIBILITY_WONT_BE_SUPPORTED && !defined CVAPI_EXPORTS + //#error "Viz is in beta state now. Please define macro above to use it" +#endif + +#include +#include +#include + +namespace cv +{ + namespace viz + { + class CV_EXPORTS Viz3d + { + public: + typedef cv::viz::Color Color; + typedef void (*KeyboardCallback)(const KeyboardEvent&, void*); + typedef void (*MouseCallback)(const MouseEvent&, void*); + + Viz3d(const String& window_name = String()); + Viz3d(const Viz3d&); + Viz3d& operator=(const Viz3d&); + ~Viz3d(); + + void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity()); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; + void removeAllWidgets(); + + void showImage(InputArray image, const Size& window_size = Size(-1, -1)); + + void setWidgetPose(const String &id, const Affine3d &pose); + void updateWidgetPose(const String &id, const Affine3d &pose); + Affine3d getWidgetPose(const String &id) const; + + void setCamera(const Camera &camera); + Camera getCamera() const; + Affine3d getViewerPose(); + void setViewerPose(const Affine3d &pose); + + void resetCameraViewpoint(const String &id); + void resetCamera(); + + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); + + Size getWindowSize() const; + void setWindowSize(const Size &window_size); + String getWindowName() const; + void saveScreenshot(const String &file); + void setWindowPosition(const Point& window_position); + void setFullScreen(bool mode = true); + void setBackgroundColor(const Color& color = Color::black(), const Color& color2 = Color::not_set()); + void setBackgroundTexture(InputArray image = noArray()); + void setBackgroundMeshLab(); + + void spin(); + void spinOnce(int time = 1, bool force_redraw = false); + bool wasStopped() const; + void close(); + + void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); + void registerMouseCallback(MouseCallback callback, void* cookie = 0); + + void setRenderingProperty(const String &id, int property, double value); + double getRenderingProperty(const String &id, int property); + + void setRepresentation(int representation); + private: + + struct VizImpl; + VizImpl* impl_; + + void create(const String &window_name); + void release(); + + friend class VizStorage; + }; + + } /* namespace viz */ +} /* namespace cv */ + +#endif diff --git a/modules/viz/include/opencv2/viz/vizcore.hpp b/modules/viz/include/opencv2/viz/vizcore.hpp new file mode 100644 index 0000000000..0fde95b2f1 --- /dev/null +++ b/modules/viz/include/opencv2/viz/vizcore.hpp @@ -0,0 +1,127 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __OPENCV_VIZCORE_HPP__ +#define __OPENCV_VIZCORE_HPP__ + +#include +#include +#include + +namespace cv +{ + namespace viz + { + //! takes coordiante frame data and builds transfrom to global coordinate frame + CV_EXPORTS Affine3d makeTransformToGlobal(const Vec3d& axis_x, const Vec3d& axis_y, const Vec3d& axis_z, const Vec3d& origin = Vec3d::all(0)); + + //! constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation) + CV_EXPORTS Affine3d makeCameraPose(const Vec3d& position, const Vec3d& focal_point, const Vec3d& y_dir); + + //! retrieves a window by its name. If no window with such name, then it creates new. + CV_EXPORTS Viz3d getWindowByName(const String &window_name); + + //! Unregisters all Viz windows from internal database. After it 'getWindowByName()' will create new windows instead getting existing from the database. + CV_EXPORTS void unregisterAllWindows(); + + //! Displays image in specified window + CV_EXPORTS Viz3d imshow(const String& window_name, InputArray image, const Size& window_size = Size(-1, -1)); + + //! checks float value for Nan + inline bool isNan(float x) + { + unsigned int *u = reinterpret_cast(&x); + return ((u[0] & 0x7f800000) == 0x7f800000) && (u[0] & 0x007fffff); + } + + //! checks double value for Nan + inline bool isNan(double x) + { + unsigned int *u = reinterpret_cast(&x); + return (u[1] & 0x7ff00000) == 0x7ff00000 && (u[0] != 0 || (u[1] & 0x000fffff) != 0); + } + + //! checks vectors for Nans + template inline bool isNan(const Vec<_Tp, cn>& v) + { return isNan(v.val[0]) || isNan(v.val[1]) || isNan(v.val[2]); } + + //! checks point for Nans + template inline bool isNan(const Point3_<_Tp>& p) + { return isNan(p.x) || isNan(p.y) || isNan(p.z); } + + + /////////////////////////////////////////////////////////////////////////////////////////////// + /// Read/write clouds. Supported formats: ply, xyz, obj and stl (readonly) + + CV_EXPORTS void writeCloud(const String& file, InputArray cloud, InputArray colors = noArray(), InputArray normals = noArray(), bool binary = false); + CV_EXPORTS Mat readCloud (const String& file, OutputArray colors = noArray(), OutputArray normals = noArray()); + + /////////////////////////////////////////////////////////////////////////////////////////////// + /// Reads mesh. Only ply format is supported now and no texture load support + + CV_EXPORTS Mesh readMesh(const String& file); + + /////////////////////////////////////////////////////////////////////////////////////////////// + /// Read/write poses and trajectories + + CV_EXPORTS bool readPose(const String& file, Affine3d& pose, const String& tag = "pose"); + CV_EXPORTS void writePose(const String& file, const Affine3d& pose, const String& tag = "pose"); + + //! takes vector> with T = float/dobule and writes to a sequence of files with given filename format + CV_EXPORTS void writeTrajectory(InputArray traj, const String& files_format = "pose%05d.xml", int start = 0, const String& tag = "pose"); + + //! takes vector> with T = float/dobule and loads poses from sequence of files + CV_EXPORTS void readTrajectory(OutputArray traj, const String& files_format = "pose%05d.xml", int start = 0, int end = INT_MAX, const String& tag = "pose"); + + + /////////////////////////////////////////////////////////////////////////////////////////////// + /// Computing normals for mesh + + CV_EXPORTS void computeNormals(const Mesh& mesh, OutputArray normals); + + } /* namespace viz */ +} /* namespace cv */ + +#endif /* __OPENCV_VIZCORE_HPP__ */ diff --git a/modules/viz/include/opencv2/viz/widget_accessor.hpp b/modules/viz/include/opencv2/viz/widget_accessor.hpp new file mode 100644 index 0000000000..734f6ce559 --- /dev/null +++ b/modules/viz/include/opencv2/viz/widget_accessor.hpp @@ -0,0 +1,69 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__ +#define __OPENCV_VIZ_WIDGET_ACCESSOR_HPP__ + +#include +#include +#include + +namespace cv +{ + namespace viz + { + class Widget; + + //The class is only that depends on VTK in its interface. + //It is indended for those users who want to develop own widgets system using VTK library API. + struct CV_EXPORTS WidgetAccessor + { + static vtkSmartPointer getProp(const Widget &widget); + static void setProp(Widget &widget, vtkSmartPointer prop); + }; + } +} + +#endif diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp new file mode 100644 index 0000000000..2c49b9d0e2 --- /dev/null +++ b/modules/viz/include/opencv2/viz/widgets.hpp @@ -0,0 +1,396 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __OPENCV_VIZ_WIDGETS_HPP__ +#define __OPENCV_VIZ_WIDGETS_HPP__ + +#include + +namespace cv +{ + namespace viz + { + ///////////////////////////////////////////////////////////////////////////// + /// Widget rendering properties + enum RenderingProperties + { + POINT_SIZE, + OPACITY, + LINE_WIDTH, + FONT_SIZE, + REPRESENTATION, + IMMEDIATE_RENDERING, + SHADING + }; + + enum RepresentationValues + { + REPRESENTATION_POINTS, + REPRESENTATION_WIREFRAME, + REPRESENTATION_SURFACE + }; + + enum ShadingValues + { + SHADING_FLAT, + SHADING_GOURAUD, + SHADING_PHONG + }; + + ///////////////////////////////////////////////////////////////////////////// + /// The base class for all widgets + class CV_EXPORTS Widget + { + public: + Widget(); + Widget(const Widget& other); + Widget& operator=(const Widget& other); + ~Widget(); + + //! Create a widget directly from ply file + static Widget fromPlyFile(const String &file_name); + + //! Rendering properties of this particular widget + void setRenderingProperty(int property, double value); + double getRenderingProperty(int property) const; + + //! Casting between widgets + template _W cast(); + private: + class Impl; + Impl *impl_; + friend struct WidgetAccessor; + }; + + ///////////////////////////////////////////////////////////////////////////// + /// The base class for all 3D widgets + class CV_EXPORTS Widget3D : public Widget + { + public: + Widget3D() {} + + //! widget position manipulation, i.e. place where it is rendered + void setPose(const Affine3d &pose); + void updatePose(const Affine3d &pose); + Affine3d getPose() const; + + //! update internal widget data, i.e. points, normals, etc. + void applyTransform(const Affine3d &transform); + + void setColor(const Color &color); + + }; + + ///////////////////////////////////////////////////////////////////////////// + /// The base class for all 2D widgets + class CV_EXPORTS Widget2D : public Widget + { + public: + Widget2D() {} + + void setColor(const Color &color); + }; + + ///////////////////////////////////////////////////////////////////////////// + /// Simple widgets + + class CV_EXPORTS WLine : public Widget3D + { + public: + WLine(const Point3d &pt1, const Point3d &pt2, const Color &color = Color::white()); + }; + + class CV_EXPORTS WPlane : public Widget3D + { + public: + //! created default plane with center point at origin and normal oriented along z-axis + WPlane(const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); + + //! repositioned plane + WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, + const Size2d& size = Size2d(1.0, 1.0), const Color &color = Color::white()); + }; + + class CV_EXPORTS WSphere : public Widget3D + { + public: + WSphere(const cv::Point3d ¢er, double radius, int sphere_resolution = 10, const Color &color = Color::white()); + }; + + class CV_EXPORTS WArrow : public Widget3D + { + public: + WArrow(const Point3d& pt1, const Point3d& pt2, double thickness = 0.03, const Color &color = Color::white()); + }; + + class CV_EXPORTS WCircle : public Widget3D + { + public: + //! creates default planar circle centred at origin with plane normal along z-axis + WCircle(double radius, double thickness = 0.01, const Color &color = Color::white()); + + //! creates repositioned circle + WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness = 0.01, const Color &color = Color::white()); + }; + + class CV_EXPORTS WCone : public Widget3D + { + public: + //! create default cone, oriented along x-axis with center of its base located at origin + WCone(double length, double radius, int resolution = 6.0, const Color &color = Color::white()); + + //! creates repositioned cone + WCone(double radius, const Point3d& center, const Point3d& tip, int resolution = 6.0, const Color &color = Color::white()); + }; + + class CV_EXPORTS WCylinder : public Widget3D + { + public: + WCylinder(const Point3d& axis_point1, const Point3d& axis_point2, double radius, int numsides = 30, const Color &color = Color::white()); + }; + + class CV_EXPORTS WCube : public Widget3D + { + public: + WCube(const Point3d& min_point = Vec3d::all(-0.5), const Point3d& max_point = Vec3d::all(0.5), + bool wire_frame = true, const Color &color = Color::white()); + }; + + class CV_EXPORTS WPolyLine : public Widget3D + { + public: + WPolyLine(InputArray points, const Color &color = Color::white()); + }; + + ///////////////////////////////////////////////////////////////////////////// + /// Text and image widgets + + class CV_EXPORTS WText : public Widget2D + { + public: + WText(const String &text, const Point &pos, int font_size = 20, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + + class CV_EXPORTS WText3D : public Widget3D + { + public: + //! creates text label in 3D. If face_camera = false, text plane normal is oriented along z-axis. Use widget pose to orient it properly + WText3D(const String &text, const Point3d &position, double text_scale = 1., bool face_camera = true, const Color &color = Color::white()); + + void setText(const String &text); + String getText() const; + }; + + class CV_EXPORTS WImageOverlay : public Widget2D + { + public: + WImageOverlay(InputArray image, const Rect &rect); + void setImage(InputArray image); + }; + + class CV_EXPORTS WImage3D : public Widget3D + { + public: + //! Creates 3D image in a plane centered at the origin with normal orientaion along z-axis, + //! image x- and y-axes are oriented along x- and y-axes of 3d world + WImage3D(InputArray image, const Size2d &size); + + //! Creates 3D image at a given position, pointing in the direction of the normal, and having the up_vector orientation + WImage3D(InputArray image, const Size2d &size, const Vec3d ¢er, const Vec3d &normal, const Vec3d &up_vector); + + void setImage(InputArray image); + }; + + ///////////////////////////////////////////////////////////////////////////// + /// Compond widgets + + class CV_EXPORTS WCoordinateSystem : public Widget3D + { + public: + WCoordinateSystem(double scale = 1.0); + }; + + class CV_EXPORTS WGrid : public Widget3D + { + public: + //! Creates grid at the origin and normal oriented along z-axis + WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); + + //! Creates repositioned grid + WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, + const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white()); + }; + + class CV_EXPORTS WCameraPosition : public Widget3D + { + public: + //! Creates camera coordinate frame (axes) at the origin + WCameraPosition(double scale = 1.0); + //! Creates frustum based on the intrinsic marix K at the origin + WCameraPosition(const Matx33d &K, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum based on the field of view at the origin + WCameraPosition(const Vec2d &fov, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane + WCameraPosition(const Matx33d &K, InputArray image, double scale = 1.0, const Color &color = Color::white()); + //! Creates frustum and display given image at the far plane + WCameraPosition(const Vec2d &fov, InputArray image, double scale = 1.0, const Color &color = Color::white()); + }; + + ///////////////////////////////////////////////////////////////////////////// + /// Trajectories + + class CV_EXPORTS WTrajectory : public Widget3D + { + public: + enum {FRAMES = 1, PATH = 2, BOTH = FRAMES + PATH }; + + //! Takes vector> and displays trajectory of the given path either by coordinate frames or polyline + WTrajectory(InputArray path, int display_mode = WTrajectory::PATH, double scale = 1.0, const Color &color = Color::white()); + }; + + class CV_EXPORTS WTrajectoryFrustums : public Widget3D + { + public: + //! Takes vector> and displays trajectory of the given path by frustums + WTrajectoryFrustums(InputArray path, const Matx33d &K, double scale = 1., const Color &color = Color::white()); + + //! Takes vector> and displays trajectory of the given path by frustums + WTrajectoryFrustums(InputArray path, const Vec2d &fov, double scale = 1., const Color &color = Color::white()); + }; + + class CV_EXPORTS WTrajectorySpheres: public Widget3D + { + public: + //! Takes vector> and displays trajectory of the given path + WTrajectorySpheres(InputArray path, double line_length = 0.05, double radius = 0.007, + const Color &from = Color::red(), const Color &to = Color::white()); + }; + + ///////////////////////////////////////////////////////////////////////////// + /// Clouds + + class CV_EXPORTS WCloud: public Widget3D + { + public: + //! Each point in cloud is mapped to a color in colors + WCloud(InputArray cloud, InputArray colors); + //! All points in cloud have the same color + WCloud(InputArray cloud, const Color &color = Color::white()); + }; + + class CV_EXPORTS WPaintedCloud: public Widget3D + { + public: + //! Paint cloud with default gradient between cloud bounds points + WPaintedCloud(InputArray cloud); + + //! Paint cloud with default gradient between given points + WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2); + + //! Paint cloud with gradient specified by given colors between given points + WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2, const Color& c1, const Color c2); + }; + + class CV_EXPORTS WCloudCollection : public Widget3D + { + public: + WCloudCollection(); + + //! Each point in cloud is mapped to a color in colors + void addCloud(InputArray cloud, InputArray colors, const Affine3d &pose = Affine3d::Identity()); + //! All points in cloud have the same color + void addCloud(InputArray cloud, const Color &color = Color::white(), const Affine3d &pose = Affine3d::Identity()); + }; + + class CV_EXPORTS WCloudNormals : public Widget3D + { + public: + WCloudNormals(InputArray cloud, InputArray normals, int level = 64, double scale = 0.1, const Color &color = Color::white()); + }; + + class CV_EXPORTS WMesh : public Widget3D + { + public: + WMesh(const Mesh &mesh); + WMesh(InputArray cloud, InputArray polygons, InputArray colors = noArray(), InputArray normals = noArray()); + }; + + ///////////////////////////////////////////////////////////////////////////// + /// Utility exports + + template<> CV_EXPORTS Widget2D Widget::cast(); + template<> CV_EXPORTS Widget3D Widget::cast(); + template<> CV_EXPORTS WLine Widget::cast(); + template<> CV_EXPORTS WPlane Widget::cast(); + template<> CV_EXPORTS WSphere Widget::cast(); + template<> CV_EXPORTS WCylinder Widget::cast(); + template<> CV_EXPORTS WArrow Widget::cast(); + template<> CV_EXPORTS WCircle Widget::cast(); + template<> CV_EXPORTS WCone Widget::cast(); + template<> CV_EXPORTS WCube Widget::cast(); + template<> CV_EXPORTS WCoordinateSystem Widget::cast(); + template<> CV_EXPORTS WPolyLine Widget::cast(); + template<> CV_EXPORTS WGrid Widget::cast(); + template<> CV_EXPORTS WText3D Widget::cast(); + template<> CV_EXPORTS WText Widget::cast(); + template<> CV_EXPORTS WImageOverlay Widget::cast(); + template<> CV_EXPORTS WImage3D Widget::cast(); + template<> CV_EXPORTS WCameraPosition Widget::cast(); + template<> CV_EXPORTS WTrajectory Widget::cast(); + template<> CV_EXPORTS WTrajectoryFrustums Widget::cast(); + template<> CV_EXPORTS WTrajectorySpheres Widget::cast(); + template<> CV_EXPORTS WCloud Widget::cast(); + template<> CV_EXPORTS WPaintedCloud Widget::cast(); + template<> CV_EXPORTS WCloudCollection Widget::cast(); + template<> CV_EXPORTS WCloudNormals Widget::cast(); + template<> CV_EXPORTS WMesh Widget::cast(); + + } /* namespace viz */ +} /* namespace cv */ + +#endif diff --git a/modules/viz/src/clouds.cpp b/modules/viz/src/clouds.cpp new file mode 100644 index 0000000000..4b84e8e9e1 --- /dev/null +++ b/modules/viz/src/clouds.cpp @@ -0,0 +1,441 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Point Cloud Widget implementation + +cv::viz::WCloud::WCloud(InputArray cloud, InputArray colors) +{ + CV_Assert(!cloud.empty() && !colors.empty()); + + vtkSmartPointer cloud_source = vtkSmartPointer::New(); + cloud_source->SetColorCloud(cloud, colors); + cloud_source->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, cloud_source->GetOutput()); + mapper->SetScalarModeToUsePointData(); + mapper->ImmediateModeRenderingOff(); + mapper->SetScalarRange(0, 255); + mapper->ScalarVisibilityOn(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::WCloud::WCloud(InputArray cloud, const Color &color) +{ + WCloud cloud_widget(cloud, Mat(cloud.size(), CV_8UC3, color)); + *this = cloud_widget; +} + + +template<> cv::viz::WCloud cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Painted Cloud Widget implementation + +cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud) +{ + vtkSmartPointer cloud_source = vtkSmartPointer::New(); + cloud_source->SetCloud(cloud); + cloud_source->Update(); + + Vec6d bounds(cloud_source->GetOutput()->GetPoints()->GetBounds()); + + vtkSmartPointer elevation = vtkSmartPointer::New(); + elevation->SetInputConnection(cloud_source->GetOutputPort()); + elevation->SetLowPoint(bounds[0], bounds[2], bounds[4]); + elevation->SetHighPoint(bounds[1], bounds[3], bounds[5]); + elevation->SetScalarRange(0.0, 1.0); + elevation->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput())); + mapper->ImmediateModeRenderingOff(); + mapper->ScalarVisibilityOn(); + mapper->SetColorModeToMapScalars(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2) +{ + vtkSmartPointer cloud_source = vtkSmartPointer::New(); + cloud_source->SetCloud(cloud); + + vtkSmartPointer elevation = vtkSmartPointer::New(); + elevation->SetInputConnection(cloud_source->GetOutputPort()); + elevation->SetLowPoint(p1.x, p1.y, p1.z); + elevation->SetHighPoint(p2.x, p2.y, p2.z); + elevation->SetScalarRange(0.0, 1.0); + elevation->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput())); + mapper->ImmediateModeRenderingOff(); + mapper->ScalarVisibilityOn(); + mapper->SetColorModeToMapScalars(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2, const Color& c1, const Color c2) +{ + vtkSmartPointer cloud_source = vtkSmartPointer::New(); + cloud_source->SetCloud(cloud); + + vtkSmartPointer elevation = vtkSmartPointer::New(); + elevation->SetInputConnection(cloud_source->GetOutputPort()); + elevation->SetLowPoint(p1.x, p1.y, p1.z); + elevation->SetHighPoint(p2.x, p2.y, p2.z); + elevation->SetScalarRange(0.0, 1.0); + elevation->Update(); + + Color vc1 = vtkcolor(c1), vc2 = vtkcolor(c2); + vtkSmartPointer color_transfer = vtkSmartPointer::New(); + color_transfer->SetColorSpaceToRGB(); + color_transfer->AddRGBPoint(0.0, vc1[0], vc1[1], vc1[2]); + color_transfer->AddRGBPoint(1.0, vc2[0], vc2[1], vc2[2]); + color_transfer->SetScaleToLinear(); + color_transfer->Build(); + + //if in future some need to replace color table with real scalars, then this can be done usine next calls: + //vtkDataArray *float_scalars = vtkPolyData::SafeDownCast(elevation->GetOutput())->GetPointData()->GetArray("Elevation"); + //vtkSmartPointer polydata = cloud_source->GetOutput(); + //polydata->GetPointData()->SetScalars(color_transfer->MapScalars(float_scalars, VTK_COLOR_MODE_DEFAULT, 0)); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput())); + mapper->ImmediateModeRenderingOff(); + mapper->ScalarVisibilityOn(); + mapper->SetColorModeToMapScalars(); + mapper->SetLookupTable(color_transfer); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::WPaintedCloud cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Cloud Collection Widget implementation + +cv::viz::WCloudCollection::WCloudCollection() +{ + // Just create the actor + vtkSmartPointer actor = vtkSmartPointer::New(); + WidgetAccessor::setProp(*this, actor); +} + +void cv::viz::WCloudCollection::addCloud(InputArray cloud, InputArray colors, const Affine3d &pose) +{ + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetColorCloud(cloud, colors); + + vtkSmartPointer polydata = VtkUtils::TransformPolydata(source->GetOutputPort(), pose); + + vtkSmartPointer actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Incompatible widget type." && actor); + + vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + if (!mapper) + { + // This is the first cloud + mapper = vtkSmartPointer::New(); + mapper->SetScalarRange(0, 255); + mapper->SetScalarModeToUsePointData(); + mapper->ScalarVisibilityOn(); + mapper->ImmediateModeRenderingOff(); + VtkUtils::SetInputData(mapper, polydata); + + actor->SetNumberOfCloudPoints(std::max(1, polydata->GetNumberOfPoints()/10)); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); + return; + } + + vtkPolyData *currdata = vtkPolyData::SafeDownCast(mapper->GetInput()); + CV_Assert("Cloud Widget without data" && currdata); + + vtkSmartPointer append_filter = vtkSmartPointer::New(); + VtkUtils::AddInputData(append_filter, currdata); + VtkUtils::AddInputData(append_filter, polydata); + append_filter->Update(); + + VtkUtils::SetInputData(mapper, append_filter->GetOutput()); + + actor->SetNumberOfCloudPoints(std::max(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10)); +} + +void cv::viz::WCloudCollection::addCloud(InputArray cloud, const Color &color, const Affine3d &pose) +{ + addCloud(cloud, Mat(cloud.size(), CV_8UC3, color), pose); +} + +template<> cv::viz::WCloudCollection cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Cloud Normals Widget implementation + +cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, double scale, const Color &color) +{ + Mat cloud = _cloud.getMat(); + Mat normals = _normals.getMat(); + + CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4); + CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type()); + + int sqlevel = (int)std::sqrt((double)level); + int ystep = (cloud.cols > 1 && cloud.rows > 1) ? sqlevel : 1; + int xstep = (cloud.cols > 1 && cloud.rows > 1) ? sqlevel : level; + + vtkSmartPointer points = vtkSmartPointer::New(); + points->SetDataType(cloud.depth() == CV_32F ? VTK_FLOAT : VTK_DOUBLE); + + vtkSmartPointer lines = vtkSmartPointer::New(); + + int s_chs = cloud.channels(); + int n_chs = normals.channels(); + int total = 0; + + for(int y = 0; y < cloud.rows; y += ystep) + { + if (cloud.depth() == CV_32F) + { + const float *srow = cloud.ptr(y); + const float *send = srow + cloud.cols * s_chs; + const float *nrow = normals.ptr(y); + + for (; srow < send; srow += xstep * s_chs, nrow += xstep * n_chs) + if (!isNan(srow) && !isNan(nrow)) + { + Vec3f endp = Vec3f(srow) + Vec3f(nrow) * (float)scale; + + points->InsertNextPoint(srow); + points->InsertNextPoint(endp.val); + + lines->InsertNextCell(2); + lines->InsertCellPoint(total++); + lines->InsertCellPoint(total++); + } + } + else + { + const double *srow = cloud.ptr(y); + const double *send = srow + cloud.cols * s_chs; + const double *nrow = normals.ptr(y); + + for (; srow < send; srow += xstep * s_chs, nrow += xstep * n_chs) + if (!isNan(srow) && !isNan(nrow)) + { + Vec3d endp = Vec3d(srow) + Vec3d(nrow) * (double)scale; + + points->InsertNextPoint(srow); + points->InsertNextPoint(endp.val); + + lines->InsertNextCell(2); + lines->InsertCellPoint(total++); + lines->InsertCellPoint(total++); + } + } + } + + vtkSmartPointer polyData = vtkSmartPointer::New(); + polyData->SetPoints(points); + polyData->SetLines(lines); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetColorModeToMapScalars(); + mapper->SetScalarModeToUsePointData(); + VtkUtils::SetInputData(mapper, polyData); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::WCloudNormals cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Mesh Widget implementation + +cv::viz::WMesh::WMesh(const Mesh &mesh) +{ + CV_Assert(mesh.cloud.rows == 1 && mesh.polygons.type() == CV_32SC1); + + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords); + source->Update(); + + Mat lookup_buffer(1, mesh.cloud.total(), CV_32SC1); + int *lookup = lookup_buffer.ptr(); + for(int y = 0, index = 0; y < mesh.cloud.rows; ++y) + { + int s_chs = mesh.cloud.channels(); + + if (mesh.cloud.depth() == CV_32F) + { + const float* srow = mesh.cloud.ptr(y); + const float* send = srow + mesh.cloud.cols * s_chs; + + for (; srow != send; srow += s_chs, ++lookup) + if (!isNan(srow[0]) && !isNan(srow[1]) && !isNan(srow[2])) + *lookup = index++; + } + + if (mesh.cloud.depth() == CV_64F) + { + const double* srow = mesh.cloud.ptr(y); + const double* send = srow + mesh.cloud.cols * s_chs; + + for (; srow != send; srow += s_chs, ++lookup) + if (!isNan(srow[0]) && !isNan(srow[1]) && !isNan(srow[2])) + *lookup = index++; + } + } + lookup = lookup_buffer.ptr(); + + vtkSmartPointer polydata = source->GetOutput(); + polydata->SetVerts(0); + + const int * polygons = mesh.polygons.ptr(); + vtkSmartPointer cell_array = vtkSmartPointer::New(); + + int idx = 0; + size_t polygons_size = mesh.polygons.total(); + for (size_t i = 0; i < polygons_size; ++idx) + { + int n_points = polygons[i++]; + + cell_array->InsertNextCell(n_points); + for (int j = 0; j < n_points; ++j, ++idx) + cell_array->InsertCellPoint(lookup[polygons[i++]]); + } + cell_array->GetData()->SetNumberOfValues(idx); + cell_array->Squeeze(); + polydata->SetStrips(cell_array); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUsePointData(); + mapper->ImmediateModeRenderingOff(); + VtkUtils::SetInputData(mapper, polydata); + + vtkSmartPointer actor = vtkSmartPointer::New(); + //actor->SetNumberOfCloudPoints(std::max(1, polydata->GetNumberOfPoints() / 10)); + actor->GetProperty()->SetRepresentationToSurface(); + actor->GetProperty()->BackfaceCullingOff(); // Backface culling is off for higher efficiency + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->EdgeVisibilityOff(); + actor->GetProperty()->ShadingOff(); + actor->SetMapper(mapper); + + if (!mesh.texture.empty()) + { + vtkSmartPointer image_source = vtkSmartPointer::New(); + image_source->SetImage(mesh.texture); + + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(image_source->GetOutputPort()); + actor->SetTexture(texture); + } + + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::WMesh::WMesh(InputArray cloud, InputArray polygons, InputArray colors, InputArray normals) +{ + Mesh mesh; + mesh.cloud = cloud.getMat(); + mesh.colors = colors.getMat(); + mesh.normals = normals.getMat(); + mesh.polygons = polygons.getMat(); + *this = WMesh(mesh); +} + +template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} diff --git a/modules/viz/src/interactor_style.cpp b/modules/viz/src/interactor_style.cpp new file mode 100644 index 0000000000..75003a2b66 --- /dev/null +++ b/modules/viz/src/interactor_style.cpp @@ -0,0 +1,639 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +// OpenCV Viz module is complete rewrite of +// PCL visualization module (www.pointclouds.org) +// +//M*/ + +#include "precomp.hpp" + + +namespace cv { namespace viz +{ + vtkStandardNewMacro(InteractorStyle) +}} + + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::Initialize() +{ + // Set windows size (width, height) to unknown (-1) + win_size_ = Vec2i(-1, -1); + win_pos_ = Vec2i(0, 0); + max_win_size_ = Vec2i(-1, -1); + + init_ = true; + stereo_anaglyph_mask_default_ = true; + + // Initialize the keyboard event callback as none + keyboardCallback_ = 0; + keyboard_callback_cookie_ = 0; + + // Initialize the mouse event callback as none + mouseCallback_ = 0; + mouse_callback_cookie_ = 0; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::saveScreenshot(const String &file) +{ + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + + vtkSmartPointer wif = vtkSmartPointer::New(); + wif->SetInput(Interactor->GetRenderWindow()); + + vtkSmartPointer snapshot_writer = vtkSmartPointer::New(); + snapshot_writer->SetInputConnection(wif->GetOutputPort()); + snapshot_writer->SetFileName(file.c_str()); + snapshot_writer->Write(); + + cout << "Screenshot successfully captured (" << file.c_str() << ")" << endl; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::exportScene(const String &file) +{ + vtkSmartPointer exporter; + if (file.size() > 5 && file.substr(file.size() - 5) == ".vrml") + { + exporter = vtkSmartPointer::New(); + vtkVRMLExporter::SafeDownCast(exporter)->SetFileName(file.c_str()); + } + else + { + exporter = vtkSmartPointer::New(); + vtkOBJExporter::SafeDownCast(exporter)->SetFilePrefix(file.c_str()); + } + + exporter->SetInput(Interactor->GetRenderWindow()); + exporter->Write(); + + cout << "Scene successfully exported (" << file.c_str() << ")" << endl; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::zoomIn() +{ + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + // Zoom in + StartDolly(); + double factor = 10.0 * 0.2 * .5; + Dolly(std::pow(1.1, factor)); + EndDolly(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::zoomOut() +{ + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + // Zoom out + StartDolly(); + double factor = 10.0 * -0.2 * .5; + Dolly(std::pow(1.1, factor)); + EndDolly(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnChar() +{ + // Make sure we ignore the same events we handle in OnKeyDown to avoid calling things twice + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + if (Interactor->GetKeyCode() >= '0' && Interactor->GetKeyCode() <= '9') + return; + + String key(Interactor->GetKeySym()); + if (key.find("XF86ZoomIn") != String::npos) + zoomIn(); + else if (key.find("XF86ZoomOut") != String::npos) + zoomOut(); + + int keymod = Interactor->GetAltKey(); + + switch (Interactor->GetKeyCode()) + { + // All of the options below simply exit + case 'h': case 'H': + case 'l': case 'L': + case 'p': case 'P': + case 'j': case 'J': + case 'c': case 'C': + case 43: // KEY_PLUS + case 45: // KEY_MINUS + case 'f': case 'F': + case 'g': case 'G': + case 'o': case 'O': + case 'u': case 'U': + case 'q': case 'Q': + { + break; + } + // S and R have a special !ALT case + case 'r': case 'R': + case 's': case 'S': + { + if (!keymod) + Superclass::OnChar(); + break; + } + default: + { + Superclass::OnChar(); + break; + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie) +{ + // Register the callback function and store the user data + mouseCallback_ = callback; + mouse_callback_cookie_ = cookie; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie) +{ + // Register the callback function and store the user data + keyboardCallback_ = callback; + keyboard_callback_cookie_ = cookie; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +int cv::viz::InteractorStyle::getModifiers() +{ + int modifiers = KeyboardEvent::NONE; + + if (Interactor->GetAltKey()) + modifiers |= KeyboardEvent::ALT; + + if (Interactor->GetControlKey()) + modifiers |= KeyboardEvent::CTRL; + + if (Interactor->GetShiftKey()) + modifiers |= KeyboardEvent::SHIFT; + return modifiers; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnKeyDown() +{ + CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_); + FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]); + + // Save the initial windows width/height + if (win_size_[0] == -1 || win_size_[1] == -1) + win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); + + bool alt = Interactor->GetAltKey() != 0; + + std::string key(Interactor->GetKeySym()); + if (key.find("XF86ZoomIn") != std::string::npos) + zoomIn(); + else if (key.find("XF86ZoomOut") != std::string::npos) + zoomOut(); + + switch (Interactor->GetKeyCode()) + { + case 'h': case 'H': + { + std::cout << "| Help:\n" + "-------\n" + " p, P : switch to a point-based representation\n" + " w, W : switch to a wireframe-based representation (where available)\n" + " s, S : switch to a surface-based representation (where available)\n" + "\n" + " j, J : take a .PNG snapshot of the current window view\n" + " k, K : export scene to Wavefront .obj format\n" + " ALT + k, K : export scene to VRML format\n" + " c, C : display current camera/window parameters\n" + " f, F : fly to point mode, hold the key and move mouse where to fly\n" + "\n" + " e, E : exit the interactor\n" + " q, Q : stop and call VTK's TerminateApp\n" + "\n" + " +/- : increment/decrement overall point size\n" + " +/- [+ ALT] : zoom in/out \n" + "\n" + " r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n" + "\n" + " ALT + s, S : turn stereo mode on/off\n" + " ALT + f, F : switch between maximized window mode and original size\n" + "\n" + << std::endl; + break; + } + + // Switch representation to points + case 'p': case 'P': + { + vtkSmartPointer ac = CurrentRenderer->GetActors(); + vtkCollectionSimpleIterator ait; + for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) + for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) + { + vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); + apart->GetProperty()->SetRepresentationToPoints(); + } + break; + } + + // Save a PNG snapshot + case 'j': case 'J': + saveScreenshot(cv::format("screenshot-%d.png", (unsigned int)time(0))); break; + + // Export scene as in obj or vrml format + case 'k': case 'K': + { + String format = alt ? "scene-%d.vrml" : "scene-%d"; + exportScene(cv::format(format.c_str(), (unsigned int)time(0))); + break; + } + + // display current camera settings/parameters + case 'c': case 'C': + { + vtkSmartPointer cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera(); + + Vec2d clip(cam->GetClippingRange()); + Vec3d focal(cam->GetFocalPoint()), pos(cam->GetPosition()), view(cam->GetViewUp()); + Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition()); + Vec2i win_size(Interactor->GetRenderWindow()->GetSize()); + double angle = cam->GetViewAngle () / 180.0 * CV_PI; + + String data = cv::format("clip(%f,%f) focal(%f,%f,%f) pos(%f,%f,%f) view(%f,%f,%f) angle(%f) winsz(%d,%d) winpos(%d,%d)", + clip[0], clip[1], focal[0], focal[1], focal[2], pos[0], pos[1], pos[2], view[0], view[1], view[2], + angle, win_size[0], win_size[1], win_pos[0], win_pos[1]); + + std::cout << data.c_str() << std::endl; + + break; + } + case '=': + { + zoomIn(); + break; + } + case 43: // KEY_PLUS + { + if (alt) + zoomIn(); + else + { + vtkSmartPointer ac = CurrentRenderer->GetActors(); + vtkCollectionSimpleIterator ait; + for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) + for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) + { + vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); + float psize = apart->GetProperty()->GetPointSize(); + if (psize < 63.0f) + apart->GetProperty()->SetPointSize(psize + 1.0f); + } + } + break; + } + case 45: // KEY_MINUS + { + if (alt) + zoomOut(); + else + { + vtkSmartPointer ac = CurrentRenderer->GetActors(); + vtkCollectionSimpleIterator ait; + for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); ) + for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); ) + { + vtkActor* apart = vtkActor::SafeDownCast(path->GetLastNode()->GetViewProp()); + float psize = apart->GetProperty()->GetPointSize(); + if (psize > 1.0f) + apart->GetProperty()->SetPointSize(psize - 1.0f); + } + } + break; + } + // Switch between maximize and original window size + case 'f': case 'F': + { + if (alt) + { + Vec2i screen_size(Interactor->GetRenderWindow()->GetScreenSize()); + Vec2i win_size(Interactor->GetRenderWindow()->GetSize()); + + // Is window size = max? + if (win_size == max_win_size_) + { + Interactor->GetRenderWindow()->SetSize(win_size_.val); + Interactor->GetRenderWindow()->SetPosition(win_pos_.val); + Interactor->GetRenderWindow()->Render(); + Interactor->Render(); + } + // Set to max + else + { + win_pos_ = Vec2i(Interactor->GetRenderWindow()->GetPosition()); + win_size_ = win_size; + + Interactor->GetRenderWindow()->SetSize(screen_size.val); + Interactor->GetRenderWindow()->Render(); + Interactor->Render(); + max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize()); + } + } + else + { + AnimState = VTKIS_ANIM_ON; + Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer); + vtkSmartPointer picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker()); + if (picker) + if (picker->GetPath()) + Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition()); + AnimState = VTKIS_ANIM_OFF; + } + break; + } + // 's'/'S' w/out ALT + case 's': case 'S': + { + if (alt) + { + vtkSmartPointer window = Interactor->GetRenderWindow(); + if (!window->GetStereoRender()) + { + static Vec2i red_blue(4, 3), magenta_green(2, 5); + window->SetAnaglyphColorMask (stereo_anaglyph_mask_default_ ? red_blue.val : magenta_green.val); + stereo_anaglyph_mask_default_ = !stereo_anaglyph_mask_default_; + } + window->SetStereoRender(!window->GetStereoRender()); + Interactor->Render(); + } + else + Superclass::OnKeyDown(); + break; + } + + case 'o': case 'O': + { + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + cam->SetParallelProjection(!cam->GetParallelProjection()); + CurrentRenderer->Render(); + break; + } + + // Overwrite the camera reset + case 'r': case 'R': + { + if (!alt) + { + Superclass::OnKeyDown(); + break; + } + + WidgetActorMap::iterator it = widget_actor_map_->begin(); + // it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault. + for (; it != widget_actor_map_->end(); ++it) + { + vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second); + if (actor && actor->GetUserMatrix()) + break; + } + + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + + // if a valid transformation was found, use it otherwise fall back to default view point. + if (it != widget_actor_map_->end()) + { + vtkMatrix4x4* m = vtkProp3D::SafeDownCast(it->second)->GetUserMatrix(); + + cam->SetFocalPoint(m->GetElement(0, 3) - m->GetElement(0, 2), + m->GetElement(1, 3) - m->GetElement(1, 2), + m->GetElement(2, 3) - m->GetElement(2, 2)); + + cam->SetViewUp (m->GetElement(0, 1), m->GetElement(1, 1), m->GetElement(2, 1)); + cam->SetPosition(m->GetElement(0, 3), m->GetElement(1, 3), m->GetElement(2, 3)); + } + else + { + cam->SetPosition(0, 0, 0); + cam->SetFocalPoint(0, 0, 1); + cam->SetViewUp(0, -1, 0); + } + + // go to the next actor for the next key-press event. + if (it != widget_actor_map_->end()) + ++it; + else + it = widget_actor_map_->begin(); + + CurrentRenderer->SetActiveCamera(cam); + CurrentRenderer->ResetCameraClippingRange(); + CurrentRenderer->Render(); + break; + } + + case 'q': case 'Q': + { + Interactor->ExitCallback(); + return; + } + default: + { + Superclass::OnKeyDown(); + break; + } + } + + KeyboardEvent event(KeyboardEvent::KEY_DOWN, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers()); + if (keyboardCallback_) + keyboardCallback_(event, keyboard_callback_cookie_); + Interactor->Render(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnKeyUp() +{ + KeyboardEvent event(KeyboardEvent::KEY_UP, Interactor->GetKeySym(), Interactor->GetKeyCode(), getModifiers()); + if (keyboardCallback_) + keyboardCallback_(event, keyboard_callback_cookie_); + Superclass::OnKeyUp(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnMouseMove() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + Superclass::OnMouseMove(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnLeftButtonDown() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event(type, MouseEvent::LeftButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + Superclass::OnLeftButtonDown(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnLeftButtonUp() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + Superclass::OnLeftButtonUp(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnMiddleButtonDown() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event(type, MouseEvent::MiddleButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + Superclass::OnMiddleButtonDown(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnMiddleButtonUp() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + Superclass::OnMiddleButtonUp(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnRightButtonDown() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick; + MouseEvent event(type, MouseEvent::RightButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + Superclass::OnRightButtonDown(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnRightButtonUp() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + Superclass::OnRightButtonUp(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnMouseWheelForward() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + if (Interactor->GetRepeatCount() && mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if (Interactor->GetAltKey()) + { + // zoom + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + double opening_angle = cam->GetViewAngle(); + if (opening_angle > 15.0) + opening_angle -= 1.0; + + cam->SetViewAngle(opening_angle); + cam->Modified(); + CurrentRenderer->ResetCameraClippingRange(); + CurrentRenderer->Modified(); + CurrentRenderer->Render(); + Interactor->Render(); + } + else + Superclass::OnMouseWheelForward(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnMouseWheelBackward() +{ + Vec2i p(Interactor->GetEventPosition()); + MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, getModifiers()); + if (mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if (Interactor->GetRepeatCount() && mouseCallback_) + mouseCallback_(event, mouse_callback_cookie_); + + if (Interactor->GetAltKey()) + { + // zoom + vtkSmartPointer cam = CurrentRenderer->GetActiveCamera(); + double opening_angle = cam->GetViewAngle(); + if (opening_angle < 170.0) + opening_angle += 1.0; + + cam->SetViewAngle(opening_angle); + cam->Modified(); + CurrentRenderer->ResetCameraClippingRange(); + CurrentRenderer->Modified(); + CurrentRenderer->Render(); + Interactor->Render(); + } + else + Superclass::OnMouseWheelBackward(); +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::InteractorStyle::OnTimer() +{ + CV_Assert("Interactor style not initialized." && init_); + Interactor->Render(); +} diff --git a/modules/viz/src/interactor_style.hpp b/modules/viz/src/interactor_style.hpp new file mode 100644 index 0000000000..8d01697a87 --- /dev/null +++ b/modules/viz/src/interactor_style.hpp @@ -0,0 +1,119 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __OPENCV_VIZ_INTERACTOR_STYLE_H__ +#define __OPENCV_VIZ_INTERACTOR_STYLE_H__ + +namespace cv +{ + namespace viz + { + class InteractorStyle : public vtkInteractorStyleTrackballCamera + { + public: + static InteractorStyle *New(); + virtual ~InteractorStyle() {} + + // this macro defines Superclass, the isA functionality and the safe downcast method + vtkTypeMacro(InteractorStyle, vtkInteractorStyleTrackballCamera) + + /** \brief Initialization routine. Must be called before anything else. */ + virtual void Initialize(); + + void setWidgetActorMap(const Ptr& actors) { widget_actor_map_ = actors; } + void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0); + void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0); + void saveScreenshot(const String &file); + void exportScene(const String &file); + + private: + /** \brief Set to true after initialization is complete. */ + bool init_; + + Ptr widget_actor_map_; + + Vec2i win_size_; + Vec2i win_pos_; + Vec2i max_win_size_; + + /** \brief Interactor style internal method. Gets called whenever a key is pressed. */ + virtual void OnChar(); + + // Keyboard events + virtual void OnKeyDown(); + virtual void OnKeyUp(); + + // mouse button events + virtual void OnMouseMove(); + virtual void OnLeftButtonDown(); + virtual void OnLeftButtonUp(); + virtual void OnMiddleButtonDown(); + virtual void OnMiddleButtonUp(); + virtual void OnRightButtonDown(); + virtual void OnRightButtonUp(); + virtual void OnMouseWheelForward(); + virtual void OnMouseWheelBackward(); + + /** \brief Interactor style internal method. Gets called periodically if a timer is set. */ + virtual void OnTimer(); + + void zoomIn(); + void zoomOut(); + + /** \brief True if we're using red-blue colors for anaglyphic stereo, false if magenta-green. */ + bool stereo_anaglyph_mask_default_; + + void (*keyboardCallback_)(const KeyboardEvent&, void*); + void *keyboard_callback_cookie_; + + void (*mouseCallback_)(const MouseEvent&, void*); + void *mouse_callback_cookie_; + + int getModifiers(); + }; + } +} + +#endif diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp new file mode 100644 index 0000000000..d9681ce83b --- /dev/null +++ b/modules/viz/src/precomp.hpp @@ -0,0 +1,324 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __OPENCV_VIZ_PRECOMP_HPP__ +#define __OPENCV_VIZ_PRECOMP_HPP__ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(_WIN32) || defined(__CYGWIN__) +# include /* unlink */ +#else +# include /* unlink */ +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +namespace cv +{ + namespace viz + { + typedef std::map > WidgetActorMap; + typedef std::map VizMap; + + class VizStorage + { + public: + static void unregisterAll(); + + //! window names automatically have Viz - prefix even though not provided by the users + static String generateWindowName(const String &window_name); + + private: + VizStorage(); // Static + ~VizStorage(); + + static void add(const Viz3d& window); + static Viz3d& get(const String &window_name); + static void remove(const String &window_name); + static bool windowExists(const String &window_name); + static void removeUnreferenced(); + + static VizMap storage; + friend class Viz3d; + }; + + template inline _Tp normalized(const _Tp& v) { return v * 1/norm(v); } + + template inline bool isNan(const _Tp* data) + { + return isNan(data[0]) || isNan(data[1]) || isNan(data[2]); + } + + inline vtkSmartPointer getActor(const Widget3D& widget) + { + return vtkActor::SafeDownCast(WidgetAccessor::getProp(widget)); + } + + inline vtkSmartPointer getPolyData(const Widget3D& widget) + { + vtkSmartPointer mapper = getActor(widget)->GetMapper(); + return vtkPolyData::SafeDownCast(mapper->GetInput()); + } + + inline vtkSmartPointer vtkmatrix(const cv::Matx44d &matrix) + { + vtkSmartPointer vtk_matrix = vtkSmartPointer::New(); + vtk_matrix->DeepCopy(matrix.val); + return vtk_matrix; + } + + inline Color vtkcolor(const Color& color) + { + Color scaled_color = color * (1.0/255.0); + std::swap(scaled_color[0], scaled_color[2]); + return scaled_color; + } + + inline Vec3d get_random_vec(double from = -10.0, double to = 10.0) + { + RNG& rng = theRNG(); + return Vec3d(rng.uniform(from, to), rng.uniform(from, to), rng.uniform(from, to)); + } + + struct VtkUtils + { + template + static void SetInputData(vtkSmartPointer filter, vtkPolyData* polydata) + { + #if VTK_MAJOR_VERSION <= 5 + filter->SetInput(polydata); + #else + filter->SetInputData(polydata); + #endif + } + template + static void SetSourceData(vtkSmartPointer filter, vtkPolyData* polydata) + { + #if VTK_MAJOR_VERSION <= 5 + filter->SetSource(polydata); + #else + filter->SetSourceData(polydata); + #endif + } + + template + static void SetInputData(vtkSmartPointer filter, vtkImageData* polydata) + { + #if VTK_MAJOR_VERSION <= 5 + filter->SetInput(polydata); + #else + filter->SetInputData(polydata); + #endif + } + + template + static void AddInputData(vtkSmartPointer filter, vtkPolyData *polydata) + { + #if VTK_MAJOR_VERSION <= 5 + filter->AddInput(polydata); + #else + filter->AddInputData(polydata); + #endif + } + + static vtkSmartPointer FillScalars(size_t size, const Color& color) + { + Vec3b rgb = Vec3d(color[2], color[1], color[0]); + Vec3b* color_data = new Vec3b[size]; + std::fill(color_data, color_data + size, rgb); + + vtkSmartPointer scalars = vtkSmartPointer::New(); + scalars->SetName("Colors"); + scalars->SetNumberOfComponents(3); + scalars->SetNumberOfTuples(size); + scalars->SetArray(color_data->val, size * 3, 0); + return scalars; + } + + static vtkSmartPointer ComputeNormals(vtkSmartPointer polydata) + { + vtkSmartPointer normals_generator = vtkSmartPointer::New(); + normals_generator->ComputePointNormalsOn(); + normals_generator->ComputeCellNormalsOff(); + normals_generator->SetFeatureAngle(0.1); + normals_generator->SetSplitting(0); + normals_generator->SetConsistency(1); + normals_generator->SetAutoOrientNormals(0); + normals_generator->SetFlipNormals(0); + normals_generator->SetNonManifoldTraversal(1); + VtkUtils::SetInputData(normals_generator, polydata); + normals_generator->Update(); + return normals_generator->GetOutput(); + } + + static vtkSmartPointer TransformPolydata(vtkSmartPointer algorithm_output_port, const Affine3d& pose) + { + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->SetMatrix(vtkmatrix(pose.matrix)); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetTransform(transform); + transform_filter->SetInputConnection(algorithm_output_port); + transform_filter->Update(); + return transform_filter->GetOutput(); + } + + static vtkSmartPointer TransformPolydata(vtkSmartPointer polydata, const Affine3d& pose) + { + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->SetMatrix(vtkmatrix(pose.matrix)); + + vtkSmartPointer transform_filter = vtkSmartPointer::New(); + VtkUtils::SetInputData(transform_filter, polydata); + transform_filter->SetTransform(transform); + transform_filter->Update(); + return transform_filter->GetOutput(); + } + }; + } +} + +#include "interactor_style.hpp" +#include "vizimpl.hpp" + + +#endif diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp new file mode 100644 index 0000000000..f3d24f757c --- /dev/null +++ b/modules/viz/src/shapes.cpp @@ -0,0 +1,1088 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// line widget implementation +cv::viz::WLine::WLine(const Point3d &pt1, const Point3d &pt2, const Color &color) +{ + vtkSmartPointer line = vtkSmartPointer::New(); + line->SetPoint1(pt1.x, pt1.y, pt1.z); + line->SetPoint2(pt2.x, pt2.y, pt2.z); + line->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, line->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::WLine cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// sphere widget implementation + +cv::viz::WSphere::WSphere(const Point3d ¢er, double radius, int sphere_resolution, const Color &color) +{ + vtkSmartPointer sphere = vtkSmartPointer::New(); + sphere->SetRadius(radius); + sphere->SetCenter(center.x, center.y, center.z); + sphere->SetPhiResolution(sphere_resolution); + sphere->SetThetaResolution(sphere_resolution); + sphere->LatLongTessellationOff(); + sphere->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, sphere->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::WSphere cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// plane widget implementation + +cv::viz::WPlane::WPlane(const Size2d& size, const Color &color) +{ + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetOrigin(-0.5 * size.width, -0.5 * size.height, 0.0); + plane->SetPoint1( 0.5 * size.width, -0.5 * size.height, 0.0); + plane->SetPoint2(-0.5 * size.width, 0.5 * size.height, 0.0); + plane->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, plane->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + actor->GetProperty()->LightingOff(); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +cv::viz::WPlane::WPlane(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, const Size2d& size, const Color &color) +{ + Vec3d zvec = normalize(normal); + Vec3d xvec = normalize(new_yaxis.cross(zvec)); + Vec3d yvec = zvec.cross(xvec); + + WPlane plane(size, color); + plane.applyTransform(makeTransformToGlobal(xvec, yvec, zvec, center)); + *this = plane; +} + +template<> cv::viz::WPlane cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// arrow widget implementation + +cv::viz::WArrow::WArrow(const Point3d& pt1, const Point3d& pt2, double thickness, const Color &color) +{ + vtkSmartPointer arrow_source = vtkSmartPointer::New(); + arrow_source->SetShaftRadius(thickness); + arrow_source->SetTipRadius(thickness * 3.0); + arrow_source->SetTipLength(thickness * 10.0); + + Vec3d arbitrary = get_random_vec(); + Vec3d start_point(pt1.x, pt1.y, pt1.z), end_point(pt2.x, pt2.y, pt2.z); + + double length = norm(end_point - start_point); + + Vec3d xvec = normalized(end_point - start_point); + Vec3d zvec = normalized(xvec.cross(arbitrary)); + Vec3d yvec = zvec.cross(xvec); + + Matx33d R = makeTransformToGlobal(xvec, yvec, zvec).rotation(); + Affine3d transform_with_scale(R * length, start_point); + + vtkSmartPointer polydata = VtkUtils::TransformPolydata(arrow_source->GetOutputPort(), transform_with_scale); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, polydata); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::WArrow cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// circle widget implementation + +cv::viz::WCircle::WCircle(double radius, double thickness, const Color &color) +{ + vtkSmartPointer disk = vtkSmartPointer::New(); + disk->SetCircumferentialResolution(30); + disk->SetInnerRadius(radius - thickness); + disk->SetOuterRadius(radius + thickness); + disk->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, disk->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->GetProperty()->LightingOff(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); + +} + +cv::viz::WCircle::WCircle(double radius, const Point3d& center, const Vec3d& normal, double thickness, const Color &color) +{ + Vec3d arbitrary = get_random_vec(); + Vec3d zvec = normalized(normal); + Vec3d xvec = normalized(zvec.cross(arbitrary)); + Vec3d yvec = zvec.cross(xvec); + + WCircle circle(radius, thickness, color); + circle.applyTransform(makeTransformToGlobal(xvec, yvec, zvec, center)); + *this = circle; +} + +template<> cv::viz::WCircle cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// WCone widget implementation + +cv::viz::WCone::WCone(double length, double radius, int resolution, const Color &color) +{ + vtkSmartPointer cone_source = vtkSmartPointer::New(); + cone_source->SetCenter(length*0.5, 0.0, 0.0); + cone_source->SetHeight(length); + cone_source->SetRadius(radius); + cone_source->SetResolution(resolution); + cone_source->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, cone_source->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +cv::viz::WCone::WCone(double radius, const Point3d& center, const Point3d& tip, int resolution, const Color &color) +{ + Vec3d arbitrary = get_random_vec(); + Vec3d xvec = normalized(Vec3d(tip - center)); + Vec3d zvec = normalized(xvec.cross(arbitrary)); + Vec3d yvec = zvec.cross(xvec); + + WCone circle(norm(tip - center), radius, resolution, color); + circle.applyTransform(makeTransformToGlobal(xvec, yvec, zvec, center)); + *this = circle; +} + +template<> cv::viz::WCone cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// cylinder widget implementation + +cv::viz::WCylinder::WCylinder(const Point3d& axis_point1, const Point3d& axis_point2, double radius, int numsides, const Color &color) +{ + vtkSmartPointer line = vtkSmartPointer::New(); + line->SetPoint1(axis_point1.x, axis_point1.y, axis_point1.z); + line->SetPoint2(axis_point2.x, axis_point2.y, axis_point2.z); + + vtkSmartPointer tuber = vtkSmartPointer::New(); + tuber->SetInputConnection(line->GetOutputPort()); + tuber->SetNumberOfSides(numsides); + tuber->SetRadius(radius); + tuber->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, tuber->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::WCylinder cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// cylinder widget implementation + +cv::viz::WCube::WCube(const Point3d& min_point, const Point3d& max_point, bool wire_frame, const Color &color) +{ + double bounds[6]; + bounds[0] = std::min(min_point.x, max_point.x); + bounds[1] = std::max(min_point.x, max_point.x); + bounds[2] = std::min(min_point.y, max_point.y); + bounds[3] = std::max(min_point.y, max_point.y); + bounds[4] = std::min(min_point.z, max_point.z); + bounds[5] = std::max(min_point.z, max_point.z); + + vtkSmartPointer cube; + if (wire_frame) + { + cube = vtkSmartPointer::New(); + vtkOutlineSource::SafeDownCast(cube)->SetBounds(bounds); + } + else + { + cube = vtkSmartPointer::New(); + vtkCubeSource::SafeDownCast(cube)->SetBounds(bounds); + } + cube->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, cube->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::WCube cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// coordinate system widget implementation + +cv::viz::WCoordinateSystem::WCoordinateSystem(double scale) +{ + vtkSmartPointer axes = vtkSmartPointer::New(); + axes->SetOrigin(0, 0, 0); + axes->SetScaleFactor(scale); + axes->Update(); + + vtkSmartPointer colors = vtkSmartPointer::New(); + colors->SetNumberOfComponents(3); + colors->InsertNextTuple3(255, 0, 0); + colors->InsertNextTuple3(255, 0, 0); + colors->InsertNextTuple3(0, 255, 0); + colors->InsertNextTuple3(0, 255, 0); + colors->InsertNextTuple3(0, 0, 255); + colors->InsertNextTuple3(0, 0, 255); + + vtkSmartPointer polydata = axes->GetOutput(); + polydata->GetPointData()->SetScalars(colors); + + vtkSmartPointer tube_filter = vtkSmartPointer::New(); + VtkUtils::SetInputData(tube_filter, polydata); + tube_filter->SetRadius(axes->GetScaleFactor() / 50.0); + tube_filter->SetNumberOfSides(6); + tube_filter->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUsePointData(); + VtkUtils::SetInputData(mapper, tube_filter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::WCoordinateSystem cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// polyline widget implementation + +cv::viz::WPolyLine::WPolyLine(InputArray _points, const Color &color) +{ + CV_Assert(_points.type() == CV_32FC3 || _points.type() == CV_32FC4 || _points.type() == CV_64FC3 || _points.type() == CV_64FC4); + + const float *fpoints = _points.getMat().ptr(); + const double *dpoints = _points.getMat().ptr(); + size_t total = _points.total(); + int s_chs = _points.channels(); + + vtkSmartPointer points = vtkSmartPointer::New(); + points->SetDataType(_points.depth() == CV_32F ? VTK_FLOAT : VTK_DOUBLE); + points->SetNumberOfPoints(total); + + if (_points.depth() == CV_32F) + for(size_t i = 0; i < total; ++i, fpoints += s_chs) + points->SetPoint(i, fpoints); + + if (_points.depth() == CV_64F) + for(size_t i = 0; i < total; ++i, dpoints += s_chs) + points->SetPoint(i, dpoints); + + vtkSmartPointer cell_array = vtkSmartPointer::New(); + cell_array->Allocate(cell_array->EstimateSize(1, total)); + cell_array->InsertNextCell(total); + for(size_t i = 0; i < total; ++i) + cell_array->InsertCellPoint(i); + + vtkSmartPointer scalars = VtkUtils::FillScalars(total, color); + + vtkSmartPointer polydata = vtkSmartPointer::New(); + polydata->SetPoints(points); + polydata->SetLines(cell_array); + polydata->GetPointData()->SetScalars(scalars); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, polydata); + mapper->SetScalarRange(0, 255); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::WPolyLine cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// grid widget implementation + + +cv::viz::WGrid::WGrid(const Vec2i &cells, const Vec2d &cells_spacing, const Color &color) +{ + vtkSmartPointer grid_data = vtkSmartPointer::New(); + + // Add 1 to dimensions because in ImageData dimensions is the number of lines + // - however here it means number of cells + grid_data->SetDimensions(cells[0]+1, cells[1]+1, 1); + grid_data->SetSpacing(cells_spacing[0], cells_spacing[1], 0.); + + // Set origin of the grid to be the middle of the grid + grid_data->SetOrigin(cells[0] * cells_spacing[0] * (-0.5), cells[1] * cells_spacing[1] * (-0.5), 0); + + // Extract the edges so we have the grid + vtkSmartPointer extract_edges = vtkSmartPointer::New(); + VtkUtils::SetInputData(extract_edges, grid_data); + extract_edges->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, extract_edges->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +cv::viz::WGrid::WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, const Vec2i &cells, const Vec2d &cells_spacing, const Color &color) +{ + Vec3d zvec = normalize(normal); + Vec3d xvec = normalize(new_yaxis.cross(zvec)); + Vec3d yvec = zvec.cross(xvec); + + WGrid grid(cells, cells_spacing, color); + grid.applyTransform(makeTransformToGlobal(xvec, yvec, zvec, center)); + *this = grid; +} + +template<> cv::viz::WGrid cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// text3D widget implementation + +cv::viz::WText3D::WText3D(const String &text, const Point3d &position, double text_scale, bool face_camera, const Color &color) +{ + vtkSmartPointer textSource = vtkSmartPointer::New(); + textSource->SetText(text.c_str()); + textSource->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(textSource->GetOutputPort()); + + if (face_camera) + { + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + actor->SetPosition(position.x, position.y, position.z); + actor->SetScale(text_scale); + WidgetAccessor::setProp(*this, actor); + } + else + { + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + actor->SetPosition(position.x, position.y, position.z); + actor->SetScale(text_scale); + actor->GetProperty()->LightingOff(); + WidgetAccessor::setProp(*this, actor); + } + + setColor(color); +} + +void cv::viz::WText3D::setText(const String &text) +{ + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("This widget does not support text." && actor); + + // Update text source + vtkPolyDataMapper *mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + vtkVectorText * textSource = vtkVectorText::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); + CV_Assert("This widget does not support text." && textSource); + + textSource->SetText(text.c_str()); + textSource->Modified(); + textSource->Update(); +} + +cv::String cv::viz::WText3D::getText() const +{ + vtkFollower *actor = vtkFollower::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("This widget does not support text." && actor); + + vtkPolyDataMapper *mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + vtkVectorText * textSource = vtkVectorText::SafeDownCast(mapper->GetInputConnection(0,0)->GetProducer()); + CV_Assert("This widget does not support text." && textSource); + + return textSource->GetText(); +} + +template<> cv::viz::WText3D cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// text widget implementation + +cv::viz::WText::WText(const String &text, const Point &pos, int font_size, const Color &color) +{ + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetDisplayPosition(pos.x, pos.y); + actor->SetInput(text.c_str()); + + actor->GetProperty()->SetDisplayLocationToForeground(); + + vtkSmartPointer tprop = actor->GetTextProperty(); + tprop->SetFontSize(font_size); + tprop->SetFontFamilyToCourier(); + tprop->SetJustificationToLeft(); + tprop->BoldOn(); + + Color c = vtkcolor(color); + tprop->SetColor(c.val); + + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::WText cv::viz::Widget::cast() +{ + Widget2D widget = this->cast(); + return static_cast(widget); +} + +void cv::viz::WText::setText(const String &text) +{ + vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("This widget does not support text." && actor); + actor->SetInput(text.c_str()); +} + +cv::String cv::viz::WText::getText() const +{ + vtkTextActor *actor = vtkTextActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("This widget does not support text." && actor); + return actor->GetInput(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// image overlay widget implementation + +cv::viz::WImageOverlay::WImageOverlay(InputArray image, const Rect &rect) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetImage(image); + Size sz = image.size(); + + // Scale the image based on the Rect, and flip to match y-ais orientation + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->Scale(sz.width/(double)rect.width, sz.height/(double)rect.height, 1.0); + transform->RotateX(180); + + vtkSmartPointer image_reslice = vtkSmartPointer::New(); + image_reslice->SetResliceTransform(transform); + image_reslice->SetInputConnection(source->GetOutputPort()); + image_reslice->SetOutputDimensionality(2); + image_reslice->InterpolateOn(); + image_reslice->AutoCropOutputOn(); + image_reslice->Update(); + + vtkSmartPointer image_mapper = vtkSmartPointer::New(); + image_mapper->SetInputConnection(image_reslice->GetOutputPort()); + image_mapper->SetColorWindow(255); // OpenCV color + image_mapper->SetColorLevel(127.5); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(image_mapper); + actor->SetPosition(rect.x, rect.y); + actor->GetProperty()->SetDisplayLocationToForeground(); + + WidgetAccessor::setProp(*this, actor); +} + +void cv::viz::WImageOverlay::setImage(InputArray image) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("This widget does not support overlay image." && actor); + + vtkImageMapper *mapper = vtkImageMapper::SafeDownCast(actor->GetMapper()); + CV_Assert("This widget does not support overlay image." && mapper); + \ + Vec6i extent; + mapper->GetInput()->GetExtent(extent.val); + Size size(extent[1], extent[3]); + + // Create the vtk image and set its parameters based on input image + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetImage(image); + Size sz = image.size(); + + // Scale the image based on the Rect, and flip to match y-ais orientation + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->Scale(sz.width/(double)size.width, sz.height/(double)size.height, 1.0); + transform->RotateX(180); + + vtkSmartPointer image_reslice = vtkSmartPointer::New(); + image_reslice->SetResliceTransform(transform); + image_reslice->SetInputConnection(source->GetOutputPort()); + image_reslice->SetOutputDimensionality(2); + image_reslice->InterpolateOn(); + image_reslice->AutoCropOutputOn(); + image_reslice->Update(); + + mapper->SetInputConnection(image_reslice->GetOutputPort()); +} + +template<> cv::viz::WImageOverlay cv::viz::Widget::cast() +{ + Widget2D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// image 3D widget implementation + +cv::viz::WImage3D::WImage3D(InputArray image, const Size2d &size) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetImage(image); + + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(source->GetOutputPort()); + + vtkSmartPointer plane = vtkSmartPointer::New(); + plane->SetOrigin(-0.5 * size.width, -0.5 * size.height, 0.0); + plane->SetPoint1( 0.5 * size.width, -0.5 * size.height, 0.0); + plane->SetPoint2(-0.5 * size.width, 0.5 * size.height, 0.0); + + vtkSmartPointer textured_plane = vtkSmartPointer::New(); + textured_plane->SetInputConnection(plane->GetOutputPort()); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputConnection(textured_plane->GetOutputPort()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + actor->SetTexture(texture); + actor->GetProperty()->ShadingOff(); + actor->GetProperty()->LightingOff(); + + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::WImage3D::WImage3D(InputArray image, const Size2d &size, const Vec3d ¢er, const Vec3d &normal, const Vec3d &up_vector) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + // Compute the transformation matrix for drawing the camera frame in a scene + Vec3d n = normalize(normal); + Vec3d u = normalize(up_vector.cross(n)); + Vec3d v = n.cross(u); + Affine3d pose = makeTransformToGlobal(u, v, n, center); + + WImage3D image3d(image, size); + image3d.applyTransform(pose); + *this = image3d; +} + +void cv::viz::WImage3D::setImage(InputArray image) +{ + CV_Assert(!image.empty() && image.depth() == CV_8U); + + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("This widget does not support 3D image." && actor); + + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetImage(image); + + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(source->GetOutputPort()); + + actor->SetTexture(texture); +} + +template<> cv::viz::WImage3D cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// camera position widget implementation + +namespace cv { namespace viz { namespace +{ + struct CameraPositionUtils + { + static vtkSmartPointer createFrustum(double aspect_ratio, double fovy, double scale) + { + vtkSmartPointer camera = vtkSmartPointer::New(); + camera->SetViewAngle(fovy); + camera->SetPosition(0.0, 0.0, 0.0); + camera->SetViewUp(0.0, 1.0, 0.0); + camera->SetFocalPoint(0.0, 0.0, 1.0); + camera->SetClippingRange(1e-9, scale); + + double planes_array[24]; + camera->GetFrustumPlanes(aspect_ratio, planes_array); + + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planes_array); + + vtkSmartPointer frustumSource = vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + + vtkSmartPointer extract_edges = vtkSmartPointer::New(); + extract_edges->SetInputConnection(frustumSource->GetOutputPort()); + extract_edges->Update(); + + return extract_edges->GetOutput(); + } + + static Mat ensureColorImage(InputArray image) + { + Mat color(image.size(), CV_8UC3); + if (image.channels() == 1) + { + Vec3b *drow = color.ptr(); + for(int y = 0; y < color.rows; ++y) + { + const unsigned char *srow = image.getMat().ptr(y); + const unsigned char *send = srow + color.cols; + for(;srow < send;) + *drow++ = Vec3b::all(*srow++); + } + } + else + image.getMat().copyTo(color); + return color; + } + }; +}}} + +cv::viz::WCameraPosition::WCameraPosition(double scale) +{ + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, getPolyData(WCoordinateSystem(scale))); + mapper->SetScalarModeToUsePointData(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, double scale, const Color &color) +{ + double f_x = K(0,0), f_y = K(1,1), c_y = K(1,2); + + // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) + double fovy = 2.0 * atan2(c_y, f_y) * 180 / CV_PI; + double aspect_ratio = f_y / f_x; + + vtkSmartPointer polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, polydata); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, double scale, const Color &color) +{ + double aspect_ratio = tan(fov[0] * 0.5) / tan(fov[1] * 0.5); + double fovy = fov[1] * 180 / CV_PI; + + vtkSmartPointer polydata = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, polydata); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, InputArray _image, double scale, const Color &color) +{ + CV_Assert(!_image.empty() && _image.depth() == CV_8U); + Mat image = CameraPositionUtils::ensureColorImage(_image); + image.at(0, 0) = Vec3d(color.val); //workaround of VTK limitation + + double f_y = K(1,1), c_y = K(1,2); + // Assuming that this is an ideal camera (c_y and c_x are at the center of the image) + double fovy = 2.0 * atan2(c_y, f_y) * 180.0 / CV_PI; + double far_end_height = 2.00 * c_y * scale / f_y; + double aspect_ratio = image.cols/(double)image.rows; + double image_scale = far_end_height/image.rows; + + WImage3D image_widget(image, Size2d(image.cols, image.rows) * image_scale); + image_widget.applyTransform(Affine3d().translate(Vec3d(0, 0, scale))); + vtkSmartPointer plane = getPolyData(image_widget); + + vtkSmartPointer frustum = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale); + + // Frustum needs to be textured or else it can't be combined with image + vtkSmartPointer frustum_texture = vtkSmartPointer::New(); + VtkUtils::SetInputData(frustum_texture, frustum); + frustum_texture->SetSRange(0.0, 0.0); // Texture mapping with only one pixel + frustum_texture->SetTRange(0.0, 0.0); // from the image to have constant color + + vtkSmartPointer append_filter = vtkSmartPointer::New(); + append_filter->AddInputConnection(frustum_texture->GetOutputPort()); + VtkUtils::AddInputData(append_filter, plane); + + vtkSmartPointer actor = getActor(image_widget); + actor->GetMapper()->SetInputConnection(append_filter->GetOutputPort()); + WidgetAccessor::setProp(*this, actor); +} + +cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, InputArray _image, double scale, const Color &color) +{ + CV_Assert(!_image.empty() && _image.depth() == CV_8U); + Mat image = CameraPositionUtils::ensureColorImage(_image); + image.at(0, 0) = Vec3d(color.val); //workaround of VTK limitation + + double fovy = fov[1] * 180.0 / CV_PI; + double far_end_height = 2.0 * scale * tan(fov[1] * 0.5); + double aspect_ratio = image.cols/(double)image.rows; + double image_scale = far_end_height/image.rows; + + WImage3D image_widget(image, Size2d(image.cols, image.rows) * image_scale); + image_widget.applyTransform(Affine3d().translate(Vec3d(0, 0, scale))); + vtkSmartPointer plane = getPolyData(image_widget); + + vtkSmartPointer frustum = CameraPositionUtils::createFrustum(aspect_ratio, fovy, scale); + + // Frustum needs to be textured or else it can't be combined with image + vtkSmartPointer frustum_texture = vtkSmartPointer::New(); + VtkUtils::SetInputData(frustum_texture, frustum); + frustum_texture->SetSRange(0.0, 0.0); // Texture mapping with only one pixel + frustum_texture->SetTRange(0.0, 0.0); // from the image to have constant color + + vtkSmartPointer append_filter = vtkSmartPointer::New(); + append_filter->AddInputConnection(frustum_texture->GetOutputPort()); + VtkUtils::AddInputData(append_filter, plane); + + vtkSmartPointer actor = getActor(image_widget); + actor->GetMapper()->SetInputConnection(append_filter->GetOutputPort()); + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::WCameraPosition cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// trajectory widget implementation + +cv::viz::WTrajectory::WTrajectory(InputArray _path, int display_mode, double scale, const Color &color) +{ + vtkSmartPointer append_filter = vtkSmartPointer::New(); + + // Bitwise and with 3 in order to limit the domain to 2 bits + if (display_mode & WTrajectory::PATH) + { + Mat points = vtkTrajectorySource::ExtractPoints(_path); + vtkSmartPointer polydata = getPolyData(WPolyLine(points, color)); + VtkUtils::AddInputData(append_filter, polydata); + } + + if (display_mode & WTrajectory::FRAMES) + { + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetTrajectory(_path); + + vtkSmartPointer glyph = getPolyData(WCoordinateSystem(scale)); + + vtkSmartPointer tensor_glyph = vtkSmartPointer::New(); + tensor_glyph->SetInputConnection(source->GetOutputPort()); + VtkUtils::SetSourceData(tensor_glyph, glyph); + tensor_glyph->ExtractEigenvaluesOff(); // Treat as a rotation matrix, not as something with eigenvalues + tensor_glyph->ThreeGlyphsOff(); + tensor_glyph->SymmetricOff(); + tensor_glyph->ColorGlyphsOff(); + + append_filter->AddInputConnection(tensor_glyph->GetOutputPort()); + } + append_filter->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, append_filter->GetOutput()); + mapper->SetScalarModeToUsePointData(); + mapper->SetScalarRange(0, 255); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::WTrajectory cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// WTrajectoryFrustums widget implementation + +cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Matx33d &K, double scale, const Color &color) +{ + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetTrajectory(_path); + + vtkSmartPointer glyph = getPolyData(WCameraPosition(K, scale)); + + vtkSmartPointer tensor_glyph = vtkSmartPointer::New(); + tensor_glyph->SetInputConnection(source->GetOutputPort()); + VtkUtils::SetSourceData(tensor_glyph, glyph); + tensor_glyph->ExtractEigenvaluesOff(); // Treat as a rotation matrix, not as something with eigenvalues + tensor_glyph->ThreeGlyphsOff(); + tensor_glyph->SymmetricOff(); + tensor_glyph->ColorGlyphsOff(); + tensor_glyph->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, tensor_glyph->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +cv::viz::WTrajectoryFrustums::WTrajectoryFrustums(InputArray _path, const Vec2d &fov, double scale, const Color &color) +{ + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetTrajectory(_path); + + vtkSmartPointer glyph = getPolyData(WCameraPosition(fov, scale)); + + vtkSmartPointer tensor_glyph = vtkSmartPointer::New(); + tensor_glyph->SetInputConnection(source->GetOutputPort()); + VtkUtils::SetSourceData(tensor_glyph, glyph); + tensor_glyph->ExtractEigenvaluesOff(); // Treat as a rotation matrix, not as something with eigenvalues + tensor_glyph->ThreeGlyphsOff(); + tensor_glyph->SymmetricOff(); + tensor_glyph->ColorGlyphsOff(); + tensor_glyph->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + VtkUtils::SetInputData(mapper, tensor_glyph->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); + setColor(color); +} + +template<> cv::viz::WTrajectoryFrustums cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// WTrajectorySpheres widget implementation + +cv::viz::WTrajectorySpheres::WTrajectorySpheres(InputArray _path, double line_length, double radius, const Color &from, const Color &to) +{ + CV_Assert(_path.kind() == _InputArray::STD_VECTOR || _path.kind() == _InputArray::MAT); + CV_Assert(_path.type() == CV_32FC(16) || _path.type() == CV_64FC(16)); + + Mat path64; + _path.getMat().convertTo(path64, CV_64F); + Affine3d *traj = path64.ptr(); + size_t total = path64.total(); + + vtkSmartPointer append_filter = vtkSmartPointer::New(); + + for(size_t i = 0; i < total; ++i) + { + Vec3d curr = traj[i].translation(); + + vtkSmartPointer sphere_source = vtkSmartPointer::New(); + sphere_source->SetCenter(curr.val); + sphere_source->SetRadius( (i == 0) ? 2 * radius : radius ); + sphere_source->Update(); + + double alpha = static_cast(i)/total; + Color c = from * (1 - alpha) + to * alpha; + + vtkSmartPointer polydata = sphere_source->GetOutput(); + polydata->GetCellData()->SetScalars(VtkUtils::FillScalars(polydata->GetNumberOfCells(), c)); + VtkUtils::AddInputData(append_filter, polydata); + + if (i > 0) + { + Vec3d prev = traj[i-1].translation(); + Vec3d lvec = prev - curr; + + if(norm(lvec) > line_length) + lvec = normalize(lvec) * line_length; + + Vec3d lend = curr + lvec; + + vtkSmartPointer line_source = vtkSmartPointer::New(); + line_source->SetPoint1(curr.val); + line_source->SetPoint2(lend.val); + line_source->Update(); + vtkSmartPointer polydata_ = line_source->GetOutput(); + polydata_->GetCellData()->SetScalars(VtkUtils::FillScalars(polydata_->GetNumberOfCells(), c)); + VtkUtils::AddInputData(append_filter, polydata_); + } + } + append_filter->Update(); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetScalarModeToUseCellData(); + VtkUtils::SetInputData(mapper, append_filter->GetOutput()); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + WidgetAccessor::setProp(*this, actor); +} + +template<> cv::viz::WTrajectorySpheres cv::viz::Widget::cast() +{ + Widget3D widget = this->cast(); + return static_cast(widget); +} diff --git a/modules/viz/src/types.cpp b/modules/viz/src/types.cpp new file mode 100644 index 0000000000..2e32a63279 --- /dev/null +++ b/modules/viz/src/types.cpp @@ -0,0 +1,206 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +//////////////////////////////////////////////////////////////////// +/// Events + +cv::viz::KeyboardEvent::KeyboardEvent(Action _action, const String& _symbol, unsigned char _code, int _modifiers) + : action(_action), symbol(_symbol), code(_code), modifiers(_modifiers) {} + +cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _pointer, int _modifiers) + : type(_type), button(_button), pointer(_pointer), modifiers(_modifiers) {} + +//////////////////////////////////////////////////////////////////// +/// cv::viz::Mesh3d + +cv::viz::Mesh cv::viz::Mesh::load(const String& file) +{ + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(file.c_str()); + reader->Update(); + + vtkSmartPointer polydata = reader->GetOutput(); + CV_Assert("File does not exist or file format is not supported." && polydata); + + Mesh mesh; + vtkSmartPointer sink = vtkSmartPointer::New(); + sink->SetOutput(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords); + sink->SetInputConnection(reader->GetOutputPort()); + sink->Write(); + + // Now handle the polygons + vtkSmartPointer polygons = polydata->GetPolys(); + mesh.polygons.create(1, polygons->GetSize(), CV_32SC1); + int* poly_ptr = mesh.polygons.ptr(); + + polygons->InitTraversal(); + vtkIdType nr_cell_points, *cell_points; + while (polygons->GetNextCell(nr_cell_points, cell_points)) + { + *poly_ptr++ = nr_cell_points; + for (vtkIdType i = 0; i < nr_cell_points; ++i) + *poly_ptr++ = (int)cell_points[i]; + } + + return mesh; +} + +//////////////////////////////////////////////////////////////////// +/// Camera implementation + +cv::viz::Camera::Camera(double fx, double fy, double cx, double cy, const Size &window_size) +{ + init(fx, fy, cx, cy, window_size); +} + +cv::viz::Camera::Camera(const Vec2d &fov, const Size &window_size) +{ + CV_Assert(window_size.width > 0 && window_size.height > 0); + setClip(Vec2d(0.01, 1000.01)); // Default clipping + setFov(fov); + window_size_ = window_size; + // Principal point at the center + principal_point_ = Vec2f(static_cast(window_size.width)*0.5f, static_cast(window_size.height)*0.5f); + focal_ = Vec2f(principal_point_[0] / tan(fov_[0]*0.5f), principal_point_[1] / tan(fov_[1]*0.5f)); +} + +cv::viz::Camera::Camera(const cv::Matx33d & K, const Size &window_size) +{ + double f_x = K(0,0); + double f_y = K(1,1); + double c_x = K(0,2); + double c_y = K(1,2); + init(f_x, f_y, c_x, c_y, window_size); +} + +cv::viz::Camera::Camera(const Matx44d &proj, const Size &window_size) +{ + CV_Assert(window_size.width > 0 && window_size.height > 0); + + double near = proj(2,3) / (proj(2,2) - 1.0); + double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0); + double left = near * (proj(0,2)-1) / proj(0,0); + double right = 2.0 * near / proj(0,0) + left; + double bottom = near * (proj(1,2)-1) / proj(1,1); + double top = 2.0 * near / proj(1,1) + bottom; + + double epsilon = 2.2204460492503131e-16; + + principal_point_[0] = fabs(left-right) < epsilon ? window_size.width * 0.5 : (left * window_size.width) / (left - right); + principal_point_[1] = fabs(top-bottom) < epsilon ? window_size.height * 0.5 : (top * window_size.height) / (top - bottom); + + focal_[0] = -near * principal_point_[0] / left; + focal_[1] = near * principal_point_[1] / top; + + setClip(Vec2d(near, far)); + fov_[0] = atan2(principal_point_[0], focal_[0]) + atan2(window_size.width-principal_point_[0], focal_[0]); + fov_[1] = atan2(principal_point_[1], focal_[1]) + atan2(window_size.height-principal_point_[1], focal_[1]); + + window_size_ = window_size; +} + +void cv::viz::Camera::init(double fx, double fy, double cx, double cy, const Size &window_size) +{ + CV_Assert(window_size.width > 0 && window_size.height > 0); + setClip(Vec2d(0.01, 1000.01));// Default clipping + + fov_[0] = atan2(cx, fx) + atan2(window_size.width - cx, fx); + fov_[1] = atan2(cy, fy) + atan2(window_size.height - cy, fy); + + principal_point_[0] = cx; + principal_point_[1] = cy; + + focal_[0] = fx; + focal_[1] = fy; + + window_size_ = window_size; +} + +void cv::viz::Camera::setWindowSize(const Size &window_size) +{ + CV_Assert(window_size.width > 0 && window_size.height > 0); + + // Get the scale factor and update the principal points + float scalex = static_cast(window_size.width) / static_cast(window_size_.width); + float scaley = static_cast(window_size.height) / static_cast(window_size_.height); + + principal_point_[0] *= scalex; + principal_point_[1] *= scaley; + focal_ *= scaley; + // Vertical field of view is fixed! Update horizontal field of view + fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0])); + + window_size_ = window_size; +} + +void cv::viz::Camera::computeProjectionMatrix(Matx44d &proj) const +{ + double top = clip_[0] * principal_point_[1] / focal_[1]; + double left = -clip_[0] * principal_point_[0] / focal_[0]; + double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0]; + double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1]; + + double temp1 = 2.0 * clip_[0]; + double temp2 = 1.0 / (right - left); + double temp3 = 1.0 / (top - bottom); + double temp4 = 1.0 / (clip_[0] - clip_[1]); + + proj = Matx44d::zeros(); + proj(0,0) = temp1 * temp2; + proj(1,1) = temp1 * temp3; + proj(0,2) = (right + left) * temp2; + proj(1,2) = (top + bottom) * temp3; + proj(2,2) = (clip_[1]+clip_[0]) * temp4; + proj(3,2) = -1.0; + proj(2,3) = (temp1 * clip_[1]) * temp4; +} + +cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size) +{ + Matx33d K(525.0, 0.0, 320.0, 0.0, 525.0, 240.0, 0.0, 0.0, 1.0); + return Camera(K, window_size); +} diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp new file mode 100644 index 0000000000..56f978c0ea --- /dev/null +++ b/modules/viz/src/viz3d.cpp @@ -0,0 +1,148 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(0) { create(window_name); } + +cv::viz::Viz3d::Viz3d(const Viz3d& other) : impl_(other.impl_) +{ + if (impl_) + CV_XADD(&impl_->ref_counter, 1); +} + +cv::viz::Viz3d& cv::viz::Viz3d::operator=(const Viz3d& other) +{ + if (this != &other) + { + release(); + impl_ = other.impl_; + if (impl_) + CV_XADD(&impl_->ref_counter, 1); + } + return *this; +} + +cv::viz::Viz3d::~Viz3d() { release(); } + +void cv::viz::Viz3d::create(const String &window_name) +{ + if (impl_) + release(); + + if (VizStorage::windowExists(window_name)) + *this = VizStorage::get(window_name); + else + { + impl_ = new VizImpl(window_name); + impl_->ref_counter = 1; + + // Register the window + VizStorage::add(*this); + } +} + +void cv::viz::Viz3d::release() +{ + if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) + { + delete impl_; + impl_ = 0; + } + + if (impl_ && impl_->ref_counter == 1) + VizStorage::removeUnreferenced(); + + impl_ = 0; +} + +void cv::viz::Viz3d::spin() { impl_->spin(); } +void cv::viz::Viz3d::spinOnce(int time, bool force_redraw) { impl_->spinOnce(time, force_redraw); } +bool cv::viz::Viz3d::wasStopped() const { return impl_->wasStopped(); } +void cv::viz::Viz3d::close() { impl_->close(); } + +void cv::viz::Viz3d::registerKeyboardCallback(KeyboardCallback callback, void* cookie) +{ impl_->registerKeyboardCallback(callback, cookie); } + +void cv::viz::Viz3d::registerMouseCallback(MouseCallback callback, void* cookie) +{ impl_->registerMouseCallback(callback, cookie); } + +void cv::viz::Viz3d::showWidget(const String &id, const Widget &widget, const Affine3d &pose) { impl_->showWidget(id, widget, pose); } +void cv::viz::Viz3d::removeWidget(const String &id) { impl_->removeWidget(id); } +cv::viz::Widget cv::viz::Viz3d::getWidget(const String &id) const { return impl_->getWidget(id); } +void cv::viz::Viz3d::removeAllWidgets() { impl_->removeAllWidgets(); } + +void cv::viz::Viz3d::showImage(InputArray image, const Size& window_size) { impl_->showImage(image, window_size); } + +void cv::viz::Viz3d::setWidgetPose(const String &id, const Affine3d &pose) { impl_->setWidgetPose(id, pose); } +void cv::viz::Viz3d::updateWidgetPose(const String &id, const Affine3d &pose) { impl_->updateWidgetPose(id, pose); } +cv::Affine3d cv::viz::Viz3d::getWidgetPose(const String &id) const { return impl_->getWidgetPose(id); } + +void cv::viz::Viz3d::setCamera(const Camera &camera) { impl_->setCamera(camera); } +cv::viz::Camera cv::viz::Viz3d::getCamera() const { return impl_->getCamera(); } +void cv::viz::Viz3d::setViewerPose(const Affine3d &pose) { impl_->setViewerPose(pose); } +cv::Affine3d cv::viz::Viz3d::getViewerPose() { return impl_->getViewerPose(); } + +void cv::viz::Viz3d::resetCameraViewpoint(const String &id) { impl_->resetCameraViewpoint(id); } +void cv::viz::Viz3d::resetCamera() { impl_->resetCamera(); } + +void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) { impl_->convertToWindowCoordinates(pt, window_coord); } +void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } + +cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } +void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size); } +cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } +void cv::viz::Viz3d::saveScreenshot(const String &file) { impl_->saveScreenshot(file); } +void cv::viz::Viz3d::setWindowPosition(const Point& window_position) { impl_->setWindowPosition(window_position); } +void cv::viz::Viz3d::setFullScreen(bool mode) { impl_->setFullScreen(mode); } +void cv::viz::Viz3d::setBackgroundColor(const Color& color, const Color& color2) { impl_->setBackgroundColor(color, color2); } + +void cv::viz::Viz3d::setBackgroundTexture(InputArray image) { impl_->setBackgroundTexture(image); } +void cv::viz::Viz3d::setBackgroundMeshLab() {impl_->setBackgroundMeshLab(); } + +void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double value) { getWidget(id).setRenderingProperty(property, value); } +double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { return getWidget(id).getRenderingProperty(property); } + +void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); } diff --git a/modules/viz/src/vizcore.cpp b/modules/viz/src/vizcore.cpp new file mode 100644 index 0000000000..b4ec83bd44 --- /dev/null +++ b/modules/viz/src/vizcore.cpp @@ -0,0 +1,312 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +cv::Affine3d cv::viz::makeTransformToGlobal(const Vec3d& axis_x, const Vec3d& axis_y, const Vec3d& axis_z, const Vec3d& origin) +{ + Affine3d::Mat3 R(axis_x[0], axis_y[0], axis_z[0], + axis_x[1], axis_y[1], axis_z[1], + axis_x[2], axis_y[2], axis_z[2]); + + return Affine3d(R, origin); +} + +cv::Affine3d cv::viz::makeCameraPose(const Vec3d& position, const Vec3d& focal_point, const Vec3d& y_dir) +{ + // Compute the transformation matrix for drawing the camera frame in a scene + Vec3d n = normalize(focal_point - position); + Vec3d u = normalize(y_dir.cross(n)); + Vec3d v = n.cross(u); + + return makeTransformToGlobal(u, v, n, position); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// VizStorage implementation + +cv::viz::VizMap cv::viz::VizStorage::storage; +void cv::viz::VizStorage::unregisterAll() { storage.clear(); } + +cv::viz::Viz3d& cv::viz::VizStorage::get(const String &window_name) +{ + String name = generateWindowName(window_name); + VizMap::iterator vm_itr = storage.find(name); + CV_Assert(vm_itr != storage.end()); + return vm_itr->second; +} + +void cv::viz::VizStorage::add(const Viz3d& window) +{ + String window_name = window.getWindowName(); + VizMap::iterator vm_itr = storage.find(window_name); + CV_Assert(vm_itr == storage.end()); + storage.insert(std::make_pair(window_name, window)); +} + +bool cv::viz::VizStorage::windowExists(const String &window_name) +{ + String name = generateWindowName(window_name); + return storage.find(name) != storage.end(); +} + +void cv::viz::VizStorage::removeUnreferenced() +{ + for(VizMap::iterator pos = storage.begin(); pos != storage.end();) + if(pos->second.impl_->ref_counter == 1) + storage.erase(pos++); + else + ++pos; +} + +cv::String cv::viz::VizStorage::generateWindowName(const String &window_name) +{ + String output = "Viz"; + // Already is Viz + if (window_name == output) + return output; + + String prefixed = output + " - "; + if (window_name.substr(0, prefixed.length()) == prefixed) + output = window_name; // Already has "Viz - " + else if (window_name.substr(0, output.length()) == output) + output = prefixed + window_name; // Doesn't have prefix + else + output = (window_name == "" ? output : prefixed + window_name); + + return output; +} + +cv::viz::Viz3d cv::viz::getWindowByName(const String &window_name) { return Viz3d (window_name); } +void cv::viz::unregisterAllWindows() { VizStorage::unregisterAll(); } + +cv::viz::Viz3d cv::viz::imshow(const String& window_name, InputArray image, const Size& window_size) +{ + Viz3d viz = getWindowByName(window_name); + viz.showImage(image, window_size); + return viz; +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Read/write clouds. Supported formats: ply, stl, xyz, obj + +void cv::viz::writeCloud(const String& file, InputArray cloud, InputArray colors, InputArray normals, bool binary) +{ + CV_Assert(file.size() > 4 && "Extention is required"); + String extention = file.substr(file.size()-4); + + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetColorCloudNormals(cloud, colors, normals); + + vtkSmartPointer writer; + if (extention == ".xyz") + { + writer = vtkSmartPointer::New(); + vtkXYZWriter::SafeDownCast(writer)->SetFileName(file.c_str()); + } + else if (extention == ".ply") + { + writer = vtkSmartPointer::New(); + vtkPLYWriter::SafeDownCast(writer)->SetFileName(file.c_str()); + vtkPLYWriter::SafeDownCast(writer)->SetFileType(binary ? VTK_BINARY : VTK_ASCII); + vtkPLYWriter::SafeDownCast(writer)->SetArrayName("Colors"); + } + else if (extention == ".obj") + { + writer = vtkSmartPointer::New(); + vtkOBJWriter::SafeDownCast(writer)->SetFileName(file.c_str()); + } + else + CV_Assert(!"Unsupported format"); + + writer->SetInputConnection(source->GetOutputPort()); + writer->Write(); +} + +cv::Mat cv::viz::readCloud(const String& file, OutputArray colors, OutputArray normals) +{ + CV_Assert(file.size() > 4 && "Extention is required"); + String extention = file.substr(file.size()-4); + + vtkSmartPointer reader; + if (extention == ".xyz") + { + reader = vtkSmartPointer::New(); + vtkSimplePointsReader::SafeDownCast(reader)->SetFileName(file.c_str()); + } + else if (extention == ".ply") + { + reader = vtkSmartPointer::New(); + CV_Assert(vtkPLYReader::CanReadFile(file.c_str())); + vtkPLYReader::SafeDownCast(reader)->SetFileName(file.c_str()); + } + else if (extention == ".obj") + { + reader = vtkSmartPointer::New(); + vtkOBJReader::SafeDownCast(reader)->SetFileName(file.c_str()); + } + else if (extention == ".stl") + { + reader = vtkSmartPointer::New(); + vtkSTLReader::SafeDownCast(reader)->SetFileName(file.c_str()); + } + else + CV_Assert(!"Unsupported format"); + + cv::Mat cloud; + + vtkSmartPointer sink = vtkSmartPointer::New(); + sink->SetInputConnection(reader->GetOutputPort()); + sink->SetOutput(cloud, colors, normals); + sink->Write(); + + return cloud; +} + +cv::viz::Mesh cv::viz::readMesh(const String& file) { return Mesh::load(file); } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Read/write poses and trajectories + +bool cv::viz::readPose(const String& file, Affine3d& pose, const String& tag) +{ + FileStorage fs(file, FileStorage::READ); + if (!fs.isOpened()) + return false; + + Mat hdr(pose.matrix, false); + fs[tag] >> hdr; + if (hdr.empty() || hdr.cols != pose.matrix.cols || hdr.rows != pose.matrix.rows) + return false; + + hdr.convertTo(pose.matrix, CV_64F); + return true; +} + +void cv::viz::writePose(const String& file, const Affine3d& pose, const String& tag) +{ + FileStorage fs(file, FileStorage::WRITE); + fs << tag << Mat(pose.matrix, false); +} + +void cv::viz::readTrajectory(OutputArray _traj, const String& files_format, int start, int end, const String& tag) +{ + CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT); + + start = max(0, std::min(start, end)); + end = std::max(start, end); + + std::vector traj; + + for(int i = start; i < end; ++i) + { + Affine3d affine; + bool ok = readPose(cv::format(files_format.c_str(), i), affine, tag); + if (!ok) + break; + + traj.push_back(affine); + } + + Mat(traj).convertTo(_traj, _traj.depth()); +} + +void cv::viz::writeTrajectory(InputArray _traj, const String& files_format, int start, const String& tag) +{ + if (_traj.kind() == _InputArray::STD_VECTOR_MAT) + { + std::vector& v = *(std::vector*)_traj.obj; + + for(size_t i = 0, index = max(0, start); i < v.size(); ++i, ++index) + { + Affine3d affine; + Mat pose = v[i]; + CV_Assert(pose.type() == CV_32FC(16) || pose.type() == CV_64FC(16)); + pose.copyTo(affine.matrix); + writePose(cv::format(files_format.c_str(), index), affine, tag); + } + return; + } + + if (_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT) + { + CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16)); + + Mat traj = _traj.getMat(); + + if (traj.depth() == CV_32F) + for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) + writePose(cv::format(files_format.c_str(), index), traj.at(i), tag); + + if (traj.depth() == CV_64F) + for(size_t i = 0, index = max(0, start); i < traj.total(); ++i, ++index) + writePose(cv::format(files_format.c_str(), index), traj.at(i), tag); + } + + CV_Assert(!"Unsupported array kind"); +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Computing normals for mesh + +void cv::viz::computeNormals(const Mesh& mesh, OutputArray _normals) +{ + vtkSmartPointer polydata = getPolyData(WMesh(mesh)); + vtkSmartPointer with_normals = VtkUtils::ComputeNormals(polydata); + + vtkSmartPointer generic_normals = with_normals->GetPointData()->GetNormals(); + if(generic_normals) + { + Mat normals(1, generic_normals->GetNumberOfTuples(), CV_64FC3); + Vec3d *optr = normals.ptr(); + + for(int i = 0; i < generic_normals->GetNumberOfTuples(); ++i, ++optr) + generic_normals->GetTuple(i, optr->val); + + normals.convertTo(_normals, mesh.cloud.type()); + } + else + _normals.release(); +} diff --git a/modules/viz/src/vizimpl.cpp b/modules/viz/src/vizimpl.cpp new file mode 100644 index 0000000000..5fa49e2f96 --- /dev/null +++ b/modules/viz/src/vizimpl.cpp @@ -0,0 +1,542 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + + +///////////////////////////////////////////////////////////////////////////////////////////// +cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false), + window_position_(Vec2i(std::numeric_limits::min())), widget_actor_map_(new WidgetActorMap) +{ + renderer_ = vtkSmartPointer::New(); + window_name_ = VizStorage::generateWindowName(name); + + // Create render window + window_ = vtkSmartPointer::New(); + cv::Vec2i window_size = cv::Vec2i(window_->GetScreenSize()) / 2; + window_->SetSize(window_size.val); + window_->AddRenderer(renderer_); + + // Create the interactor style + style_ = vtkSmartPointer::New(); + style_->setWidgetActorMap(widget_actor_map_); + style_->UseTimersOn(); + style_->Initialize(); + + timer_callback_ = vtkSmartPointer::New(); + exit_callback_ = vtkSmartPointer::New(); + exit_callback_->viz = this; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::TimerCallback::Execute(vtkObject* caller, unsigned long event_id, void* cookie) +{ + if (event_id == vtkCommand::TimerEvent && timer_id == *reinterpret_cast(cookie)) + { + vtkSmartPointer interactor = vtkRenderWindowInteractor::SafeDownCast(caller); + interactor->TerminateApp(); + } +} + +void cv::viz::Viz3d::VizImpl::ExitCallback::Execute(vtkObject*, unsigned long event_id, void*) +{ + if (event_id == vtkCommand::ExitEvent) + { + viz->interactor_->TerminateApp(); + viz->interactor_ = 0; + } +} + +///////////////////////////////////////////////////////////////////////////////////////////// + +bool cv::viz::Viz3d::VizImpl::wasStopped() const +{ + bool stopped = spin_once_state_ ? interactor_ == 0 : false; + spin_once_state_ &= !stopped; + return stopped; +} + +void cv::viz::Viz3d::VizImpl::close() +{ + if (!interactor_) + return; + interactor_->GetRenderWindow()->Finalize(); + interactor_->TerminateApp(); // This tends to close the window... + interactor_ = 0; +} + +void cv::viz::Viz3d::VizImpl::recreateRenderWindow() +{ +#if !defined _MSC_VER + //recreating is workaround for Ubuntu -- a crash in x-server + Vec2i window_size(window_->GetSize()); + int fullscreen = window_->GetFullScreen(); + + window_ = vtkSmartPointer::New(); + if (window_position_[0] != std::numeric_limits::min()) //also workaround + window_->SetPosition(window_position_.val); + + window_->SetSize(window_size.val); + window_->SetFullScreen(fullscreen); + window_->AddRenderer(renderer_); +#endif +} + + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::spin() +{ + recreateRenderWindow(); + interactor_ = vtkSmartPointer::New(); + interactor_->SetRenderWindow(window_); + interactor_->SetInteractorStyle(style_); + window_->AlphaBitPlanesOff(); + window_->PointSmoothingOff(); + window_->LineSmoothingOff(); + window_->PolygonSmoothingOff(); + window_->SwapBuffersOn(); + window_->SetStereoTypeToAnaglyph(); + window_->Render(); + window_->SetWindowName(window_name_.c_str()); + interactor_->Start(); + interactor_ = 0; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw) +{ + if (interactor_ == 0) + { + spin_once_state_ = true; + recreateRenderWindow(); + interactor_ = vtkSmartPointer::New(); + interactor_->SetRenderWindow(window_); + interactor_->SetInteractorStyle(style_); + interactor_->AddObserver(vtkCommand::TimerEvent, timer_callback_); + interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_); + window_->AlphaBitPlanesOff(); + window_->PointSmoothingOff(); + window_->LineSmoothingOff(); + window_->PolygonSmoothingOff(); + window_->SwapBuffersOn(); + window_->SetStereoTypeToAnaglyph(); + window_->Render(); + window_->SetWindowName(window_name_.c_str()); + } + + vtkSmartPointer local = interactor_; + + if (force_redraw) + local->Render(); + + timer_callback_->timer_id = local->CreateRepeatingTimer(std::max(1, time)); + local->Start(); + local->DestroyTimer(timer_callback_->timer_id); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3d &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + if (exists) + { + // Remove it if it exists and add it again + removeActorFromRenderer(wam_itr->second); + } + // Get the actor and set the user matrix + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget)); + if (actor) + { + // If the actor is 3D, apply pose + vtkSmartPointer matrix = vtkmatrix(pose.matrix); + actor->SetUserMatrix(matrix); + actor->Modified(); + } + // If the actor is a vtkFollower, then it should always face the camera + vtkFollower *follower = vtkFollower::SafeDownCast(actor); + if (follower) + { + follower->SetCamera(renderer_->GetActiveCamera()); + } + + renderer_->AddActor(WidgetAccessor::getProp(widget)); + (*widget_actor_map_)[id] = WidgetAccessor::getProp(widget); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::removeWidget(const String &id) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert("Widget does not exist." && exists); + CV_Assert("Widget could not be removed." && removeActorFromRenderer(wam_itr->second)); + widget_actor_map_->erase(wam_itr); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const +{ + WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert("Widget does not exist." && exists); + + Widget widget; + WidgetAccessor::setProp(widget, wam_itr->second); + return widget; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3d &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert("Widget does not exist." && exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); + CV_Assert("Widget is not 3D." && actor); + + vtkSmartPointer matrix = vtkmatrix(pose.matrix); + actor->SetUserMatrix(matrix); + actor->Modified(); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3d &pose) +{ + WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert("Widget does not exist." && exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); + CV_Assert("Widget is not 3D." && actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + if (!matrix) + { + setWidgetPose(id, pose); + return ; + } + Affine3d updated_pose = pose * Affine3d(*matrix->Element); + matrix = vtkmatrix(updated_pose.matrix); + + actor->SetUserMatrix(matrix); + actor->Modified(); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +cv::Affine3d cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const +{ + WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id); + bool exists = wam_itr != widget_actor_map_->end(); + CV_Assert("Widget does not exist." && exists); + + vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second); + CV_Assert("Widget is not 3D." && actor); + + return Affine3d(*actor->GetUserMatrix()->Element); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::saveScreenshot(const String &file) { style_->saveScreenshot(file.c_str()); } + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void* cookie) +{ style_->registerMouseCallback(callback, cookie); } + +void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(KeyboardCallback callback, void* cookie) +{ style_->registerKeyboardCallback(callback, cookie); } + + +////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::removeAllWidgets() +{ + widget_actor_map_->clear(); + renderer_->RemoveAllViewProps(); +} +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::showImage(InputArray image, const Size& window_size) +{ + removeAllWidgets(); + if (window_size.width > 0 && window_size.height > 0) + setWindowSize(window_size); + + showWidget("showImage", WImageOverlay(image, Rect(Point(0,0), getWindowSize()))); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(vtkSmartPointer actor) +{ + vtkPropCollection* actors = renderer_->GetViewProps(); + actors->InitTraversal(); + vtkProp* current_actor = NULL; + while ((current_actor = actors->GetNextProp()) != NULL) + if (current_actor == actor) + { + renderer_->RemoveActor(actor); + return true; + } + return false; +} + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color, const Color& color2) +{ + Color c = vtkcolor(color), c2 = vtkcolor(color2); + bool gradient = color2[0] >= 0 && color2[1] >= 0 && color2[2] >= 0; + + if (gradient) + { + renderer_->SetBackground(c2.val); + renderer_->SetBackground2(c.val); + renderer_->GradientBackgroundOn(); + } + else + { + renderer_->SetBackground(c.val); + renderer_->GradientBackgroundOff(); + } +} + +void cv::viz::Viz3d::VizImpl::setBackgroundMeshLab() +{ setBackgroundColor(Color(2, 1, 1), Color(240, 120, 120)); } + +////////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setBackgroundTexture(InputArray image) +{ + if (image.empty()) + { + renderer_->SetBackgroundTexture(0); + renderer_->TexturedBackgroundOff(); + return; + } + + vtkSmartPointer source = vtkSmartPointer::New(); + source->SetImage(image); + + vtkSmartPointer image_flip = vtkSmartPointer::New(); + image_flip->SetFilteredAxis(1); // Vertical flip + image_flip->SetInputConnection(source->GetOutputPort()); + + vtkSmartPointer texture = vtkSmartPointer::New(); + texture->SetInputConnection(image_flip->GetOutputPort()); + //texture->Update(); + + renderer_->SetBackgroundTexture(texture); + renderer_->TexturedBackgroundOn(); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera) +{ + vtkSmartPointer active_camera = renderer_->GetActiveCamera(); + + // Set the intrinsic parameters of the camera + window_->SetSize(camera.getWindowSize().width, camera.getWindowSize().height); + double aspect_ratio = static_cast(camera.getWindowSize().width)/static_cast(camera.getWindowSize().height); + + Matx44d proj_mat; + camera.computeProjectionMatrix(proj_mat); + + // Use the intrinsic parameters of the camera to simulate more realistically + vtkSmartPointer vtk_matrix = active_camera->GetProjectionTransformMatrix(aspect_ratio, -1.0, 1.0); + Matx44d old_proj_mat(*vtk_matrix->Element); + + // This is a hack around not being able to set Projection Matrix + vtkSmartPointer transform = vtkSmartPointer::New(); + transform->SetMatrix(vtkmatrix(proj_mat * old_proj_mat.inv())); + active_camera->SetUserTransform(transform); + + renderer_->ResetCameraClippingRange(); + renderer_->Render(); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const +{ + vtkSmartPointer active_camera = renderer_->GetActiveCamera(); + + Size window_size(renderer_->GetRenderWindow()->GetSize()[0], + renderer_->GetRenderWindow()->GetSize()[1]); + double aspect_ratio = window_size.width / (double)window_size.height; + + vtkSmartPointer proj_matrix = active_camera->GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f); + return Camera(Matx44d(*proj_matrix->Element), window_size); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3d &pose) +{ + vtkCamera& camera = *renderer_->GetActiveCamera(); + + // Position = extrinsic translation + cv::Vec3d pos_vec = pose.translation(); + + // Rotate the view vector + cv::Matx33d rotation = pose.rotation(); + cv::Vec3d y_axis(0.0, 1.0, 0.0); + cv::Vec3d up_vec(rotation * y_axis); + + // Compute the new focal point + cv::Vec3d z_axis(0.0, 0.0, 1.0); + cv::Vec3d focal_vec = pos_vec + rotation * z_axis; + + camera.SetPosition(pos_vec.val); + camera.SetFocalPoint(focal_vec.val); + camera.SetViewUp(up_vec.val); + + renderer_->ResetCameraClippingRange(); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +cv::Affine3d cv::viz::Viz3d::VizImpl::getViewerPose() +{ + vtkCamera& camera = *renderer_->GetActiveCamera(); + + Vec3d pos(camera.GetPosition()); + Vec3d view_up(camera.GetViewUp()); + Vec3d focal(camera.GetFocalPoint()); + + Vec3d y_axis = normalized(view_up); + Vec3d z_axis = normalized(focal - pos); + Vec3d x_axis = normalized(y_axis.cross(z_axis)); + + return makeTransformToGlobal(x_axis, y_axis, z_axis, pos); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord) +{ + Vec3d window_pt; + vtkInteractorObserver::ComputeWorldToDisplay(renderer_, pt.x, pt.y, pt.z, window_pt.val); + window_coord = window_pt; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) +{ + Vec4d world_pt; + vtkInteractorObserver::ComputeDisplayToWorld(renderer_, window_coord.x, window_coord.y, window_coord.z, world_pt.val); + Vec3d cam_pos(renderer_->GetActiveCamera()->GetPosition()); + origin = cam_pos; + direction = normalize(Vec3d(world_pt.val) - cam_pos); +} + +///////////////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::resetCameraViewpoint(const String &id) +{ + vtkSmartPointer camera_pose; + static WidgetActorMap::iterator it = widget_actor_map_->find(id); + if (it != widget_actor_map_->end()) + { + vtkProp3D *actor = vtkProp3D::SafeDownCast(it->second); + CV_Assert("Widget is not 3D." && actor); + camera_pose = actor->GetUserMatrix(); + } + else + return; + + // Prevent a segfault + if (!camera_pose) return; + + vtkSmartPointer cam = renderer_->GetActiveCamera(); + cam->SetPosition(camera_pose->GetElement(0, 3), + camera_pose->GetElement(1, 3), + camera_pose->GetElement(2, 3)); + + cam->SetFocalPoint(camera_pose->GetElement(0, 3) - camera_pose->GetElement(0, 2), + camera_pose->GetElement(1, 3) - camera_pose->GetElement(1, 2), + camera_pose->GetElement(2, 3) - camera_pose->GetElement(2, 2)); + + cam->SetViewUp(camera_pose->GetElement(0, 1), + camera_pose->GetElement(1, 1), + camera_pose->GetElement(2, 1)); + + renderer_->SetActiveCamera(cam); + renderer_->ResetCameraClippingRange(); + renderer_->Render(); +} + +/////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::resetCamera() +{ + renderer_->ResetCamera(); +} + +/////////////////////////////////////////////////////////////////////////////////// +void cv::viz::Viz3d::VizImpl::setRepresentation(int representation) +{ + vtkActorCollection * actors = renderer_->GetActors(); + actors->InitTraversal(); + vtkActor * actor; + switch (representation) + { + case REPRESENTATION_POINTS: + { + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToPoints(); + break; + } + case REPRESENTATION_SURFACE: + { + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToSurface(); + break; + } + case REPRESENTATION_WIREFRAME: + { + while ((actor = actors->GetNextActor()) != NULL) + actor->GetProperty()->SetRepresentationToWireframe(); + break; + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////////// +cv::String cv::viz::Viz3d::VizImpl::getWindowName() const { return window_name_; } +void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode) { window_->SetFullScreen(mode); } +void cv::viz::Viz3d::VizImpl::setWindowPosition(const Point& position) { window_position_ = position; window_->SetPosition(position.x, position.y); } +void cv::viz::Viz3d::VizImpl::setWindowSize(const Size& window_size) { window_->SetSize(window_size.width, window_size.height); } +cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(Point(Vec2i(window_->GetSize()))); } diff --git a/modules/viz/src/vizimpl.hpp b/modules/viz/src/vizimpl.hpp new file mode 100644 index 0000000000..02675e0a5c --- /dev/null +++ b/modules/viz/src/vizimpl.hpp @@ -0,0 +1,138 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __OPENCV_VIZ_VIZ3D_IMPL_HPP__ +#define __OPENCV_VIZ_VIZ3D_IMPL_HPP__ + +struct cv::viz::Viz3d::VizImpl +{ +public: + typedef Viz3d::KeyboardCallback KeyboardCallback; + typedef Viz3d::MouseCallback MouseCallback; + + int ref_counter; + + VizImpl(const String &name); + virtual ~VizImpl() {} + + bool wasStopped() const; + void close(); + + void spin(); + void spinOnce(int time = 1, bool force_redraw = false); + + void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity()); + void removeWidget(const String &id); + Widget getWidget(const String &id) const; + void removeAllWidgets(); + + void showImage(InputArray image, const Size& window_size); + + void setWidgetPose(const String &id, const Affine3d &pose); + void updateWidgetPose(const String &id, const Affine3d &pose); + Affine3d getWidgetPose(const String &id) const; + + void setRepresentation(int representation); + + void setCamera(const Camera &camera); + Camera getCamera() const; + + /** \brief Reset the camera to a given widget */ + void resetCameraViewpoint(const String& id); + void resetCamera(); + + void setViewerPose(const Affine3d &pose); + Affine3d getViewerPose(); + + void convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord); + void converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction); + + void saveScreenshot(const String &file); + void setWindowPosition(const Point& position); + Size getWindowSize() const; + void setWindowSize(const Size& window_size); + void setFullScreen(bool mode); + String getWindowName() const; + void setBackgroundColor(const Color& color, const Color& color2); + void setBackgroundTexture(InputArray image); + void setBackgroundMeshLab(); + + void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); + void registerMouseCallback(MouseCallback callback, void* cookie = 0); + +private: + struct TimerCallback : public vtkCommand + { + static TimerCallback* New() { return new TimerCallback; } + virtual void Execute(vtkObject* caller, unsigned long event_id, void* cookie); + int timer_id; + }; + + struct ExitCallback : public vtkCommand + { + static ExitCallback* New() { return new ExitCallback; } + virtual void Execute(vtkObject*, unsigned long event_id, void*); + VizImpl* viz; + }; + + mutable bool spin_once_state_; + vtkSmartPointer interactor_; + + vtkSmartPointer window_; + String window_name_; + Vec2i window_position_; + + vtkSmartPointer timer_callback_; + vtkSmartPointer exit_callback_; + + vtkSmartPointer renderer_; + vtkSmartPointer style_; + Ptr widget_actor_map_; + + bool removeActorFromRenderer(vtkSmartPointer actor); + void recreateRenderWindow(); +}; + +#endif diff --git a/modules/viz/src/vtk/vtkCloudMatSink.cpp b/modules/viz/src/vtk/vtkCloudMatSink.cpp new file mode 100644 index 0000000000..09ef0cca99 --- /dev/null +++ b/modules/viz/src/vtk/vtkCloudMatSink.cpp @@ -0,0 +1,158 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace viz +{ + vtkStandardNewMacro(vtkCloudMatSink); +}} + +cv::viz::vtkCloudMatSink::vtkCloudMatSink() {} +cv::viz::vtkCloudMatSink::~vtkCloudMatSink() {} + +void cv::viz::vtkCloudMatSink::SetOutput(OutputArray _cloud, OutputArray _colors, OutputArray _normals, OutputArray _tcoords) +{ + cloud = _cloud; + colors = _colors; + normals = _normals; + tcoords = _tcoords; +} + +void cv::viz::vtkCloudMatSink::WriteData() +{ + vtkPolyData *input = this->GetInput(); + if (!input) + return; + + vtkSmartPointer points_Data = input->GetPoints(); + + if (cloud.needed() && points_Data) + { + int vtktype = points_Data->GetDataType(); + CV_Assert(vtktype == VTK_FLOAT || vtktype == VTK_DOUBLE); + + cloud.create(1, points_Data->GetNumberOfPoints(), vtktype == VTK_FLOAT ? CV_32FC3 : CV_64FC3); + Vec3d *ddata = cloud.getMat().ptr(); + Vec3f *fdata = cloud.getMat().ptr(); + + if (cloud.depth() == CV_32F) + for(size_t i = 0; i < cloud.total(); ++i) + *fdata++ = Vec3d(points_Data->GetPoint(i)); + + if (cloud.depth() == CV_64F) + for(size_t i = 0; i < cloud.total(); ++i) + *ddata++ = Vec3d(points_Data->GetPoint(i)); + } + else + cloud.release(); + + vtkSmartPointer scalars_data = input->GetPointData() ? input->GetPointData()->GetScalars() : 0; + + if (colors.needed() && scalars_data) + { + int channels = scalars_data->GetNumberOfComponents(); + int vtktype = scalars_data->GetDataType(); + + CV_Assert((channels == 3 || channels == 4) && "Only 3- or 4-channel color data support is implemented"); + CV_Assert(cloud.total() == (size_t)scalars_data->GetNumberOfTuples()); + + Mat buffer(cloud.size(), CV_64FC(channels)); + Vec3d *cptr = buffer.ptr(); + for(size_t i = 0; i < buffer.total(); ++i) + *cptr++ = Vec3d(scalars_data->GetTuple(i)); + + buffer.convertTo(colors, CV_8U, vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE ? 255.0 : 1.0); + } + else + colors.release(); + + vtkSmartPointer normals_data = input->GetPointData() ? input->GetPointData()->GetNormals() : 0; + + if (normals.needed() && normals_data) + { + int channels = normals_data->GetNumberOfComponents(); + int vtktype = normals_data->GetDataType(); + + CV_Assert((vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE) && (channels == 3 || channels == 4)); + CV_Assert(cloud.total() == (size_t)normals_data->GetNumberOfTuples()); + + Mat buffer(cloud.size(), CV_64FC(channels)); + Vec3d *cptr = buffer.ptr(); + for(size_t i = 0; i < buffer.total(); ++i) + *cptr++ = Vec3d(normals_data->GetTuple(i)); + + buffer.convertTo(normals, vtktype == VTK_FLOAT ? CV_32F : CV_64F); + } + else + normals.release(); + + vtkSmartPointer coords_data = input->GetPointData() ? input->GetPointData()->GetTCoords() : 0; + + if (tcoords.needed() && coords_data) + { + int vtktype = coords_data->GetDataType(); + + CV_Assert(vtktype == VTK_FLOAT || VTK_FLOAT == VTK_DOUBLE); + CV_Assert(cloud.total() == (size_t)coords_data->GetNumberOfTuples()); + + Mat buffer(cloud.size(), CV_64FC2); + Vec2d *cptr = buffer.ptr(); + for(size_t i = 0; i < buffer.total(); ++i) + *cptr++ = Vec2d(coords_data->GetTuple(i)); + + buffer.convertTo(tcoords, vtktype == VTK_FLOAT ? CV_32F : CV_64F); + + } + else + tcoords.release(); +} + +void cv::viz::vtkCloudMatSink::PrintSelf(ostream& os, vtkIndent indent) +{ + Superclass::PrintSelf(os, indent); + os << indent << "Cloud: " << cloud.needed() << "\n"; + os << indent << "Colors: " << colors.needed() << "\n"; + os << indent << "Normals: " << normals.needed() << "\n"; +} diff --git a/modules/viz/src/vtk/vtkCloudMatSink.h b/modules/viz/src/vtk/vtkCloudMatSink.h new file mode 100644 index 0000000000..44d7e52a5a --- /dev/null +++ b/modules/viz/src/vtk/vtkCloudMatSink.h @@ -0,0 +1,79 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __vtkCloudMatSink_h +#define __vtkCloudMatSink_h + +#include +#include + +namespace cv +{ + namespace viz + { + class vtkCloudMatSink : public vtkPolyDataWriter + { + public: + static vtkCloudMatSink *New(); + vtkTypeMacro(vtkCloudMatSink,vtkPolyDataWriter) + void PrintSelf(ostream& os, vtkIndent indent); + + void SetOutput(OutputArray cloud, OutputArray colors = noArray(), OutputArray normals = noArray(), OutputArray tcoords = noArray()); + + protected: + vtkCloudMatSink(); + ~vtkCloudMatSink(); + + void WriteData(); + + _OutputArray cloud, colors, normals, tcoords; + + private: + vtkCloudMatSink(const vtkCloudMatSink&); // Not implemented. + void operator=(const vtkCloudMatSink&); // Not implemented. + }; + } +} + +#endif diff --git a/modules/viz/src/vtk/vtkCloudMatSource.cpp b/modules/viz/src/vtk/vtkCloudMatSource.cpp new file mode 100644 index 0000000000..74d01bbd01 --- /dev/null +++ b/modules/viz/src/vtk/vtkCloudMatSource.cpp @@ -0,0 +1,286 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace viz +{ + vtkStandardNewMacro(vtkCloudMatSource); + + template struct VtkDepthTraits; + + template<> struct VtkDepthTraits + { + const static int data_type = VTK_FLOAT; + typedef vtkFloatArray array_type; + }; + + template<> struct VtkDepthTraits + { + const static int data_type = VTK_DOUBLE; + typedef vtkDoubleArray array_type; + }; +}} + +cv::viz::vtkCloudMatSource::vtkCloudMatSource() { SetNumberOfInputPorts(0); } +cv::viz::vtkCloudMatSource::~vtkCloudMatSource() {} + +int cv::viz::vtkCloudMatSource::SetCloud(InputArray _cloud) +{ + CV_Assert(_cloud.depth() == CV_32F || _cloud.depth() == CV_64F); + CV_Assert(_cloud.channels() == 3 || _cloud.channels() == 4); + + Mat cloud = _cloud.getMat(); + + int total = _cloud.depth() == CV_32F ? filterNanCopy(cloud) : filterNanCopy(cloud); + + vertices = vtkSmartPointer::New(); + vertices->Allocate(vertices->EstimateSize(1, total)); + vertices->InsertNextCell(total); + for(int i = 0; i < total; ++i) + vertices->InsertCellPoint(i); + + return total; +} + +int cv::viz::vtkCloudMatSource::SetColorCloud(InputArray _cloud, InputArray _colors) +{ + int total = SetCloud(_cloud); + + if (_colors.empty()) + return total; + + CV_Assert(_colors.depth() == CV_8U && _colors.channels() <= 4 && _colors.channels() != 2); + CV_Assert(_colors.size() == _cloud.size()); + + Mat cloud = _cloud.getMat(); + Mat colors = _colors.getMat(); + + if (cloud.depth() == CV_32F) + filterNanColorsCopy(colors, cloud, total); + else if (cloud.depth() == CV_64F) + filterNanColorsCopy(colors, cloud, total); + + return total; +} + +int cv::viz::vtkCloudMatSource::SetColorCloudNormals(InputArray _cloud, InputArray _colors, InputArray _normals) +{ + int total = SetColorCloud(_cloud, _colors); + + if (_normals.empty()) + return total; + + CV_Assert(_normals.depth() == CV_32F || _normals.depth() == CV_64F); + CV_Assert(_normals.channels() == 3 || _normals.channels() == 4); + CV_Assert(_normals.size() == _cloud.size()); + + Mat c = _cloud.getMat(); + Mat n = _normals.getMat(); + + if (n.depth() == CV_32F && c.depth() == CV_32F) + filterNanNormalsCopy(n, c, total); + else if (n.depth() == CV_32F && c.depth() == CV_64F) + filterNanNormalsCopy(n, c, total); + else if (n.depth() == CV_64F && c.depth() == CV_32F) + filterNanNormalsCopy(n, c, total); + else if (n.depth() == CV_64F && c.depth() == CV_64F) + filterNanNormalsCopy(n, c, total); + else + CV_Assert(!"Unsupported normals/cloud type"); + + return total; +} + +int cv::viz::vtkCloudMatSource::SetColorCloudNormalsTCoords(InputArray _cloud, InputArray _colors, InputArray _normals, InputArray _tcoords) +{ + int total = SetColorCloudNormals(_cloud, _colors, _normals); + + if (_tcoords.empty()) + return total; + + CV_Assert(_tcoords.depth() == CV_32F || _tcoords.depth() == CV_64F); + CV_Assert(_tcoords.channels() == 2 && _tcoords.size() == _cloud.size()); + + Mat cl = _cloud.getMat(); + Mat tc = _tcoords.getMat(); + + if (tc.depth() == CV_32F && cl.depth() == CV_32F) + filterNanTCoordsCopy(tc, cl, total); + else if (tc.depth() == CV_32F && cl.depth() == CV_64F) + filterNanTCoordsCopy(tc, cl, total); + else if (tc.depth() == CV_64F && cl.depth() == CV_32F) + filterNanTCoordsCopy(tc, cl, total); + else if (tc.depth() == CV_64F && cl.depth() == CV_64F) + filterNanTCoordsCopy(tc, cl, total); + else + CV_Assert(!"Unsupported tcoords/cloud type"); + + return total; +} + +int cv::viz::vtkCloudMatSource::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector) +{ + vtkInformation *outInfo = outputVector->GetInformationObject(0); + vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); + + output->SetPoints(points); + output->SetVerts(vertices); + if (scalars) + output->GetPointData()->SetScalars(scalars); + + if (normals) + output->GetPointData()->SetNormals(normals); + + if (tcoords) + output->GetPointData()->SetTCoords(tcoords); + + return 1; +} + +template +int cv::viz::vtkCloudMatSource::filterNanCopy(const Mat& cloud) +{ + CV_DbgAssert(DataType<_Tp>::depth == cloud.depth()); + points = vtkSmartPointer::New(); + points->SetDataType(VtkDepthTraits<_Tp>::data_type); + points->Allocate(cloud.total()); + points->SetNumberOfPoints(cloud.total()); + + int s_chs = cloud.channels(); + int total = 0; + for (int y = 0; y < cloud.rows; ++y) + { + const _Tp* srow = cloud.ptr<_Tp>(y); + const _Tp* send = srow + cloud.cols * s_chs; + + for (; srow != send; srow += s_chs) + if (!isNan(srow)) + points->SetPoint(total++, srow); + } + points->SetNumberOfPoints(total); + points->Squeeze(); + return total; +} + +template +void cv::viz::vtkCloudMatSource::filterNanColorsCopy(const Mat& cloud_colors, const Mat& mask, int total) +{ + Vec3b* array = new Vec3b[total]; + Vec3b* pos = array; + + int s_chs = cloud_colors.channels(); + int m_chs = mask.channels(); + for (int y = 0; y < cloud_colors.rows; ++y) + { + const unsigned char* srow = cloud_colors.ptr(y); + const unsigned char* send = srow + cloud_colors.cols * s_chs; + const _Msk* mrow = mask.ptr<_Msk>(y); + + if (cloud_colors.channels() == 1) + { + for (; srow != send; srow += s_chs, mrow += m_chs) + if (!isNan(mrow)) + *pos++ = Vec3b(srow[0], srow[0], srow[0]); + } + else + for (; srow != send; srow += s_chs, mrow += m_chs) + if (!isNan(mrow)) + *pos++ = Vec3b(srow[2], srow[1], srow[0]); + + } + + scalars = vtkSmartPointer::New(); + scalars->SetName("Colors"); + scalars->SetNumberOfComponents(3); + scalars->SetNumberOfTuples(total); + scalars->SetArray(array->val, total * 3, 0); +} + +template +void cv::viz::vtkCloudMatSource::filterNanNormalsCopy(const Mat& cloud_normals, const Mat& mask, int total) +{ + normals = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New(); + normals->SetName("Normals"); + normals->SetNumberOfComponents(3); + normals->SetNumberOfTuples(total); + + int s_chs = cloud_normals.channels(); + int m_chs = mask.channels(); + + int pos = 0; + for (int y = 0; y < cloud_normals.rows; ++y) + { + const _Tn* srow = cloud_normals.ptr<_Tn>(y); + const _Tn* send = srow + cloud_normals.cols * s_chs; + + const _Msk* mrow = mask.ptr<_Msk>(y); + + for (; srow != send; srow += s_chs, mrow += m_chs) + if (!isNan(mrow)) + normals->SetTuple(pos++, srow); + } +} + +template +void cv::viz::vtkCloudMatSource::filterNanTCoordsCopy(const Mat& _tcoords, const Mat& mask, int total) +{ + typedef Vec<_Tn, 2> Vec2; + tcoords = vtkSmartPointer< typename VtkDepthTraits<_Tn>::array_type >::New(); + tcoords->SetName("TextureCoordinates"); + tcoords->SetNumberOfComponents(2); + tcoords->SetNumberOfTuples(total); + + int pos = 0; + for (int y = 0; y < mask.rows; ++y) + { + const Vec2* srow = _tcoords.ptr(y); + const Vec2* send = srow + _tcoords.cols; + const _Msk* mrow = mask.ptr<_Msk>(y); + + for (; srow != send; ++srow, mrow += mask.channels()) + if (!isNan(mrow)) + tcoords->SetTuple(pos++, srow->val); + } +} diff --git a/modules/viz/src/vtk/vtkCloudMatSource.h b/modules/viz/src/vtk/vtkCloudMatSource.h new file mode 100644 index 0000000000..4097f9cc87 --- /dev/null +++ b/modules/viz/src/vtk/vtkCloudMatSource.h @@ -0,0 +1,96 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __vtkCloudMatSource_h +#define __vtkCloudMatSource_h + +#include +#include +#include +#include +#include + +namespace cv +{ + namespace viz + { + class vtkCloudMatSource : public vtkPolyDataAlgorithm + { + public: + static vtkCloudMatSource *New(); + vtkTypeMacro(vtkCloudMatSource,vtkPolyDataAlgorithm) + + virtual int SetCloud(InputArray cloud); + virtual int SetColorCloud(InputArray cloud, InputArray colors); + virtual int SetColorCloudNormals(InputArray cloud, InputArray colors, InputArray normals); + virtual int SetColorCloudNormalsTCoords(InputArray cloud, InputArray colors, InputArray normals, InputArray tcoords); + + protected: + vtkCloudMatSource(); + ~vtkCloudMatSource(); + + int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + + vtkSmartPointer points; + vtkSmartPointer vertices; + vtkSmartPointer scalars; + vtkSmartPointer normals; + vtkSmartPointer tcoords; + private: + vtkCloudMatSource(const vtkCloudMatSource&); // Not implemented. + void operator=(const vtkCloudMatSource&); // Not implemented. + + template int filterNanCopy(const Mat& cloud); + template void filterNanColorsCopy(const Mat& cloud_colors, const Mat& mask, int total); + + template + void filterNanNormalsCopy(const Mat& cloud_normals, const Mat& mask, int total); + + template + void filterNanTCoordsCopy(const Mat& tcoords, const Mat& mask, int total); + }; + } +} + +#endif diff --git a/modules/viz/src/vtk/vtkImageMatSource.cpp b/modules/viz/src/vtk/vtkImageMatSource.cpp new file mode 100644 index 0000000000..58a5642d46 --- /dev/null +++ b/modules/viz/src/vtk/vtkImageMatSource.cpp @@ -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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace viz +{ + vtkStandardNewMacro(vtkImageMatSource); +}} + +cv::viz::vtkImageMatSource::vtkImageMatSource() +{ + this->SetNumberOfInputPorts(0); + this->ImageData = vtkImageData::New(); +} + +int cv::viz::vtkImageMatSource::RequestInformation(vtkInformation *, vtkInformationVector**, vtkInformationVector *outputVector) +{ + vtkInformation* outInfo = outputVector->GetInformationObject(0); + + outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), this->ImageData->GetExtent(), 6); + outInfo->Set(vtkDataObject::SPACING(), 1.0, 1.0, 1.0); + outInfo->Set(vtkDataObject::ORIGIN(), 0.0, 0.0, 0.0); + + vtkDataObject::SetPointDataActiveScalarInfo(outInfo, this->ImageData->GetScalarType(), this->ImageData->GetNumberOfScalarComponents()); + return 1; +} + +int cv::viz::vtkImageMatSource::RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector *outputVector) +{ + vtkInformation *outInfo = outputVector->GetInformationObject(0); + + vtkImageData *output = vtkImageData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()) ); + output->ShallowCopy(this->ImageData); + return 1; +} + +void cv::viz::vtkImageMatSource::SetImage(InputArray _image) +{ + CV_Assert(_image.depth() == CV_8U && (_image.channels() == 1 || _image.channels() == 3 || _image.channels() == 4)); + + Mat image = _image.getMat(); + + this->ImageData->SetDimensions(image.cols, image.rows, 1); +#if VTK_MAJOR_VERSION <= 5 + this->ImageData->SetNumberOfScalarComponents(image.channels()); + this->ImageData->SetScalarTypeToUnsignedChar(); + this->ImageData->AllocateScalars(); +#else + this->ImageData->AllocateScalars(VTK_UNSIGNED_CHAR, image.channels()); +#endif + + switch(image.channels()) + { + case 1: copyGrayImage(image, this->ImageData); break; + case 3: copyRGBImage (image, this->ImageData); break; + case 4: copyRGBAImage(image, this->ImageData); break; + } + this->ImageData->Modified(); +} + +void cv::viz::vtkImageMatSource::copyGrayImage(const Mat &source, vtkSmartPointer output) +{ + unsigned char* dptr = reinterpret_cast(output->GetScalarPointer()); + size_t elem_step = output->GetIncrements()[1]/sizeof(unsigned char); + + for (int y = 0; y < source.rows; ++y) + { + unsigned char* drow = dptr + elem_step * y; + const unsigned char *srow = source.ptr(y); + for (int x = 0; x < source.cols; ++x) + drow[x] = *srow++; + } +} + +void cv::viz::vtkImageMatSource::copyRGBImage(const Mat &source, vtkSmartPointer output) +{ + Vec3b* dptr = reinterpret_cast(output->GetScalarPointer()); + size_t elem_step = output->GetIncrements()[1]/sizeof(Vec3b); + + for (int y = 0; y < source.rows; ++y) + { + Vec3b* drow = dptr + elem_step * y; + const unsigned char *srow = source.ptr(y); + for (int x = 0; x < source.cols; ++x, srow += source.channels()) + drow[x] = Vec3b(srow[2], srow[1], srow[0]); + } +} + +void cv::viz::vtkImageMatSource::copyRGBAImage(const Mat &source, vtkSmartPointer output) +{ + Vec4b* dptr = reinterpret_cast(output->GetScalarPointer()); + size_t elem_step = output->GetIncrements()[1]/sizeof(Vec4b); + + for (int y = 0; y < source.rows; ++y) + { + Vec4b* drow = dptr + elem_step * y; + const unsigned char *srow = source.ptr(y); + for (int x = 0; x < source.cols; ++x, srow += source.channels()) + drow[x] = Vec4b(srow[2], srow[1], srow[0], srow[3]); + } +} diff --git a/modules/viz/src/vtk/vtkImageMatSource.h b/modules/viz/src/vtk/vtkImageMatSource.h new file mode 100644 index 0000000000..db0c093ed8 --- /dev/null +++ b/modules/viz/src/vtk/vtkImageMatSource.h @@ -0,0 +1,82 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +#ifndef __vtkImageMatSource_h +#define __vtkImageMatSource_h + +namespace cv +{ + namespace viz + { + class vtkImageMatSource : public vtkImageAlgorithm + { + public: + static vtkImageMatSource *New(); + vtkTypeMacro(vtkImageMatSource,vtkImageAlgorithm); + + void SetImage(InputArray image); + + protected: + vtkImageMatSource(); + ~vtkImageMatSource() {} + + vtkSmartPointer ImageData; + + int RequestInformation(vtkInformation*, vtkInformationVector**, vtkInformationVector*); + int RequestData (vtkInformation*, vtkInformationVector**, vtkInformationVector*); + private: + vtkImageMatSource(const vtkImageMatSource&); // Not implemented. + void operator=(const vtkImageMatSource&); // Not implemented. + + static void copyGrayImage(const Mat &source, vtkSmartPointer output); + static void copyRGBImage (const Mat &source, vtkSmartPointer output); + static void copyRGBAImage(const Mat &source, vtkSmartPointer output); + }; + } +} + + +#endif diff --git a/modules/viz/src/vtk/vtkOBJWriter.cpp b/modules/viz/src/vtk/vtkOBJWriter.cpp new file mode 100644 index 0000000000..452ad19a7a --- /dev/null +++ b/modules/viz/src/vtk/vtkOBJWriter.cpp @@ -0,0 +1,241 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace viz +{ + vtkStandardNewMacro(vtkOBJWriter); +}} + +cv::viz::vtkOBJWriter::vtkOBJWriter() +{ + std::ofstream fout; // only used to extract the default precision + this->DecimalPrecision = fout.precision(); + this->FileName = NULL; + this->FileType = VTK_ASCII; +} + +cv::viz::vtkOBJWriter::~vtkOBJWriter(){} + +void cv::viz::vtkOBJWriter::WriteData() +{ + vtkPolyData *input = this->GetInput(); + if (!input) + return; + + std::ostream *outfilep = this->OpenVTKFile(); + if (!outfilep) + return; + + std::ostream& outfile = *outfilep; + + //write header + outfile << "# wavefront obj file written by the visualization toolkit" << std::endl << std::endl; + outfile << "mtllib NONE" << std::endl << std::endl; + + // write out the points + for (int i = 0; i < input->GetNumberOfPoints(); i++) + { + Vec3d p; + input->GetPoint(i, p.val); + outfile << std::setprecision(this->DecimalPrecision) << "v " << p[0] << " " << p[1] << " " << p[2] << std::endl; + } + + const int idStart = 1; + + // write out the point data + vtkSmartPointer normals = input->GetPointData()->GetNormals(); + if(normals) + { + for (int i = 0; i < normals->GetNumberOfTuples(); i++) + { + Vec3d p; + normals->GetTuple(i, p.val); + outfile << std::setprecision(this->DecimalPrecision) << "vn " << p[0] << " " << p[1] << " " << p[2] << std::endl; + } + } + + vtkSmartPointer tcoords = input->GetPointData()->GetTCoords(); + if (tcoords) + { + for (int i = 0; i < tcoords->GetNumberOfTuples(); i++) + { + Vec2d p; + tcoords->GetTuple(i, p.val); + outfile << std::setprecision(this->DecimalPrecision) << "vt " << p[0] << " " << p[1] << std::endl; + } + } + + // write out a group name and material + outfile << std::endl << "g grp" << idStart << std::endl; + outfile << "usemtl mtlNONE" << std::endl; + + // write out verts if any + if (input->GetNumberOfVerts() > 0) + { + vtkIdType npts = 0, *index = 0; + vtkCellArray *cells = input->GetVerts(); + for (cells->InitTraversal(); cells->GetNextCell(npts, index); ) + { + outfile << "p "; + for (int i = 0; i < npts; i++) + outfile << index[i] + idStart << " "; + outfile << std::endl; + } + } + + // write out lines if any + if (input->GetNumberOfLines() > 0) + { + vtkIdType npts = 0, *index = 0; + vtkCellArray *cells = input->GetLines(); + for (cells->InitTraversal(); cells->GetNextCell(npts, index); ) + { + outfile << "l "; + if (tcoords) + { + for (int i = 0; i < npts; i++) + outfile << index[i] + idStart << "/" << index[i] + idStart << " "; + } + else + for (int i = 0; i < npts; i++) + outfile << index[i] + idStart << " "; + + outfile << std::endl; + } + } + + // write out polys if any + if (input->GetNumberOfPolys() > 0) + { + vtkIdType npts = 0, *index = 0; + vtkCellArray *cells = input->GetPolys(); + for (cells->InitTraversal(); cells->GetNextCell(npts, index); ) + { + outfile << "f "; + for (int i = 0; i < npts; i++) + { + if (normals) + { + if (tcoords) + outfile << index[i] + idStart << "/" << index[i] + idStart << "/" << index[i] + idStart << " "; + else + outfile << index[i] + idStart << "//" << index[i] + idStart << " "; + } + else + { + if (tcoords) + outfile << index[i] + idStart << " " << index[i] + idStart << " "; + else + outfile << index[i] + idStart << " "; + } + } + outfile << std::endl; + } + } + + // write out tstrips if any + if (input->GetNumberOfStrips() > 0) + { + vtkIdType npts = 0, *index = 0; + vtkCellArray *cells = input->GetStrips(); + for (cells->InitTraversal(); cells->GetNextCell(npts, index); ) + { + for (int i = 2, i1, i2; i < npts; ++i) + { + if (i % 2) + { + i1 = i - 1; + i2 = i - 2; + } + else + { + i1 = i - 1; + i2 = i - 2; + } + + if(normals) + { + if (tcoords) + { + outfile << "f " << index[i1] + idStart << "/" << index[i1] + idStart << "/" << index[i1] + idStart << " " + << index[i2]+ idStart << "/" << index[i2] + idStart << "/" << index[i2] + idStart << " " + << index[i] + idStart << "/" << index[i] + idStart << "/" << index[i] + idStart << std::endl; + } + else + { + outfile << "f " << index[i1] + idStart << "//" << index[i1] + idStart << " " << index[i2] + idStart + << "//" << index[i2] + idStart << " " << index[i] + idStart << "//" << index[i] + idStart << std::endl; + } + } + else + { + if (tcoords) + { + outfile << "f " << index[i1] + idStart << "/" << index[i1] + idStart << " " << index[i2] + idStart + << "/" << index[i2] + idStart << " " << index[i] + idStart << "/" << index[i] + idStart << std::endl; + } + else + outfile << "f " << index[i1] + idStart << " " << index[i2] + idStart << " " << index[i] + idStart << std::endl; + } + } /* for (int i = 2; i < npts; ++i) */ + } + } /* if (input->GetNumberOfStrips() > 0) */ + + this->CloseVTKFile(outfilep); + + // Delete the file if an error occurred + if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError) + { + vtkErrorMacro("Ran out of disk space; deleting file: " << this->FileName); + unlink(this->FileName); + } +} + +void cv::viz::vtkOBJWriter::PrintSelf(ostream& os, vtkIndent indent) +{ + Superclass::PrintSelf(os, indent); + os << indent << "DecimalPrecision: " << DecimalPrecision << "\n"; +} diff --git a/modules/viz/src/vtk/vtkOBJWriter.h b/modules/viz/src/vtk/vtkOBJWriter.h new file mode 100644 index 0000000000..f8889884d7 --- /dev/null +++ b/modules/viz/src/vtk/vtkOBJWriter.h @@ -0,0 +1,79 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __vtkOBJWriter_h +#define __vtkOBJWriter_h + +#include + +namespace cv +{ + namespace viz + { + class vtkOBJWriter : public vtkPolyDataWriter + { + public: + static vtkOBJWriter *New(); + vtkTypeMacro(vtkOBJWriter,vtkPolyDataWriter) + void PrintSelf(ostream& os, vtkIndent indent); + + vtkGetMacro(DecimalPrecision, int); + vtkSetMacro(DecimalPrecision, int); + + protected: + vtkOBJWriter(); + ~vtkOBJWriter(); + + void WriteData(); + + int DecimalPrecision; + + private: + vtkOBJWriter(const vtkOBJWriter&); // Not implemented. + void operator=(const vtkOBJWriter&); // Not implemented. + }; + } +} + +#endif diff --git a/modules/viz/src/vtk/vtkTrajectorySource.cpp b/modules/viz/src/vtk/vtkTrajectorySource.cpp new file mode 100644 index 0000000000..e098a1d553 --- /dev/null +++ b/modules/viz/src/vtk/vtkTrajectorySource.cpp @@ -0,0 +1,110 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace viz +{ + vtkStandardNewMacro(vtkTrajectorySource); +}} + +cv::viz::vtkTrajectorySource::vtkTrajectorySource() { SetNumberOfInputPorts(0); } +cv::viz::vtkTrajectorySource::~vtkTrajectorySource() {} + +void cv::viz::vtkTrajectorySource::SetTrajectory(InputArray _traj) +{ + CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT); + CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16)); + + Mat traj; + _traj.getMat().convertTo(traj, CV_64F); + const Affine3d* dpath = traj.ptr(); + size_t total = traj.total(); + + points = vtkSmartPointer::New(); + points->SetDataType(VTK_DOUBLE); + points->SetNumberOfPoints(total); + + tensors = vtkSmartPointer::New(); + tensors->SetNumberOfComponents(9); + tensors->SetNumberOfTuples(total); + + for(size_t i = 0; i < total; ++i, ++dpath) + { + Matx33d R = dpath->rotation().t(); // transposed because of + tensors->SetTuple(i, R.val); // column major order + + Vec3d p = dpath->translation(); + points->SetPoint(i, p.val); + } +} + +cv::Mat cv::viz::vtkTrajectorySource::ExtractPoints(InputArray _traj) +{ + CV_Assert(_traj.kind() == _InputArray::STD_VECTOR || _traj.kind() == _InputArray::MAT); + CV_Assert(_traj.type() == CV_32FC(16) || _traj.type() == CV_64FC(16)); + + Mat points(1, _traj.total(), CV_MAKETYPE(_traj.depth(), 3)); + const Affine3d* dpath = _traj.getMat().ptr(); + const Affine3f* fpath = _traj.getMat().ptr(); + + if (_traj.depth() == CV_32F) + for(int i = 0; i < points.cols; ++i) + points.at(i) = fpath[i].translation(); + + if (_traj.depth() == CV_64F) + for(int i = 0; i < points.cols; ++i) + points.at(i) = dpath[i].translation(); + + return points; +} + +int cv::viz::vtkTrajectorySource::RequestData(vtkInformation *vtkNotUsed(request), vtkInformationVector **vtkNotUsed(inputVector), vtkInformationVector *outputVector) +{ + vtkInformation *outInfo = outputVector->GetInformationObject(0); + vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); + output->SetPoints(points); + output->GetPointData()->SetTensors(tensors); + return 1; +} diff --git a/modules/viz/src/vtk/vtkTrajectorySource.h b/modules/viz/src/vtk/vtkTrajectorySource.h new file mode 100644 index 0000000000..f6c9c77b9c --- /dev/null +++ b/modules/viz/src/vtk/vtkTrajectorySource.h @@ -0,0 +1,84 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __vtkTrajectorySource_h +#define __vtkTrajectorySource_h + +#include +#include +#include +#include +#include + +namespace cv +{ + namespace viz + { + class vtkTrajectorySource : public vtkPolyDataAlgorithm + { + public: + static vtkTrajectorySource *New(); + vtkTypeMacro(vtkTrajectorySource,vtkPolyDataAlgorithm) + + virtual void SetTrajectory(InputArray trajectory); + + static Mat ExtractPoints(InputArray trajectory); + + protected: + vtkTrajectorySource(); + ~vtkTrajectorySource(); + + vtkSmartPointer points; + vtkSmartPointer tensors; + + int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *); + private: + vtkTrajectorySource(const vtkTrajectorySource&); // Not implemented. + void operator=(const vtkTrajectorySource&); // Not implemented. + + }; + } +} + +#endif diff --git a/modules/viz/src/vtk/vtkXYZWriter.cpp b/modules/viz/src/vtk/vtkXYZWriter.cpp new file mode 100644 index 0000000000..4518a0103a --- /dev/null +++ b/modules/viz/src/vtk/vtkXYZWriter.cpp @@ -0,0 +1,93 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +namespace cv { namespace viz +{ + vtkStandardNewMacro(vtkXYZWriter); +}} + +cv::viz::vtkXYZWriter::vtkXYZWriter() +{ + std::ofstream fout; // only used to extract the default precision + this->DecimalPrecision = fout.precision(); +} + +void cv::viz::vtkXYZWriter::WriteData() +{ + vtkPolyData *input = this->GetInput(); + if (!input) + return; + + // OpenVTKFile() will report any errors that happen + ostream *outfilep = this->OpenVTKFile(); + if (!outfilep) + return; + + ostream &outfile = *outfilep; + + for(vtkIdType i = 0; i < input->GetNumberOfPoints(); ++i) + { + Vec3d p; + input->GetPoint(i, p.val); + outfile << std::setprecision(this->DecimalPrecision) << p[0] << " " << p[1] << " " << p[2] << std::endl; + } + + // Close the file + this->CloseVTKFile(outfilep); + + // Delete the file if an error occurred + if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError) + { + vtkErrorMacro("Ran out of disk space; deleting file: " << this->FileName); + unlink(this->FileName); + } +} + +void cv::viz::vtkXYZWriter::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os,indent); + os << indent << "DecimalPrecision: " << this->DecimalPrecision << "\n"; +} diff --git a/modules/viz/src/vtk/vtkXYZWriter.h b/modules/viz/src/vtk/vtkXYZWriter.h new file mode 100644 index 0000000000..3db18b793b --- /dev/null +++ b/modules/viz/src/vtk/vtkXYZWriter.h @@ -0,0 +1,78 @@ +/*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) 2013, 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. +// +// Authors: +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifndef __vtkXYZWriter_h +#define __vtkXYZWriter_h + +#include "vtkPolyDataWriter.h" + +namespace cv +{ + namespace viz + { + class vtkXYZWriter : public vtkPolyDataWriter + { + public: + static vtkXYZWriter *New(); + vtkTypeMacro(vtkXYZWriter,vtkPolyDataWriter) + void PrintSelf(ostream& os, vtkIndent indent); + + vtkGetMacro(DecimalPrecision, int) + vtkSetMacro(DecimalPrecision, int) + + protected: + vtkXYZWriter(); + ~vtkXYZWriter(){} + + void WriteData(); + + int DecimalPrecision; + + private: + vtkXYZWriter(const vtkXYZWriter&); // Not implemented. + void operator=(const vtkXYZWriter&); // Not implemented. + }; + } +} +#endif diff --git a/modules/viz/src/widget.cpp b/modules/viz/src/widget.cpp new file mode 100644 index 0000000000..33b467ebc7 --- /dev/null +++ b/modules/viz/src/widget.cpp @@ -0,0 +1,327 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#include "precomp.hpp" + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// widget implementation + +class cv::viz::Widget::Impl +{ +public: + vtkSmartPointer prop; + Impl() : prop(0) {} +}; + +cv::viz::Widget::Widget() : impl_( new Impl() ) { } + +cv::viz::Widget::Widget(const Widget& other) : impl_( new Impl() ) +{ + if (other.impl_ && other.impl_->prop) + impl_->prop = other.impl_->prop; +} + +cv::viz::Widget& cv::viz::Widget::operator=(const Widget& other) +{ + if (!impl_) + impl_ = new Impl(); + + if (other.impl_) + impl_->prop = other.impl_->prop; + return *this; +} + +cv::viz::Widget::~Widget() +{ + if (impl_) + { + delete impl_; + impl_ = 0; + } +} + +cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name) +{ + CV_Assert(vtkPLYReader::CanReadFile(file_name.c_str())); + + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(file_name.c_str()); + + vtkSmartPointer mapper = vtkSmartPointer::New(); + mapper->SetInputConnection( reader->GetOutputPort() ); + mapper->ImmediateModeRenderingOff(); + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->GetProperty()->SetInterpolationToFlat(); + actor->GetProperty()->BackfaceCullingOn(); + actor->SetMapper(mapper); + + Widget widget; + WidgetAccessor::setProp(widget, actor); + return widget; +} + +void cv::viz::Widget::setRenderingProperty(int property, double value) +{ + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget type is not supported." && actor); + + switch (property) + { + case POINT_SIZE: actor->GetProperty()->SetPointSize(float(value)); break; + case OPACITY: actor->GetProperty()->SetOpacity(value); break; + case LINE_WIDTH: actor->GetProperty()->SetLineWidth(float(value)); break; + case IMMEDIATE_RENDERING: actor->GetMapper()->SetImmediateModeRendering(int(value)); break; + case FONT_SIZE: + { + vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor); + CV_Assert("Widget does not have text content." && text_actor); + text_actor->GetTextProperty()->SetFontSize(int(value)); + break; + } + case REPRESENTATION: + { + switch (int(value)) + { + case REPRESENTATION_POINTS: actor->GetProperty()->SetRepresentationToPoints(); break; + case REPRESENTATION_WIREFRAME: actor->GetProperty()->SetRepresentationToWireframe(); break; + case REPRESENTATION_SURFACE: actor->GetProperty()->SetRepresentationToSurface(); break; + } + break; + } + case SHADING: + { + switch (int(value)) + { + case SHADING_FLAT: actor->GetProperty()->SetInterpolationToFlat(); break; + case SHADING_GOURAUD: + { + if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) + { + vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + CV_Assert("Can't set shading property for such type of widget" && mapper); + + vtkSmartPointer with_normals = VtkUtils::ComputeNormals(mapper->GetInput()); + VtkUtils::SetInputData(mapper, with_normals); + } + actor->GetProperty()->SetInterpolationToGouraud(); + break; + } + case SHADING_PHONG: + { + if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals()) + { + vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + CV_Assert("Can't set shading property for such type of widget" && mapper); + + vtkSmartPointer with_normals = VtkUtils::ComputeNormals(mapper->GetInput()); + VtkUtils::SetInputData(mapper, with_normals); + } + actor->GetProperty()->SetInterpolationToPhong(); + break; + } + } + break; + } + default: + CV_Assert("setPointCloudRenderingProperties: Unknown property"); + } + actor->Modified(); +} + +double cv::viz::Widget::getRenderingProperty(int property) const +{ + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget type is not supported." && actor); + + double value = 0.0; + switch (property) + { + case POINT_SIZE: value = actor->GetProperty()->GetPointSize(); break; + case OPACITY: value = actor->GetProperty()->GetOpacity(); break; + case LINE_WIDTH: value = actor->GetProperty()->GetLineWidth(); break; + case IMMEDIATE_RENDERING: value = actor->GetMapper()->GetImmediateModeRendering(); break; + + case FONT_SIZE: + { + vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor); + CV_Assert("Widget does not have text content." && text_actor); + value = text_actor->GetTextProperty()->GetFontSize();; + break; + } + case REPRESENTATION: + { + switch (actor->GetProperty()->GetRepresentation()) + { + case VTK_POINTS: value = REPRESENTATION_POINTS; break; + case VTK_WIREFRAME: value = REPRESENTATION_WIREFRAME; break; + case VTK_SURFACE: value = REPRESENTATION_SURFACE; break; + } + break; + } + case SHADING: + { + switch (actor->GetProperty()->GetInterpolation()) + { + case VTK_FLAT: value = SHADING_FLAT; break; + case VTK_GOURAUD: value = SHADING_GOURAUD; break; + case VTK_PHONG: value = SHADING_PHONG; break; + } + break; + } + default: + CV_Assert("getPointCloudRenderingProperties: Unknown property"); + } + return value; +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// widget accessor implementaion + +vtkSmartPointer cv::viz::WidgetAccessor::getProp(const Widget& widget) +{ + return widget.impl_->prop; +} + +void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer prop) +{ + widget.impl_->prop = prop; +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// widget3D implementation + +void cv::viz::Widget3D::setPose(const Affine3d &pose) +{ + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget is not 3D." && actor); + + vtkSmartPointer matrix = vtkmatrix(pose.matrix); + actor->SetUserMatrix(matrix); + actor->Modified(); +} + +void cv::viz::Widget3D::updatePose(const Affine3d &pose) +{ + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget is not 3D." && actor); + + vtkSmartPointer matrix = actor->GetUserMatrix(); + if (!matrix) + { + setPose(pose); + return; + } + + Affine3d updated_pose = pose * Affine3d(*matrix->Element); + matrix = vtkmatrix(updated_pose.matrix); + + actor->SetUserMatrix(matrix); + actor->Modified(); +} + +cv::Affine3d cv::viz::Widget3D::getPose() const +{ + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget is not 3D." && actor); + return Affine3d(*actor->GetUserMatrix()->Element); +} + +void cv::viz::Widget3D::applyTransform(const Affine3d &transform) +{ + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget is not 3D actor." && actor); + + vtkSmartPointer mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper()); + CV_Assert("Widget doesn't have a polydata mapper" && mapper); + mapper->Update(); + + VtkUtils::SetInputData(mapper, VtkUtils::TransformPolydata(mapper->GetInput(), transform)); +} + +void cv::viz::Widget3D::setColor(const Color &color) +{ + // Cast to actor instead of prop3d since prop3d doesn't provide getproperty + vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget type is not supported." && actor); + + Color c = vtkcolor(color); + actor->GetMapper()->ScalarVisibilityOff(); + actor->GetProperty()->SetColor(c.val); + actor->GetProperty()->SetEdgeColor(c.val); + actor->Modified(); +} + +template<> cv::viz::Widget3D cv::viz::Widget::cast() +{ + vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget cannot be cast." && actor); + + Widget3D widget; + WidgetAccessor::setProp(widget, actor); + return widget; +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// widget2D implementation + +void cv::viz::Widget2D::setColor(const Color &color) +{ + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget type is not supported." && actor); + Color c = vtkcolor(color); + actor->GetProperty()->SetColor(c.val); + actor->Modified(); +} + +template<> cv::viz::Widget2D cv::viz::Widget::cast() +{ + vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this)); + CV_Assert("Widget cannot be cast." && actor); + + Widget2D widget; + WidgetAccessor::setProp(widget, actor); + return widget; +} diff --git a/modules/viz/test/test_main.cpp b/modules/viz/test/test_main.cpp new file mode 100644 index 0000000000..e737d2db31 --- /dev/null +++ b/modules/viz/test/test_main.cpp @@ -0,0 +1,3 @@ +#include "test_precomp.hpp" + +CV_TEST_MAIN("viz") diff --git a/modules/viz/test/test_precomp.cpp b/modules/viz/test/test_precomp.cpp new file mode 100644 index 0000000000..c2673fee69 --- /dev/null +++ b/modules/viz/test/test_precomp.cpp @@ -0,0 +1,24 @@ +#include "test_precomp.hpp" + +cv::String cv::Path::combine(const String& item1, const String& item2) +{ + if (item1.empty()) + return item2; + + if (item2.empty()) + return item1; + + char last = item1[item1.size()-1]; + + bool need_append = last != '/' && last != '\\'; + return item1 + (need_append ? "/" : "") + item2; +} + +cv::String cv::Path::combine(const String& item1, const String& item2, const String& item3) +{ return combine(combine(item1, item2), item3); } + +cv::String cv::Path::change_extension(const String& file, const String& ext) +{ + String::size_type pos = file.find_last_of('.'); + return pos == String::npos ? file : file.substr(0, pos+1) + ext; +} diff --git a/modules/viz/test/test_precomp.hpp b/modules/viz/test/test_precomp.hpp new file mode 100644 index 0000000000..cd00b6e73b --- /dev/null +++ b/modules/viz/test/test_precomp.hpp @@ -0,0 +1,104 @@ +/*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) 2013, 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. +// +// Authors: +// * Ozan Tonkal, ozantonkal@gmail.com +// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com +// +//M*/ + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" +# if defined __clang__ || defined __APPLE__ +# pragma GCC diagnostic ignored "-Wmissing-prototypes" +# pragma GCC diagnostic ignored "-Wextra" +# endif +#endif + +#ifndef __OPENCV_TEST_PRECOMP_HPP__ +#define __OPENCV_TEST_PRECOMP_HPP__ + +#include "opencv2/ts/ts.hpp" +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace cv +{ + struct Path + { + static String combine(const String& item1, const String& item2); + static String combine(const String& item1, const String& item2, const String& item3); + static String change_extension(const String& file, const String& ext); + }; + + inline cv::String get_dragon_ply_file_path() + { + return Path::combine(cvtest::TS::ptr()->get_data_path(), "dragon.ply"); + } + + template + inline std::vector< Affine3<_Tp> > generate_test_trajectory() + { + std::vector< Affine3<_Tp> > result; + + for (int i = 0, j = 0; i <= 270; i += 3, j += 10) + { + double x = 2 * cos(i * 3 * CV_PI/180.0) * (1.0 + 0.5 * cos(1.2 + i * 1.2 * CV_PI/180.0)); + double y = 0.25 + i/270.0 + sin(j * CV_PI/180.0) * 0.2 * sin(0.6 + j * 1.5 * CV_PI/180.0); + double z = 2 * sin(i * 3 * CV_PI/180.0) * (1.0 + 0.5 * cos(1.2 + i * CV_PI/180.0)); + result.push_back(viz::makeCameraPose(Vec3d(x, y, z), Vec3d::all(0.0), Vec3d(0.0, 1.0, 0.0))); + } + return result; + } + + inline Mat make_gray(const Mat& image) + { + Mat chs[3]; split(image, chs); + return 0.114 * chs[0] + 0.58 * chs[1] + 0.3 * chs[2]; + } +} + +#endif diff --git a/modules/viz/test/test_tutorial2.cpp b/modules/viz/test/test_tutorial2.cpp new file mode 100644 index 0000000000..a901adc2c7 --- /dev/null +++ b/modules/viz/test/test_tutorial2.cpp @@ -0,0 +1,54 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +void tutorial2() +{ + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); + + /// Add line to represent (1,1,1) axis + viz::WLine axis(Point3f(-1.0, -1.0, -1.0), Point3d(1.0, 1.0, 1.0)); + axis.setRenderingProperty(viz::LINE_WIDTH, 4.0); + myWindow.showWidget("Line Widget", axis); + + /// Construct a cube widget + viz::WCube cube_widget(Point3d(0.5, 0.5, 0.0), Point3d(0.0, 0.0, -0.5), true, viz::Color::blue()); + cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0); + + /// Display widget (update if already displayed) + myWindow.showWidget("Cube Widget", cube_widget); + + /// Rodrigues vector + Vec3d rot_vec = Vec3d::all(0); + double translation_phase = 0.0, translation = 0.0; + while(!myWindow.wasStopped()) + { + /* Rotation using rodrigues */ + /// Rotate around (1,1,1) + rot_vec[0] += CV_PI * 0.01; + rot_vec[1] += CV_PI * 0.01; + rot_vec[2] += CV_PI * 0.01; + + /// Shift on (1,1,1) + translation_phase += CV_PI * 0.01; + translation = sin(translation_phase); + + /// Construct pose + Affine3d pose(rot_vec, Vec3d(translation, translation, translation)); + + myWindow.setWidgetPose("Cube Widget", pose); + + myWindow.spinOnce(1, true); + } +} + + +TEST(Viz, DISABLED_tutorial2_pose_of_widget) +{ + tutorial2(); +} diff --git a/modules/viz/test/test_tutorial3.cpp b/modules/viz/test/test_tutorial3.cpp new file mode 100644 index 0000000000..590e29ebfd --- /dev/null +++ b/modules/viz/test/test_tutorial3.cpp @@ -0,0 +1,64 @@ +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +/** + * @function main + */ +void tutorial3(bool camera_pov) +{ + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); + + /// Let's assume camera has the following properties + Point3d cam_pos(3.0, 3.0, 3.0), cam_focal_point(3.0, 3.0, 2.0), cam_y_dir(-1.0, 0.0, 0.0); + + /// We can get the pose of the cam using makeCameraPose + Affine3d cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + + /// We can get the transformation matrix from camera coordinate system to global using + /// - makeTransformToGlobal. We need the axes of the camera + Affine3d transform = viz::makeTransformToGlobal(Vec3d(0.0, -1.0, 0.0), Vec3d(-1.0, 0.0, 0.0), Vec3d(0.0, 0.0, -1.0), cam_pos); + + /// Create a cloud widget. + Mat dragon_cloud = viz::readCloud(get_dragon_ply_file_path()); + viz::WCloud cloud_widget(dragon_cloud, viz::Color::green()); + + /// Pose of the widget in camera frame + Affine3d cloud_pose = Affine3d().translate(Vec3d(0.0, 0.0, 3.0)); + /// Pose of the widget in global frame + Affine3d cloud_pose_global = transform * cloud_pose; + + /// Visualize camera frame + if (!camera_pov) + { + viz::WCameraPosition cpw(0.5); // Coordinate axes + viz::WCameraPosition cpw_frustum(Vec2f(0.889484f, 0.523599f)); // Camera frustum + myWindow.showWidget("CPW", cpw, cam_pose); + myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); + } + + /// Visualize widget + myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); + + /// Set the viewer pose to that of camera + if (camera_pov) + myWindow.setViewerPose(cam_pose); + + /// Start event loop. + myWindow.spin(); +} + +TEST(Viz, DISABLED_tutorial3_global_view) +{ + tutorial3(false); +} + +TEST(Viz, DISABLED_tutorial3_camera_view) +{ + tutorial3(true); +} diff --git a/modules/viz/test/test_viz3d.cpp b/modules/viz/test/test_viz3d.cpp new file mode 100644 index 0000000000..45d3cdc3cf --- /dev/null +++ b/modules/viz/test/test_viz3d.cpp @@ -0,0 +1,64 @@ +/*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) 2000-2008, Intel Corporation, all rights reserved. + // Copyright (C) 2008-2013, Willow Garage Inc., 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*/ +#include "test_precomp.hpp" + +using namespace cv; + +TEST(Viz_viz3d, DISABLED_develop) +{ + cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path()); + + cv::viz::Viz3d viz("abc"); + viz.setBackgroundMeshLab(); + viz.showWidget("coo", cv::viz::WCoordinateSystem(1)); + viz.showWidget("cloud", cv::viz::WPaintedCloud(cloud)); + + //---->>>>> + //std::vector gt, es; + //cv::viz::readTrajectory(gt, "d:/Datasets/trajs/gt%05d.xml"); + //cv::viz::readTrajectory(es, "d:/Datasets/trajs/es%05d.xml"); + //cv::Mat cloud = cv::viz::readCloud(get_dragon_ply_file_path()); + //---->>>>> + + + viz.spin(); +} diff --git a/modules/viz/test/tests_simple.cpp b/modules/viz/test/tests_simple.cpp new file mode 100644 index 0000000000..f84b60a475 --- /dev/null +++ b/modules/viz/test/tests_simple.cpp @@ -0,0 +1,407 @@ +/*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) 2000-2008, Intel Corporation, all rights reserved. + // Copyright (C) 2008-2013, Willow Garage Inc., 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*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace cv::viz; + +TEST(Viz, show_cloud_bluberry) +{ + Mat dragon_cloud = readCloud(get_dragon_ply_file_path()); + + Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); + + Viz3d viz("show_cloud_bluberry"); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("dragon", WCloud(dragon_cloud, Color::bluberry()), pose); + + viz.showWidget("text2d", WText("Bluberry cloud", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_cloud_random_color) +{ + Mat dragon_cloud = readCloud(get_dragon_ply_file_path()); + + Mat colors(dragon_cloud.size(), CV_8UC3); + theRNG().fill(colors, RNG::UNIFORM, 0, 255); + + Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); + + Viz3d viz("show_cloud_random_color"); + viz.setBackgroundMeshLab(); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("dragon", WCloud(dragon_cloud, colors), pose); + viz.showWidget("text2d", WText("Random color cloud", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_cloud_masked) +{ + Mat dragon_cloud = readCloud(get_dragon_ply_file_path()); + + Vec3f qnan = Vec3f::all(std::numeric_limits::quiet_NaN()); + for(size_t i = 0; i < dragon_cloud.total(); ++i) + if (i % 15 != 0) + dragon_cloud.at(i) = qnan; + + Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); + + Viz3d viz("show_cloud_masked"); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("dragon", WCloud(dragon_cloud), pose); + viz.showWidget("text2d", WText("Nan masked cloud", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_cloud_collection) +{ + Mat cloud = readCloud(get_dragon_ply_file_path()); + + WCloudCollection ccol; + ccol.addCloud(cloud, Color::white(), Affine3d().translate(Vec3d(0, 0, 0)).rotate(Vec3d(CV_PI/2, 0, 0))); + ccol.addCloud(cloud, Color::blue(), Affine3d().translate(Vec3d(1, 0, 0))); + ccol.addCloud(cloud, Color::red(), Affine3d().translate(Vec3d(2, 0, 0))); + + Viz3d viz("show_cloud_collection"); + viz.setBackgroundColor(Color::mlab()); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("ccol", ccol); + viz.showWidget("text2d", WText("Cloud collection", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_painted_clouds) +{ + Mat cloud = readCloud(get_dragon_ply_file_path()); + + Viz3d viz("show_painted_clouds"); + viz.setBackgroundMeshLab(); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("cloud1", WPaintedCloud(cloud), Affine3d(Vec3d(0.0, -CV_PI/2, 0.0), Vec3d(-1.5, 0.0, 0.0))); + viz.showWidget("cloud2", WPaintedCloud(cloud, Vec3d(0.0, -0.75, -1.0), Vec3d(0.0, 0.75, 0.0)), Affine3d(Vec3d(0.0, CV_PI/2, 0.0), Vec3d(1.5, 0.0, 0.0))); + viz.showWidget("cloud3", WPaintedCloud(cloud, Vec3d(0.0, 0.0, -1.0), Vec3d(0.0, 0.0, 1.0), Color::blue(), Color::red())); + viz.showWidget("arrow", WArrow(Vec3d(0.0, 1.0, -1.0), Vec3d(0.0, 1.0, 1.0), 0.009, Color::raspberry())); + viz.showWidget("text2d", WText("Painted clouds", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_mesh) +{ + Mesh mesh = Mesh::load(get_dragon_ply_file_path()); + + Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); + + Viz3d viz("show_mesh"); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("mesh", WMesh(mesh), pose); + viz.showWidget("text2d", WText("Just mesh", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_mesh_random_colors) +{ + Mesh mesh = Mesh::load(get_dragon_ply_file_path()); + theRNG().fill(mesh.colors, RNG::UNIFORM, 0, 255); + + Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); + + Viz3d viz("show_mesh_random_color"); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("mesh", WMesh(mesh), pose); + viz.setRenderingProperty("mesh", SHADING, SHADING_PHONG); + viz.showWidget("text2d", WText("Random color mesh", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_textured_mesh) +{ + Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); + + std::vector points; + std::vector tcoords; + std::vector polygons; + for(size_t i = 0; i < 64; ++i) + { + double angle = CV_PI/2 * i/64.0; + points.push_back(Vec3d(0.00, cos(angle), sin(angle))*0.75); + points.push_back(Vec3d(1.57, cos(angle), sin(angle))*0.75); + tcoords.push_back(Vec2d(0.0, i/64.0)); + tcoords.push_back(Vec2d(1.0, i/64.0)); + } + + for(size_t i = 0; i < points.size()/2-1; ++i) + { + int polys[] = {3, 2*i, 2*i+1, 2*i+2, 3, 2*i+1, 2*i+2, 2*i+3}; + polygons.insert(polygons.end(), polys, polys + sizeof(polys)/sizeof(polys[0])); + } + + cv::viz::Mesh mesh; + mesh.cloud = Mat(points, true).reshape(3, 1); + mesh.tcoords = Mat(tcoords, true).reshape(2, 1); + mesh.polygons = Mat(polygons, true).reshape(1, 1); + mesh.texture = lena; + + Viz3d viz("show_textured_mesh"); + viz.setBackgroundMeshLab(); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("mesh", WMesh(mesh)); + viz.setRenderingProperty("mesh", SHADING, SHADING_PHONG); + viz.showWidget("text2d", WText("Textured mesh", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_polyline) +{ + Mat polyline(1, 32, CV_64FC3); + for(size_t i = 0; i < polyline.total(); ++i) + polyline.at(i) = Vec3d(i/16.0, cos(i * CV_PI/6), sin(i * CV_PI/6)); + + Viz3d viz("show_polyline"); + viz.showWidget("polyline", WPolyLine(Mat(polyline), Color::apricot())); + viz.showWidget("coosys", WCoordinateSystem()); + viz.showWidget("text2d", WText("Polyline", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_sampled_normals) +{ + Mesh mesh = Mesh::load(get_dragon_ply_file_path()); + computeNormals(mesh, mesh.normals); + + Affine3d pose = Affine3d().rotate(Vec3d(0, 0.8, 0)); + + Viz3d viz("show_sampled_normals"); + viz.showWidget("mesh", WMesh(mesh), pose); + viz.showWidget("normals", WCloudNormals(mesh.cloud, mesh.normals, 30, 0.1f, Color::green()), pose); + viz.setRenderingProperty("normals", LINE_WIDTH, 2.0); + viz.showWidget("text2d", WText("Cloud or mesh normals", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_trajectories) +{ + std::vector path = generate_test_trajectory(), sub0, sub1, sub2, sub3, sub4, sub5; + + Mat(path).rowRange(0, path.size()/10+1).copyTo(sub0); + Mat(path).rowRange(path.size()/10, path.size()/5+1).copyTo(sub1); + Mat(path).rowRange(path.size()/5, 11*path.size()/12).copyTo(sub2); + Mat(path).rowRange(11*path.size()/12, path.size()).copyTo(sub3); + Mat(path).rowRange(3*path.size()/4, 33*path.size()/40).copyTo(sub4); + Mat(path).rowRange(33*path.size()/40, 9*path.size()/10).copyTo(sub5); + Matx33d K(1024.0, 0.0, 320.0, 0.0, 1024.0, 240.0, 0.0, 0.0, 1.0); + + Viz3d viz("show_trajectories"); + viz.showWidget("coos", WCoordinateSystem()); + viz.showWidget("sub0", WTrajectorySpheres(sub0, 0.25, 0.07)); + viz.showWidget("sub1", WTrajectory(sub1, WTrajectory::PATH, 0.2, Color::brown())); + viz.showWidget("sub2", WTrajectory(sub2, WTrajectory::FRAMES, 0.2)); + viz.showWidget("sub3", WTrajectory(sub3, WTrajectory::BOTH, 0.2, Color::green())); + viz.showWidget("sub4", WTrajectoryFrustums(sub4, K, 0.3, Color::yellow())); + viz.showWidget("sub5", WTrajectoryFrustums(sub5, Vec2d(0.78, 0.78), 0.15)); + viz.showWidget("text2d", WText("Different kinds of supported trajectories", Point(20, 20), 20, Color::green())); + + int i = 0; + while(!viz.wasStopped()) + { + double a = --i % 360; + Vec3d pose(sin(a * CV_PI/180), 0.7, cos(a * CV_PI/180)); + viz.setViewerPose(makeCameraPose(pose * 7.5, Vec3d(0.0, 0.5, 0.0), Vec3d(0.0, 0.1, 0.0))); + viz.spinOnce(20, true); + } + viz.resetCamera(); + viz.spin(); +} + +TEST(Viz, show_trajectory_reposition) +{ + std::vector path = generate_test_trajectory(); + + Viz3d viz("show_trajectory_reposition_to_origin"); + viz.showWidget("coos", WCoordinateSystem()); + viz.showWidget("sub3", WTrajectory(Mat(path).rowRange(0, path.size()/3), WTrajectory::BOTH, 0.2, Color::brown()), path.front().inv()); + viz.showWidget("text2d", WText("Trajectory resposition to origin", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_camera_positions) +{ + Matx33d K(1024.0, 0.0, 320.0, 0.0, 1024.0, 240.0, 0.0, 0.0, 1.0); + Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); + Mat gray = make_gray(lena); + + Affine3d poses[2]; + for(int i = 0; i < 2; ++i) + { + Vec3d pose = 5 * Vec3d(sin(3.14 + 2.7 + i*60 * CV_PI/180), 0.4 - i*0.3, cos(3.14 + 2.7 + i*60 * CV_PI/180)); + poses[i] = makeCameraPose(pose, Vec3d(0.0, 0.0, 0.0), Vec3d(0.0, -0.1, 0.0)); + } + + Viz3d viz("show_camera_positions"); + viz.showWidget("sphe", WSphere(Point3d(0,0,0), 1.0, 10, Color::orange_red())); + viz.showWidget("coos", WCoordinateSystem(1.5)); + viz.showWidget("pos1", WCameraPosition(0.75), poses[0]); + viz.showWidget("pos2", WCameraPosition(Vec2d(0.78, 0.78), lena, 2.2, Color::green()), poses[0]); + viz.showWidget("pos3", WCameraPosition(0.75), poses[1]); + viz.showWidget("pos4", WCameraPosition(K, gray, 3, Color::indigo()), poses[1]); + viz.showWidget("text2d", WText("Camera positions with images", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_overlay_image) +{ + Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); + Mat gray = make_gray(lena); + + Size2d half_lsize = Size2d(lena.cols, lena.rows) * 0.5; + + Viz3d viz("show_overlay_image"); + viz.setBackgroundMeshLab(); + Size vsz = viz.getWindowSize(); + + viz.showWidget("coos", WCoordinateSystem()); + viz.showWidget("cube", WCube()); + viz.showWidget("img1", WImageOverlay(lena, Rect(Point(10, 10), half_lsize))); + viz.showWidget("img2", WImageOverlay(gray, Rect(Point(vsz.width-10-lena.cols/2, 10), half_lsize))); + viz.showWidget("img3", WImageOverlay(gray, Rect(Point(10, vsz.height-10-lena.rows/2), half_lsize))); + viz.showWidget("img5", WImageOverlay(lena, Rect(Point(vsz.width-10-lena.cols/2, vsz.height-10-lena.rows/2), half_lsize))); + viz.showWidget("text2d", WText("Overlay images", Point(20, 20), 20, Color::green())); + + int i = 0; + while(!viz.wasStopped()) + { + double a = ++i % 360; + Vec3d pose(sin(a * CV_PI/180), 0.7, cos(a * CV_PI/180)); + viz.setViewerPose(makeCameraPose(pose * 3, Vec3d(0.0, 0.5, 0.0), Vec3d(0.0, 0.1, 0.0))); + viz.getWidget("img1").cast().setImage(lena * pow(sin(i*10*CV_PI/180) * 0.5 + 0.5, 1.0)); + viz.spinOnce(1, true); + } + viz.showWidget("text2d", WText("Overlay images (stopped)", Point(20, 20), 20, Color::green())); + viz.spin(); +} + + +TEST(Viz, show_image_method) +{ + Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); + + Viz3d viz("show_image_method"); + viz.showImage(lena); + viz.spinOnce(1500, true); + viz.showImage(lena, lena.size()); + viz.spinOnce(1500, true); + + cv::viz::imshow("show_image_method", make_gray(lena)).spin(); +} + +TEST(Viz, show_image_3d) +{ + Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); + Mat gray = make_gray(lena); + + Viz3d viz("show_image_3d"); + viz.setBackgroundMeshLab(); + viz.showWidget("coos", WCoordinateSystem()); + viz.showWidget("cube", WCube()); + viz.showWidget("arr0", WArrow(Vec3d(0.5, 0.0, 0.0), Vec3d(1.5, 0.0, 0.0), 0.009, Color::raspberry())); + viz.showWidget("img0", WImage3D(lena, Size2d(1.0, 1.0)), Affine3d(Vec3d(0.0, CV_PI/2, 0.0), Vec3d(.5, 0.0, 0.0))); + viz.showWidget("arr1", WArrow(Vec3d(-0.5, -0.5, 0.0), Vec3d(0.2, 0.2, 0.0), 0.009, Color::raspberry())); + viz.showWidget("img1", WImage3D(gray, Size2d(1.0, 1.0), Vec3d(-0.5, -0.5, 0.0), Vec3d(1.0, 1.0, 0.0), Vec3d(0.0, 1.0, 0.0))); + + viz.showWidget("arr3", WArrow(Vec3d::all(-0.5), Vec3d::all(0.5), 0.009, Color::raspberry())); + + viz.showWidget("text2d", WText("Images in 3D", Point(20, 20), 20, Color::green())); + + int i = 0; + while(!viz.wasStopped()) + { + viz.getWidget("img0").cast().setImage(lena * pow(sin(i++*7.5*CV_PI/180) * 0.5 + 0.5, 1.0)); + viz.spinOnce(1, true); + } + viz.showWidget("text2d", WText("Images in 3D (stopped)", Point(20, 20), 20, Color::green())); + viz.spin(); +} + +TEST(Viz, show_simple_widgets) +{ + Viz3d viz("show_simple_widgets"); + viz.setBackgroundMeshLab(); + + viz.showWidget("coos", WCoordinateSystem()); + viz.showWidget("cube", WCube()); + viz.showWidget("cub0", WCube(Vec3d::all(-1.0), Vec3d::all(-0.5), false, Color::indigo())); + viz.showWidget("arro", WArrow(Vec3d::all(-0.5), Vec3d::all(0.5), 0.009, Color::raspberry())); + viz.showWidget("cir1", WCircle(0.5, 0.01, Color::bluberry())); + viz.showWidget("cir2", WCircle(0.5, Point3d(0.5, 0.0, 0.0), Vec3d(1.0, 0.0, 0.0), 0.01, Color::apricot())); + + viz.showWidget("cyl0", WCylinder(Vec3d(-0.5, 0.5, -0.5), Vec3d(0.5, 0.5, -0.5), 0.125, 30, Color::brown())); + viz.showWidget("con0", WCone(0.25, 0.125, 6, Color::azure())); + viz.showWidget("con1", WCone(0.125, Point3d(0.5, -0.5, 0.5), Point3d(0.5, -1.0, 0.5), 6, Color::turquoise())); + + viz.showWidget("text2d", WText("Different simple widgets", Point(20, 20), 20, Color::green())); + viz.showWidget("text3d", WText3D("Simple 3D text", Point3d( 0.5, 0.5, 0.5), 0.125, false, Color::green())); + + viz.showWidget("plane1", WPlane(Size2d(0.25, 0.75))); + viz.showWidget("plane2", WPlane(Vec3d(0.5, -0.5, -0.5), Vec3d(0.0, 1.0, 1.0), Vec3d(1.0, 1.0, 0.0), Size2d(1.0, 0.5), Color::gold())); + + viz.showWidget("grid1", WGrid(Vec2i(7,7), Vec2d::all(0.75), Color::gray()), Affine3d().translate(Vec3d(0.0, 0.0, -1.0))); + + viz.spin(); + viz.getWidget("text2d").cast().setText("Different simple widgets (updated)"); + viz.getWidget("text3d").cast().setText("Updated text 3D"); + viz.spin(); +} + +TEST(Viz, show_follower) +{ + Viz3d viz("show_follower"); + + viz.showWidget("coos", WCoordinateSystem()); + viz.showWidget("cube", WCube()); + viz.showWidget("t3d_2", WText3D("Simple 3D follower", Point3d(-0.5, -0.5, 0.5), 0.125, true, Color::green())); + viz.showWidget("text2d", WText("Follower: text always facing camera", Point(20, 20), 20, Color::green())); + viz.setBackgroundMeshLab(); + viz.spin(); + viz.getWidget("t3d_2").cast().setText("Updated follower 3D"); + viz.spin(); +} diff --git a/platforms/android/android.toolchain.cmake b/platforms/android/android.toolchain.cmake index 68b256fbd0..457164a1ee 100644 --- a/platforms/android/android.toolchain.cmake +++ b/platforms/android/android.toolchain.cmake @@ -1,5 +1,5 @@ # Copyright (c) 2010-2011, Ethan Rublee -# Copyright (c) 2011-2013, Andrey Kamaev +# Copyright (c) 2011-2014, Andrey Kamaev # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -12,9 +12,9 @@ # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # -# 3. The name of the copyright holders may be used to endorse or promote -# products derived from this software without specific prior written -# permission. +# 3. Neither the name of the copyright holder 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 @@ -29,12 +29,12 @@ # POSSIBILITY OF SUCH DAMAGE. # ------------------------------------------------------------------------------ -# Android CMake toolchain file, for use with the Android NDK r5-r8 +# Android CMake toolchain file, for use with the Android NDK r5-r9 # Requires cmake 2.6.3 or newer (2.8.5 or newer is recommended). # See home page: https://github.com/taka-no-me/android-cmake # # The file is mantained by the OpenCV project. The latest version can be get at -# https://github.com/Itseez/opencv/tree/master/platforms/android/android.toolchain.cmake +# http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake # # Usage Linux: # $ export ANDROID_NDK=/absolute/path/to/the/android-ndk @@ -87,8 +87,7 @@ # "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP. # "x86" - matches to the NDK ABI with the same name. # See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation. -# "mips" - matches to the NDK ABI with the same name -# (It is not tested on real devices by the authos of this toolchain) +# "mips" - matches to the NDK ABI with the same name. # See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation. # # ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for. @@ -292,6 +291,16 @@ # - April 2013 # [+] support non-release NDK layouts (from Linaro git and Android git) # [~] automatically detect if explicit link to crtbegin_*.o is needed +# - June 2013 +# [~] fixed stl include path for standalone toolchain made by NDK >= r8c +# - July 2013 +# [+] updated for NDK r9 +# - November 2013 +# [+] updated for NDK r9b +# - December 2013 +# [+] updated for NDK r9c +# - January 2014 +# [~] fix copying of shared STL # ------------------------------------------------------------------------------ cmake_minimum_required( VERSION 2.6.3 ) @@ -318,7 +327,7 @@ set( CMAKE_SYSTEM_VERSION 1 ) # rpath makes low sence for Android set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." ) -set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r9b -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" ) +set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r9c -r9b -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" ) if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS) if( CMAKE_HOST_WIN32 ) file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS ) @@ -464,7 +473,7 @@ endif() # detect current host platform -if( NOT DEFINED ANDROID_NDK_HOST_X64 AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64") +if( NOT DEFINED ANDROID_NDK_HOST_X64 AND (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64" OR CMAKE_HOST_APPLE) ) set( ANDROID_NDK_HOST_X64 1 CACHE BOOL "Try to use 64-bit compiler toolchain" ) mark_as_advanced( ANDROID_NDK_HOST_X64 ) endif() @@ -484,9 +493,7 @@ else() message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" ) endif() -# CMAKE_HOST_SYSTEM_PROCESSOR on MacOS X always says i386 on Intel platform -# So we do not trust ANDROID_NDK_HOST_X64 on Apple hosts -if( NOT ANDROID_NDK_HOST_X64 AND NOT CMAKE_HOST_APPLE) +if( NOT ANDROID_NDK_HOST_X64 ) set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) endif() @@ -634,30 +641,27 @@ endif() macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath ) foreach( __toolchain ${${__availableToolchainsLst}} ) - # Skip renderscript folder. It's not C++ toolchain - if (NOT ${__toolchain} STREQUAL "renderscript") - if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" ) - string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" ) - else() - set( __gcc_toolchain "${__toolchain}" ) - endif() - __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" ) - if( __machine ) - string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" ) - if( __machine MATCHES i686 ) - set( __arch "x86" ) - elseif( __machine MATCHES arm ) - set( __arch "arm" ) - elseif( __machine MATCHES mipsel ) - set( __arch "mipsel" ) - endif() - list( APPEND __availableToolchainMachines "${__machine}" ) - list( APPEND __availableToolchainArchs "${__arch}" ) - list( APPEND __availableToolchainCompilerVersions "${__version}" ) - list( APPEND ${__availableToolchainsVar} "${__toolchain}" ) + if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" ) + string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" ) + else() + set( __gcc_toolchain "${__toolchain}" ) + endif() + __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" ) + if( __machine ) + string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" ) + if( __machine MATCHES i686 ) + set( __arch "x86" ) + elseif( __machine MATCHES arm ) + set( __arch "arm" ) + elseif( __machine MATCHES mipsel ) + set( __arch "mipsel" ) endif() - unset( __gcc_toolchain ) + list( APPEND __availableToolchainMachines "${__machine}" ) + list( APPEND __availableToolchainArchs "${__arch}" ) + list( APPEND __availableToolchainCompilerVersions "${__version}" ) + list( APPEND ${__availableToolchainsVar} "${__toolchain}" ) endif() + unset( __gcc_toolchain ) endforeach() endmacro() @@ -687,6 +691,7 @@ if( BUILD_WITH_ANDROID_NDK ) endif() __LIST_FILTER( __availableToolchainsLst "^[.]" ) __LIST_FILTER( __availableToolchainsLst "llvm" ) + __LIST_FILTER( __availableToolchainsLst "renderscript" ) __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 ) __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" ) @@ -975,7 +980,11 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN ) set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" ) if( NOT ANDROID_STL STREQUAL "none" ) - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" ) + set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/include/c++/${ANDROID_COMPILER_VERSION}" ) + if( NOT EXISTS "${ANDROID_STL_INCLUDE_DIRS}" ) + # old location ( pre r8c ) + set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" ) + endif() if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" ) list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" ) elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" ) @@ -1130,15 +1139,7 @@ endif() # case of shared STL linkage if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl ) string( REPLACE "_static.a" "_shared.so" __libstl "${__libstl}" ) - if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" ) - get_filename_component( __libstlname "${__libstl}" NAME ) - execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess ) - if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}") - message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" ) - endif() - unset( __fileCopyProcess ) - unset( __libstlname ) - endif() + # TODO: check if .so file exists before the renaming endif() @@ -1503,7 +1504,8 @@ endif() # global includes and link directories include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} ) -link_directories( "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ) +get_filename_component(__android_install_path "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ABSOLUTE) # avoid CMP0015 policy warning +link_directories( "${__android_install_path}" ) # detect if need link crtbegin_so.o explicitly if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK ) @@ -1555,6 +1557,18 @@ if(NOT _CMAKE_IN_TRY_COMPILE) set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" ) endif() +# copy shaed stl library to build directory +if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" ) + get_filename_component( __libstlname "${__libstl}" NAME ) + execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess ) + if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}") + message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" ) + endif() + unset( __fileCopyProcess ) + unset( __libstlname ) +endif() + + # set these global flags for cmake client scripts to change behavior set( ANDROID True ) set( BUILD_ANDROID True ) @@ -1663,6 +1677,19 @@ if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" ) endif() +# force cmake to produce / instead of \ in build commands for Ninja generator +if( CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_HOST_WIN32 ) + # it is a bad hack after all + # CMake generates Ninja makefiles with UNIX paths only if it thinks that we are going to build with MinGW + set( CMAKE_COMPILER_IS_MINGW TRUE ) # tell CMake that we are MinGW + set( CMAKE_CROSSCOMPILING TRUE ) # stop recursion + enable_language( C ) + enable_language( CXX ) + # unset( CMAKE_COMPILER_IS_MINGW ) # can't unset because CMake does not convert back-slashes in response files without it + unset( MINGW ) +endif() + + # set some obsolete variables for backward compatibility set( ANDROID_SET_OBSOLETE_VARIABLES ON CACHE BOOL "Define obsolete Andrid-specific cmake variables" ) mark_as_advanced( ANDROID_SET_OBSOLETE_VARIABLES ) @@ -1717,7 +1744,7 @@ endif() # BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used # ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform # ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86" or "mips" depending on ANDROID_ABI -# ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b, r8c, r8d, r8e; set only for NDK +# ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b, r8c, r8d, r8e, r9, r9b, r9c; set only for NDK # ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI # ANDROID_SYSROOT : path to the compiler sysroot # TOOL_OS_SUFFIX : "" or ".exe" depending on host platform diff --git a/platforms/android/service/engine/jni/Tests/HardwareDetectionTest.cpp b/platforms/android/service/engine/jni/Tests/HardwareDetectionTest.cpp index 83dd9c27e1..8e7dfab006 100644 --- a/platforms/android/service/engine/jni/Tests/HardwareDetectionTest.cpp +++ b/platforms/android/service/engine/jni/Tests/HardwareDetectionTest.cpp @@ -55,7 +55,7 @@ TEST(Parse, ParseEmptyString) EXPECT_FALSE(ParseString(a, key, value)); } -TEST(Parse, ParseStringWithoutSeporator) +TEST(Parse, ParseStringWithoutSeparator) { string a = "qqqwww"; string key; diff --git a/samples/android/native-activity/src/org/opencv/samples/NativeActivity/CvNativeActivity.java b/samples/android/native-activity/src/org/opencv/samples/NativeActivity/CvNativeActivity.java index 04da9a9496..b9db22de1f 100644 --- a/samples/android/native-activity/src/org/opencv/samples/NativeActivity/CvNativeActivity.java +++ b/samples/android/native-activity/src/org/opencv/samples/NativeActivity/CvNativeActivity.java @@ -21,6 +21,7 @@ public class CvNativeActivity extends Activity { System.loadLibrary("native_activity"); Intent intent = new Intent(CvNativeActivity.this, android.app.NativeActivity.class); CvNativeActivity.this.startActivity(intent); + CvNativeActivity.this.finish(); } break; default: { @@ -34,7 +35,7 @@ public class CvNativeActivity extends Activity { Log.i(TAG, "Instantiated new " + this.getClass()); } - @Override + @Override public void onResume() { super.onResume(); diff --git a/samples/android/tutorial-4-cuda/CMakeLists.txt b/samples/android/tutorial-4-cuda/CMakeLists.txt index a011b33492..da9fe9871d 100644 --- a/samples/android/tutorial-4-cuda/CMakeLists.txt +++ b/samples/android/tutorial-4-cuda/CMakeLists.txt @@ -1,15 +1,16 @@ set(sample example-tutorial-4-cuda) -ocv_check_dependencies(opencv_core opencv_java opencv_gpu) +ocv_check_dependencies(opencv_core opencv_features2d opencv_java opencv_gpu) if (OCV_DEPENDENCIES_FOUND) if(BUILD_FAT_JAVA_LIB) set(native_deps opencv_java opencv_gpu) else() - set(native_deps opencv_gpu) + set(native_deps opencv_core opencv_features2d opencv_java opencv_gpu) endif() - add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11 ${ANDROID_SDK_TARGET} NATIVE_DEPS ${native_deps}) + add_android_project(${sample} "${CMAKE_CURRENT_SOURCE_DIR}" LIBRARY_DEPS ${OpenCV_BINARY_DIR} SDK_TARGET 11 ${ANDROID_SDK_TARGET} NATIVE_DEPS ${native_deps} EMBED_CUDA ON FORCE_EMBED_OPENCV ON) + if(TARGET ${sample}) add_dependencies(opencv_android_examples ${sample}) endif() diff --git a/samples/android/tutorial-4-cuda/jni/Android.mk b/samples/android/tutorial-4-cuda/jni/Android.mk index 3d709dff3b..e14b1990f2 100644 --- a/samples/android/tutorial-4-cuda/jni/Android.mk +++ b/samples/android/tutorial-4-cuda/jni/Android.mk @@ -2,6 +2,8 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) +INSTALL_CUDA_LIBRARIES:=on +OPENCV_INSTALL_MODULES:=on CUDA_TOOLKIT_DIR=$(CUDA_TOOLKIT_ROOT) include ../../sdk/native/jni/OpenCV.mk diff --git a/samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java b/samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java index c1753b68cc..6a8cb5ec04 100644 --- a/samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java +++ b/samples/android/tutorial-4-cuda/src/org/opencv/samples/tutorial4/Tutorial4Activity.java @@ -49,29 +49,6 @@ public class Tutorial4Activity extends Activity implements CvCameraViewListener2 { Log.i(TAG, "OpenCV loaded successfully"); - // Check CUDA support - if (Gpu.getCudaEnabledDeviceCount() <= 0) - { - Log.e(TAG, "No CUDA capable device found!"); - AlertDialog InitFailedDialog = new AlertDialog.Builder(Tutorial4Activity.this).create(); - InitFailedDialog.setTitle("OpenCV CUDA error"); - InitFailedDialog.setMessage("CUDA compatible device was not found!"); - InitFailedDialog.setCancelable(false); // This blocks the 'BACK' button - InitFailedDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new OnClickListener() { - - public void onClick(DialogInterface dialog, int which) { - Tutorial4Activity.this.finish(); - } - }); - InitFailedDialog.show(); - } - else - { - // Load native library after(!) OpenCV initialization - Log.i(TAG, "Found CUDA capable device!"); - System.loadLibrary("cuda_sample"); - mOpenCvCameraView.enableView(); - } } break; default: { @@ -120,7 +97,32 @@ public class Tutorial4Activity extends Activity implements CvCameraViewListener2 public void onResume() { super.onResume(); - OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_8, this, mLoaderCallback); + if (OpenCVLoader.initDebug(true)) + { + // Check CUDA support + if (Gpu.getCudaEnabledDeviceCount() <= 0) + { + Log.e(TAG, "No CUDA capable device found!"); + AlertDialog InitFailedDialog = new AlertDialog.Builder(Tutorial4Activity.this).create(); + InitFailedDialog.setTitle("OpenCV CUDA error"); + InitFailedDialog.setMessage("CUDA compatible device was not found!"); + InitFailedDialog.setCancelable(false); // This blocks the 'BACK' button + InitFailedDialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Tutorial4Activity.this.finish(); + } + }); + InitFailedDialog.show(); + } + else + { + // Load native library after(!) OpenCV initialization + Log.i(TAG, "Found CUDA capable device!"); + System.loadLibrary("cuda_sample"); + mOpenCvCameraView.enableView(); + } + + } } public void onDestroy() { diff --git a/samples/c/CMakeLists.txt b/samples/c/CMakeLists.txt index ab6e15dbf2..6d374e7443 100644 --- a/samples/c/CMakeLists.txt +++ b/samples/c/CMakeLists.txt @@ -54,6 +54,6 @@ endif() if (INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB C_SAMPLES *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) install(FILES ${C_SAMPLES} - DESTINATION share/OpenCV/samples/c + DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/c PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples) endif () diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index e0842d9e4a..1f55ed90f3 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -82,6 +82,8 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) ocv_list_filterout(cpp_samples "/gpu/") endif() + ocv_list_filterout(cpp_samples "viz") + foreach(sample_filename ${cpp_samples}) get_filename_component(sample ${sample_filename} NAME_WE) OPENCV_DEFINE_CPP_EXAMPLE(${sample} ${sample_filename}) @@ -91,6 +93,6 @@ endif() if (INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB C_SAMPLES *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) install(FILES ${C_SAMPLES} - DESTINATION share/OpenCV/samples/cpp + DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/cpp PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples) endif() diff --git a/samples/cpp/Qt_sample/CMakeLists.txt b/samples/cpp/Qt_sample/CMakeLists.txt index e831f752f6..f465947dbc 100644 --- a/samples/cpp/Qt_sample/CMakeLists.txt +++ b/samples/cpp/Qt_sample/CMakeLists.txt @@ -7,6 +7,6 @@ FIND_PACKAGE( OpenCV REQUIRED ) find_package (OpenGL REQUIRED) -ADD_EXECUTABLE(OpenGL_Qt_Binding main.cpp) +ADD_EXECUTABLE(OpenGL_Qt_Binding qt_opengl.cpp) TARGET_LINK_LIBRARIES(OpenGL_Qt_Binding ${OpenCV_LIBS} ${OPENGL_LIBRARIES} ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cube4.avi ${CMAKE_CURRENT_BINARY_DIR}/cube4.avi COPYONLY) diff --git a/samples/cpp/Qt_sample/main.cpp b/samples/cpp/Qt_sample/main.cpp deleted file mode 100644 index 6969544a0c..0000000000 --- a/samples/cpp/Qt_sample/main.cpp +++ /dev/null @@ -1,275 +0,0 @@ -//Yannick Verdie 2010 - -//--- Please read help() below: --- - -#include -#include - -#include -#include -#include -#include -#include - -#if defined WIN32 || defined _WIN32 || defined WINCE - #include - #undef small - #undef min - #undef max - #undef abs -#endif - -#ifdef __APPLE__ - #include -#else - #include -#endif - -using namespace std; -using namespace cv; - -static void help() -{ - cout << "\nThis demo demonstrates the use of the Qt enhanced version of the highgui GUI interface\n" - " and dang if it doesn't throw in the use of of the POSIT 3D tracking algorithm too\n" - "It works off of the video: cube4.avi\n" - "Using OpenCV version %s\n" << CV_VERSION << "\n\n" -" 1). This demo is mainly based on work from Javier Barandiaran Martirena\n" -" See this page http://code.opencv.org/projects/opencv/wiki/Posit.\n" -" 2). This is a demo to illustrate how to use **OpenGL Callback**.\n" -" 3). You need Qt binding to compile this sample with OpenGL support enabled.\n" -" 4). The features' detection is very basic and could highly be improved \n" -" (basic thresholding tuned for the specific video) but 2).\n" -" 5) THANKS TO Google Summer of Code 2010 for supporting this work!\n" << endl; -} - -#define FOCAL_LENGTH 600 -#define CUBE_SIZE 10 - -static void renderCube(float size) -{ - glBegin(GL_QUADS); - // Front Face - glNormal3f( 0.0f, 0.0f, 1.0f); - glVertex3f( 0.0f, 0.0f, 0.0f); - glVertex3f( size, 0.0f, 0.0f); - glVertex3f( size, size, 0.0f); - glVertex3f( 0.0f, size, 0.0f); - // Back Face - glNormal3f( 0.0f, 0.0f,-1.0f); - glVertex3f( 0.0f, 0.0f, size); - glVertex3f( 0.0f, size, size); - glVertex3f( size, size, size); - glVertex3f( size, 0.0f, size); - // Top Face - glNormal3f( 0.0f, 1.0f, 0.0f); - glVertex3f( 0.0f, size, 0.0f); - glVertex3f( size, size, 0.0f); - glVertex3f( size, size, size); - glVertex3f( 0.0f, size, size); - // Bottom Face - glNormal3f( 0.0f,-1.0f, 0.0f); - glVertex3f( 0.0f, 0.0f, 0.0f); - glVertex3f( 0.0f, 0.0f, size); - glVertex3f( size, 0.0f, size); - glVertex3f( size, 0.0f, 0.0f); - // Right face - glNormal3f( 1.0f, 0.0f, 0.0f); - glVertex3f( size, 0.0f, 0.0f); - glVertex3f( size, 0.0f, size); - glVertex3f( size, size, size); - glVertex3f( size, size, 0.0f); - // Left Face - glNormal3f(-1.0f, 0.0f, 0.0f); - glVertex3f( 0.0f, 0.0f, 0.0f); - glVertex3f( 0.0f, size, 0.0f); - glVertex3f( 0.0f, size, size); - glVertex3f( 0.0f, 0.0f, size); - glEnd(); -} - - -static void on_opengl(void* param) -{ - //Draw the object with the estimated pose - glLoadIdentity(); - glScalef( 1.0f, 1.0f, -1.0f); - glMultMatrixf( (float*)param ); - glEnable( GL_LIGHTING ); - glEnable( GL_LIGHT0 ); - glEnable( GL_BLEND ); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - renderCube( CUBE_SIZE ); - glDisable(GL_BLEND); - glDisable( GL_LIGHTING ); -} - -static void initPOSIT(std::vector *modelPoints) -{ - //Create the model pointss - modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, 0.0f)); //The first must be (0,0,0) - modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, CUBE_SIZE)); - modelPoints->push_back(cvPoint3D32f(CUBE_SIZE, 0.0f, 0.0f)); - modelPoints->push_back(cvPoint3D32f(0.0f, CUBE_SIZE, 0.0f)); -} - -static void foundCorners(vector *srcImagePoints, const Mat& source, Mat& grayImage) -{ - cvtColor(source, grayImage, COLOR_RGB2GRAY); - GaussianBlur(grayImage, grayImage, Size(11,11), 0, 0); - normalize(grayImage, grayImage, 0, 255, NORM_MINMAX); - threshold(grayImage, grayImage, 26, 255, THRESH_BINARY_INV); //25 - - Mat MgrayImage = grayImage; - //For debug - //MgrayImage = MgrayImage.clone();//deep copy - vector > contours; - vector hierarchy; - findContours(MgrayImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); - - Point p; - vector srcImagePoints_temp(4,cvPoint2D32f(0,0)); - - if (contours.size() == srcImagePoints_temp.size()) - { - - for(size_t i = 0 ; i y = 0 - //> x = 1 - //< x = 2 - //< y = 3 - - //get point 0; - size_t index = 0; - for(size_t i = 1 ; i srcImagePoints_temp.at(index).y) - index = i; - } - srcImagePoints->at(0) = srcImagePoints_temp.at(index); - - //get point 1; - index = 0; - for(size_t i = 1 ; i srcImagePoints_temp.at(index).x) - index = i; - } - srcImagePoints->at(1) = srcImagePoints_temp.at(index); - - //get point 2; - index = 0; - for(size_t i = 1 ; iat(2) = srcImagePoints_temp.at(index); - - //get point 3; - index = 0; - for(size_t i = 1 ; iat(3) = srcImagePoints_temp.at(index); - - Mat Msource = source; - stringstream ss; - for(size_t i = 0 ; iat(i),5,Scalar(0,0,255)); - putText(Msource,ss.str(),srcImagePoints->at(i),FONT_HERSHEY_SIMPLEX,1,Scalar(0,0,255)); - ss.str(""); - - //new coordinate system in the middle of the frame and reversed (camera coordinate system) - srcImagePoints->at(i) = cvPoint2D32f(srcImagePoints_temp.at(i).x-source.cols/2,source.rows/2-srcImagePoints_temp.at(i).y); - } - } - -} - -static void createOpenGLMatrixFrom(float *posePOSIT,const CvMatr32f &rotationMatrix, const CvVect32f &translationVector) -{ - - - //coordinate system returned is relative to the first 3D input point - for (int f=0; f<3; f++) - { - for (int c=0; c<3; c++) - { - posePOSIT[c*4+f] = rotationMatrix[f*3+c]; //transposed - } - } - posePOSIT[3] = 0.0; - posePOSIT[7] = 0.0; - posePOSIT[11] = 0.0; - posePOSIT[12] = translationVector[0]; - posePOSIT[13] = translationVector[1]; - posePOSIT[14] = translationVector[2]; - posePOSIT[15] = 1.0; -} - -int main(void) -{ - help(); - VideoCapture video("cube4.avi"); - CV_Assert(video.isOpened()); - - Mat source, grayImage; - - video >> source; - - namedWindow("original", WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO); - namedWindow("POSIT", WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO); - displayOverlay("POSIT", "We lost the 4 corners' detection quite often (the red circles disappear). This demo is only to illustrate how to use OpenGL callback.\n -- Press ESC to exit.", 10000); - - float OpenGLMatrix[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - setOpenGlDrawCallback("POSIT",on_opengl,OpenGLMatrix); - - vector modelPoints; - initPOSIT(&modelPoints); - - //Create the POSIT object with the model points - CvPOSITObject* positObject = cvCreatePOSITObject( &modelPoints[0], (int)modelPoints.size() ); - - CvMatr32f rotation_matrix = new float[9]; - CvVect32f translation_vector = new float[3]; - CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 100, 1.0e-4f); - - vector srcImagePoints(4,cvPoint2D32f(0,0)); - - - while(waitKey(33) != 27) - { - video >> source; - imshow("original",source); - - foundCorners(&srcImagePoints,source,grayImage); - cvPOSIT( positObject, &srcImagePoints[0], FOCAL_LENGTH, criteria, rotation_matrix, translation_vector ); - createOpenGLMatrixFrom(OpenGLMatrix,rotation_matrix,translation_vector); - - imshow("POSIT",source); - - if (video.get(CV_CAP_PROP_POS_AVI_RATIO) > 0.99) - video.set(CV_CAP_PROP_POS_AVI_RATIO, 0); - } - - destroyAllWindows(); - cvReleasePOSITObject(&positObject); - - return 0; -} diff --git a/samples/cpp/Qt_sample/qt_opengl.cpp b/samples/cpp/Qt_sample/qt_opengl.cpp new file mode 100644 index 0000000000..2878da4c00 --- /dev/null +++ b/samples/cpp/Qt_sample/qt_opengl.cpp @@ -0,0 +1,268 @@ +// Yannick Verdie 2010 +// --- Please read help() below: --- + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +using namespace std; +using namespace cv; + +static void help() +{ + cout << "This demo demonstrates the use of the Qt enhanced version of the highgui GUI interface\n" + "and dang if it doesn't throw in the use of of the POSIT 3D tracking algorithm too\n" + "It works off of the video: cube4.avi\n" + "Using OpenCV version " << CV_VERSION << "\n\n" + + " 1) This demo is mainly based on work from Javier Barandiaran Martirena\n" + " See this page http://code.opencv.org/projects/opencv/wiki/Posit.\n" + " 2) This is a demo to illustrate how to use **OpenGL Callback**.\n" + " 3) You need Qt binding to compile this sample with OpenGL support enabled.\n" + " 4) The features' detection is very basic and could highly be improved\n" + " (basic thresholding tuned for the specific video) but 2).\n" + " 5) Thanks to Google Summer of Code 2010 for supporting this work!\n" << endl; +} + +#define FOCAL_LENGTH 600 +#define CUBE_SIZE 0.5 + +static void renderCube(float size) +{ + glBegin(GL_QUADS); + // Front Face + glNormal3f( 0.0f, 0.0f, 1.0f); + glVertex3f( 0.0f, 0.0f, 0.0f); + glVertex3f( size, 0.0f, 0.0f); + glVertex3f( size, size, 0.0f); + glVertex3f( 0.0f, size, 0.0f); + // Back Face + glNormal3f( 0.0f, 0.0f,-1.0f); + glVertex3f( 0.0f, 0.0f, size); + glVertex3f( 0.0f, size, size); + glVertex3f( size, size, size); + glVertex3f( size, 0.0f, size); + // Top Face + glNormal3f( 0.0f, 1.0f, 0.0f); + glVertex3f( 0.0f, size, 0.0f); + glVertex3f( size, size, 0.0f); + glVertex3f( size, size, size); + glVertex3f( 0.0f, size, size); + // Bottom Face + glNormal3f( 0.0f,-1.0f, 0.0f); + glVertex3f( 0.0f, 0.0f, 0.0f); + glVertex3f( 0.0f, 0.0f, size); + glVertex3f( size, 0.0f, size); + glVertex3f( size, 0.0f, 0.0f); + // Right face + glNormal3f( 1.0f, 0.0f, 0.0f); + glVertex3f( size, 0.0f, 0.0f); + glVertex3f( size, 0.0f, size); + glVertex3f( size, size, size); + glVertex3f( size, size, 0.0f); + // Left Face + glNormal3f(-1.0f, 0.0f, 0.0f); + glVertex3f( 0.0f, 0.0f, 0.0f); + glVertex3f( 0.0f, size, 0.0f); + glVertex3f( 0.0f, size, size); + glVertex3f( 0.0f, 0.0f, size); + glEnd(); +} + +static void on_opengl(void* param) +{ + //Draw the object with the estimated pose + glLoadIdentity(); + glScalef( 1.0f, 1.0f, -1.0f); + glMultMatrixf( (float*)param ); + glEnable( GL_LIGHTING ); + glEnable( GL_LIGHT0 ); + glEnable( GL_BLEND ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + renderCube( CUBE_SIZE ); + glDisable(GL_BLEND); + glDisable( GL_LIGHTING ); +} + +static void initPOSIT(std::vector * modelPoints) +{ + // Create the model pointss + modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, 0.0f)); // The first must be (0, 0, 0) + modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, CUBE_SIZE)); + modelPoints->push_back(cvPoint3D32f(CUBE_SIZE, 0.0f, 0.0f)); + modelPoints->push_back(cvPoint3D32f(0.0f, CUBE_SIZE, 0.0f)); +} + +static void foundCorners(vector * srcImagePoints, const Mat & source, Mat & grayImage) +{ + cvtColor(source, grayImage, COLOR_RGB2GRAY); + GaussianBlur(grayImage, grayImage, Size(11, 11), 0, 0); + normalize(grayImage, grayImage, 0, 255, NORM_MINMAX); + threshold(grayImage, grayImage, 26, 255, THRESH_BINARY_INV); //25 + + Mat MgrayImage = grayImage; + vector > contours; + vector hierarchy; + findContours(MgrayImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); + + Point p; + vector srcImagePoints_temp(4, cvPoint2D32f(0, 0)); + + if (contours.size() == srcImagePoints_temp.size()) + { + for (size_t i = 0; i < contours.size(); i++ ) + { + p.x = p.y = 0; + + for (size_t j = 0 ; j < contours[i].size(); j++) + p += contours[i][j]; + + srcImagePoints_temp.at(i) = cvPoint2D32f(float(p.x) / contours[i].size(), float(p.y) / contours[i].size()); + } + + // Need to keep the same order + // > y = 0 + // > x = 1 + // < x = 2 + // < y = 3 + + // get point 0; + size_t index = 0; + for (size_t i = 1 ; i srcImagePoints_temp.at(index).y) + index = i; + srcImagePoints->at(0) = srcImagePoints_temp.at(index); + + // get point 1; + index = 0; + for (size_t i = 1 ; i srcImagePoints_temp.at(index).x) + index = i; + srcImagePoints->at(1) = srcImagePoints_temp.at(index); + + // get point 2; + index = 0; + for (size_t i = 1 ; iat(2) = srcImagePoints_temp.at(index); + + // get point 3; + index = 0; + for (size_t i = 1 ; iat(3) = srcImagePoints_temp.at(index); + + Mat Msource = source; + stringstream ss; + for (size_t i = 0; iat(i), 5, Scalar(0, 0, 255)); + putText(Msource, ss.str(), srcImagePoints->at(i), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255)); + ss.str(""); + + // new coordinate system in the middle of the frame and reversed (camera coordinate system) + srcImagePoints->at(i) = cvPoint2D32f(srcImagePoints_temp.at(i).x - source.cols / 2, + source.rows / 2 - srcImagePoints_temp.at(i).y); + } + } +} + +static void createOpenGLMatrixFrom(float * posePOSIT, const CvMatr32f & rotationMatrix, + const CvVect32f & translationVector) +{ + // coordinate system returned is relative to the first 3D input point + for (int f = 0; f < 3; f++) + for (int c = 0; c < 3; c++) + posePOSIT[c * 4 + f] = rotationMatrix[f * 3 + c]; // transposed + + posePOSIT[3] = translationVector[0]; + posePOSIT[7] = translationVector[1]; + posePOSIT[11] = translationVector[2]; + posePOSIT[12] = 0.0f; + posePOSIT[13] = 0.0f; + posePOSIT[14] = 0.0f; + posePOSIT[15] = 1.0f; +} + +int main(void) +{ + help(); + + string fileName = "cube4.avi"; + VideoCapture video(fileName); + if (!video.isOpened()) + { + cerr << "Video file " << fileName << " could not be opened" << endl; + return EXIT_FAILURE; + } + + Mat source, grayImage; + video >> source; + + namedWindow("Original", WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO); + namedWindow("POSIT", WINDOW_OPENGL | CV_WINDOW_FREERATIO); + resizeWindow("POSIT", source.cols, source.rows); + + displayOverlay("POSIT", "We lost the 4 corners' detection quite often (the red circles disappear).\n" + "This demo is only to illustrate how to use OpenGL callback.\n" + " -- Press ESC to exit.", 10000); + + float OpenGLMatrix[] = { 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 }; + setOpenGlContext("POSIT"); + setOpenGlDrawCallback("POSIT", on_opengl, OpenGLMatrix); + + vector modelPoints; + initPOSIT(&modelPoints); + + // Create the POSIT object with the model points + CvPOSITObject* positObject = cvCreatePOSITObject( &modelPoints[0], (int)modelPoints.size()); + + CvMatr32f rotation_matrix = new float[9]; + CvVect32f translation_vector = new float[3]; + CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 100, 1e-4f); + vector srcImagePoints(4, cvPoint2D32f(0, 0)); + + while (waitKey(33) != 27) + { + video >> source; + if (source.empty()) + break; + + imshow("Original", source); + + foundCorners(&srcImagePoints, source, grayImage); + cvPOSIT(positObject, &srcImagePoints[0], FOCAL_LENGTH, criteria, rotation_matrix, translation_vector); + createOpenGLMatrixFrom(OpenGLMatrix, rotation_matrix, translation_vector); + + updateWindow("POSIT"); + + if (video.get(CV_CAP_PROP_POS_AVI_RATIO) > 0.99) + video.set(CV_CAP_PROP_POS_AVI_RATIO, 0); + } + + setOpenGlDrawCallback("POSIT", NULL, NULL); + destroyAllWindows(); + cvReleasePOSITObject(&positObject); + + delete[]rotation_matrix; + delete[]translation_vector; + + return EXIT_SUCCESS; +} diff --git a/samples/cpp/stitching_detailed.cpp b/samples/cpp/stitching_detailed.cpp index 7394a72821..4162addb38 100644 --- a/samples/cpp/stitching_detailed.cpp +++ b/samples/cpp/stitching_detailed.cpp @@ -355,7 +355,7 @@ int main(int argc, char* argv[]) Ptr finder; if (features_type == "surf") { -#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) if (try_gpu && gpu::getCudaEnabledDeviceCount() > 0) finder = new SurfFeaturesFinderGpu(); else @@ -543,7 +543,7 @@ int main(int argc, char* argv[]) // Warp images and their masks Ptr warper_creator; -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) if (try_gpu && gpu::getCudaEnabledDeviceCount() > 0) { if (warp_type == "plane") warper_creator = new cv::PlaneWarperGpu(); @@ -608,7 +608,7 @@ int main(int argc, char* argv[]) seam_finder = new detail::VoronoiSeamFinder(); else if (seam_find_type == "gc_color") { -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) if (try_gpu && gpu::getCudaEnabledDeviceCount() > 0) seam_finder = new detail::GraphCutSeamFinderGpu(GraphCutSeamFinderBase::COST_COLOR); else @@ -617,7 +617,7 @@ int main(int argc, char* argv[]) } else if (seam_find_type == "gc_colorgrad") { -#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID) +#if defined(HAVE_OPENCV_GPU) if (try_gpu && gpu::getCudaEnabledDeviceCount() > 0) seam_finder = new detail::GraphCutSeamFinderGpu(GraphCutSeamFinderBase::COST_COLOR_GRAD); else diff --git a/samples/cpp/tutorial_code/viz/bunny.ply b/samples/cpp/tutorial_code/viz/bunny.ply new file mode 100644 index 0000000000..7d34233395 --- /dev/null +++ b/samples/cpp/tutorial_code/viz/bunny.ply @@ -0,0 +1,5752 @@ +ply +format ascii 1.0 +comment zipper output +element vertex 1889 +property float x +property float y +property float z +property float confidence +property float intensity +element face 3851 +property list uchar int vertex_indices +end_header +-0.0369122 0.127512 0.00276757 0.850855 0.5 +-0.0457707 0.130327 0.00306785 0.900159 0.5 +-0.0708847 0.149834 0.0388672 0.398443 0.5 +-0.00331557 0.130403 0.0212208 0.85268 0.5 +-0.0211979 0.1272 0.00915278 0.675938 0.5 +-0.0265255 0.12592 0.00874866 0.711533 0.5 +0.0339261 0.112038 0.0269672 0.652757 0.5 +0.0376485 0.110455 0.0145481 0.708171 0.5 +-0.0259368 0.111118 0.0379115 0.454541 0.437538 +0.027952 0.120939 0.0215377 0.533079 0.5 +-0.0628308 0.155987 -0.0150105 0.404517 0.5 +0.0390029 0.106711 0.0215202 0.535542 0.5 +0.0447976 0.0950477 0.00866471 0.579563 0.425995 +-0.0330636 0.173619 -0.0031267 0.365607 0.5 +-0.0808069 0.136243 0.0495014 0.499575 0.5 +-0.0705086 0.12445 0.0526685 0.564827 0.5 +0.00874873 0.131225 0.0145345 0.748371 0.5 +0.0401015 0.106711 0.00874166 0.680399 0.5 +0.0379483 0.100145 -0.00827134 0.600054 0.5 +-0.0906538 0.137201 0.0207305 0.824561 0.5 +-0.0841655 0.110667 0.0275273 0.690889 0.5 +-0.0705214 0.156214 0.0144536 0.807492 0.5 +-0.083872 0.15212 0.0282652 0.248168 0.41865 +0.00305028 0.12432 0.0332425 0.555044 0.354559 +0.00870828 0.124165 0.0330348 0.653433 0.5 +-0.0328896 0.12613 0.00300653 0.898771 0.5 +-0.0506302 0.143065 0.0150611 0.691477 0.5 +-0.0757863 0.13637 0.050172 0.566256 0.5 +-0.0027191 0.128962 0.0264678 0.271491 0.462815 +-0.0460961 0.125118 0.0263142 0.539149 0.5 +-0.0785104 0.0942728 -0.0109192 0.710999 0.5 +0.0216915 0.125373 0.0211452 0.530957 0.5 +-0.0888469 0.124305 0.00237041 0.635593 0.5 +0.040386 0.100825 -0.00303043 0.574857 0.5 +-0.0884145 0.117791 0.00268555 0.487167 0.430737 +-0.0319074 0.177421 -0.00491879 0.269231 0.447035 +-0.0765825 0.143224 0.0455148 0.414139 0.5 +-0.0209748 0.112544 0.0388613 0.482541 0.5 +-0.020836 0.179425 -0.0221622 0.341071 0.440034 +-0.0377039 0.167987 -0.0130391 0.396317 0.473039 +-0.0331765 0.12681 0.00839958 0.896274 0.5 +0.00893926 0.127114 0.0292916 0.350014 0.41288 +-0.044944 0.131083 0.0147963 0.599596 0.5 +-0.0266041 0.12515 0.00282384 0.73687 0.5 +0.0144285 0.12328 0.0319185 0.625269 0.5 +0.019244 0.122284 0.0308314 0.611204 0.34486 +-0.0390225 0.167317 0.00215527 0.413994 0.469929 +-0.08808 0.129976 0.00206377 0.625486 0.5 +-0.0537203 0.142608 0.0266058 0.696873 0.5 +0.043095 0.0980072 0.0191617 0.665192 0.5 +0.0432138 0.100117 0.00866473 0.691828 0.5 +0.0415448 0.0944954 0.0275695 0.671611 0.5 +-0.0578726 0.155337 0.0149245 0.394763 0.437313 +-0.0231577 0.157375 -0.0046304 0.136389 0.380194 +-0.0683123 0.145735 0.0420568 0.751812 0.5 +-0.0708351 0.142847 0.0451248 0.627973 0.5 +-0.070664 0.0642894 0.0209789 0.413051 0.5 +-0.0761519 0.130581 0.0525324 0.629117 0.5 +-0.0640036 0.161784 -0.0208118 0.449093 0.5 +-0.0706461 0.155711 0.00252406 0.855717 0.5 +-0.0924366 0.118434 0.0399838 0.673877 0.5 +-0.0635349 0.156052 0.0148814 0.798496 0.5 +0.0282675 0.118192 0.0274382 0.635485 0.5 +0.0392736 0.0938857 -0.00915453 0.585857 0.459742 +-0.0695973 0.164844 -0.0174846 0.548789 0.5 +-0.00892354 0.123904 0.0330319 0.602316 0.374044 +0.0269099 0.0942476 0.0444911 0.649753 0.5 +-0.0146258 0.162377 -0.0144398 0.338176 0.5 +-0.0450983 0.167072 0.00289327 0.449091 0.5 +-0.0761536 0.172742 -0.0384391 0.256591 0.4298 +-0.0858274 0.105458 0.00472318 0.523819 0.297125 +0.0370431 0.110443 0.0207229 0.52623 0.448558 +0.0321593 0.0994027 0.0380657 0.733041 0.5 +-0.075287 0.146433 0.0428582 0.424358 0.5 +-0.0395145 0.171107 0.000531747 0.452893 0.5 +-0.0839586 0.11215 0.00148754 0.436727 0.419097 +0.0446848 0.0883378 0.0216285 0.487783 0.481728 +0.0161783 0.127819 0.0220535 0.481793 0.5 +-0.00251635 0.0397232 0.0474087 0.280725 0.5 +0.00303163 0.0406968 0.0460422 0.331809 0.5 +-0.0143059 0.128197 0.00333856 0.693854 0.5 +-0.0526117 0.155596 0.0109972 0.561042 0.5 +-0.0332043 0.17776 -0.00906223 0.212789 0.5 +0.0394391 0.106654 0.00306577 0.522321 0.489889 +-0.0923799 0.1249 0.0327641 0.848517 0.5 +0.0454681 0.0882959 0.0146642 0.575503 0.5 +-0.0274495 0.179802 -0.00925837 0.258799 0.457369 +-0.072504 0.146297 0.0429682 0.549207 0.5 +-0.0579959 0.129793 0.0383118 0.658867 0.444043 +0.043117 0.0923689 0.0251649 0.622686 0.5 +-0.00865718 0.130323 0.0149721 0.633691 0.5 +-0.0141304 0.129188 0.0147431 0.547632 0.5 +-0.0707877 0.15583 0.00921954 0.739059 0.5 +-0.00952731 0.127041 0.0281475 0.375412 0.377874 +-0.0646289 0.153404 0.0329146 0.855321 0.5 +-0.0706939 0.15347 0.0328596 0.444959 0.455263 +0.0208126 0.118434 0.0336393 0.519282 0.5 +-0.0396566 0.173008 -0.00299705 0.274377 0.177706 +-0.0442176 0.170815 -0.00391429 0.245926 0.5 +-0.0582565 0.0395149 0.0457796 0.417977 0.459314 +-0.0523033 0.0401501 0.04623 0.454776 0.456044 +-0.0760211 0.161274 -0.0145891 0.267801 0.372187 +-0.0693983 0.163016 -0.0140293 0.403228 0.45768 +0.0399663 0.106491 0.014952 0.713602 0.5 +0.041536 0.0950084 -0.00475737 0.490139 0.464008 +-0.0470079 0.163779 0.00528295 0.432857 0.486946 +-0.0402546 0.161678 0.00298655 0.447592 0.5 +-0.0386569 0.0389805 0.0441153 0.509262 0.5 +-0.0704175 0.166991 -0.0216976 0.332592 0.447054 +-0.0254201 0.0886622 0.0503827 0.608282 0.5 +-0.0886334 0.137429 0.00876953 0.549009 0.5 +-0.014179 0.12627 0.0266417 0.420759 0.5 +-0.0360017 0.17408 -0.0118959 0.409753 0.289042 +-0.0886251 0.0937834 0.00823534 0.753697 0.5 +-0.0648672 0.155874 -0.00891497 0.595216 0.5 +-0.0704508 0.137752 -0.00774011 0.446131 0.5 +-0.0750154 0.166247 -0.0219558 0.263106 0.5 +0.0299465 0.114869 0.0300239 0.642356 0.5 +0.0398138 0.0998788 0.0273101 0.51725 0.5 +-0.015242 0.111698 0.0407424 0.605597 0.5 +-0.0700387 0.118219 0.0524379 0.585543 0.5 +0.0149973 0.112399 0.0386082 0.669811 0.5 +-0.036487 0.171225 0.000545037 0.438578 0.5 +-0.0641664 0.118551 -0.00968333 0.569796 0.5 +-0.071817 0.166979 -0.0463822 0.381568 0.451091 +-0.0913559 0.14534 0.0246937 0.648478 0.5 +0.00903703 0.112569 0.0396571 0.549283 0.408623 +0.0324674 0.0997396 -0.0141603 0.732658 0.5 +0.0417911 0.101845 0.00188609 0.547756 0.5 +0.00302992 0.112517 0.0415434 0.592572 0.5 +-0.0650368 0.148485 0.0382561 0.62562 0.5 +-0.0706519 0.13063 0.0502497 0.563116 0.5 +-0.0144471 0.128935 0.00903509 0.682121 0.5 +0.00292575 0.131541 0.00912318 0.795238 0.5 +-0.0625682 0.151125 0.035875 0.463512 0.5 +0.0349829 0.113328 0.0214487 0.620597 0.5 +0.021327 0.0385664 0.0392992 0.259499 0.426724 +0.0145125 0.093771 0.0501571 0.654705 0.5 +-0.00923752 0.112849 0.0413907 0.615633 0.5 +0.0415329 0.100906 0.0210277 0.662312 0.5 +0.0422859 0.101486 0.0146614 0.569693 0.490777 +-0.0773783 0.112839 -0.00448759 0.505277 0.5 +-0.078035 0.137641 -0.00517379 0.466714 0.5 +0.00873437 0.106347 -0.0202193 0.792948 0.5 +0.0090324 0.13035 0.0211569 0.465873 0.5 +0.00301322 0.130902 0.0206741 0.592486 0.5 +-0.00286342 0.13115 0.0147367 0.587804 0.5 +-0.0391578 0.12569 0.0207996 0.438744 0.464814 +-0.0205725 0.123523 0.0265579 0.445477 0.415699 +-0.0644194 0.155634 0.00928477 0.611624 0.331941 +-0.0463385 0.131411 0.0207671 0.674928 0.5 +-0.0532034 0.0439067 0.044658 0.417403 0.440199 +-0.00297651 0.131046 0.00884967 0.738924 0.5 +-0.089664 0.137755 0.0263925 0.80362 0.5 +-0.00888731 0.124273 -0.00880284 0.767738 0.284429 +-0.0460971 0.0385107 0.0446891 0.654962 0.5 +-0.0649255 0.178874 -0.0579325 0.245129 0.411885 +-0.0329347 0.124601 0.0211235 0.32811 0.5 +-0.0831301 0.149901 0.0334123 0.331963 0.314683 +-0.0895652 0.093948 0.0149303 0.603378 0.5 +-0.0328901 0.124518 -0.00282055 0.63839 0.5 +-0.0845271 0.106161 0.00204328 0.338681 0.43162 +-0.0469341 0.155816 0.00872921 0.470367 0.484595 +0.0206202 0.123943 0.0267275 0.477255 0.5 +-0.026256 0.117499 0.0321672 0.543293 0.5 +-0.021392 0.118632 0.0336445 0.468887 0.429556 +-0.0195069 0.116132 0.0368525 0.534732 0.411301 +-0.0761618 0.118382 0.0520923 0.490413 0.5 +0.00889281 0.0395765 0.0451727 0.476347 0.38769 +-0.0534736 0.159548 0.00753828 0.476667 0.5 +-0.0469464 0.161226 0.00680216 0.495992 0.483766 +-0.0574886 0.154862 0.0204748 0.677314 0.5 +0.0317199 0.117635 0.0202007 0.579556 0.5 +0.0378683 0.105514 -0.00259159 0.588286 0.5 +-0.0811847 0.137693 -0.00253994 0.641736 0.5 +-0.0764348 0.124515 0.0528345 0.65366 0.5 +0.0343816 0.106104 -0.00900254 0.534403 0.5 +0.0457922 0.088316 0.00867097 0.586292 0.439394 +-0.0703288 0.0944195 -0.0159143 0.511499 0.5 +-0.0756048 0.0937947 -0.0135536 0.429902 0.5 +-0.058657 0.156369 0.0093256 0.31374 0.5 +-0.0637335 0.153848 0.00222718 0.478676 0.5 +-0.0777278 0.0960024 0.0363437 0.678588 0.5 +-0.0868519 0.136556 0.00309926 0.517441 0.5 +-0.0455299 0.0432404 0.0432162 0.712662 0.5 +-0.0402011 0.045749 0.0408051 0.669165 0.320516 +-0.0654123 0.160403 -0.0149066 0.335302 0.5 +-0.0318898 0.0387174 0.0510004 0.553401 0.5 +-0.0267997 0.0453977 0.0509311 0.501112 0.5 +-0.0271043 0.0396972 0.0535379 0.487956 0.5 +-0.0215575 0.0460868 0.0517209 0.709553 0.5 +-0.0143078 0.0445295 0.0504368 0.575852 0.5 +-0.00981594 0.043264 0.0493162 0.448927 0.393067 +-0.00348436 0.044054 0.0472086 0.598081 0.5 +0.009577 0.0458139 0.0465877 0.519814 0.433928 +0.02048 0.111086 0.0379569 0.681163 0.5 +-0.0141831 0.128547 0.0200007 0.293349 0.5 +-0.0526702 0.144108 0.0210347 0.639643 0.5 +-0.0634838 0.17384 -0.0527131 0.549906 0.5 +-0.0366553 0.171999 -0.0125745 0.436075 0.5 +-0.0525548 0.131228 0.0328277 0.727547 0.5 +-0.0659567 0.132023 0.0442925 0.724494 0.5 +-0.0921726 0.11832 0.0267606 0.794672 0.5 +0.0452792 0.0882737 0.00268175 0.507794 0.5 +-0.00305651 0.112889 0.0417789 0.635396 0.5 +-0.0451955 0.161396 -0.00871567 0.424682 0.5 +-0.0402914 0.160933 -0.0115368 0.411895 0.405943 +-0.0521414 0.0701165 0.0389584 0.682177 0.456916 +-0.0383315 0.093604 -0.0232581 0.72469 0.5 +-0.0690556 0.137374 0.046352 0.61723 0.5 +-0.0695996 0.167401 -0.0516299 0.518552 0.5 +-0.00246047 0.124102 0.0337609 0.444043 0.5 +-0.0398624 0.128204 0.00299348 0.864483 0.5 +-0.0753331 0.149032 0.0395625 0.432149 0.5 +-0.0701432 0.160618 -0.00917801 0.464361 0.5 +-0.0589378 0.0440425 0.0434222 0.437887 0.447715 +-0.0207164 0.126445 0.00312493 0.710427 0.5 +-0.00850666 0.0467286 0.0481052 0.613173 0.5 +0.00300323 0.0450308 0.0469911 0.464978 0.5 +-0.0802174 0.148665 0.0379438 0.47939 0.5 +-0.0819961 0.130698 0.0513437 0.54405 0.5 +0.00273088 0.106333 -0.0209927 0.733954 0.5 +-0.0757273 0.0885687 -0.0138399 0.397424 0.5 +-0.0698477 0.0882875 -0.0167823 0.420617 0.5 +-0.0668508 0.159243 -0.0102161 0.42216 0.440727 +-0.0226988 0.0885773 0.0536309 0.546444 0.5 +-0.00281419 0.0990077 0.0505614 0.455087 0.5 +0.0452902 0.0696213 0.0253974 0.33948 0.5 +-0.0525629 0.0472823 0.040482 0.279548 0.5 +-0.046959 0.0466581 0.0408127 0.43714 0.5 +-0.0691348 0.156682 -0.00276369 0.629099 0.5 +-0.0897599 0.150073 0.0220744 0.276354 0.5 +-0.0702883 0.155637 0.0263654 0.47565 0.441038 +-0.0765031 0.154893 0.0266005 0.799832 0.5 +-0.00804843 0.0987379 0.0505998 0.327523 0.438474 +0.0300791 0.11567 -0.00430465 0.66246 0.5 +-0.0923054 0.117757 0.0334441 0.476916 0.5 +-0.0331192 0.0449511 0.0462474 0.432059 0.466683 +-0.0337794 0.113308 0.034612 0.683562 0.5 +-0.0521291 0.113769 0.0349566 0.515399 0.5 +0.0437636 0.0825382 -0.0027974 0.568535 0.5 +-0.0202819 0.126016 0.0210507 0.374818 0.437592 +0.0327872 0.043925 0.0295904 0.650152 0.5 +-0.0453372 0.155266 -0.0075525 0.386286 0.5 +-0.0284609 0.173987 -0.0175958 0.379432 0.418735 +0.0268448 0.0881755 -0.0223077 0.715629 0.5 +-0.0308231 0.0923023 -0.0246377 0.474586 0.431409 +-0.0899732 0.149975 0.0141115 0.257143 0.5 +0.0381804 0.105121 0.0266947 0.534482 0.490368 +0.00842001 0.12907 0.0258154 0.374593 0.448613 +-0.0266549 0.0942999 -0.0265555 0.294426 0.332222 +-0.0279896 0.0475815 0.0485532 0.381268 0.5 +-0.0150037 0.048073 0.0483203 0.576068 0.5 +-0.00298993 0.0473817 0.0491102 0.446744 0.431743 +0.00376754 0.0477551 0.0502037 0.495901 0.44823 +0.00748504 0.0473851 0.0493363 0.494952 0.5 +-0.0581651 0.149751 0.032858 0.470966 0.5 +-0.0720688 0.136456 0.0490662 0.625357 0.5 +-0.0810638 0.0939541 -0.0082617 0.685573 0.5 +0.0380863 0.0458646 0.0307423 0.807573 0.5 +-0.0253234 0.182998 -0.0108168 0.245054 0.5 +-0.0230508 0.183235 -0.0110157 0.246322 0.458572 +0.00323317 0.129146 0.0263855 0.347796 0.441746 +-0.0626125 0.149788 -0.00343342 0.691705 0.5 +-0.0591471 0.0466998 0.0395843 0.0883466 0.213805 +-0.0353862 0.0471292 0.0414241 0.656538 0.5 +-0.0194948 0.0486404 0.0485565 0.373069 0.5 +-0.00849455 0.0521633 0.0517688 0.61481 0.5 +-0.00296485 0.051429 0.0527827 0.53012 0.5 +0.00279019 0.0517664 0.0528352 0.560812 0.423049 +0.00904034 0.0517165 0.051222 0.558244 0.5 +0.0443839 0.0943042 0.00268377 0.582116 0.455816 +-0.0886145 0.111113 0.0148415 0.604102 0.5 +-0.0885219 0.144027 0.0329221 0.623335 0.5 +0.0440719 0.0937787 0.0206165 0.493368 0.454688 +0.0436531 0.0980341 0.0146596 0.668233 0.5 +-0.0650976 0.153799 -0.00285808 0.715743 0.5 +-0.0517297 0.0490759 0.0371355 0 0 +-0.0331222 0.0518259 0.0385377 0.676102 0.5 +-0.0377352 0.127448 0.0152358 0.612182 0.5 +-0.00906608 0.100701 0.0460122 0.338462 0.5 +-0.0410683 0.128416 0.0134054 0.417331 0.5 +-0.0712056 0.158724 -0.00521868 0.246338 0.5 +-0.0266313 0.0501544 0.044695 0.182016 0.5 +-0.0211065 0.0519946 0.0455753 0.195646 0.404388 +-0.0168667 0.0505241 0.0476889 0.520032 0.5 +-0.0147601 0.0527687 0.050103 0.451613 0.5 +-0.0626395 0.149972 -0.00897733 0.363787 0.461156 +-0.090861 0.124732 0.00627835 0.587249 0.5 +-0.0255786 0.0923499 -0.0315595 0.294527 0.5 +-0.0709738 0.172947 -0.052768 0.460427 0.5 +-0.0588974 0.143232 -0.00327646 0.48145 0.5 +-0.0943643 0.12436 0.0216467 0.570519 0.5 +0.0337044 0.112449 -0.00269877 0.532211 0.5 +-0.0515051 0.136557 0.0263185 0.72719 0.5 +-0.00886593 0.121199 0.0360577 0.614897 0.5 +-0.061729 0.155665 -0.0259512 0.690546 0.5 +-0.0862637 0.10567 0.0206042 0.519516 0.5 +-0.0895584 0.138606 0.032689 0.685876 0.5 +-0.0268168 0.123904 0.0208113 0.428255 0.5 +0.0341937 0.0515433 0.033081 0.609925 0.5 +0.0401268 0.0512743 0.0322702 0.669803 0.5 +0.0449306 0.0526595 0.0319582 0.655209 0.5 +-0.0405348 0.117168 0.0319438 0.657986 0.5 +-0.0636902 0.155546 -0.0390642 0.523327 0.5 +0.0278663 0.100401 0.0410064 0.689793 0.5 +-0.0275828 0.179275 -0.0157605 0.314049 0.5 +-0.0758871 0.0942302 0.0383961 0.647987 0.457049 +0.0138371 0.129201 0.0203961 0.412341 0.5 +-0.0152723 0.0998429 0.0451638 0.271215 0.427554 +-0.00916763 0.129718 0.0206646 0.438679 0.430152 +-0.0512444 0.0516901 0.0334801 0.192432 0.5 +-0.0461563 0.0523184 0.0379981 0.311543 0.5 +-0.0410001 0.05272 0.0393793 0.629588 0.477809 +-0.0270993 0.0526642 0.0393104 0.155274 0.5 +0.0434924 0.0931097 -0.00154028 0.576953 0.480183 +-0.0823819 0.112683 0.045427 0.438131 0.5 +-0.092066 0.118055 0.00909937 0.325678 0.5 +-0.00448884 0.121713 0.0362976 0.591545 0.5 +0.0147346 0.129423 0.0143146 0.840212 0.5 +-0.0158113 0.161888 -0.00973584 0.202865 0.5 +-0.0778838 0.149704 -0.00337488 0.403345 0.5 +-0.0865357 0.12477 -0.00166991 0.677311 0.5 +0.0153656 0.126058 0.0275381 0.479299 0.429147 +-0.0388913 0.123761 0.0249778 0.514489 0.5 +-0.0390351 0.121238 0.0283673 0.510424 0.470651 +-0.0324963 0.120237 0.0283344 0.568849 0.348087 +-0.0149052 0.12311 0.0316417 0.446842 0.5 +-0.0582873 0.117688 0.0386719 0.634635 0.5 +-0.0626536 0.161861 -0.0264031 0.685413 0.5 +-0.0818147 0.141639 0.0444825 0.392929 0.5 +0.0350734 0.100071 0.0345975 0.716199 0.5 +0.0311856 0.11215 0.0310216 0.689434 0.5 +-0.0335778 0.11743 0.031458 0.525408 0.5 +-0.059637 0.153475 0.031348 0.93076 0.5 +-0.0481256 0.0536625 0.0362191 0.58186 0.5 +-0.059026 0.156388 0.00269852 0.133166 0.5 +-0.0211187 0.0578754 0.0461125 0.660553 0.5 +-0.082738 0.124721 0.050554 0.665202 0.5 +-0.0466997 0.11363 0.0348133 0.568902 0.5 +-0.0107262 0.179662 -0.0277472 0.400699 0.458536 +0.0347725 0.0894441 -0.0170339 0.702331 0.5 +-0.0891825 0.100351 0.0148945 0.574286 0.477791 +0.0257275 0.122894 0.0207337 0.498278 0.5 +-0.0883949 0.100277 0.00841226 0.477822 0.5 +-0.0649858 0.155518 0.0263367 0.864791 0.5 +-0.0768402 0.154073 0.00257877 0.57436 0.5 +-0.0576877 0.154146 0.0262123 0.402162 0.5 +-0.0266966 0.125729 0.0145923 0.393422 0.5 +-0.076376 0.155782 0.0208875 0.505065 0.5 +-0.0763295 0.167188 -0.039594 0.405226 0.426366 +-0.0771877 0.100229 -0.0103313 0.528684 0.5 +-0.0153681 0.0590839 0.0519909 0.652683 0.5 +-0.010206 0.0576345 0.0535443 0.781548 0.413019 +-0.00350044 0.0578672 0.0543757 0.774384 0.5 +0.00300818 0.0568916 0.0538692 0.704357 0.5 +0.0088308 0.0580497 0.0529859 0.692645 0.5 +0.0410915 0.0820775 -0.00893411 0.500391 0.430286 +0.0395449 0.0576373 0.0318985 0.612032 0.4505 +-0.0762443 0.139336 0.0484763 0.588653 0.42756 +-0.0324306 0.120379 -0.00955344 0.656019 0.5 +-0.0194451 0.0881559 0.0557639 0.449983 0.473992 +-0.074787 0.159471 -0.00898201 0.281303 0.5 +-0.0639935 0.15611 0.0210031 0.687157 0.5 +-0.0762438 0.153101 0.0322442 0.323875 0.45561 +-0.00876679 0.128727 0.025102 0.735708 0.5 +0.0282216 0.112237 -0.00983067 0.567922 0.385391 +-0.0451341 0.0593225 0.0387559 0.511245 0.5 +-0.0405005 0.0579499 0.040202 0.540369 0.5 +-0.033993 0.0584028 0.038704 0.646744 0.5 +-0.0272756 0.0585468 0.0382285 0.571263 0.5 +-0.0248608 0.122913 0.0245429 0.379391 0.5 +-0.0825276 0.154355 0.0206132 0.385494 0.444119 +-0.00884271 0.129403 0.00305159 0.702319 0.5 +0.0207587 0.126654 0.0147646 0.624434 0.5 +-0.0394868 0.173351 -0.00839443 0.199648 0.251821 +-0.028421 0.114019 0.0347746 0.603313 0.5 +-0.0193575 0.122009 0.0306737 0.55532 0.5 +-0.0691626 0.161675 -0.0514614 0.38665 0.5 +-0.0516736 0.15006 0.0148119 0.716684 0.5 +-0.0156325 0.120151 0.0349054 0.470635 0.336572 +0.0467454 0.0582319 0.0314404 0.576429 0.5 +-0.0770165 0.0685425 0.0147863 0.703257 0.5 +-0.00967101 0.173225 -0.0264945 0.379771 0.5 +-0.0213141 0.184813 -0.0151112 0.186313 0.403961 +-0.0766524 0.0882188 0.0382876 0.650646 0.5 +-0.0540219 0.0521463 0.0110698 0.270787 0.5 +-0.0219451 0.126821 0.0155536 0.534695 0.5 +-0.0820391 0.153392 0.0264506 0.292051 0.4047 +-0.0213183 0.124468 -0.00290836 0.782181 0.5 +-0.0268364 0.123465 -0.00321538 0.727949 0.5 +-0.0312035 0.177796 -0.0133521 0.371348 0.5 +-0.00749945 0.0598042 0.0553302 0.778631 0.5 +-0.00108951 0.0601245 0.0554892 0.776353 0.5 +0.00280202 0.0599746 0.0555283 0.768603 0.5 +-0.051797 0.118119 0.033678 0.677092 0.438456 +0.00302464 0.131618 0.0149353 0.692956 0.5 +0.0446005 0.0942619 0.0151198 0.554026 0.5 +-0.0880636 0.111855 0.00852285 0.304511 0.3924 +-0.0704321 0.144096 -0.0148369 0.130446 0.5 +-0.0820967 0.0943634 0.0322765 0.629357 0.5 +-0.0269642 0.120812 0.0275676 0.345323 0.386314 +-0.0540164 0.149968 0.0253393 0.49489 0.5 +-0.0800337 0.0995053 -0.00770139 0.499264 0.5 +0.00922138 0.12038 0.0360924 0.562107 0.5 +0.00286056 0.117968 0.0387331 0.649494 0.5 +-0.0936229 0.118494 0.0206524 0.664933 0.5 +-0.0409923 0.113229 0.035109 0.667726 0.5 +-0.0822185 0.154488 0.0146661 0.500539 0.5 +-0.0625956 0.155202 -0.0329876 0.814083 0.5 +-0.0462511 0.124621 -0.00898124 0.590842 0.5 +-0.0220336 0.160676 -0.00426008 0.309766 0.47069 +-0.065621 0.172767 -0.0466049 0.613718 0.5 +-0.0762614 0.155884 0.0148687 0.717415 0.5 +-0.0644988 0.149044 -0.0265159 0.690046 0.5 +-0.0581979 0.0593456 0.0210895 0.079935 0 +-0.0335439 0.122618 0.0254024 0.514037 0.5 +-0.0826578 0.153434 0.00921403 0.601617 0.5 +-0.049999 0.132417 0.0286961 0.650903 0.5 +0.0088217 0.131096 0.00864908 0.834131 0.5 +-0.0154842 0.0644282 0.0533754 0.608033 0.445048 +-0.00871951 0.065015 0.0556827 0.650491 0.470895 +-0.00324815 0.0640003 0.0562816 0.762387 0.5 +0.00292601 0.0643094 0.0563956 0.748671 0.5 +0.00738462 0.0651614 0.0553402 0.488299 0.46872 +-0.0143174 0.116971 0.037836 0.441459 0.5 +-0.00299223 0.118083 0.0390751 0.65526 0.5 +-0.00864301 0.117816 0.0385662 0.681198 0.5 +-0.0532884 0.0571719 0.0206631 0.106703 0 +-0.0882588 0.100387 0.0210097 0.535268 0.5 +-0.0324377 0.099703 -0.0227313 0.620611 0.5 +0.0425072 0.0603725 0.0302275 0.744481 0.5 +0.0523383 0.0580401 0.0290457 0.405493 0.41666 +0.0413612 0.0877503 -0.00929235 0.635782 0.5 +-0.0581547 0.0620148 0.0270981 0.448705 0.5 +-0.0530328 0.0590503 0.0266933 0.136202 0.5 +-0.0477227 0.135526 0.0148654 0.740469 0.5 +0.00323512 0.0983053 0.0504424 0.395048 0.366076 +0.0150627 0.119642 0.034806 0.696033 0.374342 +-0.0453373 0.0643061 0.0391142 0.587502 0.5 +-0.0394097 0.0644278 0.0414133 0.715885 0.5 +-0.033068 0.0642666 0.0396407 0.650585 0.5 +-0.0270237 0.0644489 0.0395335 0.617817 0.5 +-0.0881604 0.149479 0.0268507 0.265855 0.5 +-0.0640727 0.143434 -0.00894036 0.668887 0.5 +0.00286033 0.121151 0.036139 0.623932 0.5 +-0.0827306 0.138152 0.0466993 0.412428 0.5 +-0.00261511 0.127006 0.030132 0.335862 0.5 +0.0355841 0.108498 -0.00452523 0.461807 0.466834 +0.0219203 0.114136 0.0356941 0.554683 0.5 +-0.0379555 0.161954 -0.0128021 0.499753 0.5 +-0.0526362 0.0643632 0.0340621 0.277414 0.5 +0.025874 0.123374 0.0143811 0.506732 0.5 +-0.0451406 0.131184 0.00901599 0.493237 0.5 +-0.075778 0.155361 -0.00310678 0.708579 0.5 +-0.0739145 0.156437 -0.0274945 0.645327 0.5 +-0.0833056 0.100778 -0.00354288 0.490806 0.397415 +-0.0767099 0.173942 -0.0452732 0.259897 0.5 +0.00846106 0.116985 0.038033 0.66824 0.5 +-0.0200899 0.184788 -0.020546 0.237973 0.106197 +-0.046571 0.120413 0.0285524 0.752764 0.5 +-0.0515313 0.123718 -0.0088569 0.538005 0.5 +0.0212116 0.105804 -0.0171101 0.576137 0.468722 +-0.0938613 0.124487 0.0151416 0.737559 0.5 +0.0414591 0.064577 0.0290352 0.617794 0.5 +0.0466725 0.0643471 0.0285539 0.486488 0.5 +0.0526423 0.0634018 0.0283831 0.501229 0.5 +-0.0468141 0.168322 -0.00285433 0.371444 0.5 +-0.0869152 0.0944156 0.00293118 0.494536 0.346642 +-0.0773713 0.161559 -0.0267238 0.476378 0.5 +-0.0396095 0.126677 -0.00334699 0.853498 0.5 +-0.0271315 0.0764239 0.0455715 0.693464 0.5 +-0.0587953 0.107012 -0.0177177 0.484023 0.5 +-0.0748314 0.11156 -0.00720996 0.44421 0.5 +-0.0642623 0.0888181 -0.018733 0.676741 0.5 +-0.0325172 0.0881157 -0.0255424 0.370176 0.330832 +0.00325654 0.0700086 0.0561047 0.731659 0.5 +0.0103151 0.0636713 0.0537558 0.477793 0.458716 +0.0432701 0.0979967 0.00267804 0.544182 0.465461 +-0.0708223 0.156244 0.021207 0.768676 0.5 +-0.0584176 0.0702277 0.0384322 0.673529 0.5 +-0.0703207 0.112305 -0.00963846 0.530989 0.5 +-0.0581653 0.0881983 -0.0208369 0.619673 0.5 +-0.0443038 0.0877156 -0.0218942 0.693083 0.5 +-0.0488091 0.0660127 0.0373959 0.829801 0.5 +0.00269411 0.126911 0.030114 0.419275 0.5 +0.0239692 0.12105 0.0288706 0.523768 0.5 +-0.0469203 0.117468 0.0314407 0.649888 0.5 +-0.091552 0.143361 0.0201623 0.515231 0.5 +-0.0907563 0.143859 0.0263089 0.504684 0.469425 +-0.0495713 0.144022 0.00976642 0.636632 0.45621 +-0.0770934 0.15583 -0.0147903 0.519503 0.5 +-0.0868322 0.105634 0.00887573 0.731519 0.5 +-0.082848 0.131648 -0.00299747 0.386393 0.5 +-0.0384249 0.106407 -0.0201393 0.79815 0.5 +-0.0823953 0.118841 -0.00336022 0.540306 0.5 +-0.0102333 0.0876697 -0.0375101 0.564234 0.5 +-0.00789361 0.089842 -0.0363492 0.755212 0.5 +-0.0579097 0.111769 -0.0161856 0.463258 0.5 +0.0140074 0.105793 -0.0193841 0.554632 0.5 +-0.00328561 0.105435 -0.0225198 0.740261 0.5 +-0.0409613 0.070972 0.0419904 0.795206 0.5 +-0.033501 0.0710512 0.0409793 0.706864 0.5 +-0.0272732 0.0701361 0.0410332 0.726443 0.5 +-0.0161963 0.127121 0.0228897 0.305628 0.5 +-0.0190644 0.127936 0.0133818 0.519435 0.5 +-0.0149926 0.0694778 0.0545159 0.595577 0.5 +-0.00932719 0.0707313 0.0562936 0.785998 0.5 +-0.002994 0.0710941 0.0575426 0.779773 0.5 +0.00838831 0.0714267 0.0556585 0.671976 0.5 +0.0102531 0.0693533 0.0547665 0.525573 0.5 +-0.0323939 0.153399 -0.00240332 0.209483 0.5 +0.0435981 0.0881514 0.0254203 0.603121 0.478265 +-0.0586529 0.124882 -0.00781093 0.700525 0.5 +-0.0204287 0.107045 -0.022046 0.723165 0.5 +-0.0382961 0.0879422 -0.0229335 0.629507 0.5 +-0.081573 0.113394 -0.00173083 0.508624 0.426711 +-0.0380811 0.154778 -0.00889149 0.748063 0.5 +-0.00212588 0.0889926 -0.0354677 0.782073 0.5 +0.00904065 0.100193 -0.0222794 0.54652 0.5 +-0.0467068 0.0700493 0.0405769 0.710023 0.5 +-0.0779974 0.151244 0.0352264 0.347296 0.5 +0.0149019 0.116126 0.0367849 0.635361 0.5 +-0.07603 0.106301 -0.0087688 0.520423 0.5 +-0.0885261 0.137839 0.0393964 0.651389 0.5 +-0.0703112 0.131278 -0.00857724 0.737784 0.5 +0.0419377 0.0703605 0.0288832 0.54196 0.5 +0.0514194 0.0684326 0.0256968 0.512602 0.5 +-0.0922548 0.124813 0.0393757 0.806636 0.5 +0.0135035 0.128105 0.0250558 0.487288 0.424656 +-0.0704618 0.125421 -0.00881334 0.801453 0.5 +-0.0703931 0.118731 -0.00840961 0.381625 0.5 +-0.0719685 0.106305 -0.0114493 0.499561 0.5 +-0.0646972 0.161498 -0.0573125 0.41682 0.5 +0.0463693 0.0715128 0.0216754 0.461473 0.448797 +-0.0538246 0.153497 0.0152346 0.602795 0.402362 +-0.0142869 0.0724666 0.0554243 0.617853 0.5 +-0.0394057 0.118512 -0.01336 0.602235 0.5 +-0.0280509 0.0880065 -0.0330858 0.33771 0.5 +-0.00957701 0.168254 -0.0212321 0.359593 0.5 +-0.0445856 0.167324 -0.00782662 0.413138 0.327414 +-0.0513101 0.161594 -0.00355965 0.292939 0.5 +-0.0702356 0.179304 -0.0569867 0.253404 0.5 +-0.0644695 0.168402 -0.0398946 0.676128 0.5 +-0.0089459 0.130139 0.00911776 0.703889 0.5 +0.00219503 0.0880369 -0.0342201 0.75972 0.5 +-0.0268891 0.16726 -0.0174204 0.847505 0.5 +-0.0525985 0.155054 -0.00368706 0.37123 0.419006 +-0.0761618 0.131736 -0.00696723 0.42394 0.44361 +-0.0759576 0.07099 0.0265672 0.757943 0.5 +-0.00875341 0.10588 -0.02285 0.71177 0.5 +-0.0519242 0.1493 -0.00277595 0.483301 0.5 +-0.016371 0.18465 -0.0214272 0.271878 0.5 +-0.020548 0.0705632 0.0520411 0.601639 0.5 +-0.0813371 0.120073 0.049533 0.662828 0.5 +-0.0625087 0.149934 -0.0150319 0.415531 0.480025 +-0.0831098 0.10651 0.0273461 0.515033 0.5 +-0.011119 0.163582 -0.018751 0.17813 0.5 +-0.00291057 0.101147 0.0456419 0.307462 0.5 +-0.0635467 0.0660523 0.0318653 0.49936 0.45677 +-0.0511979 0.0873878 -0.0217212 0.75515 0.5 +-0.0530335 0.0740367 0.0417219 0.727079 0.5 +-0.0465007 0.0756701 0.0421325 0.696934 0.5 +-0.022314 0.0760359 0.0530306 0.607912 0.5 +-0.0151351 0.0764056 0.0563566 0.616605 0.5 +-0.00900601 0.0766621 0.0575852 0.791265 0.5 +-0.00299732 0.0767339 0.0584651 0.678647 0.450838 +0.00347424 0.0769755 0.0565905 0.523043 0.5 +0.00860763 0.0767538 0.0557293 0.612782 0.5 +-0.0271239 0.156216 -0.00302734 0.139755 0.329034 +-0.0633091 0.16738 -0.0580906 0.358909 0.45373 +-0.0873943 0.144225 0.00902371 0.583528 0.5 +-0.0626891 0.162297 -0.0470925 0.70746 0.5 +0.0370111 0.110397 0.00265294 0.516602 0.481774 +-0.0744006 0.144062 -0.00864565 0.417075 0.5 +-0.0244124 0.183841 -0.0135068 0.166659 0.5 +-0.0803381 0.0715473 0.0150483 0.5669 0.5 +-0.0644528 0.0761561 0.040638 0.610448 0.476331 +-0.0588413 0.0753794 0.0421022 0.634349 0.5 +-0.0524294 0.077372 0.0433357 0.774603 0.5 +-0.0484981 0.0769334 0.043281 0.674446 0.5 +-0.0414954 0.0773856 0.0429005 0.752035 0.5 +-0.0395008 0.0754808 0.0425134 0.72256 0.5 +-0.033488 0.0764759 0.0414605 0.748994 0.5 +-0.0627838 0.162163 -0.0530538 0.691143 0.5 +0.0381456 0.0881056 -0.0138675 0.676152 0.5 +-0.0642837 0.0396418 0.039624 0.532543 0.5 +-0.0526672 0.121335 -0.010917 0.523608 0.5 +-0.0738104 0.162942 -0.037093 0.458525 0.324439 +-0.0490869 0.13938 0.00889895 0.657159 0.5 +-0.0495771 0.166027 -0.00171113 0.322064 0.5 +-0.0709736 0.161609 -0.0450808 0.365011 0.420984 +0.0251847 0.12195 0.0254854 0.524179 0.5 +-0.0193615 0.0781018 0.0558163 0.595703 0.4544 +-0.0265458 0.120645 -0.00911332 0.52669 0.5 +-0.061796 0.155741 -0.0207923 0.443336 0.5 +-0.082476 0.110295 0.0324103 0.745977 0.5 +-0.0691674 0.156314 -0.050857 0.360984 0.5 +-0.0622848 0.16236 -0.0396288 0.427869 0.464762 +-0.088248 0.113803 0.0264606 0.595923 0.5 +-0.0575392 0.0787026 0.0436363 0.801201 0.5 +-0.0298439 0.0782596 0.0421168 0.771067 0.5 +-0.0677617 0.0876701 0.0434928 0.59211 0.5 +-0.0921939 0.131884 0.015227 0.781723 0.5 +-0.0878987 0.111742 0.0209206 0.698028 0.5 +-0.049353 0.139298 0.0147955 0.761861 0.5 +-0.0327071 0.173321 -0.0149209 0.384317 0.5 +-0.0866298 0.152851 0.0149144 0.267781 0.5 +-0.0779646 0.100025 0.035185 0.697079 0.5 +-0.0935537 0.118404 0.0151524 0.667612 0.5 +-0.084908 0.10801 0.0228537 0.694681 0.5 +-0.0210677 0.0821213 0.0562096 0.557699 0.5 +-0.0149957 0.082187 0.0572635 0.665194 0.5 +-0.00899671 0.0822178 0.0576875 0.71377 0.5 +-0.00299966 0.0822055 0.0574653 0.668024 0.472979 +0.0034748 0.0817533 0.0567544 0.69456 0.5 +0.00824833 0.082992 0.0556315 0.615627 0.5 +0.0102414 0.0812949 0.0546523 0.424956 0.485927 +-0.0398496 0.123966 -0.00878898 0.60318 0.5 +-0.092257 0.124769 0.00902091 0.309094 0.468872 +-0.0436728 0.126191 0.0209533 0.472028 0.413108 +-0.0820425 0.105873 -0.00271871 0.341089 0.347157 +-0.0663016 0.0807623 0.0424437 0.632223 0.5 +-0.0639939 0.0836688 0.0439754 0.778832 0.5 +-0.058539 0.0825906 0.0439671 0.770991 0.5 +-0.0521209 0.0822523 0.0446262 0.782751 0.5 +-0.0467559 0.0828569 0.0439458 0.699516 0.399968 +-0.0424962 0.0810729 0.0423266 0.617938 0.5 +-0.0404903 0.0830123 0.0430984 0.712874 0.5 +-0.0365108 0.0825773 0.0434355 0.675696 0.5 +-0.032204 0.0824171 0.0421121 0.529763 0.5 +-0.0864005 0.152981 0.0204492 0.250247 0.416029 +-0.0235661 0.115415 0.0353667 0.518805 0.471584 +-0.0764871 0.111685 0.0461598 0.498936 0.5 +-0.0763895 0.14977 -0.00829972 0.604451 0.5 +-0.0754801 0.161855 -0.0327796 0.39691 0.5 +-0.0285733 0.0828247 0.0462702 0.636794 0.5 +-0.0862819 0.100797 0.0028483 0.65379 0.5 +0.021088 0.08242 0.0504086 0.491924 0.475524 +-0.0801892 0.143128 -0.00230055 0.641961 0.5 +0.00844098 0.124407 -0.00878569 0.555015 0.5 +0.0147552 0.0825883 0.0529115 0.480476 0.5 +-0.061995 0.161169 -0.032654 0.499509 0.5 +-0.0807571 0.1525 0.0307996 0.295115 0.454522 +-0.00295953 0.130272 0.00279699 0.742188 0.5 +-0.0153619 0.0884791 0.0565599 0.818561 0.5 +-0.00899729 0.0878977 0.0570287 0.818958 0.5 +-0.00299611 0.0880658 0.0568489 0.695384 0.5 +0.00301457 0.0885291 0.0562756 0.81087 0.5 +0.00834267 0.0873808 0.0555541 0.577038 0.479545 +-0.00897481 0.0941651 -0.0338408 0.678465 0.5 +0.0314278 0.11673 0.0250113 0.597807 0.5 +-0.0760602 0.155337 0.0093949 0.68566 0.5 +0.0257808 0.116776 -0.00728909 0.54747 0.36626 +-0.0646577 0.0882843 0.0447113 0.69894 0.5 +-0.058996 0.0882997 0.0449149 0.778337 0.5 +-0.0529958 0.0883132 0.0451395 0.696869 0.45083 +-0.0465421 0.0881579 0.0443187 0.605881 0.5 +-0.0404961 0.0876863 0.0430941 0.556958 0.5 +-0.0331792 0.0885648 0.04366 0.668172 0.5 +-0.0280482 0.0879652 0.046363 0.699915 0.5 +0.0150626 0.0881784 0.0517745 0.702815 0.5 +0.0205955 0.087113 0.0492325 0.678548 0.5 +-0.0702712 0.0823874 0.0409431 0.628092 0.5 +-0.0296926 0.0896882 -0.0286839 0.317989 0.390463 +-0.0236137 0.179242 -0.0115629 0.264741 0.5 +-0.0809391 0.100029 0.0323433 0.683272 0.5 +-0.0928336 0.130683 0.0207107 0.62518 0.472282 +-0.0761771 0.156201 -0.0204165 0.612769 0.5 +0.0146577 0.129396 0.00843576 0.595962 0.5 +0.0104845 0.089766 0.0542005 0.46622 0.5 +-0.072579 0.161253 -0.0389447 0.482103 0.5 +-0.0322741 0.110391 -0.0184574 0.809584 0.5 +-0.0550172 0.150108 0.027792 0.412797 0.5 +-0.071635 0.0883254 0.0414652 0.604622 0.463567 +-0.0424904 0.0895336 0.0426086 0.959715 0.5 +0.0207945 0.0897491 0.0484315 0.669841 0.5 +0.0273189 0.118845 -0.00265658 0.615055 0.5 +0.0285218 0.121112 0.0162366 0.593248 0.434231 +-0.00899735 0.0930598 0.0559298 0.639163 0.5 +-0.00291176 0.118727 -0.0144021 0.826286 0.5 +-0.0885191 0.113233 0.0327948 0.447552 0.461926 +-0.0713744 0.0938304 0.0415269 0.544171 0.444972 +-0.0641029 0.0935514 0.0439488 0.597795 0.395518 +-0.0584965 0.0944146 0.0446213 0.678752 0.5 +-0.0515853 0.0939836 0.0442383 0.634435 0.477778 +-0.0465591 0.0937901 0.0436103 0.714507 0.5 +-0.0414914 0.0942416 0.0425268 0.490492 0.46307 +-0.0377723 0.0933327 0.0434889 0.620752 0.5 +-0.0332864 0.0945766 0.0443868 0.723538 0.5 +-0.0263807 0.094318 0.0450568 0.620324 0.5 +-0.0141606 0.0929618 0.0553898 0.503825 0.5 +-0.00319641 0.0930898 0.0557853 0.624082 0.5 +0.00150357 0.0931879 0.0551544 0.492015 0.5 +0.00367616 0.0950752 0.0535295 0.508462 0.5 +0.00915739 0.0941794 0.0519212 0.597357 0.452723 +0.0216553 0.0937794 0.0473202 0.671835 0.5 +-0.0702968 0.174481 -0.045888 0.43732 0.455145 +-0.0305889 0.168899 -0.00702359 0.59106 0.5 +-0.0528191 0.162649 0.00296711 0.343566 0.5 +-0.0890968 0.0940104 0.0208024 0.539357 0.478012 +-0.0626249 0.173112 -0.0586131 0.353011 0.447085 +-0.0443835 0.105923 -0.0201903 0.683228 0.5 +-0.0664958 0.0951776 0.0424531 0.672396 0.5 +-0.0324384 0.126415 0.0146752 0.445893 0.463327 +-0.0152469 0.0961657 0.0518098 0.323594 0.5 +-0.0097537 0.0960506 0.0535818 0.446732 0.426556 +-0.00304601 0.0963367 0.0537791 0.579525 0.5 +0.01642 0.0957081 0.0480381 0.687032 0.5 +-0.0876548 0.105191 0.0148253 0.774556 0.5 +-0.0699417 0.0763232 0.0381496 0.596573 0.5 +0.0358078 0.0958594 -0.0120328 0.738943 0.5 +0.0374966 0.100154 0.031249 0.720944 0.5 +-0.0530195 0.150059 0.0207323 0.696139 0.5 +-0.0905911 0.131765 0.0328667 0.816274 0.5 +-0.0709717 0.147309 -0.0268389 0.224341 0.389051 +-0.0443321 0.0935075 -0.0222668 0.709831 0.5 +-0.0400911 0.128618 0.00909496 0.81345 0.5 +-0.0710054 0.100275 0.0398128 0.481571 0.5 +-0.0653063 0.100124 0.0417262 0.670525 0.470095 +-0.0589969 0.0980495 0.0430328 0.779482 0.5 +-0.0529938 0.0980631 0.0432952 0.836255 0.5 +-0.0469951 0.0980659 0.043235 0.637806 0.5 +-0.0408476 0.100401 0.0414668 0.648927 0.395789 +-0.0323344 0.0988071 0.0435216 0.652032 0.5 +-0.0259464 0.0998425 0.0438947 0.737424 0.5 +-0.0212066 0.0999849 0.0444194 0.576924 0.5 +0.00749586 0.09835 0.0488255 0.46146 0.5 +0.0090271 0.101109 0.0469975 0.470012 0.5 +0.0153076 0.100008 0.0472449 0.600016 0.5 +0.0208175 0.100067 0.0453866 0.595024 0.46889 +-0.0648326 0.131509 -0.00838673 0.790869 0.5 +-0.0740297 0.150832 -0.0323367 0.406089 0.5 +-0.0932444 0.124885 0.026841 0.802537 0.5 +-0.0633239 0.169093 -0.0610358 0.362406 0.5 +-0.0771158 0.162488 -0.0202679 0.465605 0.5 +-0.0585669 0.0647555 0.0323611 0.494963 0.328305 +0.0377689 0.110383 0.00969065 0.710008 0.5 +-0.0503559 0.0935892 -0.0218956 0.807094 0.5 +-0.0589961 0.101543 0.042437 0.529374 0.5 +-0.0516647 0.101981 0.0417488 0.647378 0.5 +-0.0469248 0.101325 0.0421166 0.608323 0.5 +-0.0352173 0.101965 0.0413638 0.751982 0.5 +0.00285015 0.100935 0.0464433 0.395489 0.5 +-0.075479 0.150312 -0.0143808 0.730394 0.5 +-0.078936 0.108126 -0.00525459 0.540251 0.381971 +-0.0251472 0.168981 -0.0187156 0.757996 0.5 +-0.071457 0.113692 0.0499983 0.429195 0.5 +-0.0747771 0.0997536 0.0377868 0.551123 0.5 +-0.0902919 0.137212 0.0146286 0.495279 0.5 +-0.0264568 0.105883 0.0411765 0.58994 0.471484 +-0.0209966 0.1044 0.0429589 0.797197 0.5 +-0.0145208 0.105597 0.0430511 0.780555 0.5 +-0.00899316 0.10622 0.0435541 0.510194 0.5 +-0.00289533 0.105882 0.0438861 0.384284 0.5 +0.00245231 0.105621 0.0429868 0.332307 0.5 +0.00945613 0.104903 0.0439002 0.435482 0.5 +0.0149913 0.104769 0.0443348 0.548532 0.5 +-0.0772186 0.106139 0.0350601 0.430274 0.367589 +-0.0708601 0.106945 0.0381598 0.402417 0.5 +-0.0652985 0.106577 0.0390805 0.558067 0.398761 +-0.0583896 0.105623 0.0405326 0.594554 0.5 +-0.0529341 0.106445 0.0398435 0.644542 0.398207 +-0.0461638 0.105797 0.0404843 0.759883 0.5 +-0.0400204 0.106789 0.0388993 0.653599 0.5 +-0.03311 0.106322 0.0394461 0.532024 0.5 +0.0193026 0.10477 0.0431964 0.486674 0.480281 +-0.0501412 0.13774 0.00286739 0.569746 0.5 +0.0266104 0.105911 0.0384052 0.650339 0.5 +0.0438719 0.088439 -0.0031027 0.506353 0.478726 +-0.0590381 0.113203 0.0362299 0.87726 0.5 +-0.021499 0.107851 0.0414162 0.584043 0.5 +-0.0164951 0.107881 0.0420289 0.633836 0.5 +0.00450524 0.107918 0.0419336 0.79888 0.5 +0.00856234 0.108229 0.0410531 0.820786 0.5 +0.0149994 0.10779 0.0412845 0.598409 0.5 +0.0213049 0.106041 0.0409433 0.561561 0.479574 +-0.0336665 0.167843 -0.00338268 0.478764 0.5 +-0.0587789 0.131705 -0.00671001 0.673026 0.5 +-0.0443517 0.100306 -0.0215281 0.825942 0.5 +-0.0147306 0.179604 -0.0266222 0.40888 0.5 +0.0159582 0.108177 -0.0177822 0.564672 0.468958 +-0.0638447 0.138119 -0.00733006 0.633194 0.5 +-0.0330953 0.167861 -0.0155539 0.527374 0.428366 +-0.0643684 0.125359 -0.00876153 0.813046 0.5 +-0.032583 0.161992 -0.0142418 0.852313 0.5 +-0.068568 0.110392 0.0392194 0.353622 0.364353 +-0.0643494 0.112195 0.0388907 0.34696 0.5 +-0.0593722 0.112082 0.0373875 0.588374 0.5 +-0.0529986 0.110472 0.0373551 0.513233 0.408461 +-0.0468613 0.11028 0.0378862 0.569336 0.5 +-0.040984 0.110496 0.0370883 0.553647 0.5 +-0.0320055 0.110468 0.0370438 0.565129 0.5 +-0.0074871 0.110717 0.042649 0.617568 0.5 +-0.00449218 0.110714 0.0426582 0.621679 0.5 +0.0250033 0.110611 0.0368459 0.631257 0.5 +0.025919 0.0995286 -0.0189206 0.684181 0.5 +-0.06973 0.112153 0.0457184 0.746569 0.5 +-0.045604 0.148834 -0.00329924 0.521986 0.5 +-0.0653006 0.0947889 -0.0177657 0.582853 0.5 +-0.0906677 0.13318 0.0277848 0.773217 0.5 +-0.0331508 0.094474 -0.0237799 0.742 0.5 +-0.0575764 0.0941613 -0.0208023 0.703326 0.5 +-0.0200586 0.0397198 0.0532237 0.447203 0.5 +-0.0203685 0.0352888 0.051184 0.291685 0.457265 +-0.0764163 0.125947 -0.00745144 0.524375 0.5 +-0.0205906 0.167551 -0.0139677 0.809186 0.5 +0.025858 0.116851 0.0315289 0.660225 0.5 +-0.0139279 0.167191 -0.021044 0.669958 0.5 +-0.0587481 0.149802 -0.00133886 0.562881 0.5 +0.0144191 0.0395247 0.0443396 0.266796 0.5 +0.0332953 0.105473 0.0329627 0.721815 0.5 +-0.0647461 0.114313 -0.0115219 0.592211 0.5 +-0.0520818 0.0353771 0.0449331 0.341981 0.5 +-0.015004 0.0392095 0.0513548 0.312679 0.5 +-0.0094925 0.0384962 0.049554 0.302651 0.5 +-0.0638496 0.117631 0.0454477 0.559641 0.5 +-0.0573025 0.136864 0.033162 0.554568 0.5 +0.0189101 0.0400942 0.0428502 0.270107 0.5 +-0.0508192 0.124393 0.0332635 0.581555 0.5 +-0.0182623 0.180885 -0.017743 0.594618 0.5 +-0.0651271 0.150343 -0.0325707 0.505808 0.5 +0.0332966 0.0936886 0.0400216 0.637373 0.5 +-0.0463011 0.149493 0.00833001 0.611316 0.5 +0.00260773 0.0354887 0.0450013 0.261253 0.345588 +-0.0780807 0.10971 0.0423535 0.916894 0.5 +-0.0542262 0.124756 0.0369858 0.64506 0.5 +-0.0402584 0.0361447 0.0436625 0.193197 0.5 +-0.00317483 0.0942874 -0.0331049 0.71511 0.325502 +-0.0151032 0.179716 -0.0207621 0.731902 0.5 +0.026141 0.0403246 0.0327265 0.294647 0.339561 +-0.0640247 0.111376 -0.0136272 0.608847 0.5 +0.027817 0.112309 0.0339118 0.692282 0.5 +-0.0586332 0.142774 0.0334953 0.761767 0.5 +-0.0146622 0.167501 -0.0154455 0.61604 0.5 +-0.0270893 0.167298 -0.00866399 0.642638 0.5 +0.0152056 0.045813 0.0442638 0.487785 0.5 +0.0190988 0.0442996 0.0429 0.362689 0.463942 +0.0215694 0.0456112 0.041209 0.479281 0.5 +0.0257452 0.0459137 0.0381185 0.444171 0.5 +0.0387365 0.0944447 0.0327088 0.718127 0.5 +0.0287308 0.0456722 0.0347466 0.335561 0.431941 +-0.0151805 0.173809 -0.0213305 0.730436 0.5 +-0.0658903 0.118253 0.0498126 0.307185 0.5 +-0.0628345 0.093206 -0.0188544 0.659442 0.5 +-0.0643065 0.142451 0.0394123 0.621016 0.5 +-0.040079 0.150283 0.00280951 0.491474 0.5 +-0.026851 0.173268 -0.00983852 0.620534 0.5 +-0.0207913 0.173767 -0.0147826 0.653794 0.5 +-0.0582334 0.124238 0.0403406 0.70004 0.5 +-0.0683337 0.131545 0.0479709 0.732904 0.5 +-0.0693547 0.10637 -0.012803 0.472443 0.5 +-0.0428668 0.157627 0.0050419 0.670804 0.5 +-0.0476449 0.130368 0.0258834 0.623828 0.5 +0.0379451 0.0817167 -0.0141547 0.644934 0.5 +0.0312298 0.0470286 0.0324465 0.426433 0.5 +-0.0662284 0.138149 0.042896 0.72515 0.5 +-0.0644094 0.105575 -0.0158634 0.566501 0.5 +0.0411271 0.0443713 0.0285474 0.466284 0.5 +-0.0830031 0.0762361 0.0150296 0.67606 0.5 +-0.0660167 0.123488 0.0501643 0.718404 0.5 +-0.0416352 0.155329 0.00636435 0.466436 0.5 +-0.0388456 0.155994 0.00477206 0.438555 0.402124 +-0.0551732 0.116538 0.0359195 0.457649 0.5 +-0.0600069 0.134082 0.0369434 0.682472 0.5 +0.0452816 0.0453284 0.0263124 0.471094 0.5 +0.0513161 0.0463154 0.0204963 0.342211 0.398387 +-0.0106687 0.172847 -0.0215627 0.69267 0.5 +-0.0147735 0.18419 -0.0259341 0.309641 0.5 +0.0301064 0.106776 0.0358091 0.72383 0.5 +-0.063709 0.125122 0.0457451 0.712215 0.420475 +0.0473431 0.0499217 0.0295077 0.554948 0.5 +0.0497106 0.0482066 0.0259506 0.48379 0.5 +0.0518484 0.0518415 0.0267161 0.416499 0.5 +-0.0162732 0.172938 -0.0174582 0.719256 0.5 +0.0355097 0.107304 0.0291151 0.718782 0.5 +-0.0552656 0.143077 0.0300537 0.622521 0.5 +-0.0637191 0.136482 0.0388176 0.603354 0.5 +-0.0199086 0.161072 -0.00863325 0.350317 0.5 +-0.0209172 0.179282 -0.0148523 0.455842 0.5 +0.014511 0.0513519 0.0474271 0.589102 0.5 +-0.0610259 0.126912 0.0416133 0.698375 0.5 +0.0539905 0.0494141 0.0219114 0.418448 0.5 +0.00925922 0.118865 -0.0148674 0.54369 0.457314 +-0.0268384 0.162091 -0.00836699 0.546076 0.486591 +-0.0367024 0.163198 -0.00107067 0.680811 0.5 +-0.0336432 0.155948 0.00188963 0.445666 0.44081 +-0.0280966 0.159587 0.000483069 0.431301 0.5 +-0.026491 0.16163 -0.00321758 0.537982 0.323001 +0.0206613 0.0528733 0.0451655 0.647628 0.324331 +0.0231576 0.0513069 0.0414753 0.507052 0.5 +0.0266044 0.0526516 0.039853 0.635463 0.446542 +0.0309772 0.0527823 0.0371348 0.671735 0.5 +0.0239371 0.103424 0.0418106 0.654526 0.5 +0.0568895 0.0527484 0.0209204 0.474964 0.5 +-0.0664209 0.11329 0.0441331 0.212624 0.5 +-0.0326789 0.162384 -0.00243762 0.543585 0.5 +0.0145199 0.0932586 -0.026363 0.546403 0.5 +-0.0543983 0.119186 0.0365781 0.502204 0.44785 +-0.0564272 0.132376 0.0357966 0.720059 0.5 +-0.0501636 0.142911 0.00230897 0.376445 0.5 +-0.043714 0.147707 0.0038501 0.245798 0.5 +-0.0291346 0.177171 -0.00534178 0.371295 0.5 +0.0357304 0.100363 -0.0111604 0.61591 0.5 +0.0133943 0.0541536 0.0499521 0.532724 0.5 +0.0551089 0.0545007 0.0253961 0.545646 0.5 +0.0291033 0.0572886 0.0407089 0.633826 0.5 +0.0585723 0.0583402 0.0214893 0.549998 0.477428 +-0.0740322 0.0656952 0.0144875 0.594594 0.5 +-0.0749844 0.179305 -0.0518221 0.216638 0.5 +0.0145778 0.0585769 0.0501691 0.387785 0.5 +0.0214876 0.058332 0.0470549 0.596242 0.5 +0.0259507 0.0590004 0.0437762 0.663038 0.5 +0.032833 0.0585633 0.0387158 0.630786 0.5 +0.0358218 0.0578374 0.0350365 0.591179 0.5 +0.0360585 0.0951301 0.0364902 0.726421 0.5 +-0.0886806 0.118283 0.0459142 0.444358 0.5 +0.0562736 0.0586365 0.0253398 0.57284 0.5 +0.0303311 0.0951295 0.0419589 0.717458 0.5 +-0.0222315 0.167389 -0.0110472 0.688671 0.5 +-0.0543257 0.136577 0.0307959 0.688078 0.5 +-0.0500074 0.150447 0.0117579 0.563476 0.5 +-0.0616289 0.137406 0.0354744 0.592141 0.5 +-0.0319367 0.159507 0.00191749 0.44862 0.5 +-0.0634458 0.132148 0.0406867 0.731705 0.5 +0.0368678 0.0921989 0.0367449 0.708135 0.5 +-0.0728433 0.156137 -0.0339112 0.713518 0.5 +0.0389872 0.0640689 0.0330299 0.521361 0.5 +-0.0636611 0.1488 -0.0205996 0.618447 0.5 +0.0153938 0.0648444 0.0513036 0.554385 0.463079 +0.0213958 0.0645506 0.0473078 0.414803 0.412252 +0.0265105 0.0649235 0.0439721 0.611901 0.5 +0.0302364 0.0650657 0.0415975 0.600683 0.487653 +0.0331295 0.0642221 0.0397381 0.500385 0.490901 +0.0367885 0.065027 0.0366867 0.593561 0.5 +0.0563131 0.0650782 0.0252208 0.639437 0.5 +0.0591364 0.0644742 0.0211357 0.550839 0.448044 +-0.0110683 0.167098 -0.0167807 0.360187 0.5 +-0.0605202 0.146205 0.0366666 0.591479 0.5 +0.0194528 0.0665736 0.0491642 0.603282 0.5 +-0.0286777 0.158132 0.000508817 0.402765 0.431383 +0.0253025 0.0989569 0.0434277 0.623394 0.5 +-0.0349979 0.152158 8.20736e-05 0.217633 0.5 +0.014665 0.070627 0.0528306 0.52613 0.5 +0.0202908 0.071041 0.0498828 0.634288 0.435356 +0.0230702 0.0702991 0.0473835 0.571849 0.5 +0.0263693 0.0706238 0.0441789 0.622852 0.474797 +0.0328306 0.0707606 0.0401362 0.612279 0.409693 +0.0368832 0.070672 0.0365953 0.662199 0.5 +0.0398878 0.0705632 0.0325808 0.656566 0.5 +0.0579544 0.0694794 0.0198345 0.6125 0.5 +-0.0641704 0.063724 0.0268682 0.425507 0.418571 +-0.0919499 0.114216 0.0149265 0.530043 0.5 +0.0351624 0.0819076 -0.0172502 0.760295 0.5 +-0.0862408 0.119271 -0.00117534 0.455279 0.5 +-0.0294401 0.174958 -0.00579982 0.562984 0.5 +-0.0175288 0.165418 -0.0114925 0.675539 0.5 +-0.0617869 0.117789 0.0409144 0.40334 0.5 +0.0301891 0.0723658 0.0418804 0.606777 0.5 +-0.0822099 0.149486 0.00288044 0.385889 0.468811 +-0.0760271 0.175704 -0.0506937 0.340571 0.5 +-0.0652343 0.0614738 0.0211346 0.414933 0.425841 +-0.0266574 0.110394 -0.019007 0.783101 0.5 +-0.0813538 0.0779161 0.0268055 0.756683 0.5 +0.021417 0.118723 -0.00893569 0.549 0.5 +0.0149346 0.0759297 0.0536191 0.48671 0.476705 +0.0209886 0.0761609 0.0506055 0.575091 0.5 +0.0268396 0.0762089 0.0459193 0.572664 0.5 +0.0336785 0.0760737 0.0405166 0.630563 0.5 +0.0373422 0.0760306 0.0366776 0.505468 0.5 +0.0400324 0.0763062 0.0328345 0.645662 0.5 +0.0419048 0.076876 0.0296092 0.673034 0.5 +0.0438094 0.0763805 0.0258638 0.624347 0.5 +-0.0452412 0.118472 -0.0142046 0.833781 0.5 +0.0456773 0.0768089 0.0208187 0.458504 0.467907 +-0.050165 0.137714 0.0207618 0.606401 0.481088 +-0.00327054 0.111563 -0.0203549 0.551699 0.482404 +-0.0483236 0.145111 0.00757835 0.59165 0.5 +0.0310833 0.0775315 0.0432282 0.624343 0.5 +-0.046855 0.145222 0.00288431 0.195425 0.432502 +-0.0141716 0.10541 -0.0225802 0.672132 0.5 +0.0470348 0.0753979 0.0148736 0.455861 0.5 +-0.0611433 0.140542 0.0356184 0.646306 0.5 +0.0272779 0.0823714 0.0459243 0.61663 0.478488 +0.0309212 0.08255 0.0430252 0.611382 0.5 +0.0343037 0.0825412 0.0402907 0.613309 0.465282 +0.0370354 0.0824663 0.0369099 0.642585 0.5 +-0.0799946 0.147989 -0.000835337 0.484293 0.5 +-0.0774435 0.0690153 0.00961977 0.704234 0.277826 +0.0404363 0.0826995 0.0326021 0.686672 0.5 +0.0417479 0.0827335 0.0302524 0.63553 0.5 +0.0436887 0.0825508 0.0263844 0.61829 0.5 +0.0454407 0.0825465 0.0207137 0.601475 0.480065 +-0.0822812 0.116295 0.0482855 0.66926 0.5 +-0.0844726 0.0947391 -0.00345192 0.592061 0.5 +-0.020271 0.168003 -0.0193935 0.821267 0.5 +-0.0742716 0.0668501 0.0190414 0.706894 0.5 +0.026747 0.0882417 0.0458314 0.539865 0.389736 +0.0308722 0.0882572 0.0430146 0.948814 0.5 +0.0344922 0.0883047 0.0403697 0.638338 0.5 +0.0372481 0.0881263 0.0366393 0.643327 0.5 +0.039927 0.088094 0.0326668 0.711283 0.5 +0.0419027 0.0877782 0.0290815 0.667656 0.5 +0.00264738 0.112302 -0.019871 0.766242 0.5 +-0.0703315 0.1455 -0.0205576 0.136819 0.239158 +-0.0749446 0.137879 -0.00653312 0.459033 0.397283 +-0.0266967 0.114299 -0.0159903 0.856895 0.5 +-0.0869924 0.113518 0.00410409 0.344807 0.5 +-0.0142186 0.174013 -0.0259807 0.439072 0.5 +-0.0221564 0.157852 -0.00861651 0.254248 0.5 +-0.011587 0.164129 -0.0163045 0.228563 0.367524 +-0.00997381 0.169338 -0.0247765 0.42189 0.5 +-0.082875 0.143405 0.00186692 0.494272 0.5 +0.0203757 0.0354405 -0.00287175 0 0 +0.0191274 0.0363337 -0.00917714 0.174536 0.5 +0.0184456 0.036388 -0.013479 0.173751 0.5 +0.0149535 0.0347732 -0.0154937 0.144529 0.253209 +0.0221204 0.0372026 0.0342324 0.156956 0.287305 +0.039271 0.0382866 0.00854708 0.245023 0.5 +0.0397549 0.0398545 0.002614 0.276002 0.5 +0.0221892 0.0380614 -0.00446361 0.173629 0.5 +0.0179901 0.0369066 -0.0161835 0.336518 0.5 +0.0154148 0.0392444 -0.0212861 0.367832 0.5 +0.0208023 0.100118 -0.0213392 0.648293 0.46589 +0.0446004 0.0409064 0.00927401 0.208963 0.5 +0.0435625 0.0411355 0.00427044 0.357471 0.452104 +0.0381381 0.0411139 -0.00147908 0.514406 0.5 +-0.0478807 0.135207 0.00885778 0.482359 0.5 +0.0217274 0.0404287 -0.00964433 0.311593 0.5 +0.0206744 0.0405956 -0.0144437 0.473825 0.5 +0.0192578 0.0411681 -0.0195074 0.414351 0.5 +-0.0885736 0.112913 0.0395856 0.488806 0.5 +-0.026793 0.106457 -0.0218501 0.617481 0.5 +0.0481487 0.0428585 0.0145594 0.265572 0.5 +0.0521212 0.0461655 0.0089655 0.199267 0.5 +0.0480438 0.0430647 0.00724585 0.412258 0.5 +0.0460936 0.0434131 0.00284357 0.566688 0.5 +0.0285003 0.100485 -0.0168103 0.728425 0.5 +0.0269462 0.0395833 -0.00334578 0.464947 0.5 +-0.0907856 0.117838 0.00647331 0.421552 0.5 +-0.062721 0.167567 -0.0470628 0.645866 0.5 +-0.0799532 0.106813 0.0316838 0.420249 0.5 +0.0527437 0.0462125 0.0139554 0.286197 0.5 +0.0504533 0.0466263 0.00264513 0.57721 0.5 +-0.0322581 0.117324 -0.0133273 0.811815 0.5 +0.0272475 0.0455966 -0.00927071 0.533119 0.5 +-0.0146455 0.0942084 -0.0337341 0.520871 0.5 +-0.0411545 0.16722 -0.010818 0.48116 0.5 +-0.0721385 0.156112 -0.0384102 0.511983 0.468875 +0.0456803 0.0474217 -0.00311192 0.412576 0.5 +0.0239407 0.0433254 -0.00969837 0.651864 0.5 +0.021084 0.0462585 -0.0205303 0.476548 0.5 +-0.0348527 0.0351549 -0.0307351 0.16856 0.5 +-0.0699867 0.0663066 0.0259153 0.590849 0.43032 +-0.0747071 0.149891 -0.0201453 0.5851 0.5 +-0.0845448 0.13725 0.000743181 0.580039 0.5 +0.0549514 0.0484178 0.0163982 0.295573 0.5 +0.0264565 0.0466261 -0.0141039 0.515417 0.5 +0.0225276 0.0444655 -0.0157683 0.505631 0.5 +0.0330538 0.0938135 -0.0160538 0.699679 0.5 +0.0526476 0.0694992 0.00297306 0.629664 0.372945 +0.0528544 0.0581339 -0.00277966 0.592036 0.5 +-0.0571464 0.0671799 0.0361705 0.503626 0.472266 +-0.0651544 0.157167 -0.0515491 0.708429 0.5 +-0.0493189 0.133682 0.00119868 0.355836 0.438333 +-0.032962 0.10595 -0.0206729 0.810434 0.5 +-0.0649538 0.155656 -0.045631 0.820472 0.5 +-0.0390456 0.150445 -0.00354536 0.204281 0.5 +0.0574365 0.051618 0.0145183 0.351624 0.5 +0.0574129 0.0522531 0.00903377 0.511629 0.5 +0.0536112 0.0500965 0.00204174 0.768402 0.5 +0.0512204 0.0520121 -0.00218354 0.534755 0.5 +0.0471226 0.0515811 -0.00481298 0.434179 0.5 +0.033443 0.047576 -0.0063817 0.557462 0.465257 +0.00280933 0.118297 -0.0158208 0.570337 0.473222 +-0.0147841 0.10125 -0.0238408 0.771507 0.5 +-0.0620037 0.167422 -0.0527165 0.538383 0.466596 +0.0559147 0.0528382 0.00339683 0.824166 0.5 +0.0334801 0.0518506 -0.00825293 0.591066 0.5 +0.0287814 0.0501171 -0.0157926 0.574224 0.5 +0.0256197 0.0485542 -0.0190548 0.421586 0.5 +-0.00863537 0.118406 -0.0146114 0.827086 0.5 +-0.0148322 0.117675 -0.014701 0.559736 0.5 +-0.0615138 0.145712 -0.00481276 0.466074 0.5 +0.0232531 0.12083 -0.00456186 0.617393 0.5 +-0.0401535 0.0342718 -0.0275149 0.0979878 0.5 +0.0302657 0.0496868 -0.0107289 0.647285 0.5 +0.0320066 0.111334 -0.00737407 0.536101 0.5 +-0.0211003 0.120417 -0.0102482 0.732965 0.5 +-0.0204991 0.117125 -0.0140803 0.767014 0.5 +-0.00910263 0.0383602 -0.025776 0.274297 0.5 +-0.0525144 0.11229 -0.0171034 0.442719 0.484227 +0.0202353 0.123713 -0.00247094 0.59012 0.5 +-0.0701749 0.0347541 -0.0017891 0.135623 0.5 +-0.00340266 0.114844 -0.0176928 0.826111 0.5 +0.0310248 0.053713 -0.0140522 0.572913 0.5 +0.0268191 0.0528482 -0.020339 0.412387 0.455219 +-0.0147458 0.120673 -0.0105853 0.653192 0.5 +0.0270905 0.106214 -0.0146756 0.603346 0.5 +0.0465541 0.0697991 0.00228503 0.590477 0.5 +-0.00300122 0.100676 -0.0235814 0.77298 0.5 +-0.0755874 0.076212 0.033468 0.651011 0.5 +0.059738 0.0572998 0.0151736 0.624329 0.5 +0.0595394 0.0578717 0.00861672 0.650231 0.5 +0.0572091 0.0580526 0.00253507 0.577167 0.5 +-0.0142907 0.123147 -0.00746744 0.689207 0.5 +0.0211831 0.112303 -0.0140834 0.636933 0.5 +0.0347455 0.0565046 -0.010714 0.517615 0.5 +0.0249138 0.0825163 -0.0245877 0.759593 0.5 +-0.0382227 0.114521 -0.016178 0.845616 0.5 +-0.0819485 0.0761672 0.0208322 0.76776 0.5 +-0.0269557 0.0392251 -0.0293943 0.537642 0.5 +0.0377037 0.0593401 -0.00852013 0.537798 0.5 +0.0330295 0.0586306 -0.014729 0.60439 0.5 +0.0218121 0.0515865 -0.0236492 0.56032 0.5 +-0.0204953 0.0935908 -0.0331675 0.485557 0.5 +-0.0872217 0.113521 0.0440666 0.448078 0.427651 +-0.0271537 0.0351608 0.0509267 0.96808 0.5 +-0.0503825 0.106302 -0.0194598 0.649024 0.5 +0.0266611 0.0585067 -0.0219134 0.622435 0.5 +0.00975018 0.0945932 -0.0280451 0.504262 0.457756 +-0.0205524 0.122391 -0.00754739 0.498583 0.5 +-0.0668021 0.0909191 -0.0174744 0.566525 0.5 +-0.0856155 0.0942099 -0.00109094 0.420789 0.436678 +-0.0915274 0.11444 0.0204492 0.759207 0.5 +-0.0909048 0.131701 0.00809159 0.558083 0.5 +0.0404851 0.0578886 -0.0051698 0.425865 0.437223 +0.0295964 0.0580473 -0.0178274 0.608291 0.460655 +0.0266986 0.0941359 -0.0205949 0.662934 0.5 +-0.0677104 0.172869 -0.0572602 0.695141 0.5 +0.0142001 0.118043 -0.013917 0.45799 0.403894 +-0.0698171 0.0699687 0.0326375 0.529959 0.5 +0.0607097 0.0648802 0.0151632 0.434757 0.451533 +0.0609346 0.0630505 0.0131585 0.526971 0.5 +0.0602205 0.0643718 0.00864139 0.443146 0.456896 +0.0574055 0.0638877 0.00271573 0.413274 0.5 +-0.0797793 0.103858 -0.00660016 0.553637 0.5 +-0.0563867 0.137359 -0.00421998 0.659682 0.5 +0.0344512 0.0638263 -0.0152012 0.581486 0.5 +0.0307139 0.0605317 -0.0184589 0.617611 0.449874 +0.0185684 0.121789 -0.00725624 0.61441 0.349043 +-0.0456617 0.112414 -0.0169658 0.70381 0.5 +0.0456177 0.0644845 -0.00162168 0.572144 0.5 +-0.0584268 0.0349015 0.0441202 0.767369 0.5 +-0.0747982 0.0723674 0.0308514 0.656357 0.5 +-0.0699373 0.0621854 0.0151778 0.587415 0.5 +-0.052889 0.136519 -0.00170821 0.593683 0.5 +0.0410205 0.0644886 -0.00476733 0.363401 0.5 +0.0388712 0.0646166 -0.00976797 0.384344 0.5 +0.0514871 0.0637279 -0.00174794 0.518067 0.5 +-0.0787297 0.0744551 0.0267421 0.809934 0.5 +-0.0850281 0.144269 0.00618082 0.578063 0.5 +0.0313094 0.064487 -0.0188936 0.672704 0.5 +0.0267274 0.0646171 -0.0220842 0.752591 0.5 +0.0318737 0.0877439 -0.0192705 0.740422 0.5 +-0.0772455 0.143995 -0.00470939 0.452269 0.5 +0.0132576 0.110443 -0.0183541 0.539267 0.5 +-0.00289343 0.124723 -0.00863032 0.516883 0.5 +-0.0342868 0.038582 0.0485461 0.546061 0.5 +0.0200397 0.0876233 -0.0261205 0.735721 0.5 +0.0585453 0.0705354 0.0146976 0.608535 0.5 +0.0581405 0.0699819 0.00856199 0.483528 0.5 +0.056099 0.069436 0.00424359 0.385578 0.5 +0.0370479 0.0665186 -0.0132637 0.645736 0.5 +-0.062561 0.172971 -0.0616721 0.43069 0.5 +-0.0702718 0.15494 -0.0455472 0.29179 0.457421 +-0.0916259 0.130499 0.00930481 0.432982 0.472725 +-0.070021 0.148229 -0.0328231 0.322588 0.195946 +-0.0721274 0.0680183 0.0267753 0.656727 0.5 +-0.0745337 0.15067 -0.0264303 0.331486 0.5 +0.0431087 0.0713461 -0.002764 0.390428 0.45538 +0.0421659 0.0692525 -0.00466106 0.55545 0.5 +0.0345404 0.0699378 -0.0160391 0.727409 0.5 +-0.0342368 0.122912 -0.00708584 0.432969 0.5 +0.0401518 0.070932 -0.00951127 0.706551 0.5 +0.0370706 0.0707408 -0.013301 0.722628 0.5 +0.0310856 0.0702175 -0.0192905 0.761897 0.5 +0.0283004 0.0705453 -0.0222447 0.701199 0.5 +-0.00859023 0.101699 -0.0237897 0.731824 0.5 +-0.0328234 0.0400139 -0.029875 0.413461 0.5 +-0.0830588 0.11047 0.0397334 0.931001 0.5 +0.0142724 0.123237 -0.00806485 0.479991 0.484444 +-0.0760443 0.108637 0.0389078 0.769887 0.5 +-0.0732762 0.154939 -0.0321392 0.640327 0.5 +0.0160324 0.0889232 -0.0282477 0.595959 0.5 +-0.0901677 0.131361 0.0394374 0.633972 0.457764 +0.0455828 0.0768365 0.00270178 0.323813 0.5 +-0.0516717 0.0553965 0.014906 0.168077 0.5 +-0.0376545 0.121002 -0.0109724 0.599451 0.451266 +0.0466318 0.0762885 0.00910629 0.334003 0.5 +0.0437303 0.0769241 -0.00295564 0.541016 0.5 +0.0405043 0.0766784 -0.0084913 0.540094 0.5 +0.0369463 0.0762836 -0.0128837 0.716695 0.5 +0.0349351 0.0766648 -0.0155944 0.687304 0.5 +0.0319237 0.0763904 -0.0194186 0.722365 0.5 +0.0285208 0.0758075 -0.0225233 0.729644 0.5 +-0.0646857 0.068809 0.0348219 0.518098 0.396839 +-0.00335573 0.0986136 -0.0269283 0.762285 0.5 +-0.0383606 0.100112 -0.0217661 0.633523 0.5 +-0.0705433 0.149897 -0.0387319 0.143598 0.5 +-0.0247871 0.179215 -0.0188356 0.466421 0.5 +0.00339058 0.0937023 -0.0318365 0.697748 0.5 +-0.09099 0.142689 0.0226645 0.743514 0.5 +-0.0851088 0.102115 0.000391121 0.420019 0.403283 +0.00299202 0.124707 -0.00864775 0.631346 0.5 +-0.0649459 0.167336 -0.0329944 0.692397 0.5 +0.045975 0.0827243 0.0146716 0.494123 0.463874 +0.0461931 0.0827376 0.00867911 0.540283 0.443947 +0.0453461 0.0826602 0.00269811 0.520808 0.5 +0.032594 0.082231 -0.0190597 0.700575 0.5 +-0.0707752 0.142011 -0.00901143 0.440829 0.5 +-0.0396694 0.045239 -0.0210351 0.371561 0.5 +-0.0736488 0.145787 -0.0131048 0.298566 0.5 +-0.0661855 0.1779 -0.0529018 0.456268 0.5 +-0.0698006 0.179227 -0.0517285 0.330383 0.5 +-0.0719677 0.177848 -0.0474604 0.498199 0.393806 +-0.0131817 0.0974247 0.0509808 0.29677 0.5 +-0.0760529 0.177651 -0.0471457 0.200482 0.341482 +-0.0875274 0.149451 0.00937476 0.260452 0.5 +-0.0847504 0.149536 0.00652369 0.220089 0.5 +-0.0853843 0.0980412 -0.000554198 0.453316 0.5 +-0.070162 0.172945 -0.0393132 0.377002 0.42015 +-0.0669053 0.17136 -0.0404187 0.587367 0.5 +-0.0915765 0.114644 0.0108349 0.335405 0.476851 +0.0311175 0.116345 -0.00142056 0.524001 0.485056 +-0.09039 0.144074 0.0142555 0.571623 0.5 +0.0533752 0.0724173 0.00805773 0.504643 0.5 +0.0348115 0.113636 0.00289967 0.517745 0.5 +0.0321047 0.117128 0.00373672 0.512637 0.481334 +-0.0558554 0.16013 0.00226313 0.176407 0.35978 +0.0284127 0.12005 0.00266093 0.800124 0.5 +-0.0693417 0.151526 -0.0443255 0.162625 0.220555 +0.0509143 0.0733396 0.0112131 0.81315 0.5 +0.0485286 0.0726358 0.00856732 0.779683 0.5 +0.0251471 0.122517 0.00254898 0.804299 0.5 +-0.0684168 0.170157 -0.0319531 0.535557 0.5 +-0.071028 0.171274 -0.0325886 0.712016 0.5 +-0.0765634 0.155757 -0.00874762 0.256295 0.5 +0.0525206 0.0734678 0.0148876 0.468908 0.45355 +0.035521 0.113454 0.00908801 0.654915 0.5 +0.0208324 0.125627 0.00327965 0.76886 0.5 +-0.0476722 0.134348 0.0194434 0.579216 0.488505 +-0.0746083 0.171229 -0.0326516 0.439107 0.422901 +0.0322027 0.117616 0.0093642 0.646061 0.5 +0.0162523 0.127588 0.00132734 0.679655 0.445027 +-0.0914669 0.142805 0.0167223 0.344959 0.5 +0.0290775 0.120474 0.00686894 0.798143 0.5 +0.0135909 0.12914 0.00336546 0.632038 0.474565 +-0.0861635 0.100458 0.025719 0.514874 0.431291 +-0.0653051 0.165945 -0.0269849 0.665887 0.5 +-0.0698492 0.16889 -0.0268648 0.536219 0.5 +-0.07827 0.167473 -0.032496 0.259817 0.452429 +0.0215557 0.0945234 -0.0226594 0.630702 0.48336 +0.0260612 0.123082 0.00873766 0.803075 0.5 +0.00920342 0.130081 0.00248247 0.641161 0.5 +-0.0709934 0.170517 -0.0295248 0.566905 0.409383 +-0.0760202 0.167938 -0.0272636 0.242234 0.5 +0.0525229 0.0716654 0.0211203 0.349876 0.431389 +0.0207167 0.126566 0.00922145 0.763786 0.5 +-0.0746025 0.0998033 -0.0126456 0.503102 0.5 +-0.0864333 0.0890874 0.0257055 0.752441 0.5 +0.0354941 0.113435 0.0150848 0.708057 0.5 +0.0320737 0.117698 0.0146262 0.694886 0.5 +0.00294754 0.130714 0.00292443 0.849802 0.5 +-0.0256391 0.0823957 0.0519489 0.764034 0.5 +-0.0666258 0.165416 -0.0221631 0.534987 0.5 +-0.0804177 0.153092 0.00488677 0.321879 0.39417 +-0.0645623 0.0350017 0.0151892 0.352362 0.5 +-0.0627936 0.0352479 0.02012 0.616295 0.5 +-0.0642932 0.0349381 0.0264604 0.161121 0.384305 +-0.0642421 0.0397497 0.0267659 0.206373 0.5 +-0.0652419 0.0352202 0.0324357 0.167045 0.5 +-0.06432 0.0352261 0.0387914 0.349097 0.5 +-0.0869014 0.0944088 0.0260869 0.722262 0.5 +-0.026376 0.100403 -0.0237519 0.527518 0.47737 +-0.0704394 0.0348288 0.00888692 0.228898 0.5 +-0.0696375 0.039673 0.0091864 0.30841 0.5 +-0.0678064 0.035728 0.013362 0.509091 0.5 +-0.0778433 0.0819732 0.0354617 0.774608 0.5 +-0.0809318 0.0827942 0.0325 0.767831 0.5 +-0.0712316 0.038974 0.00275642 0.155719 0.237906 +-0.0616101 0.0379618 0.0219344 0 0 +-0.0653778 0.0407054 0.0323415 0.379158 0.5 +-0.0612949 0.040108 0.0438783 0.388361 0.5 +-0.0748891 0.0826916 0.0381154 0.772848 0.5 +-0.0841641 0.133769 0.0486564 0.546232 0.467433 +-0.0849106 0.0945271 0.0290479 0.754258 0.5 +-0.082994 0.144712 0.0404065 0.382972 0.420138 +-0.0265479 0.117619 -0.0132781 0.755106 0.5 +-0.0679678 0.0383221 0.0123903 0.271535 0.306541 +-0.0639259 0.0401146 0.0151101 0.258252 0.450399 +-0.0588527 0.0407802 0.0202136 0.51937 0.5 +-0.0869621 0.135589 0.0440584 0.520567 0.5 +-0.038827 0.0398484 0.042564 0.570175 0.5 +-0.0253238 0.0773437 0.0501603 0.646885 0.5 +0.00864855 0.111878 -0.0192252 0.821439 0.5 +-0.0625014 0.04424 0.0388616 0.455153 0.47063 +-0.088493 0.125258 0.0461673 0.674925 0.5 +0.0150785 0.10107 -0.0220372 0.749486 0.5 +-0.0810533 0.0876325 0.0334622 0.750019 0.5 +-0.0636602 0.0439221 0.0322355 0.437404 0.5 +-0.0823757 0.12585 -0.00459555 0.376136 0.464207 +-0.0374554 0.042873 0.0429512 0.492581 0.5 +-0.031328 0.0432863 0.0501185 0.483275 0.5 +-0.0841802 0.0875016 0.0285815 0.671149 0.464325 +-0.0690099 0.0427216 0.00298087 0.372436 0.5 +-0.0690323 0.0427133 0.00739115 0.277083 0.5 +-0.0642007 0.0449178 0.00895163 0.562755 0.5 +-0.0630005 0.0427497 0.0133004 0.520064 0.348086 +-0.0580777 0.0444032 0.0143596 0.493924 0.5 +-0.087476 0.130712 0.0458544 0.531379 0.477045 +-0.0837712 0.0999337 0.029339 0.668895 0.5 +-0.083719 0.0822846 0.0270932 0.660348 0.5 +-0.0209183 0.0934772 0.0512134 0.479975 0.5 +-0.0868983 0.142651 0.0383505 0.486766 0.469754 +-0.0588984 0.0467651 0.00989959 0.460736 0.319245 +-0.0529144 0.0464475 0.0158024 0.381525 0.5 +-0.0881654 0.0882094 0.0209192 0.624947 0.5 +-0.0494075 0.165901 0.000731671 0.369742 0.391777 +-0.0586114 0.0473978 0.0337061 0.152377 0.410418 +-0.05614 0.0517476 0.00835186 0.396733 0.5 +-0.0865231 0.148073 0.0321271 0.367072 0.452379 +-0.0308497 0.0493297 0.0429654 0.330168 0.454747 +-0.0769102 0.114994 0.0501188 0.653806 0.5 +-0.0209065 0.0959579 0.0474195 0.622864 0.5 +-0.0509947 0.0509637 0.0150799 0.759028 0.5 +0.00842415 0.0889657 -0.0320537 0.627702 0.5 +-0.0240561 0.0544386 0.0416973 0.433194 0.5 +-0.0510392 0.0524223 0.0203213 0.262945 0.5 +-0.0526208 0.0518271 0.027021 0.695325 0.5 +-0.0504022 0.0591186 0.0326891 0.768296 0.5 +-0.0478821 0.0590694 0.0363134 0.800191 0.5 +-0.0239128 0.0586553 0.0421308 0.768223 0.5 +-0.0759314 0.119228 -0.00697007 0.568703 0.5 +-0.0183181 0.0604564 0.0506182 0.70539 0.5 +-0.0298441 0.0972531 -0.0235715 0.830462 0.5 +-0.0241926 0.0628773 0.0422936 0.709715 0.5 +-0.0223998 0.06467 0.045979 0.606456 0.5 +-0.0192899 0.0641483 0.0503928 0.754401 0.5 +-0.0260109 0.172925 -0.0191453 0.51739 0.5 +-0.0265331 0.161574 -0.0144318 0.84044 0.5 +-0.0558556 0.15572 -0.00121016 0.41523 0.5 +-0.0599028 0.136466 -0.0064456 0.660892 0.5 +-0.063538 0.071665 0.0379463 0.556494 0.5 +-0.0200417 0.0869862 -0.0378876 0.500126 0.449734 +-0.0557176 0.105745 -0.0186241 0.707273 0.5 +-0.0530691 0.143914 -0.00100898 0.728895 0.5 +-0.0256688 0.0704637 0.0438935 0.717372 0.393932 +-0.0235577 0.0693774 0.0470203 0.657726 0.5 +-0.0525759 0.127247 -0.00521525 0.567734 0.5 +-0.0787859 0.131858 -0.00545913 0.44224 0.460808 +-0.0580212 0.120088 -0.0102747 0.564344 0.455328 +-0.0396294 0.110441 -0.0186258 0.62346 0.5 +-0.0210282 0.173113 -0.0214922 0.42389 0.352327 +-0.0547593 0.0563289 0.0107147 0.179388 0.5 +-0.0435534 0.0345758 -0.024752 0.176398 0.205782 +-0.0449833 0.0346921 -0.0207483 0.159962 0.261208 +-0.0443576 0.0390403 -0.0217491 0.178142 0.5 +-0.0462855 0.0345037 -0.0153112 0.189574 0.5 +-0.046619 0.0396457 -0.0141457 0.194812 0.5 +-0.00904923 0.0343826 -0.0246429 0.15305 0.5 +0.00311748 0.100303 -0.0227929 0.684313 0.5 +-0.0690809 0.0392217 -0.00181724 0.169982 0.409113 +-0.0920289 0.131041 0.0262349 0.856795 0.5 +-0.043414 0.0372487 -0.0253064 0.219927 0.5 +0.0280974 0.0818294 -0.0220931 0.752623 0.5 +-0.067702 0.169446 -0.0560134 0.487347 0.455218 +-0.0915377 0.129674 0.0312365 0.601516 0.48259 +-0.0663086 0.0411162 -0.00443149 0.346306 0.5 +-0.0731255 0.151935 -0.0368879 0.40925 0.5 +-0.0390145 0.0394889 -0.027598 0.3765 0.5 +-0.0637372 0.0437827 -0.00264533 0.37233 0.5 +-0.0605427 0.0425565 0.0246975 0.23689 0.5 +-0.0857603 0.130763 -0.000714461 0.66754 0.5 +-0.0520472 0.0403573 -0.0107411 0.62257 0.5 +-0.0568522 0.0434504 0.0224413 0.404188 0.5 +-0.043239 0.0429342 -0.0193166 0.339314 0.38382 +-0.0438787 0.0441322 -0.0144222 0.427488 0.468839 +-0.0457505 0.046486 -0.0105694 0.340556 0.5 +-0.0645938 0.0456897 0.00313082 0.3549 0.5 +-0.0525978 0.0464843 0.0207116 0.3335 0.5 +-0.0572578 0.0459489 0.026887 0.439332 0.5 +-0.0618962 0.0443648 0.0286813 0.302557 0.45843 +-0.0331467 0.0453179 -0.0267282 0.481653 0.5 +-0.0377669 0.0443547 -0.0252099 0.392631 0.5 +-0.0320922 0.114425 -0.0162304 0.853943 0.5 +-0.0578027 0.0470669 -0.0032674 0.530144 0.5 +-0.0914954 0.147994 0.0205137 0.478387 0.480384 +-0.0400067 0.0471536 -0.0151042 0.224844 0.33752 +0.00454895 0.121869 -0.0124797 0.622385 0.5 +0.0151282 0.112708 -0.0165496 0.634759 0.463552 +-0.0525787 0.0463291 -0.00775444 0.598118 0.5 +-0.0599276 0.0475112 0.00267117 0.286734 0.429608 +-0.0726458 0.147126 -0.0218625 0.235551 0.5 +-0.0740924 0.168686 -0.0440312 0.451963 0.347747 +-0.057494 0.0515426 0.00319413 0.311918 0.5 +-0.0536918 0.0483048 0.0264945 0.447469 0.5 +-0.0147156 0.114453 -0.0172255 0.634887 0.5 +-0.0335191 0.0480424 -0.021246 0.299501 0.5 +0.019461 0.0924333 -0.0244344 0.636237 0.5 +0.0169402 0.0952065 -0.0238278 0.793707 0.5 +0.0201047 0.104156 -0.0188197 0.859301 0.5 +-0.0319642 0.0516657 -0.0152509 0.265727 0.5 +-0.0368448 0.0488256 -0.0131071 0.109826 0.5 +-0.0391265 0.0518909 -0.0109467 0.555432 0.5 +-0.00892221 0.111576 -0.0202733 0.785262 0.5 +-0.0515659 0.0515158 -0.00751393 0.527245 0.5 +-0.0557028 0.05294 -0.00268598 0.514955 0.5 +-0.0293421 0.0526398 -0.0213991 0.356317 0.5 +-0.0314453 0.0496351 -0.0193539 0.306544 0.5 +0.0322381 0.10409 -0.0128482 0.653044 0.5 +-0.0261025 0.0525801 -0.0264669 0.366688 0.5 +-0.0583031 0.116733 -0.0130038 0.568329 0.5 +-0.014851 0.111599 -0.0191484 0.630253 0.463696 +-0.0521348 0.118189 -0.0137451 0.464136 0.474515 +-0.0517493 0.0582798 -0.00896954 0.683087 0.5 +-0.0561982 0.0582462 -0.00310645 0.618759 0.5 +-0.0587989 0.0586119 0.00276734 0.328771 0.427166 +-0.0585564 0.0578416 0.00857596 0.293131 0.5 +0.019026 0.11614 -0.0131686 0.497701 0.5 +-0.0211893 0.111662 -0.0190883 0.650648 0.5 +-0.0239176 0.0561149 -0.030057 0.484351 0.5 +-0.0272603 0.058548 -0.027478 0.457773 0.5 +-0.0295766 0.0582799 -0.0217551 0.550969 0.5 +-0.0320928 0.0589382 -0.0147618 0.534177 0.453646 +0.0073938 0.121789 -0.0126555 0.654152 0.5 +-0.0251946 0.0595227 -0.0308632 0.509396 0.5 +-0.0307167 0.06013 -0.0194181 0.549851 0.422118 +-0.0650113 0.0632174 -0.00293095 0.168435 0.5 +-0.0696479 0.065751 -0.00198101 0.165663 0.5 +-0.0699926 0.0635013 0.00374106 0.275779 0.5 +-0.0799435 0.0724812 0.0191514 0.599916 0.5 +-0.0676844 0.160922 -0.0559942 0.35716 0.5 +-0.0215435 0.0636559 -0.0350431 0.45692 0.5 +-0.0258325 0.0648252 -0.0322087 0.452259 0.5 +-0.028982 0.0636438 -0.0274997 0.410415 0.5 +-0.0304226 0.0629368 -0.0224261 0.908229 0.5 +-0.0319042 0.0651819 -0.0201942 0.518875 0.434998 +-0.0332741 0.0636337 -0.0160032 0.40837 0.447765 +-0.0205547 0.034111 -0.026401 0.174612 0.215481 +-0.0743367 0.0658286 0.00833126 0.649876 0.5 +0.016103 0.120745 -0.0103843 0.509865 0.5 +-0.0770212 0.0700544 0.00316631 0.305775 0.384345 +-0.0748219 0.06693 0.00451345 0.433069 0.463791 +-0.0306317 0.0657524 -0.025453 0.517895 0.5 +-0.0711433 0.0687078 -0.00390291 0.256016 0.135401 +-0.0762625 0.0716316 -0.00295918 0.293636 0.296358 +-0.0802204 0.0713935 0.00991267 0.507181 0.5 +-0.0913413 0.148143 0.0161458 0.474933 0.5 +-0.0273736 0.0700052 -0.0335323 0.445714 0.5 +-0.0300274 0.0692073 -0.0289677 0.511122 0.5 +-0.0316277 0.0711218 -0.0266514 0.502235 0.5 +-0.0330629 0.0699765 -0.0212743 0.929225 0.5 +-0.0353642 0.0705896 -0.0177097 0.263666 0.5 +-0.0587004 0.0391044 -0.0090027 0.295521 0.5 +-0.0697696 0.0703857 -0.00808666 0.238472 0.5 +-0.0804832 0.0726462 0.00472466 0.630221 0.5 +0.0151616 0.126104 -0.00266395 0.542796 0.5 +-0.0745721 0.072883 -0.00757069 0.303203 0.5 +-0.0823908 0.076277 0.00270117 0.615888 0.5 +-0.0912831 0.133698 0.0142161 0.68945 0.5 +0.00371049 0.0968817 -0.0280931 0.670854 0.5 +-0.0761392 0.0766258 -0.00859487 0.260107 0.5 +-0.0784749 0.0748827 -0.00523624 0.238143 0.440892 +-0.0806781 0.0771902 -0.00290803 0.36458 0.43512 +-0.0834622 0.0765209 0.00927112 0.562933 0.5 +0.00983826 0.11402 -0.0178612 0.519736 0.475688 +0.00210649 0.0981565 -0.0261244 0.689185 0.5 +-0.0285085 0.0757575 -0.0348118 0.64535 0.304239 +-0.0330874 0.0761249 -0.0270661 0.564742 0.5 +-0.0346568 0.0757906 -0.0215029 0.930953 0.5 +0.0231104 0.0892807 -0.0240236 0.697809 0.45449 +-0.0312132 0.0771357 -0.0320416 0.687582 0.5 +-0.0700425 0.0763633 -0.0141464 0.485274 0.5 +-0.0861137 0.0814707 0.00908143 0.590509 0.5 +-0.086319 0.08152 0.0149936 0.698173 0.5 +-0.0208042 0.0963182 -0.0270563 0.75553 0.5 +-0.0211078 0.114391 -0.0171285 0.793027 0.5 +-0.0746162 0.0828529 -0.0139325 0.683447 0.5 +-0.077295 0.081216 -0.0100568 0.47673 0.5 +-0.0800127 0.0821605 -0.00722237 0.637376 0.5 +-0.0826334 0.0820868 -0.00324616 0.569954 0.5 +-0.0844667 0.0817669 0.00249573 0.601403 0.5 +-0.0860445 0.0832591 0.0203255 0.630527 0.5 +-0.084816 0.0816746 0.0219849 0.638209 0.5 +0.0545549 0.0661692 0.000765649 0.628404 0.43579 +-0.0331604 0.0828369 -0.0270493 0.417784 0.5 +-0.0358028 0.0829047 -0.0227723 0.112354 0 +-0.0861942 0.0842505 0.00298565 0.418742 0.5 +-0.0287072 0.0827267 -0.0349537 0.48086 0.471486 +-0.0311601 0.0822387 -0.0315627 0.627475 0.5 +-0.085403 0.141865 0.00516647 0.463398 0.5 +-0.0785169 0.0885628 -0.0107607 0.69884 0.5 +-0.0807046 0.0887676 -0.00826584 0.689404 0.5 +-0.0843972 0.0878743 -0.00349923 0.402052 0.5 +-0.0855708 0.0882073 -0.00109946 0.425364 0.422235 +-0.0876157 0.0881286 0.00369184 0.414972 0.435161 +-0.0885339 0.0876942 0.00897158 0.630733 0.5 +-0.0885791 0.0877213 0.0149616 0.665472 0.5 +-0.0643854 0.0348576 -0.00775085 0.279509 0.5 +-0.0512932 0.034227 -0.0129013 0.159841 0.5 +-0.0266839 0.0458556 -0.027274 0.610127 0.5 +-0.0146368 0.0981541 -0.0264318 0.44201 0.5 +-0.0213468 0.10077 -0.0239588 0.58675 0.5 +0.020932 0.0825954 -0.0267347 0.750174 0.5 +0.00759225 0.0928541 -0.0309237 0.580726 0.5 +-0.0144478 0.0879274 -0.0380297 0.689122 0.5 +-0.00859724 0.11451 -0.0173132 0.77831 0.5 +0.0264818 0.109935 -0.0126182 0.652634 0.5 +-0.0145855 0.0385179 -0.0267991 0.230538 0.5 +-0.0330054 0.0337044 -0.0272991 0.262513 0.5 +-0.0267872 0.0340475 -0.0271901 0.244173 0 +-0.00849157 0.0985859 -0.0270535 0.53889 0.411612 +-0.0110954 0.120824 -0.0120135 0.770076 0.5 +0.0367379 0.0925992 -0.0129888 0.684003 0.5 +-0.0571635 0.0435755 -0.00717607 0.581004 0.404197 +-0.0193328 0.0979251 -0.024792 0.661276 0.5 +-0.0203798 0.0385467 -0.0283088 0.392689 0.5 +-0.0587681 0.0337133 -0.00871891 0.1361 0.5 +-0.0517919 0.100655 -0.0213258 0.798237 0.5 +0.00702627 0.0978418 -0.0246055 0.732067 0.326346 +-0.0148892 0.126068 -0.00252126 0.467449 0.5 +0.0307578 0.092446 -0.0188519 0.704525 0.5 +0.0211049 0.0578126 -0.0266116 0.685576 0.5 +-0.0169237 0.0970481 -0.0278718 0.775366 0.5 +0.0460004 0.0581866 -0.00508589 0.612698 0.5 +-0.00944331 0.0822271 -0.0381067 0.670336 0.467319 +-0.0635881 0.0392124 -0.00717766 0.572252 0.5 +0.00864227 0.0386371 -0.0233053 0.540697 0.5 +0.0252935 0.0769557 -0.0248407 0.75695 0.5 +-0.0229653 0.0895159 -0.036199 0.454072 0.467569 +-0.0523791 0.0341193 -0.00994653 0.132813 0.5 +0.0211693 0.0643935 -0.0268578 0.690366 0.5 +-0.0515867 0.13164 -0.0028092 0.545448 0.5 +-0.0149669 0.0345529 -0.0254273 0.17846 0.5 +-0.0161167 0.127288 0.00169291 0.694465 0.5 +-0.0469232 0.128515 -0.00163965 0.389857 0.5 +-0.00961381 0.127158 -0.00378809 0.714685 0.5 +-0.0074566 0.128562 -0.00130751 0.72817 0.5 +-0.00304493 0.128909 -0.00174857 0.778769 0.5 +0.0028379 0.129022 -0.00194723 0.574275 0.5 +0.00903363 0.128674 -0.00165013 0.617309 0.5 +-0.0561607 0.131588 -0.00571429 0.687735 0.5 +-0.0457551 0.127167 -0.00484962 0.645893 0.5 +-0.00304746 0.127678 -0.00456004 0.562309 0.5 +0.00303811 0.12768 -0.00442 0.624596 0.5 +0.0101526 0.126812 -0.00466464 0.64326 0.5 +-0.0553259 0.126836 -0.00601308 0.517644 0.5 +0.00799473 0.034846 -0.0206913 0.278473 0.5 +0.0027179 0.0342191 -0.0204737 0.322372 0.5 +-0.00295804 0.0342418 -0.0216222 0.194059 0.5 +0.0134674 0.0353221 -0.0196961 0.466171 0.5 +0.00440963 0.0383063 -0.0240776 0.3469 0.5 +0.00140752 0.0383474 -0.0246147 0.361099 0.5 +-0.00309177 0.0383877 -0.0251866 0.314174 0.5 +-0.0575023 0.100661 -0.0195211 0.459895 0.452391 +-0.0485739 0.15316 -0.00547278 0.691758 0.5 +-0.0646573 0.0334831 -0.00296009 0.187639 0.5 +-0.0640796 0.100426 -0.0173936 0.44544 0.466101 +-0.0704415 0.100139 -0.0146037 0.499781 0.478548 +-0.0326376 0.155806 -0.00949884 0.828995 0.5 +0.0336094 0.0373624 0.00273412 0.290019 0.5 +0.0320943 0.0397885 -0.00195136 0.323719 0.5 +0.0158502 0.0449602 -0.0237212 0.910511 0.5 +0.00889467 0.0426449 -0.0242659 0.891863 0.5 +0.00312499 0.0452721 -0.026588 0.665265 0.460024 +-0.00298345 0.044686 -0.0272222 0.905955 0.5 +-0.00912346 0.0448524 -0.0280671 0.895801 0.5 +-0.0145351 0.0443266 -0.0277771 0.887903 0.5 +-0.0209223 0.0460913 -0.0281918 0.705844 0.5 +0.034052 0.0448434 -0.00540113 0.626363 0.5 +-0.0312646 0.158257 -0.01223 0.732334 0.5 +0.0401509 0.0448981 -0.00354586 0.446696 0.5 +0.0143253 0.0473484 -0.0251513 0.546545 0.456757 +0.00937888 0.0466526 -0.0261685 0.907397 0.5 +-0.0766531 0.0695423 0.0207982 0.774152 0.5 +0.0087246 0.0517916 -0.0291615 0.840924 0.5 +0.00299372 0.0506927 -0.0298557 0.901259 0.5 +-0.00164566 0.0489436 -0.0304144 0.872257 0.5 +-0.00321397 0.0522596 -0.0314075 0.634884 0.475184 +-0.00915341 0.0509217 -0.0318681 0.650022 0.5 +-0.0146018 0.0513752 -0.0319045 0.891033 0.5 +-0.0161558 0.0488543 -0.0303763 0.808351 0.5 +-0.0205843 0.0508011 -0.0296435 0.813106 0.5 +0.0405252 0.0518855 -0.00654453 0.65569 0.5 +0.0149309 0.0520772 -0.0273859 0.655547 0.5 +0.041884 0.0490868 -0.00604367 0.898378 0.5 +0.019962 0.0529908 -0.0261219 0.592286 0.5 +-0.0198501 0.0534234 -0.0312267 0.768335 0.5 +-0.0336273 0.0527187 -0.0106243 0.102172 0.5 +-0.0461112 0.0529158 -0.0101664 0.636429 0.372142 +-0.0204 0.161875 -0.014658 0.822907 0.5 +0.0449924 0.0530898 -0.00614891 0.575737 0.5 +0.00733679 0.0546532 -0.0305038 0.688621 0.5 +0.00283568 0.0546532 -0.0307468 0.611749 0.5 +-0.00302245 0.0577 -0.0331477 0.67582 0.5 +-0.00914668 0.0576676 -0.0341165 0.698389 0.5 +-0.01517 0.058199 -0.0349877 0.856637 0.5 +-0.0202707 0.0581031 -0.0333681 0.552506 0.5 +0.0140844 0.057965 -0.028983 0.564173 0.483714 +0.0103301 0.0588553 -0.0299472 0.602031 0.489059 +0.00732823 0.0588898 -0.0306117 0.710141 0.5 +0.0027369 0.0590151 -0.0321928 0.690932 0.5 +-0.0337187 0.0579742 -0.0115824 0.143826 0.5 +-0.0390711 0.0582467 -0.0115033 0.780735 0.5 +-0.0460474 0.0579124 -0.0115174 0.472305 0.5 +-0.00961439 0.0642168 -0.0358564 0.670518 0.457134 +-0.044157 0.0599825 -0.0123877 0.830365 0.5 +0.015251 0.0645803 -0.029567 0.626368 0.396114 +0.00839294 0.0649214 -0.0316957 0.79033 0.385997 +0.00325858 0.0643529 -0.0332439 0.728322 0.418376 +-0.00361257 0.0645861 -0.034907 0.670644 0.5 +-0.0144709 0.065006 -0.0371603 0.712311 0.5 +-0.0366623 0.060679 -0.0122791 0.525705 0.5 +-0.0526404 0.0636402 -0.0101297 0.452904 0.5 +-0.0381866 0.0648919 -0.0142073 0.543504 0.5 +-0.0452495 0.0647856 -0.0139819 0.883769 0.5 +-0.0599262 0.0622966 -0.00429285 0.195385 0.344922 +-0.0778641 0.117463 -0.00576778 0.523105 0.5 +-0.0187447 0.0664151 -0.0374779 0.820087 0.5 +-0.0577616 0.0644884 -0.00779097 0.472929 0.5 +-0.0625778 0.0655353 -0.00741131 0.379588 0.453283 +0.0251088 0.0710945 -0.0248604 0.704567 0.5 +0.021457 0.0702729 -0.0273415 0.740248 0.5 +0.0166747 0.0701586 -0.0297203 0.658948 0.5 +0.0132745 0.0702643 -0.0312074 0.651019 0.5 +0.00867525 0.0703509 -0.0324278 0.818076 0.5 +0.00229643 0.0708694 -0.0343123 0.73028 0.5 +-0.0030646 0.070381 -0.0353565 0.764349 0.5 +-0.00773679 0.0691749 -0.0362051 0.757441 0.5 +-0.0101988 0.0715122 -0.0373778 0.76291 0.5 +-0.0147454 0.0704429 -0.0382943 0.581028 0.470136 +-0.0203984 0.0706516 -0.038158 0.645161 0.5 +-0.0240967 0.0693418 -0.0362521 0.4533 0.5 +-0.0605175 0.0673597 -0.0108259 0.635082 0.5 +-0.0387293 0.0706355 -0.0168457 0.666323 0.5 +-0.0451347 0.0705064 -0.0164504 0.875899 0.5 +-0.0523435 0.0697862 -0.0145984 0.401473 0.5 +-0.0591515 0.0702891 -0.0147203 0.639534 0.5 +-0.0652515 0.0688492 -0.00993982 0.422384 0.422462 +-0.0247614 0.0719777 -0.0368317 0.497524 0.5 +-0.0637884 0.0712697 -0.0138535 0.437166 0.5 +0.0211454 0.0769268 -0.0268772 0.737516 0.5 +0.0162128 0.0765268 -0.0293784 0.712202 0.5 +0.0133247 0.0760196 -0.0306715 0.679361 0.5 +0.00907695 0.076038 -0.0330382 0.719764 0.5 +0.00245085 0.0760857 -0.0351615 0.721395 0.5 +-0.00176321 0.0762288 -0.0360688 0.799862 0.5 +-0.00476487 0.076286 -0.0369742 0.814155 0.377247 +-0.00962992 0.0765936 -0.0378651 0.627364 0.487104 +-0.0144481 0.0764118 -0.0385775 0.832444 0.5 +-0.021453 0.0763574 -0.038668 0.751656 0.5 +-0.024977 0.0762484 -0.0374518 0.39297 0.457854 +-0.0377453 0.0766164 -0.0189124 0.273711 0.5 +-0.0397395 0.0746623 -0.0180255 0.973337 0.5 +-0.0437423 0.0765905 -0.0187922 0.595439 0.440211 +-0.0466377 0.0744845 -0.0173668 0.538698 0.468502 +-0.0518623 0.0745812 -0.0175084 0.855826 0.5 +-0.0589866 0.0745368 -0.01766 0.879682 0.5 +-0.0644081 0.0756279 -0.0167529 0.562234 0.481782 +-0.0721295 0.0740256 -0.0105719 0.341576 0.432723 +-0.0615233 0.0354132 0.043881 0.499903 0.5 +-0.0524971 0.0769872 -0.0189536 0.873913 0.5 +-0.0587482 0.0767445 -0.0187462 0.882838 0.5 +0.013102 0.0809953 -0.0307917 0.69611 0.5 +0.00892296 0.0820652 -0.0325478 0.700162 0.5 +0.0022917 0.0820297 -0.0349279 0.829579 0.5 +-0.00177837 0.0804805 -0.0364471 0.647084 0.379833 +-0.00379684 0.0824193 -0.037328 0.824332 0.5 +-0.0142988 0.0820384 -0.0390211 0.832022 0.373406 +-0.0207708 0.0823862 -0.0387335 0.805306 0.5 +-0.0248089 0.0818968 -0.0377031 0.470046 0.439483 +-0.0735819 0.0777026 -0.0122023 0.445372 0.5 +0.015425 0.0831288 -0.0295207 0.735694 0.5 +-0.0383994 0.0817919 -0.0209596 0.290803 0.5 +-0.0451184 0.0815526 -0.020434 0.548777 0.45056 +-0.051814 0.0818472 -0.0211348 0.886135 0.5 +-0.0583689 0.0812724 -0.0202975 0.847354 0.5 +-0.063949 0.082768 -0.0188935 0.606874 0.5 +-0.0662709 0.080065 -0.0177832 0.593549 0.449354 +-0.0695594 0.0830593 -0.0170582 0.4495 0.5 +-0.00481814 0.086841 -0.0367951 0.827149 0.5 +-0.0248206 0.0867524 -0.0367639 0.487957 0.5 +0.0132046 0.0871602 -0.0305473 0.663835 0.5 +-0.0360837 0.0867076 -0.023791 0.366486 0.5 +-0.00877843 0.0340556 -0.0204927 0 0 +-0.0207128 0.0342382 -0.0208728 0.319674 0.5 +-0.0147915 0.0341096 -0.0207616 0.312592 0.5 +-0.0265767 0.0342963 -0.0210989 0.482378 0.5 +0.00282685 0.0351053 -0.0158136 0.508357 0.5 +0.00885967 0.034471 -0.0147487 0.490133 0.5 +-0.0390848 0.0337228 -0.0202617 0.628543 0.5 +-0.0326656 0.0345334 -0.0201874 0.788348 0.5 +-0.00224535 0.0351539 -0.0166234 0.756398 0.5 +-0.0149096 0.0357313 -0.0180956 0.933106 0.5 +-0.0114808 0.0353662 -0.0177045 0.933613 0.5 +-0.00921575 0.0380183 -0.0149732 0.909294 0.5 +-0.00282494 0.0382292 -0.0140636 0.920543 0.5 +0.00285919 0.0377324 -0.0134715 0.965028 0.5 +0.0159109 0.0347098 -0.00882204 0.420938 0.5 +-0.0306839 0.036693 -0.0184598 0.875112 0.5 +-0.0265216 0.0367471 -0.0188177 0.84266 0.5 +-0.0218341 0.0369718 -0.0184303 0.873319 0.5 +-0.0203027 0.0382765 -0.0152577 0.887215 0.5 +-0.0152596 0.0382328 -0.0156428 0.873575 0.5 +0.00738356 0.0366172 -0.0125003 0.962688 0.5 +0.00992361 0.0351979 -0.00924624 0.9642 0.5 +0.00702596 0.0378387 -0.00879015 0.927286 0.5 +-0.0396958 0.0342843 -0.014578 0.76643 0.5 +-0.0329517 0.0382154 -0.014678 0.654319 0.5 +-0.0263862 0.0385778 -0.0153644 0.924592 0.5 +0.00320835 0.0389424 -0.00953857 0.945732 0.5 +-0.0364387 0.0357946 -0.0155844 0.543249 0.5 +-0.00301526 0.0391061 -0.00886496 0.816802 0.5 +0.00831664 0.0348156 -0.00321961 0.671683 0.5 +0.0145039 0.0343685 -0.0028433 0.748562 0.5 +-0.0365752 0.0370276 -0.0136534 0.498247 0.5 +-0.0146234 0.0388055 -0.00887465 0.759701 0.5 +-0.00886749 0.0389394 -0.00890173 0.761944 0.5 +-0.0451032 0.0336721 -0.00848668 0.772585 0.5 +-0.040313 0.0350801 -0.00861758 0.462745 0.5 +-0.0206235 0.0386 -0.00878063 0.747754 0.5 +0.00267879 0.038424 -0.00319748 0.448355 0.5 +0.015044 0.0350517 0.00289039 0.579133 0.5 +0.0201479 0.0347806 0.00348327 0.403273 0.5 +0.027119 0.0353514 0.00366834 0.0909279 0.5 +0.0280785 0.0365531 0.000826759 0 0 +-0.0376066 0.0375692 -0.00942418 0.22755 0.5 +-0.0332748 0.0384549 -0.00855692 0.752109 0.5 +-0.0264541 0.0384497 -0.00886193 0.729343 0.5 +-0.00299262 0.0389582 -0.00292437 0.746846 0.5 +0.00451408 0.0356078 -0.00103635 0.413486 0.5 +0.00881079 0.0350428 0.00356828 0.588251 0.5 +0.0314184 0.0360255 0.00457907 0.187967 0.5 +-0.00888202 0.0387884 -0.00299409 0.73859 0.5 +0.00271787 0.0349091 0.00339755 0.645421 0.5 +-0.041199 0.0341471 -0.00327644 0 0 +-0.0205479 0.0384259 -0.00283766 0.741413 0.5 +-0.0146618 0.0385908 -0.00288739 0.718901 0.5 +0.00103528 0.0375917 0.000952222 0.441385 0.5 +0.0215747 0.0354906 0.0086194 0.395945 0.5 +0.0264794 0.0346514 0.00870654 0.414057 0.5 +0.0322391 0.0355412 0.00882378 0.515667 0.5 +-0.0521057 0.0334794 -0.00318207 0.614129 0.5 +-0.0455078 0.0336572 -0.00225818 0.757211 0.5 +-0.0334104 0.0383259 -0.00292317 0.611245 0.5 +-0.0265122 0.0383343 -0.00296504 0.763748 0.5 +-0.00224847 0.0383354 0.00320971 0.728422 0.5 +-0.0589386 0.0334143 -0.00291301 0.444064 0.5 +-0.00874044 0.0385976 0.00291227 0.735039 0.5 +0.00273457 0.0342734 0.0088248 0.796819 0.5 +0.00621941 0.0351341 0.00654928 0 0 +-0.080018 0.109279 0.0373655 0.503151 0.426569 +-0.0393178 0.0336443 0.00354096 0.266658 0.5 +-0.0213111 0.0382973 0.00334866 0.753895 0.5 +-0.0146196 0.0384265 0.00290922 0.762157 0.5 +-0.00353554 0.0379644 0.00874752 0.658939 0.5 +0.0276681 0.0349662 0.0149532 0.360666 0.5 +0.03282 0.0359255 0.0147037 0.719837 0.5 +0.0389763 0.0383079 0.0145025 0.635106 0.5 +-0.0523961 0.0335249 0.00326874 0.742717 0.5 +-0.0462346 0.0335696 0.00267776 0.743661 0.5 +-0.0277984 0.0382296 0.00286126 0.456211 0.5 +-0.000947006 0.0357374 0.0103469 0.779853 0.5 +0.0222276 0.0358262 0.0160256 0.180494 0.5 +0.0448051 0.0411192 0.0150961 0.294679 0.5 +-0.0581064 0.033504 0.00272997 0.775526 0.5 +-0.0352323 0.0337248 0.00491425 0.152905 0 +-0.0312985 0.0381858 0.00167702 0 0 +-0.0088641 0.03847 0.00876261 0.73345 0.5 +0.0028919 0.0342894 0.0147059 0.676527 0.5 +-0.0703332 0.0340583 0.00286723 0.639535 0.5 +-0.0648245 0.0334924 0.00301734 0.793089 0.5 +-0.0387963 0.034763 0.00935652 0.458758 0.5 +-0.0332327 0.0337932 0.00943608 0.151116 0.5 +-0.0203456 0.0382265 0.00836296 0.759992 0.5 +-0.0152156 0.0383161 0.00935801 0.755179 0.5 +-0.000385714 0.0351459 0.0134171 0.848157 0.5 +0.00663645 0.0342324 0.0159688 0 0 +0.0268074 0.0356469 0.0204126 0.619176 0.5 +0.0309391 0.0362152 0.0189937 0.762661 0.5 +0.0334119 0.0376179 0.0210082 0.70177 0.5 +-0.0515734 0.0338904 0.00817232 0.493124 0.5 +-0.0454999 0.0352808 0.00804865 0.53914 0.5 +-0.0263229 0.0380313 0.00871732 0.143858 0.5 +-0.0031858 0.0377098 0.014513 0.797449 0.5 +0.0211051 0.0351552 0.0207004 0.432057 0.5 +0.0391983 0.0395969 0.0205879 0.670001 0.5 +0.0441778 0.0418755 0.0204802 0.609797 0.5 +-0.0580282 0.0335624 0.00918162 0.776077 0.5 +-0.00922404 0.0383488 0.0150261 0.754001 0.5 +0.00313746 0.0352426 0.0204176 0.692001 0.5 +0.00877508 0.0346179 0.020856 0.290121 0.5 +0.0468489 0.0434226 0.0210936 0.239557 0.5 +-0.0648031 0.0337402 0.00884817 0.802283 0.5 +-0.0338156 0.0345063 0.0150293 0.572312 0.5 +-0.0149173 0.0382498 0.0147214 0.753708 0.5 +0.0146344 0.0345628 0.0222588 0.157065 0.5 +-0.0365655 0.0357926 0.0130139 0.391807 0.5 +-0.0262153 0.0376693 0.0148666 0.146481 0.5 +-0.0205165 0.0381248 0.0146779 0.715632 0.5 +-0.00229335 0.0382456 0.020565 0.923102 0.5 +0.014723 0.0347707 0.0263935 0.310145 0.5 +0.0210245 0.0353476 0.0265418 0.313898 0.5 +0.0250756 0.0364517 0.0246847 0.678097 0.5 +0.0273584 0.0381522 0.0267127 0.778478 0.5 +0.0321164 0.0401984 0.026762 0.778536 0.5 +-0.053829 0.0335431 0.0139547 0.458851 0.5 +0.00114114 0.037661 0.0223414 0.978558 0.5 +0.00915473 0.0353589 0.0262457 0.701449 0.5 +0.0380552 0.0412819 0.02589 0.374179 0.417844 +-0.0588034 0.0336951 0.0146283 0.798139 0.5 +-0.0339319 0.0346253 0.0202274 0.513983 0.5 +-0.0152545 0.0382629 0.0204704 0.75125 0.5 +-0.00888844 0.0384087 0.0207206 0.746481 0.5 +0.00307272 0.0384964 0.0264151 0.996029 0.5 +-0.0261643 0.0378491 0.0205422 0.603577 0.5 +-0.0205429 0.0381473 0.0213758 0.772551 0.5 +-0.0538188 0.0335608 0.0210581 0 0 +-0.00301594 0.03875 0.0263901 0.805634 0.5 +0.00756209 0.0380712 0.0285007 0.978659 0.5 +0.0143741 0.0348327 0.0331833 0.915728 0.5 +0.0198279 0.03555 0.0321213 0.749506 0.5 +0.0236875 0.0373106 0.0299772 0.517201 0.5 +-0.0588476 0.033906 0.020465 0.657735 0.5 +-0.00882687 0.0386047 0.0265705 0.756827 0.5 +0.00847025 0.0383344 0.0315598 0.739987 0.5 +0.0108958 0.035647 0.0330663 0.649316 0.5 +-0.0366651 0.0353042 0.023032 0.153172 0.5 +-0.0340084 0.0344659 0.0266224 0.263742 0.5 +-0.0270447 0.0379104 0.0270529 0.074682 0.5 +-0.0210471 0.0383013 0.026282 0.782021 0.5 +-0.0147317 0.0384888 0.0265233 0.791552 0.5 +-0.0712786 0.0733348 0.0355839 0.683322 0.427231 +-0.0388887 0.0346255 0.0265538 0.109729 0 +0.00290004 0.0393205 0.032168 0.626516 0.5 +0.0155389 0.0350901 0.0393977 0.759188 0.5 +0.0195159 0.0358111 0.0367948 0.405286 0.5 +-0.0589139 0.0341314 0.0264586 0.808252 0.5 +-0.052234 0.0340737 0.0268887 0.497915 0.5 +-0.0447866 0.0339274 0.0274346 0.154159 0.5 +-0.0310127 0.0369382 0.02848 0.240675 0.5 +-0.00908756 0.0390146 0.0330901 0.79352 0.5 +-0.00293287 0.039209 0.03365 0.804769 0.5 +0.00861952 0.0346654 0.0391536 0.125418 0.5 +-0.0149144 0.0388312 0.0324344 0.795183 0.5 +0.00392423 0.0347398 0.0399064 0.146347 0.5 +-0.0657827 0.0618455 0.00187562 0.442355 0.5 +-0.0640051 0.0606097 0.00361345 0.333039 0.5 +-0.0455164 0.0345095 0.0326748 0.510388 0.5 +-0.0385699 0.0344168 0.033204 0.485482 0.5 +-0.0342024 0.0351611 0.0325685 0.248514 0.5 +-0.0270303 0.0384799 0.0326469 0.783767 0.5 +-0.0209433 0.0387397 0.0332273 0.806699 0.5 +-0.0520994 0.0344582 0.0326775 0.466807 0.5 +-0.0313489 0.0377268 0.0321213 0.178238 0.5 +-0.00219023 0.0348305 0.0410082 0.139343 0 +0.00818206 0.0355366 0.0443043 0.642932 0.5 +0.014947 0.0361331 0.0431407 0.796588 0.5 +-0.0642564 0.0597236 0.0092932 0.716255 0.5 +-0.0584732 0.0343588 0.0331559 0.775713 0.5 +-0.0145859 0.0393004 0.0380317 0.483641 0.5 +-0.00937548 0.0394517 0.037871 0.328321 0.5 +-0.0588297 0.0579582 0.0145443 0 0 +-0.038732 0.0346956 0.0400227 0.628019 0.5 +-0.0331487 0.034492 0.0390527 0.154826 0.5 +-0.0201914 0.0391628 0.0381696 0.483919 0.5 +-0.00878985 0.0348233 0.0452949 0.139305 0.5 +-0.0031441 0.0351515 0.045825 0.295611 0.5 +-0.0701619 0.0622789 0.00863964 0.42197 0.408074 +-0.0451191 0.034688 0.0396457 0.766116 0.5 +-0.0256628 0.0389081 0.0373249 0 0 +-0.0146115 0.0348173 0.0458198 0.143796 0.5 +-0.0636462 0.0593677 0.014889 0.807508 0.5 +-0.0531671 0.0345191 0.0391729 0.74918 0.5 +-0.0595372 0.034497 0.0397515 0.783724 0.5 +-0.0329555 0.0349777 0.045552 0.474674 0.5 +-0.0262436 0.034809 0.0452831 0.162616 0.5 +-0.0215554 0.0348112 0.0459347 0.152356 0 +-0.0633407 0.0601272 0.0190813 0.939061 0.5 +-0.0471 0.0351015 0.0434178 0.627709 0.5 +-0.0120723 0.0353434 0.0494553 0.877126 0.5 +-0.016313 0.0351836 0.0504037 0.67915 0.5 +-0.0483699 0.146034 -0.00115148 0.583019 0.5 +-0.0264335 0.156562 -0.00835956 0.469485 0.437523 +-0.065003 0.144791 -0.0142909 0.400803 0.470167 +-0.066228 0.151547 -0.0394609 0.538048 0.5 +-0.0663323 0.145309 -0.018858 0.764025 0.5 +-0.0412403 0.152108 -0.00674014 0.633348 0.5 +3 4 132 80 +3 80 132 544 +3 373 80 544 +3 387 299 241 +3 859 1475 1474 +3 371 299 401 +3 401 326 333 +3 347 673 402 +3 1187 1354 386 +3 1221 457 69 +3 186 224 114 +3 1250 1256 116 +3 164 333 376 +3 19 488 1245 +3 749 19 1245 +3 667 19 749 +3 1040 412 543 +3 1359 1358 1500 +3 216 4 80 +3 152 544 146 +3 4 387 505 +3 543 1235 1205 +3 610 604 297 +3 250 801 1274 +3 504 148 111 +3 387 348 299 +3 401 333 164 +3 1484 1483 1110 +3 91 196 310 +3 90 91 310 +3 952 406 609 +3 1244 1247 1240 +3 93 327 65 +3 373 544 152 +3 373 152 644 +3 1321 158 22 +3 401 416 326 +3 644 152 1263 +3 276 59 181 +3 294 853 150 +3 308 249 529 +3 406 1124 604 +3 609 406 463 +3 146 3 145 +3 90 310 3 +3 58 186 10 +3 575 261 384 +3 25 40 43 +3 379 535 713 +3 348 704 157 +3 388 443 22 +3 396 146 145 +3 152 133 1263 +3 1830 1829 1812 +3 214 114 224 +3 157 147 324 +3 1335 430 1274 +3 282 230 214 +3 92 346 652 +3 1151 1012 1491 +3 571 1151 1491 +3 571 1491 183 +3 310 196 111 +3 91 4 505 +3 1250 116 108 +3 110 183 47 +3 1209 854 953 +3 132 4 91 +3 111 148 327 +3 93 111 327 +3 110 571 183 +3 713 171 402 +3 294 920 200 +3 81 180 52 +3 525 731 784 +3 347 256 673 +3 175 57 220 +3 338 175 220 +3 27 14 220 +3 57 27 220 +3 359 446 27 +3 359 36 446 +3 145 28 262 +3 133 16 419 +3 1447 576 1465 +3 1885 287 444 +3 133 396 16 +3 598 543 1205 +3 447 93 65 +3 73 213 36 +3 1236 1255 1250 +3 1235 1236 1250 +3 115 782 731 +3 28 93 447 +3 525 548 115 +3 299 416 401 +3 667 603 463 +3 292 667 463 +3 492 70 637 +3 133 146 396 +3 1166 1125 619 +3 1151 1219 959 +3 821 304 409 +3 1486 1487 1684 +3 15 175 167 +3 120 15 167 +3 15 131 57 +3 175 15 57 +3 57 131 27 +3 257 209 359 +3 27 257 359 +3 209 55 36 +3 359 209 36 +3 55 87 73 +3 36 55 73 +3 101 108 735 +3 108 101 64 +3 310 365 3 +3 576 859 1465 +3 262 28 447 +3 102 64 101 +3 544 91 90 +3 262 447 485 +3 485 447 211 +3 1443 1440 1442 +3 697 457 1221 +3 1008 383 1011 +3 451 435 1330 +3 129 405 426 +3 70 75 161 +3 648 693 692 +3 204 129 426 +3 812 481 123 +3 406 292 463 +3 878 1591 1009 +3 478 128 50 +3 900 979 977 +3 490 900 977 +3 241 299 371 +3 1164 701 734 +3 683 703 682 +3 719 718 682 +3 703 719 682 +3 760 759 718 +3 719 760 718 +3 137 729 728 +3 54 130 2 +3 302 358 301 +3 566 567 614 +3 1069 1103 1068 +3 1186 1190 1208 +3 4 348 387 +3 277 311 228 +3 707 226 706 +3 355 394 393 +3 773 129 755 +3 646 647 679 +3 356 355 269 +3 270 356 269 +3 424 394 356 +3 623 654 602 +3 654 683 602 +3 193 217 192 +3 1677 1676 1662 +3 1018 1019 1025 +3 597 1231 1165 +3 490 26 605 +3 299 157 416 +3 504 241 148 +3 84 528 714 +3 1247 669 1240 +3 683 719 703 +3 1886 1231 1066 +3 79 168 218 +3 211 318 426 +3 165 377 148 +3 91 505 387 +3 577 623 622 +3 692 693 707 +3 255 254 218 +3 194 270 255 +3 695 137 728 +3 1475 1498 1474 +3 67 808 1010 +3 1190 240 1208 +3 242 259 300 +3 476 509 567 +3 743 755 558 +3 1025 1024 1018 +3 194 255 218 +3 270 269 254 +3 203 271 12 +3 603 667 749 +3 1379 1395 1392 +3 783 546 1340 +3 578 600 577 +3 624 623 577 +3 600 624 577 +3 655 654 623 +3 684 683 654 +3 655 684 654 +3 720 719 683 +3 684 720 683 +3 720 739 719 +3 761 760 719 +3 739 761 719 +3 218 254 253 +3 694 695 437 +3 255 270 254 +3 1202 488 19 +3 412 1222 543 +3 60 528 84 +3 1352 494 702 +3 624 655 623 +3 1361 221 143 +3 755 129 204 +3 132 91 544 +3 543 1221 1235 +3 216 5 4 +3 1221 1236 1235 +3 754 755 204 +3 1169 732 715 +3 756 755 743 +3 1036 1035 1024 +3 728 756 743 +3 476 567 508 +3 4 5 348 +3 244 1339 546 +3 405 445 211 +3 254 269 268 +3 253 254 268 +3 381 358 302 +3 346 92 59 +3 517 450 1560 +3 1618 1333 141 +3 1498 1497 1474 +3 1231 597 1165 +3 228 264 215 +3 100 151 99 +3 151 215 99 +3 151 228 215 +3 1864 827 1870 +3 561 578 480 +3 207 561 480 +3 579 600 578 +3 561 579 578 +3 600 625 624 +3 656 655 624 +3 625 656 624 +3 685 684 655 +3 656 685 655 +3 685 721 720 +3 684 685 720 +3 721 740 739 +3 720 721 739 +3 739 740 761 +3 762 789 788 +3 761 762 788 +3 789 239 770 +3 788 789 770 +3 328 770 239 +3 423 424 476 +3 121 195 522 +3 423 476 422 +3 381 431 358 +3 148 371 401 +3 579 625 600 +3 465 464 431 +3 381 465 431 +3 464 465 227 +3 248 11 71 +3 548 142 1005 +3 740 762 761 +3 767 900 490 +3 728 743 437 +3 776 195 121 +3 1177 1176 1153 +3 1043 1034 1035 +3 137 708 729 +3 91 387 196 +3 1721 1729 1703 +3 728 729 756 +3 727 728 437 +3 196 387 241 +3 404 458 522 +3 355 354 268 +3 647 648 692 +3 979 846 901 +3 241 371 148 +3 142 1155 574 +3 269 355 268 +3 358 301 300 +3 301 358 300 +3 753 754 793 +3 184 229 228 +3 229 277 228 +3 312 311 277 +3 1845 1853 1831 +3 1523 1532 1153 +3 580 579 561 +3 1276 1280 1771 +3 580 626 625 +3 579 580 625 +3 626 657 656 +3 625 626 656 +3 656 657 685 +3 722 721 685 +3 741 740 721 +3 722 741 721 +3 740 763 762 +3 790 789 762 +3 763 790 762 +3 790 339 239 +3 789 790 239 +3 377 165 327 +3 476 508 422 +3 259 301 300 +3 162 170 169 +3 81 162 169 +3 580 561 562 +3 657 686 685 +3 229 312 277 +3 28 365 93 +3 1263 419 1254 +3 396 145 144 +3 685 686 722 +3 741 763 740 +3 133 152 146 +3 1263 133 419 +3 207 520 562 +3 520 562 580 +3 562 520 580 +3 562 626 580 +3 239 339 487 +3 597 1063 1066 +3 3 365 28 +3 649 648 615 +3 108 64 116 +3 571 1225 1218 +3 184 185 229 +3 313 312 229 +3 185 313 229 +3 439 501 520 +3 501 581 562 +3 520 501 562 +3 627 626 562 +3 581 627 562 +3 627 628 626 +3 658 657 626 +3 628 658 626 +3 658 675 657 +3 687 686 657 +3 675 687 657 +3 723 722 686 +3 687 723 686 +3 722 723 741 +3 741 723 763 +3 764 791 790 +3 763 764 790 +3 791 407 339 +3 790 791 339 +3 407 303 339 +3 303 487 339 +3 303 460 487 +3 303 325 460 +3 170 106 105 +3 105 106 68 +3 439 440 501 +3 723 764 763 +3 1 1027 453 +3 1067 511 942 +3 775 121 774 +3 1281 1270 1291 +3 368 440 439 +3 367 368 439 +3 582 581 501 +3 628 627 581 +3 658 688 687 +3 675 658 687 +3 1733 1562 1561 +3 757 775 756 +3 74 68 46 +3 398 1223 317 +3 631 607 231 +3 1465 859 1474 +3 1775 1784 1754 +3 204 138 793 +3 74 122 97 +3 584 533 570 +3 278 313 185 +3 265 278 185 +3 369 368 313 +3 278 369 313 +3 369 440 368 +3 502 501 440 +3 583 582 501 +3 502 583 501 +3 583 581 582 +3 629 628 581 +3 583 629 581 +3 629 659 658 +3 628 629 658 +3 658 659 688 +3 724 723 687 +3 688 724 687 +3 724 742 723 +3 742 765 764 +3 723 742 764 +3 764 238 791 +3 791 238 407 +3 407 238 303 +3 238 333 303 +3 333 325 303 +3 614 615 647 +3 46 122 74 +3 606 199 112 +3 441 440 369 +3 83 173 573 +3 775 776 121 +3 846 979 901 +3 441 502 440 +3 659 689 688 +3 84 714 1367 +3 535 52 171 +3 551 798 1883 +3 630 629 583 +3 629 630 659 +3 689 724 688 +3 792 238 764 +3 765 792 764 +3 1207 1208 177 +3 195 96 522 +3 122 13 97 +3 344 492 637 +3 1025 1036 1024 +3 775 774 756 +3 1012 1151 959 +3 1270 1372 1291 +3 145 3 28 +3 649 670 695 +3 517 1888 243 +3 444 399 1885 +3 370 369 278 +3 724 765 742 +3 376 333 238 +3 1372 1375 1291 +3 1060 1161 1162 +3 16 396 144 +3 369 442 441 +3 583 601 630 +3 690 689 659 +3 318 295 427 +3 138 204 427 +3 693 694 707 +3 310 111 365 +3 365 111 93 +3 636 660 659 +3 567 566 508 +3 426 405 211 +3 121 126 774 +3 471 601 583 +3 251 237 188 +3 1303 188 237 +3 278 314 370 +3 370 442 369 +3 442 503 502 +3 441 442 502 +3 503 471 583 +3 502 503 583 +3 858 302 259 +3 16 144 319 +3 660 690 659 +3 690 725 724 +3 689 690 724 +3 750 765 724 +3 725 750 724 +3 8 792 765 +3 750 8 765 +3 376 238 792 +3 8 376 792 +3 164 376 238 +3 376 164 238 +3 1381 1380 1375 +3 1135 1134 1103 +3 1104 1135 1103 +3 794 204 793 +3 447 65 211 +3 442 1347 503 +3 249 262 485 +3 1036 1043 1035 +3 522 96 438 +3 204 426 427 +3 188 283 251 +3 1235 1250 1205 +3 485 262 23 +3 597 1066 1165 +3 144 308 319 +3 1027 767 589 +3 648 649 694 +3 567 615 614 +3 821 409 304 +3 63 711 903 +3 8 164 376 +3 12 478 50 +3 171 347 402 +3 284 1327 314 +3 1447 1465 1459 +3 1456 1447 1459 +3 1329 1328 1380 +3 755 756 773 +3 756 774 773 +3 193 218 253 +3 648 694 693 +3 168 194 218 +3 190 188 189 +3 284 283 188 +3 190 284 188 +3 283 284 314 +3 262 485 23 +3 108 116 64 +3 751 750 725 +3 726 751 725 +3 751 771 750 +3 37 8 750 +3 771 37 750 +3 632 164 8 +3 569 53 411 +3 511 1560 1884 +3 386 1354 1320 +3 165 632 8 +3 37 165 8 +3 165 164 632 +3 662 661 638 +3 354 393 422 +3 401 165 148 +3 979 1883 798 +3 144 145 262 +3 413 408 349 +3 16 319 669 +3 318 211 295 +3 156 1213 198 +3 1153 1152 1119 +3 1225 1448 247 +3 190 266 284 +3 419 669 1247 +3 479 233 232 +3 166 165 37 +3 709 492 344 +3 567 568 615 +3 107 827 1864 +3 695 727 437 +3 485 211 23 +3 1254 419 1247 +3 419 16 669 +3 1884 1591 1009 +3 249 485 24 +3 41 249 24 +3 1103 1134 1133 +3 272 398 492 +3 754 204 794 +3 1498 159 113 +3 24 485 23 +3 1102 1103 1133 +3 308 144 249 +3 164 165 401 +3 692 707 706 +3 509 568 567 +3 191 252 190 +3 190 252 266 +3 252 285 284 +3 266 252 284 +3 285 286 284 +3 284 286 337 +3 144 262 249 +3 536 564 563 +3 563 564 593 +3 564 612 611 +3 593 564 611 +3 645 361 611 +3 612 645 611 +3 645 691 1313 +3 309 752 751 +3 726 309 751 +3 752 772 771 +3 751 752 771 +3 119 37 771 +3 772 119 771 +3 425 166 37 +3 119 425 37 +3 380 165 166 +3 425 380 166 +3 128 83 17 +3 50 128 17 +3 729 757 756 +3 394 423 422 +3 589 767 490 +3 424 509 476 +3 1374 1359 1531 +3 408 372 349 +3 679 692 706 +3 855 242 300 +3 766 757 730 +3 354 355 393 +3 79 218 193 +3 129 126 405 +3 126 458 405 +3 647 692 679 +3 757 766 775 +3 766 776 775 +3 1699 1014 1013 +3 393 394 422 +3 252 286 285 +3 752 119 772 +3 425 327 380 +3 696 730 729 +3 708 696 729 +3 649 695 694 +3 78 79 193 +3 1497 1498 113 +3 901 979 798 +3 404 24 445 +3 24 23 445 +3 776 795 195 +3 1340 1591 1884 +3 1035 1034 1024 +3 177 203 12 +3 380 327 425 +3 510 509 424 +3 477 510 424 +3 458 404 405 +3 192 217 252 +3 191 192 252 +3 217 267 286 +3 252 217 286 +3 286 267 352 +3 353 421 420 +3 352 353 420 +3 421 507 506 +3 506 507 536 +3 507 565 564 +3 536 507 564 +3 565 613 612 +3 564 565 612 +3 646 645 612 +3 613 646 612 +3 646 679 691 +3 645 646 691 +3 706 705 691 +3 679 706 691 +3 753 309 280 +3 138 119 752 +3 753 138 752 +3 427 425 119 +3 138 427 119 +3 295 380 425 +3 427 295 425 +3 65 327 380 +3 295 65 380 +3 769 104 315 +3 426 318 427 +3 568 616 615 +3 695 728 727 +3 404 445 405 +3 1635 1653 1453 +3 271 478 12 +3 839 136 830 +3 615 648 647 +3 311 277 228 +3 749 1245 1225 +3 353 392 421 +3 793 138 753 +3 315 104 33 +3 432 466 465 +3 381 432 465 +3 465 466 527 +3 1170 1190 1099 +3 754 794 793 +3 558 754 280 +3 193 253 217 +3 253 268 267 +3 217 253 267 +3 268 354 353 +3 267 268 353 +3 354 392 353 +3 422 421 392 +3 354 422 392 +3 422 508 507 +3 421 422 507 +3 508 566 565 +3 507 508 565 +3 614 613 565 +3 566 614 565 +3 614 647 646 +3 613 614 646 +3 168 810 194 +3 886 940 923 +3 946 945 930 +3 929 939 944 +3 940 569 887 +3 661 649 616 +3 320 919 878 +3 227 526 464 +3 882 873 866 +3 552 384 820 +3 464 927 358 +3 917 432 905 +3 879 829 820 +3 194 836 880 +3 935 466 432 +3 917 935 432 +3 1038 1725 1013 +3 1378 1391 1406 +3 173 448 293 +3 477 943 510 +3 616 568 617 +3 1405 550 980 +3 665 86 847 +3 891 906 912 +3 845 130 54 +3 999 925 822 +3 1885 928 555 +3 904 910 270 +3 315 33 478 +3 1033 1034 1042 +3 490 921 26 +3 850 257 131 +3 1070 1077 1034 +3 843 860 15 +3 120 843 15 +3 850 209 257 +3 914 913 300 +3 880 911 910 +3 641 661 616 +3 843 120 797 +3 860 870 15 +3 870 131 15 +3 870 850 131 +3 894 873 882 +3 811 248 875 +3 974 981 992 +3 850 201 131 +3 131 201 850 +3 850 201 209 +3 907 917 905 +3 694 437 226 +3 895 843 797 +3 870 860 843 +3 816 870 843 +3 870 201 850 +3 913 933 932 +3 968 969 986 +3 840 118 712 +3 816 843 895 +3 201 856 209 +3 856 845 55 +3 209 856 55 +3 931 930 911 +3 228 151 184 +3 1340 884 1884 +3 553 506 536 +3 539 867 842 +3 870 924 201 +3 977 823 490 +3 868 829 780 +3 999 1000 925 +3 198 701 156 +3 787 816 895 +3 924 877 856 +3 201 924 856 +3 877 845 856 +3 66 305 941 +3 769 203 1208 +3 848 847 919 +3 880 889 911 +3 1027 589 605 +3 957 816 787 +3 849 870 816 +3 957 849 816 +3 414 821 409 +3 1887 1004 928 +3 569 888 887 +3 459 384 552 +3 891 889 890 +3 839 892 891 +3 1080 1057 1051 +3 957 328 816 +3 328 957 816 +3 849 881 870 +3 881 849 870 +3 870 849 924 +3 481 531 123 +3 777 835 698 +3 891 892 906 +3 912 911 889 +3 891 912 889 +3 546 1339 746 +3 328 849 957 +3 849 88 924 +3 1043 1070 1034 +3 777 122 46 +3 477 929 943 +3 617 641 616 +3 822 915 72 +3 915 331 72 +3 834 806 956 +3 788 957 787 +3 770 788 787 +3 788 328 957 +3 864 877 924 +3 833 938 130 +3 845 833 130 +3 938 256 130 +3 1005 142 574 +3 661 676 137 +3 730 305 776 +3 1186 1208 1207 +3 1189 1186 1207 +3 798 1888 1067 +3 864 924 88 +3 864 922 877 +3 982 845 877 +3 922 982 877 +3 982 833 845 +3 894 905 873 +3 879 665 86 +3 879 665 847 +3 817 922 864 +3 833 982 922 +3 817 833 922 +3 894 907 905 +3 1562 1561 1038 +3 305 893 776 +3 899 864 88 +3 1071 1049 1072 +3 788 770 328 +3 776 768 795 +3 835 919 847 +3 817 864 899 +3 833 256 938 +3 1177 1195 1176 +3 1276 1771 1275 +3 155 100 813 +3 832 96 449 +3 879 384 665 +3 879 86 665 +3 834 956 320 +3 863 898 328 +3 826 849 328 +3 898 826 328 +3 849 826 88 +3 826 899 88 +3 1346 1883 900 +3 930 945 944 +3 939 930 944 +3 810 818 836 +3 838 836 837 +3 1077 1069 1034 +3 891 890 838 +3 1473 1680 1679 +3 44 24 438 +3 899 200 817 +3 1374 1391 1378 +3 466 935 527 +3 66 941 730 +3 913 906 912 +3 956 919 320 +3 662 676 661 +3 239 395 863 +3 395 898 863 +3 819 826 898 +3 826 200 899 +3 35 86 82 +3 880 270 194 +3 935 950 527 +3 670 661 695 +3 134 256 94 +3 818 837 836 +3 848 879 847 +3 395 819 898 +3 826 819 200 +3 200 920 817 +3 920 876 833 +3 817 920 833 +3 833 876 256 +3 1034 1069 1068 +3 932 933 947 +3 997 676 662 +3 836 889 880 +3 757 729 730 +3 956 806 919 +3 603 749 1460 +3 876 48 256 +3 827 107 155 +3 107 184 155 +3 830 855 841 +3 1042 1034 1068 +3 832 449 795 +3 997 662 638 +3 384 261 665 +3 997 696 676 +3 294 48 876 +3 920 294 876 +3 925 915 822 +3 1199 1231 1886 +3 941 305 730 +3 200 418 294 +3 569 940 886 +3 100 155 184 +3 840 712 331 +3 921 379 26 +3 1016 1014 1699 +3 776 766 730 +3 983 997 638 +3 676 696 137 +3 487 395 239 +3 487 819 395 +3 569 886 511 +3 940 887 923 +3 986 1000 985 +3 1125 110 47 +3 947 968 958 +3 842 874 834 +3 822 918 66 +3 985 999 998 +3 984 985 998 +3 999 822 998 +3 983 984 997 +3 984 998 997 +3 819 418 200 +3 177 85 1206 +3 12 275 397 +3 1231 1165 1066 +3 240 769 1208 +3 1000 999 985 +3 943 965 568 +3 906 913 932 +3 300 913 892 +3 997 998 66 +3 998 822 66 +3 478 33 128 +3 570 701 1076 +3 305 72 768 +3 72 811 768 +3 878 884 411 +3 878 835 884 +3 930 939 929 +3 968 978 967 +3 958 968 967 +3 946 958 967 +3 819 853 418 +3 510 943 509 +3 509 943 568 +3 151 100 184 +3 978 984 983 +3 967 978 983 +3 474 1122 799 +3 932 931 912 +3 487 460 819 +3 460 29 819 +3 819 29 853 +3 340 867 383 +3 1134 1135 1161 +3 947 946 931 +3 1411 1501 1408 +3 300 892 855 +3 356 910 929 +3 136 838 837 +3 1259 351 523 +3 887 896 923 +3 260 86 665 +3 774 129 773 +3 872 873 871 +3 906 932 912 +3 661 137 695 +3 511 886 942 +3 985 984 978 +3 968 985 978 +3 818 136 837 +3 1559 851 857 +3 872 871 865 +3 1222 1221 543 +3 548 1005 115 +3 430 1198 1065 +3 768 811 832 +3 945 967 944 +3 1132 1134 1160 +3 1019 1036 1025 +3 1134 1161 1160 +3 615 616 649 +3 1560 884 1884 +3 884 835 888 +3 214 230 114 +3 811 332 832 +3 878 411 53 +3 848 842 879 +3 842 829 879 +3 48 673 256 +3 869 811 768 +3 912 931 911 +3 935 936 950 +3 871 302 381 +3 972 991 971 +3 708 137 696 +3 1225 571 110 +3 847 955 13 +3 803 190 189 +3 865 871 858 +3 986 985 968 +3 929 944 943 +3 227 972 526 +3 888 835 896 +3 1001 1002 840 +3 1830 1841 1829 +3 50 140 275 +3 394 424 423 +3 411 884 888 +3 936 935 917 +3 907 936 917 +3 835 847 698 +3 811 6 332 +3 842 867 829 +3 1161 1060 1226 +3 1885 399 1887 +3 808 834 995 +3 1659 1658 1638 +3 65 295 211 +3 918 822 305 +3 302 871 381 +3 847 86 955 +3 1001 840 925 +3 1010 937 834 +3 1208 203 177 +3 1135 1162 1161 +3 921 81 379 +3 271 315 478 +3 948 969 947 +3 464 526 927 +3 834 848 806 +3 409 296 414 +3 302 873 432 +3 885 896 777 +3 841 892 839 +3 811 875 6 +3 1077 1104 1069 +3 1104 1103 1069 +3 68 106 46 +3 823 921 490 +3 162 81 921 +3 823 162 921 +3 989 1001 1000 +3 986 989 1000 +3 1000 1001 925 +3 888 896 887 +3 929 477 356 +3 974 972 534 +3 87 2 213 +3 915 840 331 +3 970 969 948 +3 965 641 568 +3 1207 177 1206 +3 1726 1725 1038 +3 1002 51 840 +3 814 191 803 +3 191 190 803 +3 855 892 841 +3 302 432 381 +3 173 293 573 +3 880 904 270 +3 871 873 302 +3 358 914 300 +3 239 863 328 +3 910 911 929 +3 331 712 811 +3 438 24 404 +3 892 913 906 +3 991 1002 990 +3 128 33 83 +3 810 836 194 +3 788 770 787 +3 814 803 804 +3 774 126 129 +3 242 855 830 +3 981 1189 1206 +3 927 934 914 +3 847 13 777 +3 301 358 300 +3 822 72 305 +3 641 617 568 +3 839 838 136 +3 904 880 910 +3 1850 1864 1870 +3 118 248 811 +3 949 970 948 +3 970 989 986 +3 1328 1325 1316 +3 358 927 914 +3 867 340 829 +3 943 944 966 +3 1100 221 1361 +3 530 805 525 +3 327 148 377 +3 1259 179 351 +3 1029 1028 1014 +3 969 968 947 +3 970 986 969 +3 832 795 768 +3 888 569 411 +3 342 344 113 +3 458 126 121 +3 943 966 965 +3 979 901 823 +3 823 861 162 +3 701 198 1076 +3 966 638 641 +3 769 315 271 +3 760 761 787 +3 965 966 641 +3 927 949 934 +3 949 948 934 +3 558 755 754 +3 919 835 878 +3 270 910 356 +3 852 162 861 +3 106 170 162 +3 852 106 162 +3 947 958 946 +3 815 192 191 +3 814 815 191 +3 820 384 879 +3 305 768 893 +3 698 847 777 +3 829 340 780 +3 534 972 227 +3 121 522 458 +3 1071 1077 1070 +3 846 823 901 +3 846 861 823 +3 918 305 66 +3 893 768 776 +3 1190 1186 1099 +3 67 1010 937 +3 925 840 915 +3 862 861 846 +3 862 852 861 +3 835 777 896 +3 946 945 944 +3 862 106 852 +3 1885 1887 928 +3 464 358 431 +3 526 949 927 +3 946 944 945 +3 890 889 838 +3 66 696 997 +3 1019 1561 1026 +3 1375 1380 1291 +3 1071 1061 1077 +3 712 118 811 +3 806 848 919 +3 971 990 970 +3 661 670 649 +3 971 970 949 +3 749 1225 110 +3 122 777 13 +3 35 13 955 +3 734 701 1164 +3 795 449 195 +3 874 842 848 +3 990 1002 989 +3 977 979 823 +3 526 971 949 +3 78 193 192 +3 815 78 192 +3 990 989 970 +3 834 539 842 +3 839 891 838 +3 1146 767 1064 +3 1002 1001 989 +3 840 51 118 +3 886 862 846 +3 280 754 753 +3 811 869 768 +3 906 913 912 +3 967 966 944 +3 931 946 930 +3 829 552 820 +3 886 106 862 +3 885 46 106 +3 1061 1104 1077 +3 320 67 834 +3 905 432 873 +3 874 848 834 +3 911 930 929 +3 1026 1572 1019 +3 972 974 992 +3 934 933 913 +3 914 934 913 +3 923 106 886 +3 777 46 885 +3 355 356 394 +3 449 96 195 +3 66 730 696 +3 807 96 832 +3 72 331 811 +3 896 106 923 +3 896 885 106 +3 1071 1070 1043 +3 932 947 931 +3 1049 1071 1043 +3 450 39 785 +3 946 967 945 +3 836 838 889 +3 787 761 788 +3 967 983 638 +3 966 967 638 +3 991 990 971 +3 597 1165 1231 +3 937 539 834 +3 934 948 947 +3 933 934 947 +3 886 846 942 +3 972 971 526 +3 1737 1762 1746 +3 1841 1851 1829 +3 417 1219 1218 +3 1166 110 1125 +3 159 342 113 +3 1065 1032 1274 +3 430 1065 1274 +3 1307 1320 1395 +3 767 1027 1 +3 846 798 1067 +3 735 1256 469 +3 1829 1850 1834 +3 398 317 1039 +3 288 32 34 +3 1051 1057 1058 +3 515 1684 1674 +3 1080 1079 1057 +3 1051 1058 1029 +3 1039 288 34 +3 1561 1726 1038 +3 1379 1307 1395 +3 304 642 409 +3 1396 1380 1381 +3 1030 1051 1029 +3 1219 1218 959 +3 598 1205 642 +3 1604 1615 1613 +3 1209 953 1193 +3 389 1521 1121 +3 398 75 70 +3 1314 273 524 +3 1022 1030 1021 +3 1022 1021 1016 +3 1030 1029 1021 +3 598 642 304 +3 528 1185 714 +3 1194 1209 1193 +3 177 12 397 +3 878 67 320 +3 1057 1045 1028 +3 1096 1095 1079 +3 1296 264 1319 +3 101 491 1237 +3 834 808 67 +3 1312 1484 1110 +3 963 1312 1110 +3 113 344 637 +3 1497 113 1496 +3 1119 1127 1113 +3 1312 1483 1484 +3 1799 1816 1812 +3 1079 1095 1057 +3 854 357 1191 +3 399 444 1210 +3 539 1011 383 +3 246 250 664 +3 1028 1038 1020 +3 1058 1057 1029 +3 311 1329 1396 +3 1260 1483 1312 +3 1187 1328 428 +3 1851 1864 1850 +3 317 609 619 +3 609 463 619 +3 1223 952 317 +3 603 1166 619 +3 1003 976 1094 +3 1248 556 297 +3 287 1885 555 +3 1138 1172 1163 +3 297 556 610 +3 1591 878 1009 +3 463 603 619 +3 749 110 1166 +3 1157 680 1081 +3 1886 304 409 +3 436 1027 605 +3 1015 1029 1014 +3 556 20 610 +3 20 604 610 +3 1099 1186 1189 +3 20 599 604 +3 1209 854 953 +3 1360 1550 1685 +3 492 398 70 +3 1172 1193 1192 +3 1175 1172 1192 +3 733 292 406 +3 202 733 406 +3 1010 834 67 +3 468 113 637 +3 154 1157 1081 +3 1172 1175 1163 +3 1193 854 1192 +3 953 854 1193 +3 1055 174 493 +3 1502 650 1046 +3 236 60 84 +3 1195 1194 1176 +3 85 177 397 +3 1163 1175 1148 +3 585 433 357 +3 1050 1045 1028 +3 1138 1148 1112 +3 1603 1402 1589 +3 1174 1192 1191 +3 1170 1174 1190 +3 1416 1417 1617 +3 398 1039 34 +3 75 398 1007 +3 1095 1107 1078 +3 1133 1134 1132 +3 1528 1022 1551 +3 1066 598 304 +3 292 733 667 +3 63 903 18 +3 619 1125 288 +3 1357 1355 1356 +3 733 1363 667 +3 470 1 212 +3 1017 830 136 +3 1119 1113 1095 +3 1387 231 247 +3 1107 1112 1078 +3 113 468 1496 +3 1028 1045 1050 +3 1014 1028 1013 +3 808 1011 539 +3 830 841 839 +3 12 50 275 +3 1344 1530 1115 +3 1363 153 19 +3 667 1363 19 +3 1103 1102 1068 +3 952 609 317 +3 1175 1174 1148 +3 1031 236 681 +3 595 10 555 +3 1119 1114 1587 +3 1114 1119 1096 +3 709 272 492 +3 451 736 434 +3 1174 1175 1192 +3 1380 1328 1316 +3 928 595 555 +3 153 489 1202 +3 572 598 1066 +3 19 153 1202 +3 1737 1746 1721 +3 1418 1417 1395 +3 1148 1147 1126 +3 488 1387 1448 +3 1245 488 1448 +3 1040 543 598 +3 572 1040 598 +3 1021 1029 1015 +3 1654 1653 1635 +3 329 58 595 +3 489 125 488 +3 1163 1148 1138 +3 1534 1687 1439 +3 342 709 344 +3 1112 1148 1126 +3 1202 489 488 +3 125 231 1387 +3 488 125 1387 +3 398 272 1223 +3 383 867 539 +3 414 296 928 +3 1176 1194 1172 +3 1028 1020 1013 +3 173 176 448 +3 1591 878 1009 +3 444 287 263 +3 1083 444 263 +3 272 952 1223 +3 1192 854 1191 +3 854 585 357 +3 1119 1152 1139 +3 1547 461 513 +3 296 329 595 +3 296 595 928 +3 603 749 1166 +3 1319 1329 1381 +3 1138 1152 1172 +3 63 18 33 +3 433 63 104 +3 769 433 104 +3 1174 1171 1147 +3 1372 1381 1375 +3 1613 1424 1603 +3 1113 1138 1107 +3 571 1218 1219 +3 1528 1551 1548 +3 1007 398 34 +3 1738 1737 1717 +3 1396 1329 1380 +3 1063 572 1066 +3 1153 1176 1152 +3 1139 1113 1127 +3 1119 1139 1127 +3 1191 357 1190 +3 357 240 1190 +3 1148 1174 1147 +3 29 460 325 +3 317 619 1039 +3 1754 1762 1737 +3 1329 311 1396 +3 1309 1380 1316 +3 1225 247 1218 +3 1448 1387 247 +3 1028 1045 1038 +3 1635 1453 1452 +3 116 1256 735 +3 514 1032 962 +3 1095 1078 1086 +3 1079 1095 1086 +3 357 433 240 +3 1174 1170 1171 +3 1218 1219 959 +3 1067 942 846 +3 1057 1095 1079 +3 10 114 287 +3 150 853 620 +3 555 10 287 +3 1152 1138 1139 +3 1052 1085 1370 +3 1704 1721 1703 +3 89 51 1002 +3 512 89 1002 +3 1152 1176 1172 +3 981 1206 992 +3 991 512 1002 +3 402 673 48 +3 1016 1551 1022 +3 1151 571 1219 +3 433 769 240 +3 1291 1380 1309 +3 1571 785 884 +3 589 490 605 +3 584 572 1063 +3 1057 1079 1045 +3 1138 1112 1107 +3 1045 1086 1078 +3 1095 1113 1107 +3 76 512 991 +3 1549 1552 1548 +3 203 769 271 +3 992 76 991 +3 274 89 512 +3 76 274 512 +3 274 51 89 +3 139 118 51 +3 274 139 51 +3 11 248 118 +3 139 11 118 +3 1056 1042 1068 +3 737 103 17 +3 871 302 858 +3 273 489 153 +3 1826 1835 1820 +3 197 48 294 +3 975 197 294 +3 197 713 402 +3 48 197 402 +3 584 1076 1040 +3 1079 1086 1045 +3 1029 1057 1028 +3 1139 1138 1113 +3 572 584 1040 +3 198 412 1040 +3 1076 198 1040 +3 298 273 153 +3 1500 1531 1359 +3 1096 1119 1095 +3 1194 1193 1172 +3 1560 785 1571 +3 882 866 894 +3 49 139 274 +3 1189 1207 1206 +3 1102 1133 1132 +3 1717 1721 1704 +3 1674 1487 1653 +3 584 570 1076 +3 894 1102 907 +3 821 1167 1199 +3 17 103 140 +3 50 17 140 +3 1042 1056 866 +3 1056 1068 894 +3 866 1056 894 +3 894 1068 1102 +3 1102 1132 936 +3 907 1102 936 +3 1160 950 936 +3 1132 1160 936 +3 1174 1191 1190 +3 1206 85 76 +3 992 1206 76 +3 397 274 76 +3 85 397 76 +3 275 49 274 +3 397 275 274 +3 140 139 49 +3 275 140 49 +3 103 11 139 +3 140 103 139 +3 409 642 329 +3 296 409 329 +3 436 975 1241 +3 436 605 975 +3 605 26 975 +3 26 197 975 +3 26 379 713 +3 197 26 713 +3 1010 539 937 +3 59 454 346 +3 652 408 413 +3 21 61 149 +3 171 345 347 +3 94 2 130 +3 130 256 134 +3 1004 1393 715 +3 313 368 367 +3 544 90 146 +3 81 535 379 +3 1257 527 950 +3 1257 950 1160 +3 302 301 259 +3 1004 414 928 +3 1160 1238 1257 +3 102 214 186 +3 1238 1160 1161 +3 1226 1238 1161 +3 1257 227 527 +3 95 233 364 +3 620 853 29 +3 1257 534 227 +3 282 454 230 +3 1453 1653 1452 +3 232 233 95 +3 821 1199 1886 +3 1232 1238 1226 +3 1238 981 1257 +3 1257 981 534 +3 417 408 652 +3 1233 1238 1232 +3 1027 436 42 +3 196 504 111 +3 169 180 81 +3 61 21 479 +3 631 231 388 +3 372 631 388 +3 1300 1382 1270 +3 1558 1559 857 +3 714 298 800 +3 298 153 800 +3 981 974 534 +3 704 348 5 +3 706 226 234 +3 388 231 443 +3 311 1330 1329 +3 1282 1300 1270 +3 1189 981 1238 +3 1233 1189 1238 +3 334 94 256 +3 1462 1672 1473 +3 895 786 787 +3 595 58 10 +3 1242 1251 1256 +3 489 231 125 +3 1236 1256 1250 +3 0 717 40 +3 470 212 0 +3 717 279 40 +3 276 230 59 +3 454 282 1237 +3 521 219 213 +3 417 652 346 +3 1266 417 346 +3 364 521 213 +3 171 363 345 +3 279 704 40 +3 470 0 160 +3 94 95 2 +3 42 281 717 +3 97 375 540 +3 61 479 363 +3 1216 705 706 +3 349 372 233 +3 453 42 717 +3 1241 975 150 +3 150 975 294 +3 214 362 282 +3 959 417 1266 +3 959 1219 417 +3 281 42 279 +3 408 607 372 +3 372 607 631 +3 0 40 25 +3 1221 69 1242 +3 287 114 263 +3 279 147 157 +3 704 279 157 +3 134 94 130 +3 81 52 535 +3 1265 58 329 +3 1249 1265 329 +3 82 97 13 +3 364 643 158 +3 82 375 97 +3 156 542 1214 +3 479 232 345 +3 35 82 13 +3 147 620 29 +3 102 186 58 +3 64 102 58 +3 363 479 345 +3 21 413 479 +3 652 413 21 +3 372 388 233 +3 216 43 5 +3 61 171 52 +3 413 349 479 +3 186 114 10 +3 619 288 1039 +3 697 1221 412 +3 171 61 363 +3 212 717 0 +3 1236 1242 1256 +3 607 408 417 +3 92 21 149 +3 279 42 147 +3 1221 1222 412 +3 697 1217 457 +3 156 1214 1213 +3 453 717 1 +3 552 829 868 +3 114 276 263 +3 570 734 701 +3 324 29 325 +3 1 717 212 +3 214 102 101 +3 2 364 213 +3 95 364 2 +3 74 97 68 +3 108 58 1265 +3 196 241 504 +3 416 325 326 +3 1346 900 767 +3 642 1205 1249 +3 71 135 6 +3 665 261 260 +3 389 43 216 +3 108 64 58 +3 1255 1236 1250 +3 7 1261 71 +3 1261 135 71 +3 83 737 17 +3 165 380 327 +3 147 29 324 +3 279 717 281 +3 417 1218 607 +3 1218 247 607 +3 83 573 737 +3 737 1239 7 +3 1239 1261 7 +3 42 620 147 +3 1215 697 1214 +3 1221 1242 1236 +3 1261 172 135 +3 651 62 6 +3 117 332 6 +3 62 117 6 +3 416 324 325 +3 157 324 416 +3 40 5 43 +3 1227 1239 737 +3 573 1227 737 +3 1261 1262 172 +3 172 651 6 +3 135 172 6 +3 62 807 117 +3 0 25 160 +3 364 388 643 +3 345 95 94 +3 1214 909 1215 +3 336 149 180 +3 233 388 364 +3 807 832 117 +3 1243 1262 1261 +3 1239 1243 1261 +3 42 150 620 +3 1215 1217 697 +3 1214 412 198 +3 1213 1214 198 +3 293 1227 573 +3 172 62 651 +3 878 1591 67 +3 1214 697 412 +3 1228 1243 1239 +3 1227 1228 1239 +3 96 45 438 +3 40 704 5 +3 59 92 181 +3 172 9 62 +3 643 22 158 +3 388 22 643 +3 92 149 181 +3 345 94 334 +3 652 21 92 +3 345 232 95 +3 214 101 362 +3 535 171 713 +3 1262 678 172 +3 678 9 172 +3 9 592 62 +3 479 349 233 +3 326 325 333 +3 117 832 332 +3 347 345 334 +3 234 1216 706 +3 486 62 592 +3 486 807 62 +3 884 1340 1884 +3 1270 1381 1372 +3 348 157 299 +3 1320 1418 1395 +3 1243 452 1262 +3 1262 452 678 +3 343 592 9 +3 149 61 52 +3 1224 1230 1228 +3 1246 1253 1243 +3 1243 1253 452 +3 163 486 592 +3 163 96 486 +3 2 87 54 +3 1474 1497 1496 +3 1488 1474 1496 +3 525 115 731 +3 1230 1246 1243 +3 1228 1230 1243 +3 452 343 9 +3 678 452 9 +3 31 592 343 +3 31 163 592 +3 743 226 437 +3 334 256 347 +3 149 52 180 +3 6 875 248 +3 1482 1474 1488 +3 1246 1230 1253 +3 452 31 343 +3 45 96 163 +3 364 158 521 +3 737 7 103 +3 213 73 87 +3 1063 533 584 +3 45 44 438 +3 42 436 150 +3 1244 1240 1092 +3 211 445 23 +3 1459 1465 1482 +3 1440 988 1442 +3 163 44 45 +3 1418 1354 1863 +3 436 1241 150 +3 453 1027 42 +3 108 1265 1249 +3 230 454 59 +3 1465 1474 1482 +3 311 1329 1319 +3 677 1234 1230 +3 1230 1234 1253 +3 452 374 31 +3 163 323 44 +3 282 214 230 +3 214 282 230 +3 1258 374 452 +3 1253 1258 452 +3 1215 909 1217 +3 1354 1418 1320 +3 1234 1240 1253 +3 294 418 853 +3 558 234 226 +3 11 103 71 +3 1240 1258 1253 +3 31 77 163 +3 77 323 163 +3 558 280 234 +3 214 224 186 +3 1205 1250 1249 +3 586 1296 1282 +3 1240 1234 677 +3 114 230 276 +3 1125 47 32 +3 308 77 31 +3 868 780 340 +3 1250 108 1249 +3 694 226 707 +3 288 1125 32 +3 319 31 374 +3 31 319 308 +3 529 323 77 +3 323 24 44 +3 280 309 234 +3 234 309 1216 +3 1491 1012 183 +3 77 308 529 +3 323 41 24 +3 225 361 1313 +3 6 248 71 +3 1258 669 374 +3 669 319 374 +3 249 41 323 +3 529 249 323 +3 115 444 782 +3 146 90 3 +3 309 705 1216 +3 669 1258 1240 +3 1264 109 636 +3 1302 185 1293 +3 1217 909 960 +3 237 265 1302 +3 337 1337 1336 +3 547 541 205 +3 1313 691 705 +3 286 352 337 +3 1327 1332 370 +3 798 846 901 +3 337 1338 1337 +3 361 225 611 +3 451 439 484 +3 677 1092 1240 +3 225 1313 109 +3 264 228 277 +3 352 1334 337 +3 785 783 1340 +3 309 1313 705 +3 674 683 682 +3 663 623 602 +3 622 663 710 +3 995 1591 806 +3 450 206 1047 +3 1283 99 215 +3 611 563 593 +3 475 246 664 +3 1294 1264 636 +3 442 1337 1347 +3 465 527 227 +3 659 630 636 +3 1454 1499 1527 +3 602 674 663 +3 107 1293 185 +3 1829 1851 1850 +3 109 690 660 +3 1313 690 109 +3 563 611 1264 +3 362 101 1237 +3 337 1334 1338 +3 206 450 517 +3 1347 471 503 +3 167 554 1323 +3 1468 1472 1489 +3 1091 1141 702 +3 471 563 1294 +3 715 1167 821 +3 1264 611 225 +3 1332 337 1336 +3 1004 1887 399 +3 586 1283 215 +3 1023 1252 1400 +3 1179 1370 1383 +3 1313 726 1324 +3 471 636 630 +3 352 420 1334 +3 1047 39 450 +3 99 1283 586 +3 237 1302 107 +3 14 446 330 +3 1313 361 645 +3 530 525 784 +3 1338 553 1348 +3 1337 1338 1348 +3 370 1332 442 +3 1332 1336 442 +3 715 821 414 +3 237 283 1322 +3 362 1237 282 +3 187 1303 237 +3 257 27 131 +3 801 430 1335 +3 1287 36 213 +3 554 167 338 +3 335 1331 1330 +3 311 335 1330 +3 1331 439 451 +3 506 420 421 +3 1330 1331 451 +3 663 674 1284 +3 674 385 1284 +3 184 107 185 +3 1322 283 314 +3 14 27 446 +3 439 520 484 +3 265 185 1302 +3 420 553 1338 +3 554 338 916 +3 1400 1298 1023 +3 553 563 471 +3 1324 726 1313 +3 1285 14 446 +3 434 435 451 +3 338 167 175 +3 277 311 1319 +3 546 783 244 +3 801 1335 1274 +3 338 1297 916 +3 1294 563 1264 +3 420 1338 1334 +3 783 606 244 +3 1337 1348 1347 +3 1313 1324 690 +3 311 312 335 +3 220 1285 1310 +3 1284 385 1278 +3 1128 1023 1252 +3 1285 220 14 +3 622 623 663 +3 109 660 636 +3 524 446 330 +3 1589 1402 1403 +3 338 220 1310 +3 674 682 385 +3 284 337 1332 +3 107 1302 1293 +3 663 1284 710 +3 1888 517 1067 +3 350 1251 69 +3 435 434 415 +3 435 415 428 +3 1297 338 1310 +3 682 307 385 +3 1306 1305 1280 +3 1276 1306 1280 +3 313 367 312 +3 1327 284 1332 +3 1336 1337 442 +3 1264 225 109 +3 180 169 1229 +3 475 801 246 +3 352 267 353 +3 1403 1404 1589 +3 1285 1292 1310 +3 307 682 748 +3 682 718 748 +3 1277 1276 1275 +3 1158 237 107 +3 1067 517 511 +3 1271 1282 1270 +3 489 125 443 +3 446 14 330 +3 586 1282 1271 +3 1292 1285 446 +3 446 330 1287 +3 443 125 489 +3 108 116 735 +3 813 100 99 +3 1276 1307 1306 +3 1483 1260 1317 +3 1272 586 1271 +3 1348 553 471 +3 1287 213 219 +3 330 446 1287 +3 443 231 489 +3 330 36 1287 +3 86 35 955 +3 450 785 1560 +3 1312 1304 1260 +3 1329 435 428 +3 1289 1276 1277 +3 1289 1290 1276 +3 1158 187 237 +3 1311 556 1248 +3 558 226 743 +3 1323 554 993 +3 1292 446 524 +3 273 443 489 +3 1290 1289 1277 +3 1290 1307 1276 +3 215 264 1296 +3 1304 1286 1273 +3 1260 1304 1273 +3 1311 1248 1273 +3 1286 1311 1273 +3 246 801 250 +3 1322 314 278 +3 1019 1572 1036 +3 307 748 608 +3 182 307 608 +3 1321 443 273 +3 471 1294 636 +3 215 1296 586 +3 1322 278 265 +3 542 701 1129 +3 1101 1284 1278 +3 39 783 785 +3 1304 400 1286 +3 400 1311 1286 +3 1339 244 1200 +3 1324 309 726 +3 674 602 683 +3 265 237 1322 +3 1653 1487 1470 +3 446 36 330 +3 1321 22 443 +3 1277 1267 1290 +3 1290 1308 1307 +3 1313 309 1324 +3 467 68 97 +3 1312 1279 1304 +3 367 1331 335 +3 524 330 1287 +3 1347 1348 471 +3 1308 1315 1307 +3 1365 1529 1108 +3 531 530 784 +3 123 531 784 +3 1041 556 1311 +3 666 1041 1311 +3 312 367 335 +3 1705 1707 1711 +3 690 1324 725 +3 1331 367 439 +3 710 1284 1101 +3 608 748 758 +3 170 699 169 +3 1308 1309 1315 +3 1368 1362 1371 +3 306 1200 244 +3 1279 1299 1304 +3 1304 1299 400 +3 666 1311 400 +3 251 283 237 +3 1853 1866 1871 +3 1312 963 1279 +3 1101 1279 963 +3 1314 1321 273 +3 699 1229 169 +3 1268 1290 1267 +3 1290 1309 1308 +3 386 1320 1315 +3 1320 386 1315 +3 314 1327 370 +3 542 156 701 +3 475 1486 1684 +3 1297 1185 528 +3 1031 916 60 +3 1297 1310 1185 +3 158 1321 1314 +3 1379 1305 1306 +3 553 420 506 +3 291 1342 782 +3 608 758 1041 +3 666 608 1041 +3 1635 1452 1453 +3 60 916 528 +3 916 1297 528 +3 1314 1287 158 +3 601 471 630 +3 1291 1290 1268 +3 1316 1315 1309 +3 1316 1320 1315 +3 400 608 666 +3 1292 524 1185 +3 187 189 188 +3 68 467 1318 +3 187 188 1303 +3 1281 1291 1268 +3 1290 1291 1309 +3 1320 1316 386 +3 1278 385 1299 +3 1279 1278 1299 +3 385 307 400 +3 1299 385 400 +3 307 182 400 +3 400 182 608 +3 801 208 430 +3 243 547 205 +3 1292 1185 1310 +3 1324 726 725 +3 699 170 105 +3 105 68 1318 +3 699 105 1318 +3 1316 1325 386 +3 1325 1187 386 +3 1096 1587 1114 +3 515 208 801 +3 1287 1314 524 +3 1287 219 158 +3 1541 1546 1545 +3 1540 1541 1545 +3 1361 519 1520 +3 570 1129 701 +3 785 1340 884 +3 176 903 127 +3 1232 1226 1233 +3 570 1366 1129 +3 1571 884 1560 +3 378 533 1432 +3 210 570 533 +3 378 210 533 +3 570 210 1366 +3 210 290 1129 +3 1366 210 1129 +3 1129 290 542 +3 290 909 542 +3 290 960 909 +3 124 697 290 +3 210 124 290 +3 697 457 290 +3 290 457 960 +3 960 457 1217 +3 378 124 210 +3 1477 1420 1006 +3 591 378 597 +3 1165 591 597 +3 378 591 124 +3 124 457 697 +3 124 1394 457 +3 1653 1470 1452 +3 1377 1378 1388 +3 1199 1048 1231 +3 124 350 1394 +3 1394 350 457 +3 1048 1165 1231 +3 1048 671 591 +3 1165 1048 591 +3 671 350 124 +3 591 671 124 +3 350 69 457 +3 98 467 97 +3 827 155 1880 +3 1544 1545 1157 +3 176 173 18 +3 1273 700 1260 +3 1369 1048 1199 +3 671 588 350 +3 1545 1546 1204 +3 1546 640 1204 +3 607 247 231 +3 1278 1279 1101 +3 154 1081 1513 +3 1777 1770 1785 +3 1295 499 143 +3 1850 1849 1834 +3 1199 732 1369 +3 732 1183 1369 +3 926 1048 1369 +3 1183 926 1369 +3 926 635 671 +3 1048 926 671 +3 671 635 588 +3 635 1251 350 +3 588 635 350 +3 1449 1472 1468 +3 1490 1489 1472 +3 1425 1074 1389 +3 1198 494 1065 +3 758 718 759 +3 1449 1468 1472 +3 1260 700 1317 +3 732 926 1183 +3 1449 1451 1468 +3 1468 1451 1472 +3 1490 538 1489 +3 272 406 952 +3 1183 926 732 +3 926 1183 635 +3 1426 1435 1434 +3 1449 1450 1451 +3 1421 1422 1426 +3 1426 1422 1435 +3 1469 1486 1490 +3 1472 1469 1490 +3 1183 455 635 +3 1435 1450 1449 +3 1434 1435 1449 +3 1451 1469 1472 +3 475 538 1490 +3 1486 475 1490 +3 475 664 538 +3 250 289 538 +3 664 250 538 +3 306 260 575 +3 455 1183 732 +3 1169 455 732 +3 455 469 635 +3 469 1256 1251 +3 635 469 1251 +3 1204 1389 1074 +3 1319 1381 1382 +3 1364 1370 1085 +3 1329 1396 1381 +3 1330 435 1329 +3 1444 1451 1450 +3 1435 1444 1450 +3 1520 519 1120 +3 1505 1120 1326 +3 640 883 1425 +3 1357 1364 1355 +3 1357 1370 1364 +3 1357 1211 1370 +3 1225 1245 1448 +3 1408 1423 1422 +3 1411 1408 1422 +3 1423 1436 1435 +3 1422 1423 1435 +3 1436 1437 1444 +3 1435 1436 1444 +3 1437 1452 1451 +3 1444 1437 1451 +3 1452 1470 1469 +3 1451 1452 1469 +3 1469 1470 1486 +3 1486 1674 1487 +3 1413 980 1420 +3 1470 1487 1486 +3 1537 154 1105 +3 1393 1054 1169 +3 668 455 1169 +3 1054 668 1169 +3 668 735 469 +3 455 668 469 +3 1455 1445 1446 +3 1185 524 298 +3 459 552 38 +3 1731 1739 1722 +3 1376 1211 1357 +3 1409 1408 1398 +3 1427 1437 1436 +3 1423 1427 1436 +3 1403 1388 1404 +3 84 1367 1363 +3 596 556 1041 +3 714 1185 298 +3 1004 1054 1393 +3 1210 574 399 +3 1320 1307 1315 +3 1635 1453 1438 +3 1359 1357 1356 +3 1358 1359 1356 +3 1377 1376 1357 +3 1359 1377 1357 +3 1388 1211 1376 +3 1377 1388 1376 +3 1402 1409 1398 +3 1388 1398 1211 +3 1402 1408 1409 +3 1402 1424 1423 +3 1408 1402 1423 +3 1423 1424 1427 +3 1424 1438 1437 +3 1427 1424 1437 +3 1438 1453 1452 +3 1437 1438 1452 +3 1197 828 650 +3 1111 1511 1510 +3 1300 1319 1382 +3 1010 808 539 +3 208 1198 430 +3 1200 459 38 +3 1539 1540 1544 +3 1507 1094 1405 +3 1094 976 1405 +3 475 515 801 +3 533 378 1432 +3 744 491 668 +3 1054 744 668 +3 491 101 735 +3 668 491 735 +3 384 459 1200 +3 306 384 1200 +3 1512 1197 650 +3 7 71 103 +3 1466 1295 1074 +3 1325 1328 1187 +3 1329 428 1328 +3 1507 1405 1397 +3 1120 897 1184 +3 1388 1403 1402 +3 1110 859 576 +3 1431 1110 576 +3 399 1212 744 +3 1363 800 153 +3 575 384 306 +3 1178 1100 1512 +3 1425 883 1074 +3 733 84 1363 +3 55 54 87 +3 1296 1300 1282 +3 1378 1377 1359 +3 1004 715 414 +3 1462 1479 1478 +3 1479 1492 222 +3 1478 1479 222 +3 1492 30 179 +3 222 1492 179 +3 30 351 179 +3 1544 1157 154 +3 429 297 709 +3 1110 1483 1475 +3 86 306 391 +3 700 159 1498 +3 1317 700 1498 +3 205 467 540 +3 828 518 650 +3 1672 1462 1473 +3 399 574 1212 +3 574 634 744 +3 1212 574 744 +3 634 1237 491 +3 744 634 491 +3 1367 714 1363 +3 375 606 112 +3 375 82 606 +3 82 86 391 +3 1457 1181 640 +3 1546 1457 640 +3 1479 1493 1492 +3 1493 258 30 +3 1492 1493 30 +3 429 1248 297 +3 39 375 199 +3 336 181 149 +3 1439 1511 1111 +3 1684 515 475 +3 1483 1317 1475 +3 1317 1498 1475 +3 429 342 159 +3 700 429 159 +3 1510 1052 1179 +3 1181 1130 883 +3 640 1181 883 +3 1405 980 1413 +3 1140 964 1181 +3 1509 1439 1517 +3 1479 1480 1493 +3 403 351 30 +3 258 403 30 +3 390 389 1121 +3 1400 897 1298 +3 604 272 709 +3 1460 749 603 +3 403 523 351 +3 1249 329 642 +3 1390 1466 883 +3 1382 1381 1270 +3 1363 714 800 +3 342 429 709 +3 540 375 1047 +3 297 604 709 +3 1467 1461 1201 +3 1130 1390 883 +3 1374 1454 1515 +3 1462 1480 1479 +3 1136 523 403 +3 964 1441 1181 +3 1059 1522 1128 +3 1003 221 500 +3 976 1003 500 +3 1100 1197 1512 +3 390 25 43 +3 1407 1416 1415 +3 1406 1407 1415 +3 1455 1446 1458 +3 1446 1463 1462 +3 1458 1446 1462 +3 1463 1464 1462 +3 1464 1481 1480 +3 1462 1464 1480 +3 1481 1494 1493 +3 1480 1481 1493 +3 1494 994 258 +3 1493 1494 258 +3 456 403 258 +3 994 456 258 +3 621 1136 403 +3 456 621 403 +3 621 523 1136 +3 621 745 523 +3 141 473 523 +3 745 141 523 +3 1516 1524 1476 +3 1128 245 1471 +3 1155 321 634 +3 574 1155 634 +3 599 681 202 +3 298 524 273 +3 681 236 202 +3 1368 1371 1527 +3 1263 1254 1540 +3 1502 1524 1476 +3 1476 1046 1115 +3 321 454 1237 +3 634 321 1237 +3 541 467 205 +3 467 97 540 +3 98 97 467 +3 236 84 733 +3 1446 1464 1463 +3 621 141 745 +3 1516 1476 1503 +3 1467 1201 828 +3 174 639 142 +3 202 236 733 +3 1686 1703 1702 +3 1494 1495 994 +3 1495 1123 994 +3 516 141 621 +3 1037 1059 1128 +3 590 467 541 +3 701 156 1164 +3 1398 1408 1383 +3 493 1301 322 +3 639 321 1155 +3 1429 1446 1445 +3 1481 1495 1494 +3 1220 456 994 +3 1123 1220 994 +3 954 322 495 +3 1373 493 322 +3 987 321 639 +3 260 306 86 +3 1370 1384 1383 +3 1280 1305 1362 +3 1305 1371 1362 +3 1305 1379 1371 +3 1392 1386 1371 +3 1392 1395 1386 +3 1395 1407 1386 +3 1395 1417 1416 +3 1407 1395 1416 +3 1703 1694 1704 +3 1428 1430 1429 +3 1430 1442 1446 +3 1429 1430 1446 +3 1442 1459 1464 +3 1446 1442 1464 +3 1459 1482 1481 +3 1464 1459 1481 +3 1482 1488 1481 +3 1488 1496 1495 +3 1481 1488 1495 +3 1496 468 1123 +3 1495 1496 1123 +3 637 1220 1123 +3 468 637 1123 +3 637 456 1220 +3 637 1203 456 +3 161 621 456 +3 1203 161 456 +3 75 516 621 +3 161 75 621 +3 1687 1694 1703 +3 75 34 495 +3 954 495 34 +3 34 32 322 +3 954 34 322 +3 32 47 322 +3 47 1373 322 +3 47 493 1373 +3 47 183 493 +3 183 1055 493 +3 1055 1012 174 +3 1012 639 174 +3 959 987 639 +3 1012 959 639 +3 959 321 987 +3 959 346 321 +3 346 454 321 +3 1341 1229 541 +3 1229 699 541 +3 699 1318 590 +3 541 699 590 +3 637 161 1203 +3 1615 1635 1438 +3 1300 1296 1319 +3 1379 1395 1392 +3 1615 1438 1424 +3 1613 1615 1424 +3 75 1007 34 +3 1229 1341 336 +3 700 1273 1248 +3 1392 1395 1379 +3 70 161 637 +3 183 1012 1055 +3 1673 1184 1504 +3 1159 1504 1184 +3 1266 346 959 +3 1604 1613 1603 +3 1459 1442 1456 +3 1075 1502 1503 +3 221 1100 500 +3 677 1084 1092 +3 1230 1224 677 +3 1537 1544 154 +3 1105 1097 1088 +3 1121 1105 1088 +3 1146 1346 767 +3 1087 293 176 +3 1100 1467 1197 +3 1154 585 1209 +3 962 1032 1065 +3 1765 1759 1024 +3 1408 1501 1383 +3 1516 1502 1524 +3 143 499 519 +3 1147 1142 1126 +3 1074 1094 680 +3 1399 897 1400 +3 1087 176 366 +3 235 1087 653 +3 897 1399 1184 +3 1149 1135 1061 +3 1685 1687 1360 +3 1379 1392 1371 +3 1810 259 242 +3 293 448 176 +3 1521 1537 1105 +3 235 653 677 +3 1100 1361 1467 +3 373 1538 1537 +3 1514 585 1059 +3 1059 585 341 +3 462 796 1023 +3 964 1106 1419 +3 1505 1326 1201 +3 711 63 1514 +3 964 1140 1092 +3 340 780 868 +3 796 1037 1128 +3 1037 127 796 +3 127 1037 796 +3 18 903 127 +3 1059 341 1522 +3 1508 366 1098 +3 1410 176 127 +3 293 1087 235 +3 1117 187 1876 +3 366 1508 1106 +3 1399 1159 1184 +3 1399 1400 1252 +3 1170 1099 1142 +3 1410 1037 1098 +3 903 18 127 +3 1383 1384 1211 +3 1522 341 1154 +3 1120 1505 1201 +3 1087 366 653 +3 1060 1135 1485 +3 964 1419 1130 +3 293 235 1224 +3 1244 1092 1457 +3 1545 1204 1157 +3 1252 1471 1399 +3 366 964 653 +3 1525 1126 1142 +3 160 360 1173 +3 366 176 1098 +3 499 1401 1298 +3 1539 1544 1537 +3 677 653 1084 +3 176 18 903 +3 199 375 112 +3 1520 1120 1461 +3 644 1539 1538 +3 80 1535 216 +3 176 1410 1098 +3 1140 1181 1457 +3 462 1098 796 +3 1541 1457 1546 +3 1361 1520 1467 +3 1467 1520 1461 +3 373 644 1538 +3 1106 462 781 +3 1591 834 67 +3 390 594 360 +3 160 390 360 +3 1254 1247 1541 +3 1075 1503 980 +3 903 711 127 +3 181 263 276 +3 444 1083 291 +3 1538 1539 1537 +3 1419 1106 1390 +3 519 1361 143 +3 216 1535 1521 +3 1094 976 680 +3 1441 1130 1181 +3 1006 672 1385 +3 1060 1485 1149 +3 43 389 390 +3 181 809 263 +3 1120 1201 1461 +3 1130 1419 1390 +3 1081 680 1507 +3 1231 1165 597 +3 809 1083 263 +3 964 366 1106 +3 809 181 336 +3 809 291 1083 +3 496 1506 1046 +3 650 496 1046 +3 390 1121 594 +3 1295 1003 1074 +3 1832 1845 1831 +3 1204 640 1389 +3 341 585 1154 +3 1081 1507 1082 +3 511 1884 569 +3 1197 1467 828 +3 1341 809 336 +3 1094 680 976 +3 1540 1545 1544 +3 1398 1388 1402 +3 594 1121 1088 +3 1233 1099 1189 +3 1502 1516 1503 +3 1506 1344 1115 +3 291 1137 1342 +3 1097 1513 1082 +3 1412 812 123 +3 498 831 812 +3 1412 498 812 +3 883 1466 1074 +3 1006 1420 962 +3 1399 1471 1159 +3 962 672 1006 +3 1118 1091 702 +3 1686 1687 1703 +3 653 964 1084 +3 1735 1756 1747 +3 1 470 1536 +3 127 1059 1037 +3 1046 1506 1115 +3 1288 1006 1385 +3 1044 1288 1385 +3 1147 1171 1170 +3 1170 1142 1147 +3 1137 291 1346 +3 808 1008 1011 +3 1159 245 1504 +3 672 962 1065 +3 1390 1106 781 +3 1390 1156 1466 +3 1466 1156 1295 +3 1015 1016 1021 +3 644 1540 1539 +3 1137 1533 1542 +3 1088 1089 1288 +3 594 1088 1288 +3 1721 1746 1729 +3 360 594 1044 +3 594 1288 1044 +3 245 1108 1504 +3 216 1521 389 +3 1370 1211 1384 +3 1089 1006 1288 +3 461 587 513 +3 513 587 1351 +3 1351 1414 1412 +3 1091 498 1412 +3 1414 1091 1412 +3 1115 1530 538 +3 1092 1140 1457 +3 1509 1090 1534 +3 1137 1146 1533 +3 1349 461 1547 +3 767 1 1064 +3 1529 1365 1195 +3 964 1130 1441 +3 1351 587 1414 +3 1115 538 289 +3 1405 1413 1397 +3 1513 1081 1082 +3 980 514 1420 +3 680 1094 1507 +3 461 1414 587 +3 1106 1508 462 +3 1052 1370 1179 +3 1457 1541 1247 +3 587 1414 461 +3 1420 514 962 +3 545 1201 1326 +3 63 585 1514 +3 1105 154 1097 +3 1064 1533 1146 +3 1414 587 461 +3 973 1414 587 +3 1414 973 587 +3 250 1476 289 +3 1157 1204 680 +3 1398 1383 1211 +3 1507 1397 1082 +3 1543 1349 1533 +3 1536 1543 1533 +3 1543 410 461 +3 1349 1543 461 +3 973 1141 1414 +3 1141 1091 1414 +3 1476 1115 289 +3 1084 964 1092 +3 373 1537 1521 +3 1521 1105 1121 +3 1476 250 1274 +3 1149 1525 1142 +3 1254 1541 1540 +3 1064 1 1533 +3 1082 1397 1089 +3 1088 1082 1089 +3 80 373 1521 +3 1535 80 1521 +3 1341 541 547 +3 39 199 783 +3 1536 1533 1 +3 973 1414 461 +3 410 973 461 +3 1397 1413 1420 +3 1089 1397 1420 +3 1111 1383 1501 +3 1503 1476 1274 +3 606 82 391 +3 780 38 868 +3 1135 1104 1061 +3 711 1514 1059 +3 1365 1194 1195 +3 1111 1510 1179 +3 1485 1135 1149 +3 796 1128 1252 +3 1228 293 1224 +3 644 1263 1540 +3 390 160 25 +3 63 33 104 +3 391 306 606 +3 306 244 606 +3 1097 154 1513 +3 494 672 1065 +3 1543 618 410 +3 537 973 410 +3 618 537 410 +3 1141 1352 702 +3 972 992 991 +3 1509 1534 1439 +3 1088 1097 1082 +3 1401 1023 1298 +3 53 569 1884 +3 1536 470 1543 +3 1410 127 1037 +3 1227 293 1228 +3 1128 1522 245 +3 1522 1154 245 +3 1850 1870 1849 +3 796 1252 1023 +3 173 83 33 +3 1543 470 618 +3 1242 69 1251 +3 1515 1527 1371 +3 1162 1135 1060 +3 1188 537 618 +3 1109 973 537 +3 1109 1141 973 +3 1109 1352 1141 +3 545 518 828 +3 1201 545 828 +3 1244 1457 1247 +3 1386 1515 1371 +3 1454 1518 1499 +3 1089 1477 1006 +3 462 1401 781 +3 1401 499 781 +3 63 433 585 +3 1886 1066 304 +3 1204 1074 680 +3 127 711 1059 +3 640 1425 1389 +3 1188 618 537 +3 499 1298 519 +3 1226 1060 1099 +3 1233 1226 1099 +3 1515 1454 1386 +3 1298 897 1120 +3 519 1298 1120 +3 1188 537 618 +3 1524 1502 1046 +3 1178 980 550 +3 1178 1512 1075 +3 1515 1386 1391 +3 1386 1454 1515 +3 1149 1142 1099 +3 1060 1149 1099 +3 1508 1098 462 +3 1401 462 1023 +3 1178 1075 980 +3 552 868 459 +3 1061 1525 1149 +3 1098 1037 796 +3 1524 1502 1476 +3 1476 1524 1046 +3 1828 1829 1834 +3 1089 1420 1477 +3 1352 672 494 +3 1502 1512 650 +3 1252 1128 1471 +3 1531 1518 1454 +3 1374 1531 1454 +3 1512 1502 1075 +3 1173 618 470 +3 160 1173 470 +3 1173 1188 618 +3 1173 360 1188 +3 1188 360 537 +3 360 1044 537 +3 537 1044 1109 +3 1044 1385 1109 +3 672 1352 1109 +3 1385 672 1109 +3 511 517 1560 +3 1390 781 1156 +3 223 222 178 +3 831 123 812 +3 141 1333 1618 +3 1812 1829 1828 +3 115 1005 1210 +3 1636 1637 1656 +3 1515 1454 1527 +3 1682 538 1530 +3 1637 1657 1656 +3 1072 1525 1061 +3 1071 1072 1061 +3 548 1350 142 +3 1072 1592 1525 +3 1487 1674 1684 +3 67 937 1010 +3 1754 1784 1762 +3 1462 1478 1473 +3 1137 1542 778 +3 1614 1637 1616 +3 1036 1572 1049 +3 1049 1584 1072 +3 1072 1584 1592 +3 1126 1525 1592 +3 1584 1126 1592 +3 199 606 783 +3 1499 1362 1368 +3 1680 1678 1679 +3 1049 1586 1584 +3 799 178 1558 +3 702 494 1198 +3 1499 1368 1527 +3 868 552 459 +3 1486 1487 1674 +3 1572 1584 1586 +3 1049 1572 1586 +3 779 702 1198 +3 1799 1812 1795 +3 1618 1333 141 +3 1662 1676 1675 +3 805 1350 548 +3 1026 1570 1572 +3 1572 1073 1584 +3 1073 1078 1584 +3 1112 1126 1584 +3 1078 1112 1584 +3 1617 1620 1416 +3 1676 560 483 +3 1675 1676 483 +3 1659 1678 1663 +3 1572 1570 1073 +3 1054 1004 399 +3 827 1880 1870 +3 1404 1590 1604 +3 1374 1515 1391 +3 1345 472 498 +3 802 1555 1519 +3 1655 1675 1674 +3 1416 1614 1415 +3 1407 1406 1386 +3 482 560 1676 +3 1678 1677 1663 +3 1146 1137 1346 +3 1026 1562 1570 +3 1562 1570 1572 +3 1570 1562 1572 +3 1677 482 1676 +3 547 1556 798 +3 701 734 570 +3 1589 1404 1603 +3 1641 1638 1634 +3 1639 1641 1634 +3 1657 1658 1662 +3 260 261 575 +3 156 701 1164 +3 1639 1634 1621 +3 1638 1658 1657 +3 1637 1638 1657 +3 1519 1118 702 +3 1415 1605 1590 +3 779 1519 702 +3 1406 1415 1590 +3 1663 1677 1662 +3 1641 1659 1638 +3 1658 1663 1662 +3 1635 1636 1654 +3 1562 1073 1570 +3 1687 1686 1439 +3 1047 375 39 +3 1621 1620 1617 +3 738 1519 779 +3 483 515 1674 +3 473 1333 531 +3 481 473 531 +3 1155 142 639 +3 1662 1675 1655 +3 1656 1662 1655 +3 1038 1045 1073 +3 1562 1038 1073 +3 222 179 178 +3 1428 1621 1617 +3 1675 483 1674 +3 1159 1471 245 +3 1365 245 1154 +3 1209 1365 1154 +3 245 1365 1108 +3 1637 1636 1616 +3 1416 1620 1614 +3 1638 1637 1614 +3 884 1340 1884 +3 1049 1043 1036 +3 1605 1616 1607 +3 1620 1638 1614 +3 1455 1428 1445 +3 1622 1529 1195 +3 1177 1622 1195 +3 550 976 500 +3 1587 1523 1119 +3 1428 1455 1639 +3 1096 1079 1080 +3 553 536 563 +3 1404 1604 1603 +3 1153 1622 1177 +3 641 638 661 +3 1013 1020 1038 +3 1051 1114 1096 +3 1080 1051 1096 +3 1114 1587 1096 +3 1556 243 798 +3 1532 1623 1622 +3 1153 1532 1622 +3 1642 1529 1622 +3 1623 1642 1622 +3 1642 1504 1108 +3 1529 1642 1108 +3 1378 1404 1388 +3 178 179 1559 +3 1455 1473 1641 +3 1653 1655 1674 +3 805 530 531 +3 33 18 173 +3 1605 1604 1590 +3 179 1259 1559 +3 1051 1587 1114 +3 1118 1345 1091 +3 851 523 532 +3 715 732 1167 +3 1636 1655 1654 +3 1621 1634 1620 +3 1093 1280 1362 +3 1051 1114 1587 +3 1604 1605 1607 +3 1022 1563 1051 +3 1030 1022 1051 +3 1563 1573 1114 +3 1051 1563 1114 +3 1573 1585 1587 +3 1114 1573 1587 +3 1585 1599 1523 +3 1587 1585 1523 +3 1599 1608 1532 +3 1523 1599 1532 +3 1608 1624 1623 +3 1532 1608 1623 +3 1643 1642 1623 +3 1624 1643 1623 +3 1643 1673 1504 +3 1642 1643 1504 +3 551 547 798 +3 1014 1016 1015 +3 1306 1307 1379 +3 805 548 525 +3 1656 1655 1636 +3 1333 805 531 +3 1683 1184 1673 +3 1608 1625 1624 +3 1644 1643 1624 +3 1625 1644 1624 +3 1664 1673 1643 +3 1644 1664 1643 +3 1023 1128 1252 +3 585 854 1209 +3 1351 1412 123 +3 322 1301 495 +3 799 844 474 +3 516 495 141 +3 1555 1345 1118 +3 495 1618 141 +3 1047 205 540 +3 141 1333 473 +3 1433 1426 1434 +3 597 378 1063 +3 1528 1564 1563 +3 1022 1528 1563 +3 1564 1574 1573 +3 1563 1564 1573 +3 1573 1574 1585 +3 1574 1576 1585 +3 1585 1576 1599 +3 1576 1600 1599 +3 1600 1609 1608 +3 1599 1600 1608 +3 1609 1626 1625 +3 1608 1609 1625 +3 1645 1644 1625 +3 1626 1645 1625 +3 1645 1665 1664 +3 1644 1645 1664 +3 1665 1673 1664 +3 1665 1326 1683 +3 1673 1665 1683 +3 1326 1184 1683 +3 1590 1404 1378 +3 1614 1616 1605 +3 1415 1614 1605 +3 495 1333 1618 +3 738 802 1519 +3 1473 1659 1641 +3 1301 805 1333 +3 205 206 517 +3 1405 976 550 +3 495 1301 1333 +3 1593 1601 1600 +3 1576 1593 1600 +3 1600 1601 1609 +3 716 208 515 +3 500 1178 550 +3 1259 523 851 +3 1559 1259 851 +3 831 481 812 +3 513 1349 1547 +3 1616 1636 1635 +3 222 223 1680 +3 1301 493 1350 +3 805 1301 1350 +3 1548 1552 1528 +3 1552 1565 1564 +3 1528 1552 1564 +3 1564 1565 1574 +3 1574 1565 1576 +3 1565 1577 1576 +3 1594 1593 1576 +3 1577 1594 1576 +3 1602 1601 1593 +3 1594 1602 1593 +3 1602 1610 1609 +3 1601 1602 1609 +3 1610 1627 1626 +3 1609 1610 1626 +3 1627 1646 1645 +3 1626 1627 1645 +3 1666 1665 1645 +3 1646 1666 1645 +3 1666 545 1326 +3 1665 1666 1326 +3 483 716 515 +3 547 243 1556 +3 221 1003 1295 +3 143 221 1295 +3 809 1341 547 +3 551 809 547 +3 782 1342 778 +3 731 782 778 +3 1458 1660 1455 +3 752 309 753 +3 1424 1402 1603 +3 1519 1555 1118 +3 1549 1553 1552 +3 1552 1553 1565 +3 1775 1799 1784 +3 1406 1590 1378 +3 493 174 142 +3 1350 493 142 +3 1656 1657 1662 +3 291 809 551 +3 731 778 513 +3 523 473 481 +3 1365 1209 1194 +3 1346 291 551 +3 784 731 513 +3 1550 1554 1553 +3 1549 1550 1553 +3 1566 1565 1553 +3 1554 1566 1553 +3 1566 1578 1577 +3 1565 1566 1577 +3 1578 1579 1577 +3 1577 1579 1594 +3 1579 1595 1602 +3 1594 1579 1602 +3 1595 1611 1610 +3 1602 1595 1610 +3 1628 1627 1610 +3 1611 1628 1610 +3 1628 1647 1646 +3 1627 1628 1646 +3 1647 1667 1666 +3 1646 1647 1666 +3 1667 1668 1666 +3 518 545 1666 +3 1668 518 1666 +3 1074 1003 1094 +3 1607 1616 1615 +3 123 784 513 +3 1499 1527 1454 +3 1604 1607 1615 +3 1566 1579 1578 +3 1628 1648 1647 +3 1648 1668 1667 +3 1647 1648 1667 +3 1681 518 1668 +3 778 1533 1349 +3 513 778 1349 +3 496 650 497 +3 1615 1616 1635 +3 1429 1445 1428 +3 718 758 748 +3 1678 1680 474 +3 1680 223 474 +3 778 1542 1533 +3 206 205 1047 +3 1478 222 1680 +3 1679 1678 1659 +3 857 831 498 +3 1386 1406 1391 +3 1360 1090 1554 +3 1550 1360 1554 +3 1567 1566 1554 +3 1090 1567 1554 +3 1567 1580 1579 +3 1566 1567 1579 +3 1580 1596 1595 +3 1579 1580 1595 +3 1596 1606 1611 +3 1595 1596 1611 +3 1606 1629 1628 +3 1611 1606 1628 +3 1629 1630 1628 +3 1630 1649 1648 +3 1628 1630 1648 +3 1649 1526 1668 +3 1648 1649 1668 +3 496 1681 1668 +3 1526 496 1668 +3 497 518 1681 +3 496 497 1681 +3 518 497 650 +3 1005 574 1210 +3 123 513 1351 +3 1877 1876 1865 +3 1558 1555 802 +3 799 1558 802 +3 472 857 498 +3 1455 1641 1639 +3 1634 1638 1620 +3 482 802 738 +3 1248 429 700 +3 1654 1655 1653 +3 1606 1630 1629 +3 1473 1478 1680 +3 1362 1499 1557 +3 1558 857 472 +3 1120 1184 1326 +3 857 851 831 +3 844 802 482 +3 474 844 482 +3 1555 1558 472 +3 844 799 802 +3 1342 1137 778 +3 1649 1669 1526 +3 1669 1506 496 +3 1526 1669 496 +3 1421 1411 1422 +3 851 532 481 +3 780 340 383 +3 1008 780 383 +3 1568 1567 1090 +3 1509 1568 1090 +3 1568 1581 1580 +3 1567 1568 1580 +3 1597 1596 1580 +3 1581 1597 1580 +3 1596 1597 1606 +3 1597 1612 1606 +3 1612 1631 1630 +3 1606 1612 1630 +3 1631 1650 1649 +3 1630 1631 1649 +3 1649 1650 1669 +3 1678 482 1677 +3 560 738 716 +3 1345 498 1091 +3 500 1100 1178 +3 1678 474 482 +3 1009 878 53 +3 1841 1855 1851 +3 1454 1527 1499 +3 827 107 1864 +3 495 516 75 +3 208 716 1198 +3 1428 1639 1621 +3 1771 1280 1093 +3 842 1008 808 +3 378 533 1063 +3 1582 1581 1568 +3 1659 1663 1658 +3 1865 1864 1851 +3 1503 514 980 +3 1583 1582 1568 +3 1588 1581 1582 +3 1583 1588 1582 +3 1598 1597 1581 +3 1588 1598 1581 +3 1433 1612 1597 +3 1433 1619 1612 +3 1632 1631 1612 +3 1619 1632 1612 +3 1651 1650 1631 +3 1632 1651 1631 +3 1651 1670 1669 +3 1650 1651 1669 +3 1670 1344 1506 +3 1669 1670 1506 +3 1660 1473 1455 +3 1353 842 808 +3 995 1353 808 +3 1353 1008 842 +3 1353 842 1008 +3 38 780 1008 +3 842 38 1008 +3 1517 1569 1568 +3 1509 1517 1568 +3 1569 1583 1568 +3 716 779 1198 +3 716 738 779 +3 560 482 738 +3 1360 1687 1534 +3 1353 38 842 +3 1111 1179 1383 +3 1598 1433 1597 +3 868 38 552 +3 1045 1078 1073 +3 1124 406 272 +3 1433 1632 1619 +3 474 223 1122 +3 1033 1765 1024 +3 1378 1359 1374 +3 1269 1270 1281 +3 291 782 444 +3 483 560 716 +3 1462 1473 1660 +3 499 1156 781 +3 1214 542 909 +3 1555 472 1345 +3 178 1559 1558 +3 851 481 831 +3 1269 1281 1268 +3 824 1856 1846 +3 53 1884 1009 +3 1439 1111 1517 +3 1111 1501 1569 +3 1517 1111 1569 +3 1411 1583 1569 +3 1411 1588 1583 +3 1411 1421 1588 +3 1421 1598 1588 +3 1421 1426 1598 +3 1426 1433 1598 +3 1434 1433 1598 +3 1433 1434 1598 +3 1633 1632 1433 +3 1434 1633 1433 +3 1633 1640 1632 +3 1652 1651 1632 +3 1640 1652 1632 +3 1671 1670 1651 +3 1652 1671 1651 +3 1671 1682 1344 +3 1670 1671 1344 +3 1274 1032 514 +3 1503 1274 514 +3 532 523 481 +3 1319 264 277 +3 546 806 1591 +3 546 995 806 +3 546 746 995 +3 1339 1353 995 +3 746 1339 995 +3 1339 1200 38 +3 1353 1339 38 +3 223 178 799 +3 1530 1344 1682 +3 1449 1633 1434 +3 399 744 1054 +3 831 812 123 +3 1122 223 799 +3 243 205 517 +3 1473 1679 1659 +3 1024 1034 1033 +3 1591 1340 546 +3 1501 1411 1569 +3 1156 499 1295 +3 1449 1640 1633 +3 1209 953 854 +3 1458 1462 1660 +3 1224 235 677 +3 1523 1153 1119 +3 1085 1355 1364 +3 1468 1652 1640 +3 1449 1468 1640 +3 1489 1671 1652 +3 1468 1489 1652 +3 1671 1489 1682 +3 1489 538 1682 +3 1836 1857 1844 +3 803 189 1117 +3 1685 1696 1695 +3 1785 1791 1801 +3 1808 1801 1791 +3 1791 1792 1815 +3 1751 1750 1735 +3 1843 1862 1842 +3 1210 444 115 +3 1800 1816 1799 +3 1803 1821 1802 +3 995 834 1591 +3 758 759 1182 +3 1836 1858 1857 +3 810 168 1857 +3 1858 810 1857 +3 1740 1757 1764 +3 873 872 865 +3 1808 1815 1801 +3 1815 1819 1801 +3 804 803 1117 +3 1741 1757 1740 +3 1793 865 1788 +3 1812 1816 1830 +3 804 1117 1878 +3 1561 1725 1726 +3 1857 168 824 +3 1757 1779 1764 +3 1764 1779 1786 +3 78 815 1868 +3 1822 1821 1803 +3 1717 1737 1721 +3 1844 1857 1846 +3 1725 1724 1013 +3 824 168 79 +3 1713 1718 1696 +3 1715 1714 1699 +3 1722 1730 1711 +3 1843 1842 1825 +3 1819 1843 1825 +3 1857 824 1846 +3 1821 1827 1826 +3 1809 1821 1826 +3 1815 1843 1819 +3 1821 1809 1802 +3 1548 1689 1549 +3 1733 1561 1562 +3 1733 1725 1561 +3 604 599 406 +3 406 599 202 +3 1822 1836 1821 +3 815 1881 1867 +3 1852 1855 1830 +3 1699 1706 1016 +3 54 55 845 +3 158 219 521 +3 1742 1741 1725 +3 1733 1742 1725 +3 1763 1777 1785 +3 1033 1788 1765 +3 1769 1776 1749 +3 1749 1755 1734 +3 1756 1769 1747 +3 1732 1751 1735 +3 1707 1714 1722 +3 1738 1754 1737 +3 1876 1864 1865 +3 1722 1714 1731 +3 865 1810 1787 +3 1788 865 1787 +3 1715 1732 1714 +3 1742 1757 1741 +3 1804 1803 1786 +3 1779 1804 1786 +3 1770 1791 1785 +3 1806 1810 242 +3 1722 1747 1730 +3 1705 1706 1707 +3 1804 1805 1803 +3 1835 1843 1815 +3 1346 551 1883 +3 1802 1809 1792 +3 1837 1836 1822 +3 1017 1837 1822 +3 1878 1117 1877 +3 1711 1730 1713 +3 1690 1706 1705 +3 1837 136 1836 +3 1830 1855 1841 +3 1868 1867 1856 +3 599 20 681 +3 136 1858 1836 +3 1791 1815 1808 +3 1024 1759 1018 +3 1730 1734 1713 +3 1785 1790 1756 +3 20 596 681 +3 1831 1830 1817 +3 1797 1802 1792 +3 1864 1876 827 +3 1881 815 814 +3 1787 1806 1781 +3 1116 916 1031 +3 814 1882 1872 +3 1711 1713 1697 +3 1110 1475 859 +3 1690 1705 1698 +3 1785 1801 1790 +3 1765 1787 1759 +3 596 20 556 +3 596 1180 681 +3 681 1180 1031 +3 1882 804 1872 +3 1698 1711 1697 +3 1759 1781 1758 +3 900 1883 979 +3 1696 1717 1704 +3 1026 1561 1562 +3 1769 1796 1776 +3 1013 1723 1715 +3 1734 1717 1718 +3 1832 1831 1813 +3 1180 316 1116 +3 1031 1180 1116 +3 1561 1742 1733 +3 1882 814 804 +3 1820 1835 1815 +3 1442 988 1447 +3 710 577 622 +3 1810 1806 1787 +3 596 1752 1180 +3 1180 316 1116 +3 316 1180 1116 +3 316 993 916 +3 1116 316 916 +3 1759 1787 1781 +3 1776 1800 1775 +3 1732 1735 1714 +3 1886 409 821 +3 1703 1729 1710 +3 1693 1685 1550 +3 1016 1706 1690 +3 1693 1689 1697 +3 1842 1862 1861 +3 1694 1695 1704 +3 1687 1685 1694 +3 988 382 1447 +3 1447 382 576 +3 747 797 120 +3 1776 1775 1755 +3 1199 1167 732 +3 1041 758 596 +3 596 758 1752 +3 1876 1158 107 +3 1685 1695 1694 +3 1858 818 810 +3 382 1431 576 +3 1693 1697 1696 +3 243 1888 798 +3 1117 189 187 +3 1823 1822 1803 +3 1805 1823 1803 +3 1442 1430 1443 +3 818 1858 136 +3 356 477 424 +3 382 1575 1431 +3 916 993 554 +3 467 590 1318 +3 1685 1693 1696 +3 1845 1866 1853 +3 1431 1575 1110 +3 1182 1752 758 +3 1182 1180 1752 +3 1182 825 1180 +3 1180 825 316 +3 1017 136 1837 +3 1430 1440 1443 +3 1440 908 988 +3 988 908 382 +3 1575 549 1110 +3 549 1150 963 +3 1110 549 963 +3 1825 1813 1814 +3 1796 1817 1800 +3 825 633 316 +3 1699 1714 1706 +3 633 993 316 +3 633 1323 993 +3 1430 1869 1440 +3 908 1575 382 +3 1101 963 1150 +3 1734 1738 1717 +3 1819 1825 1814 +3 1801 1819 1814 +3 633 825 1182 +3 1440 1869 908 +3 908 996 1575 +3 759 787 786 +3 1809 1826 1820 +3 1869 1145 908 +3 549 1101 1150 +3 1723 1732 1715 +3 1428 1847 1430 +3 1145 56 908 +3 908 56 996 +3 1144 1101 549 +3 1809 1820 1815 +3 1793 1788 1033 +3 797 633 1182 +3 759 797 1182 +3 1735 1750 1756 +3 996 56 1575 +3 56 549 1575 +3 1750 1763 1756 +3 1847 1848 1430 +3 1848 1859 1430 +3 1430 1859 1869 +3 56 1168 549 +3 1690 1689 1548 +3 1758 1779 1757 +3 786 797 759 +3 747 633 797 +3 633 747 1323 +3 1323 747 167 +3 865 866 873 +3 1778 1791 1770 +3 78 1868 824 +3 1805 1804 1779 +3 1428 1848 1847 +3 56 1053 1168 +3 1168 1131 1144 +3 549 1168 1144 +3 1877 1117 1876 +3 1707 1722 1711 +3 1731 1735 1739 +3 830 1823 1805 +3 830 1822 1823 +3 1859 1873 1145 +3 1869 1859 1145 +3 1131 1101 1144 +3 1814 1813 1790 +3 830 1017 1822 +3 207 562 561 +3 1772 1771 1093 +3 1557 1772 1093 +3 866 1033 1042 +3 1617 1417 1428 +3 1428 1417 1848 +3 1734 1755 1738 +3 1821 1836 1844 +3 1801 1814 1790 +3 895 797 786 +3 787 759 760 +3 1873 961 1145 +3 1145 961 56 +3 1053 1131 1168 +3 1833 1101 1131 +3 1833 710 1101 +3 1853 1871 1852 +3 1689 1690 1698 +3 1772 1275 1771 +3 1848 1417 1859 +3 242 830 1806 +3 1713 1734 1718 +3 1800 1799 1775 +3 1695 1696 1704 +3 1518 1557 1499 +3 1794 1275 1772 +3 1809 1815 1792 +3 1417 1418 1859 +3 961 951 56 +3 56 951 1053 +3 1833 1131 710 +3 1019 1742 1561 +3 1758 1757 1742 +3 1780 1779 1758 +3 1748 1557 1518 +3 1794 1277 1275 +3 1873 1879 961 +3 951 559 1053 +3 1053 559 1131 +3 1876 107 827 +3 1747 1769 1749 +3 1267 1277 1794 +3 1418 1863 1859 +3 1859 1863 1873 +3 1868 815 1867 +3 1766 1772 1557 +3 1748 1766 1557 +3 866 1793 1033 +3 559 1196 1131 +3 1196 1343 1131 +3 1131 1343 710 +3 1766 1794 1772 +3 180 1229 336 +3 415 1879 1873 +3 415 961 1879 +3 1343 577 710 +3 866 865 1793 +3 1362 1557 1093 +3 1789 1794 1766 +3 1873 1863 415 +3 1456 1442 1447 +3 1018 1742 1019 +3 1743 1748 1518 +3 1531 1743 1518 +3 1789 1267 1794 +3 434 961 415 +3 434 951 961 +3 1781 1779 1780 +3 1811 1267 1789 +3 1781 1805 1779 +3 404 522 438 +3 434 736 951 +3 736 559 951 +3 1743 1766 1748 +3 559 736 1196 +3 1722 1739 1747 +3 715 1393 1169 +3 1534 1090 1360 +3 1269 1271 1270 +3 604 1124 272 +3 1358 1531 1500 +3 1824 1268 1267 +3 1811 1824 1267 +3 155 813 1880 +3 736 480 1196 +3 1196 480 1343 +3 1343 480 577 +3 1790 1813 1796 +3 1782 1789 1766 +3 1760 1782 1766 +3 1803 1802 1797 +3 1777 1770 1785 +3 1719 1743 1531 +3 1760 1766 1743 +3 1838 1269 1268 +3 1824 1838 1268 +3 1750 1770 1777 +3 480 578 577 +3 1689 1693 1550 +3 1763 1750 1777 +3 1770 1777 1785 +3 1691 1358 1356 +3 1719 1531 1358 +3 736 1062 480 +3 1813 1831 1817 +3 1549 1689 1550 +3 1756 1763 1785 +3 1691 1356 1355 +3 1085 1691 1355 +3 1761 1760 1743 +3 1744 1761 1743 +3 1807 1811 1789 +3 1838 1271 1269 +3 78 824 79 +3 1876 187 1158 +3 1821 1844 1827 +3 1708 1719 1358 +3 1744 1743 1719 +3 1782 1807 1789 +3 1807 1824 1811 +3 1860 1271 1838 +3 736 451 1062 +3 1756 1790 1769 +3 1725 1740 1724 +3 1698 1705 1711 +3 1510 1691 1085 +3 1708 1358 1691 +3 1761 1782 1760 +3 1818 1824 1807 +3 1860 1272 1271 +3 1718 1717 1696 +3 451 207 480 +3 1062 451 480 +3 1817 1830 1816 +3 1796 1800 1776 +3 1510 1085 1052 +3 1818 1838 1824 +3 1875 1272 1860 +3 1813 1817 1796 +3 1720 1719 1708 +3 1736 1744 1719 +3 1839 1838 1818 +3 96 807 486 +3 1018 1758 1742 +3 1842 1861 1845 +3 1881 814 1872 +3 1781 1780 1758 +3 1867 1881 1872 +3 1692 1691 1510 +3 1720 1736 1719 +3 1783 1782 1761 +3 1839 1860 1838 +3 1875 1661 586 +3 1272 1875 586 +3 1806 1805 1781 +3 1712 1716 1708 +3 1727 1720 1708 +3 1716 1727 1708 +3 1854 1860 1839 +3 1143 1661 1875 +3 1661 99 586 +3 1143 99 1661 +3 1031 60 236 +3 1709 1708 1691 +3 1692 1709 1691 +3 1709 1712 1708 +3 1709 1716 1712 +3 1709 1727 1716 +3 1727 1728 1720 +3 1786 1803 1797 +3 747 120 167 +3 484 207 451 +3 1736 1753 1744 +3 1753 1761 1744 +3 1753 1783 1761 +3 1874 1860 1854 +3 1874 1875 1860 +3 1792 1791 1778 +3 824 1868 1856 +3 1817 1816 1800 +3 520 207 484 +3 1692 1700 1709 +3 1728 1727 1709 +3 1728 1745 1727 +3 1511 1688 1510 +3 1688 1692 1510 +3 1874 1143 1875 +3 1013 1715 1699 +3 1749 1776 1755 +3 1759 1758 1018 +3 1688 1701 1700 +3 1692 1688 1700 +3 1773 1783 1753 +3 1849 1854 1839 +3 813 1143 1874 +3 813 99 1143 +3 1842 1845 1832 +3 1710 1709 1700 +3 1701 1710 1700 +3 1872 804 1878 +3 1825 1842 1832 +3 1853 1852 1830 +3 1730 1749 1734 +3 1689 1698 1697 +3 1805 1806 830 +3 1710 1728 1709 +3 1840 1849 1839 +3 1831 1853 1830 +3 1724 1723 1013 +3 1729 1728 1710 +3 1849 1874 1854 +3 1849 1870 1874 +3 1741 1740 1725 +3 1755 1775 1754 +3 1731 1714 1735 +3 1747 1749 1730 +3 1706 1714 1707 +3 1729 1745 1728 +3 1767 1773 1753 +3 1880 813 1874 +3 1870 1880 1874 +3 865 858 1810 +3 1810 858 259 +3 1861 1866 1845 +3 1790 1796 1769 +3 1755 1754 1738 +3 1739 1735 1747 +3 1686 1688 1511 +3 1439 1686 1511 +3 1746 1745 1729 +3 1774 1773 1767 +3 1834 1849 1840 +3 1016 1690 1548 +3 1788 1787 1765 +3 1551 1016 1548 +3 1686 1702 1701 +3 1688 1686 1701 +3 1703 1710 1701 +3 1702 1703 1701 +3 1795 1798 1773 +3 1825 1832 1813 +3 1697 1713 1696 +3 1762 1745 1746 +3 1762 1768 1745 +3 1795 1773 1774 diff --git a/samples/cpp/tutorial_code/viz/creating_widgets.cpp b/samples/cpp/tutorial_code/viz/creating_widgets.cpp new file mode 100644 index 0000000000..9ee6c54364 --- /dev/null +++ b/samples/cpp/tutorial_code/viz/creating_widgets.cpp @@ -0,0 +1,113 @@ +/** + * @file creating_widgets.cpp + * @brief Creating custom widgets using VTK + * @author Ozan Cagri Tonkal + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace cv; +using namespace std; + +/** + * @function help + * @brief Display instructions to use this tutorial program + */ +void help() +{ + cout + << "--------------------------------------------------------------------------" << endl + << "This program shows how to create a custom widget. You can create your own " + << "widgets by extending Widget2D/Widget3D, and with the help of WidgetAccessor." << endl + << "Usage:" << endl + << "./creating_widgets" << endl + << endl; +} + +/** + * @class TriangleWidget + * @brief Defining our own 3D Triangle widget + */ +class WTriangle : public viz::Widget3D +{ + public: + WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color = viz::Color::white()); +}; + +/** + * @function TriangleWidget::TriangleWidget + * @brief Constructor + */ +WTriangle::WTriangle(const Point3f &pt1, const Point3f &pt2, const Point3f &pt3, const viz::Color & color) +{ + // Create a triangle + vtkSmartPointer points = vtkSmartPointer::New(); + points->InsertNextPoint(pt1.x, pt1.y, pt1.z); + points->InsertNextPoint(pt2.x, pt2.y, pt2.z); + points->InsertNextPoint(pt3.x, pt3.y, pt3.z); + + vtkSmartPointer triangle = vtkSmartPointer::New(); + triangle->GetPointIds()->SetId(0,0); + triangle->GetPointIds()->SetId(1,1); + triangle->GetPointIds()->SetId(2,2); + + vtkSmartPointer cells = vtkSmartPointer::New(); + cells->InsertNextCell(triangle); + + // Create a polydata object + vtkSmartPointer polyData = vtkSmartPointer::New(); + + // Add the geometry and topology to the polydata + polyData->SetPoints(points); + polyData->SetPolys(cells); + + // Create mapper and actor + vtkSmartPointer mapper = vtkSmartPointer::New(); +#if VTK_MAJOR_VERSION <= 5 + mapper->SetInput(polyData); +#else + mapper->SetInputData(polyData); +#endif + + vtkSmartPointer actor = vtkSmartPointer::New(); + actor->SetMapper(mapper); + + // Store this actor in the widget in order that visualizer can access it + viz::WidgetAccessor::setProp(*this, actor); + + // Set the color of the widget. This has to be called after WidgetAccessor. + setColor(color); +} + +/** + * @function main + */ +int main() +{ + help(); + + /// Create a window + viz::Viz3d myWindow("Creating Widgets"); + + /// Create a triangle widget + WTriangle tw(Point3f(0.0,0.0,0.0), Point3f(1.0,1.0,1.0), Point3f(0.0,1.0,0.0), viz::Color::red()); + + /// Show widget in the visualizer window + myWindow.showWidget("TRIANGLE", tw); + + /// Start event loop + myWindow.spin(); + + return 0; +} diff --git a/samples/cpp/tutorial_code/viz/launching_viz.cpp b/samples/cpp/tutorial_code/viz/launching_viz.cpp new file mode 100644 index 0000000000..55a3ddee2c --- /dev/null +++ b/samples/cpp/tutorial_code/viz/launching_viz.cpp @@ -0,0 +1,66 @@ +/** + * @file launching_viz.cpp + * @brief Launching visualization window + * @author Ozan Cagri Tonkal + */ + +#include +#include + +using namespace cv; +using namespace std; + +/** + * @function help + * @brief Display instructions to use this tutorial program + */ +void help() +{ + cout + << "--------------------------------------------------------------------------" << endl + << "This program shows how to launch a 3D visualization window. You can stop event loop to continue executing. " + << "You can access the same window via its name. You can run event loop for a given period of time. " << endl + << "Usage:" << endl + << "./launching_viz" << endl + << endl; +} + +/** + * @function main + */ +int main() +{ + help(); + /// Create a window + viz::Viz3d myWindow("Viz Demo"); + + /// Start event loop + myWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "First event loop is over" << endl; + + /// Access window via its name + viz::Viz3d sameWindow = viz::getWindowByName("Viz Demo"); + + /// Start event loop + sameWindow.spin(); + + /// Event loop is over when pressed q, Q, e, E + cout << "Second event loop is over" << endl; + + /// Event loop is over when pressed q, Q, e, E + /// Start event loop once for 1 millisecond + sameWindow.spinOnce(1, true); + while(!sameWindow.wasStopped()) + { + /// Interact with window + + /// Event loop for 1 millisecond + sameWindow.spinOnce(1, true); + } + + /// Once more event loop is stopped + cout << "Last event loop is over" << endl; + return 0; +} diff --git a/samples/cpp/tutorial_code/viz/transformations.cpp b/samples/cpp/tutorial_code/viz/transformations.cpp new file mode 100644 index 0000000000..d8713fddc1 --- /dev/null +++ b/samples/cpp/tutorial_code/viz/transformations.cpp @@ -0,0 +1,112 @@ +/** + * @file transformations.cpp + * @brief Visualizing cloud in different positions, coordinate frames, camera frustums + * @author Ozan Cagri Tonkal + */ + +#include +#include +#include + +using namespace cv; +using namespace std; + +/** + * @function help + * @brief Display instructions to use this tutorial program + */ +void help() +{ + cout + << "--------------------------------------------------------------------------" << endl + << "This program shows how to use makeTransformToGlobal() to compute required pose," + << "how to use makeCameraPose and Viz3d::setViewerPose. You can observe the scene " + << "from camera point of view (C) or global point of view (G)" << endl + << "Usage:" << endl + << "./transformations [ G | C ]" << endl + << endl; +} + +/** + * @function cvcloud_load + * @brief load bunny.ply + */ +Mat cvcloud_load() +{ + Mat cloud(1, 1889, CV_32FC3); + ifstream ifs("bunny.ply"); + + string str; + for(size_t i = 0; i < 12; ++i) + getline(ifs, str); + + Point3f* data = cloud.ptr(); + float dummy1, dummy2; + for(size_t i = 0; i < 1889; ++i) + ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2; + + cloud *= 5.0f; + return cloud; +} + +/** + * @function main + */ +int main(int argn, char **argv) +{ + help(); + + if (argn < 2) + { + cout << "Missing arguments." << endl; + return 1; + } + + bool camera_pov = (argv[1][0] == 'C'); + + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); + + /// Let's assume camera has the following properties + Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f); + + /// We can get the pose of the cam using makeCameraPose + Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); + + /// We can get the transformation matrix from camera coordinate system to global using + /// - makeTransformToGlobal. We need the axes of the camera + Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos); + + /// Create a cloud widget. + Mat bunny_cloud = cvcloud_load(); + viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); + + /// Pose of the widget in camera frame + Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f)); + /// Pose of the widget in global frame + Affine3f cloud_pose_global = transform * cloud_pose; + + /// Visualize camera frame + if (!camera_pov) + { + viz::WCameraPosition cpw(0.5); // Coordinate axes + viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum + myWindow.showWidget("CPW", cpw, cam_pose); + myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose); + } + + /// Visualize widget + myWindow.showWidget("bunny", cloud_widget, cloud_pose_global); + + /// Set the viewer pose to that of camera + if (camera_pov) + myWindow.setViewerPose(cam_pose); + + /// Start event loop. + myWindow.spin(); + + return 0; +} diff --git a/samples/cpp/tutorial_code/viz/widget_pose.cpp b/samples/cpp/tutorial_code/viz/widget_pose.cpp new file mode 100644 index 0000000000..3ecead8d93 --- /dev/null +++ b/samples/cpp/tutorial_code/viz/widget_pose.cpp @@ -0,0 +1,79 @@ +/** + * @file widget_pose.cpp + * @brief Setting pose of a widget + * @author Ozan Cagri Tonkal + */ + +#include +#include +#include + +using namespace cv; +using namespace std; + +/** + * @function help + * @brief Display instructions to use this tutorial program + */ +void help() +{ + cout + << "--------------------------------------------------------------------------" << endl + << "This program shows how to visualize a cube rotated around (1,1,1) and shifted " + << "using Rodrigues vector." << endl + << "Usage:" << endl + << "./widget_pose" << endl + << endl; +} + +/** + * @function main + */ +int main() +{ + help(); + + /// Create a window + viz::Viz3d myWindow("Coordinate Frame"); + + /// Add coordinate axes + myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem()); + + /// Add line to represent (1,1,1) axis + viz::WLine axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f)); + axis.setRenderingProperty(viz::LINE_WIDTH, 4.0); + myWindow.showWidget("Line Widget", axis); + + /// Construct a cube widget + viz::WCube cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue()); + cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0); + myWindow.showWidget("Cube Widget", cube_widget); + + /// Rodrigues vector + Mat rot_vec = Mat::zeros(1,3,CV_32F); + float translation_phase = 0.0, translation = 0.0; + while(!myWindow.wasStopped()) + { + /* Rotation using rodrigues */ + /// Rotate around (1,1,1) + rot_vec.at(0,0) += CV_PI * 0.01f; + rot_vec.at(0,1) += CV_PI * 0.01f; + rot_vec.at(0,2) += CV_PI * 0.01f; + + /// Shift on (1,1,1) + translation_phase += CV_PI * 0.01f; + translation = sin(translation_phase); + + Mat rot_mat; + Rodrigues(rot_vec, rot_mat); + + /// Construct pose + Affine3f pose(rot_mat, Vec3f(translation, translation, translation)); + + myWindow.setWidgetPose("Cube Widget", pose); + + myWindow.spinOnce(1, true); + } + + return 0; +} diff --git a/samples/gpu/CMakeLists.txt b/samples/gpu/CMakeLists.txt index 7093cf5d19..8fa539473b 100644 --- a/samples/gpu/CMakeLists.txt +++ b/samples/gpu/CMakeLists.txt @@ -83,6 +83,6 @@ endif() if (INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB install_list *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) install(FILES ${install_list} - DESTINATION share/OpenCV/samples/${project} + DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/gpu PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples) endif() diff --git a/samples/gpu/performance/CMakeLists.txt b/samples/gpu/performance/CMakeLists.txt index 0b2346f91f..de0feadd26 100644 --- a/samples/gpu/performance/CMakeLists.txt +++ b/samples/gpu/performance/CMakeLists.txt @@ -29,6 +29,7 @@ endif() if(INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB GPU_FILES performance/*.cpp performance/*.h) install(FILES ${GPU_FILES} - DESTINATION share/OpenCV/samples/gpu/performance - PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) + DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/gpu/performance + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ + COMPONENT samples) endif() diff --git a/samples/ocl/CMakeLists.txt b/samples/ocl/CMakeLists.txt index 4139211000..7fc20fd356 100644 --- a/samples/ocl/CMakeLists.txt +++ b/samples/ocl/CMakeLists.txt @@ -54,6 +54,6 @@ endif() if (INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB install_list *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) install(FILES ${install_list} - DESTINATION share/OpenCV/samples/${project} + DESTINATION ${OPENCV_SAMPLES_SRC_INSTALL_PATH}/ocl PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples) endif()