merged 2.4 into trunk

pull/2/head
Vadim Pisarevsky 13 years ago
parent 3f1c6d7357
commit d5a0088bbe
  1. 50
      CMakeLists.txt
  2. 84
      android/android.toolchain.cmake
  3. 20
      android/scripts/build.cmd
  4. 93
      cmake/OpenCVCompilerOptions.cmake
  5. 4
      cmake/OpenCVDetectAndroidSDK.cmake
  6. 2
      cmake/OpenCVDetectApacheAnt.cmake
  7. 15
      cmake/OpenCVDetectCXXCompiler.cmake
  8. 36
      cmake/OpenCVDetectPython.cmake
  9. 22
      cmake/OpenCVIOLibs.cmake
  10. 2
      cmake/OpenCVModule.cmake
  11. 13
      cmake/OpenCVUtils.cmake
  12. 25
      cmake/templates/OpenCVConfig.cmake.in
  13. 4
      doc/_themes/blue/static/default.css_t
  14. BIN
      doc/opencv2refman.pdf
  15. BIN
      doc/opencv_tutorials.pdf
  16. BIN
      doc/opencv_user.pdf
  17. 2
      doc/tutorials/introduction/linux_install/linux_install.rst
  18. 4
      doc/tutorials/introduction/windows_visual_studio_Opencv/windows_visual_studio_Opencv.rst
  19. 8
      doc/user_guide/ug_mat.rst
  20. 5
      modules/calib3d/src/calibinit.cpp
  21. 34
      modules/calib3d/src/calibration.cpp
  22. 44
      modules/contrib/src/contrib_init.cpp
  23. 2
      modules/contrib/src/hybridtracker.cpp
  24. 278
      modules/core/doc/basic_structures.rst
  25. 23
      modules/core/doc/old_basic_structures.rst
  26. BIN
      modules/core/doc/pics/rotatedrect.png
  27. 55
      modules/core/include/opencv2/core/core.hpp
  28. 322
      modules/core/include/opencv2/core/devmem2d.hpp
  29. 22
      modules/core/include/opencv2/core/mat.hpp
  30. 25
      modules/core/include/opencv2/core/operations.hpp
  31. 19
      modules/core/include/opencv2/core/types_c.h
  32. 94
      modules/core/src/algorithm.cpp
  33. 22
      modules/core/src/mathfuncs.cpp
  34. 9
      modules/core/src/precomp.hpp
  35. 57
      modules/core/src/rand.cpp
  36. 208
      modules/core/src/stat.cpp
  37. 29
      modules/core/test/test_arithm.cpp
  38. 19
      modules/core/test/test_eigen.cpp
  39. 1
      modules/core/test/test_math.cpp
  40. 81
      modules/core/test/test_operations.cpp
  41. 107
      modules/features2d/doc/common_interfaces_of_descriptor_extractors.rst
  42. 98
      modules/features2d/doc/common_interfaces_of_descriptor_matchers.rst
  43. 81
      modules/features2d/doc/common_interfaces_of_feature_detectors.rst
  44. 116
      modules/features2d/doc/common_interfaces_of_generic_descriptor_matchers.rst
  45. 540
      modules/features2d/doc/feature_detection_and_description.rst
  46. 19
      modules/features2d/include/opencv2/features2d/features2d.hpp
  47. 11
      modules/features2d/src/descriptors.cpp
  48. 212
      modules/features2d/src/detectors.cpp
  49. 263
      modules/features2d/src/features2d_init.cpp
  50. 122
      modules/features2d/test/test_bruteforcematcher.cpp
  51. 7
      modules/features2d/test/test_features2d.cpp
  52. 10
      modules/flann/src/miniflann.cpp
  53. 6
      modules/gpu/include/opencv2/gpu/gpu.hpp
  54. 43
      modules/gpu/src/cuda/optical_flow_farneback.cu
  55. 12
      modules/gpu/src/cuda/pyrlk.cu
  56. 26
      modules/gpu/src/nvidia/NCVBroxOpticalFlow.cu
  57. 2
      modules/gpu/src/nvidia/NPP_staging/NPP_staging.cu
  58. 18
      modules/gpu/src/optical_flow_farneback.cpp
  59. 3
      modules/gpu/src/orb.cpp
  60. 915
      modules/gpu/test/test_video.cpp
  61. 28
      modules/highgui/CMakeLists.txt
  62. 1
      modules/highgui/include/opencv2/highgui/highgui_c.h
  63. 159
      modules/highgui/src/cap.cpp
  64. 2
      modules/highgui/src/cap_avfoundation.mm
  65. 1
      modules/highgui/src/cap_ffmpeg.cpp
  66. 1967
      modules/highgui/src/cap_ffmpeg_impl.hpp
  67. 24
      modules/highgui/src/cap_openni.cpp
  68. 3
      modules/highgui/src/cap_pvapi.cpp
  69. 3
      modules/highgui/src/grfmt_png.cpp
  70. 2
      modules/highgui/src/window_QT.cpp
  71. 8
      modules/highgui/test/test_drawing.cpp
  72. 323
      modules/highgui/test/test_ffmpeg.cpp
  73. 56
      modules/highgui/test/test_framecount.cpp
  74. 12
      modules/highgui/test/test_grfmt.cpp
  75. 50
      modules/highgui/test/test_positioning.cpp
  76. 66
      modules/highgui/test/test_precomp.hpp
  77. 495
      modules/highgui/test/test_video_io.cpp
  78. 409
      modules/highgui/test/test_video_pos.cpp
  79. 4
      modules/imgproc/doc/geometric_transformations.rst
  80. 1
      modules/imgproc/doc/imgproc.rst
  81. 10
      modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst
  82. 3
      modules/imgproc/include/opencv2/imgproc/imgproc.hpp
  83. 4
      modules/imgproc/perf/perf_blur.cpp
  84. 2
      modules/imgproc/perf/perf_cornerEigenValsAndVecs.cpp
  85. 2
      modules/imgproc/perf/perf_integral.cpp
  86. 12
      modules/imgproc/src/contours.cpp
  87. 5
      modules/imgproc/src/smooth.cpp
  88. 9
      modules/imgproc/src/utils.cpp
  89. 52
      modules/java/CMakeLists.txt
  90. 2
      modules/java/android/.project
  91. 4
      modules/java/android/AndroidManifest.xml
  92. 7
      modules/java/android_test/src/org/opencv/test/android/UtilsTest.java
  93. 13
      modules/java/android_test/src/org/opencv/test/calib3d/Calib3dTest.java
  94. 6
      modules/java/android_test/src/org/opencv/test/core/CoreTest.java
  95. 286
      modules/java/android_test/src/org/opencv/test/core/MatTest.java
  96. 22
      modules/java/android_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java
  97. 2
      modules/java/android_test/src/org/opencv/test/features2d/BruteForceHammingLUTDescriptorMatcherTest.java
  98. 17
      modules/java/android_test/src/org/opencv/test/features2d/BruteForceL1DescriptorMatcherTest.java
  99. 15
      modules/java/android_test/src/org/opencv/test/features2d/BruteForceSL2DescriptorMatcherTest.java
  100. 15
      modules/java/android_test/src/org/opencv/test/features2d/FlannBasedDescriptorMatcherTest.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -42,10 +42,12 @@ endif(NOT CMAKE_TOOLCHAIN_FILE)
# --------------------------------------------------------------
# Top level OpenCV project
# --------------------------------------------------------------
if(NOT IOS)
cmake_minimum_required(VERSION 2.6.3)
if(CMAKE_GENERATOR MATCHES Xcode AND XCODE_VERSION VERSION_GREATER 4.3)
cmake_minimum_required(VERSION 2.8.8)
elseif(IOS)
cmake_minimum_required(VERSION 2.8.0)
else()
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 2.6.3)
endif()
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE)
@ -53,7 +55,7 @@ if(DEFINED CMAKE_BUILD_TYPE AND CMAKE_VERSION VERSION_GREATER "2.8")
set_property( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES} )
endif()
project(OpenCV)
project(OpenCV CXX C)
include(cmake/OpenCVUtils.cmake REQUIRED)
@ -140,11 +142,11 @@ OCV_OPTION(BUILD_WITH_STATIC_CRT "Enables use of staticaly linked CRT for sta
OCV_OPTION(BUILD_FAT_JAVA_LIB "Create fat java wrapper containing the whole OpenCV library" ON IF ANDROID AND NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX )
# 3rd party libs
OCV_OPTION(BUILD_ZLIB "Build zlib from source" WIN32 OR IOS )
OCV_OPTION(BUILD_TIFF "Build libtiff from source" WIN32 OR IOS OR ANDROID )
OCV_OPTION(BUILD_JASPER "Build libjasper from source" WIN32 OR IOS OR ANDROID )
OCV_OPTION(BUILD_JPEG "Build libjpeg from source" WIN32 OR IOS OR ANDROID )
OCV_OPTION(BUILD_PNG "Build libpng from source" WIN32 OR IOS OR ANDROID )
OCV_OPTION(BUILD_ZLIB "Build zlib from source" WIN32 OR IOS OR APPLE )
OCV_OPTION(BUILD_TIFF "Build libtiff from source" WIN32 OR IOS OR ANDROID OR APPLE )
OCV_OPTION(BUILD_JASPER "Build libjasper from source" WIN32 OR IOS OR ANDROID OR APPLE )
OCV_OPTION(BUILD_JPEG "Build libjpeg from source" WIN32 OR IOS OR ANDROID OR APPLE )
OCV_OPTION(BUILD_PNG "Build libpng from source" WIN32 OR IOS OR ANDROID OR APPLE )
# OpenCV installation options
# ===================================================
@ -271,7 +273,7 @@ endif()
include(cmake/OpenCVCompilerOptions.cmake REQUIRED)
# In case of Makefiles if the user does not setup CMAKE_BUILD_TYPE, assume it's Release:
if(CMAKE_GENERATOR MATCHES "Makefiles" AND "${CMAKE_BUILD_TYPE}" STREQUAL "")
if(CMAKE_GENERATOR MATCHES "Makefiles|Ninja" AND "${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE Release)
endif()
@ -368,7 +370,7 @@ if(UNIX)
endif()
endif()
if(HAVE_FFMPEG_CODEC AND HAVE_FFMPEG_FORMAT AND HAVE_FFMPEG_UTIL)
if(HAVE_FFMPEG_SWSCALE OR NOT HAVE_GENTOO_FFMPEG)
if(HAVE_FFMPEG_SWSCALE)
set(HAVE_FFMPEG 1)
endif()
endif()
@ -381,12 +383,6 @@ if(UNIX)
endif()
endif()
if(HAVE_FFMPEG)
if(NOT ALIASOF_libavformat_VERSION VERSION_LESS "52.111.0")
set(NEW_FFMPEG ON)
endif()
endif()
if(WITH_1394)
CHECK_MODULE(libdc1394-2 HAVE_DC1394_2)
if(NOT HAVE_DC1394_2)
@ -454,7 +450,6 @@ if(APPLE AND WITH_FFMPEG)
"${FFMPEG_LIB_DIR}/libavformat.a" "${FFMPEG_LIB_DIR}/libavutil.a"
"${FFMPEG_LIB_DIR}/libswscale.a")
set(HAVE_FFMPEG 1)
set(NEW_FFMPEG 1)
endif()
endif()
endif()
@ -716,6 +711,9 @@ endif()
if(CMAKE_GENERATOR MATCHES Xcode)
status(" Xcode:" ${XCODE_VERSION})
endif()
if(NOT CMAKE_GENERATOR MATCHES "Xcode|Visual Studio")
status(" Configuration:" ${CMAKE_BUILD_TYPE})
endif()
# C/C++ options
status("")
@ -817,7 +815,11 @@ else()
status(" PNG:" "NO")
endif()
if(WITH_TIFF)
status(" TIFF:" TIFF_FOUND THEN "${TIFF_LIBRARY} (ver ${TIFF_VERSION})" ELSE "build (ver ${TIFF_VERSION})")
if(TIFF_VERSION_STRING AND TIFF_FOUND)
status(" TIFF:" "${TIFF_LIBRARY} (ver ${TIFF_VERSION} - ${TIFF_VERSION_STRING})")
else()
status(" TIFF:" TIFF_FOUND THEN "${TIFF_LIBRARY} (ver ${TIFF_VERSION})" ELSE "build (ver ${TIFF_VERSION})")
endif()
else()
status(" TIFF:" "NO")
endif()
@ -909,7 +911,7 @@ status(" Use Clp:" HAVE_CLP THEN YES ELSE NO)
if(HAVE_CUDA)
status("")
status(" NVIDIA CUDA:")
status(" NVIDIA CUDA:" "(ver ${CUDA_VERSION_STRING})")
status(" Use CUFFT:" HAVE_CUFFT THEN YES ELSE NO)
status(" Use CUBLAS:" HAVE_CUBLAS THEN YES ELSE NO)
@ -923,7 +925,11 @@ status("")
status(" Python:")
status(" Interpreter:" PYTHON_EXECUTABLE THEN "${PYTHON_EXECUTABLE} (ver ${PYTHON_VERSION_FULL})" ELSE NO)
if(BUILD_opencv_python)
status(" Libraries:" HAVE_opencv_python THEN ${PYTHON_LIBRARIES} ELSE NO)
if(PYTHONLIBS_VERSION_STRING)
status(" Libraries:" HAVE_opencv_python THEN "${PYTHON_LIBRARIES} (ver ${PYTHONLIBS_VERSION_STRING})" ELSE NO)
else()
status(" Libraries:" HAVE_opencv_python THEN ${PYTHON_LIBRARIES} ELSE NO)
endif()
status(" numpy:" PYTHON_USE_NUMPY THEN "${PYTHON_NUMPY_INCLUDE_DIR} (ver ${PYTHON_NUMPY_VERSION})" ELSE "NO (Python wrappers can not be generated)")
status(" packages path:" PYTHON_EXECUTABLE THEN "${PYTHON_PACKAGES_PATH}" ELSE "-")
endif()
@ -966,6 +972,8 @@ status(" cvconfig.h is in:" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}")
status("-----------------------------------------------------------------")
status("")
ocv_finalize_status()
# ----------------------------------------------------------------------------
# Warn in the case of in-source build
# ----------------------------------------------------------------------------

@ -107,10 +107,13 @@
# under the ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}
# (depending on the target ABI). This is convenient for Android packaging.
#
# Authors:
# Ethan Rublee ethan.ruble@gmail.com
# Andrey Kamaev andrey.kamaev@itseez.com
#
# Change Log:
# - initial version December 2010 Ethan Rublee ethan.ruble@gmail.com
# - modified April 2011 Andrey Kamaev andrey.kamaev@itseez.com
# - initial version December 2010
# - modified April 2011
# [+] added possibility to build with NDK (without standalone toolchain)
# [+] support cross-compilation on Windows (native, no cygwin support)
# [+] added compiler option to force "char" type to be signed
@ -121,13 +124,13 @@
# [+] EXECUTABLE_OUTPUT_PATH is set by toolchain (required on Windows)
# [~] Fixed bug with ANDROID_API_LEVEL variable
# [~] turn off SWIG search if it is not found first time
# - modified May 2011 Andrey Kamaev andrey.kamaev@itseez.com
# - modified May 2011
# [~] ANDROID_LEVEL is renamed to ANDROID_API_LEVEL
# [+] ANDROID_API_LEVEL is detected by toolchain if not specified
# [~] added guard to prevent changing of output directories on the first
# cmake pass
# [~] toolchain exits with error if ARM_TARGET is not recognized
# - modified June 2011 Andrey Kamaev andrey.kamaev@itseez.com
# - modified June 2011
# [~] default NDK path is updated for version r5c
# [+] variable CMAKE_SYSTEM_PROCESSOR is set based on ARM_TARGET
# [~] toolchain install directory is added to linker paths
@ -135,13 +138,13 @@
# [+] added macro find_host_package, find_host_program to search
# packages/programs on the host system
# [~] fixed path to STL library
# - modified July 2011 Andrey Kamaev andrey.kamaev@itseez.com
# - modified July 2011
# [~] fixed options caching
# [~] search for all supported NDK versions
# [~] allowed spaces in NDK path
# - modified September 2011 Andrey Kamaev andrey.kamaev@itseez.com
# - modified September 2011
# [~] updated for NDK r6b
# - modified November 2011 Andrey Kamaev andrey.kamaev@itseez.com
# - modified November 2011
# [*] rewritten for NDK r7
# [+] x86 toolchain support (experimental)
# [+] added "armeabi-v6 with VFP" ABI for ARMv6 processors.
@ -154,24 +157,26 @@
# [~] ARM_TARGET is renamed to ANDROID_ABI
# [~] ARMEABI_NDK_NAME is renamed to ANDROID_NDK_ABI_NAME
# [~] ANDROID_API_LEVEL is renamed to ANDROID_NATIVE_API_LEVEL
# - modified January 2012 Andrey Kamaev andrey.kamaev@itseez.com
# - modified January 2012
# [+] added stlport_static support (experimental)
# [+] added special check for cygwin
# [+] filtered out hidden files (starting with .) while globbing inside NDK
# [+] automatically applied GLESv2 linkage fix for NDK revisions 5-6
# [+] added ANDROID_GET_ABI_RAWNAME to get NDK ABI names by CMake flags
# - modified February 2012 Andrey Kamaev andrey.kamaev@itseez.com
# - modified February 2012
# [+] updated for NDK r7b
# [~] fixed cmake try_compile() command
# [~] Fix for missing install_name_tool on OS X
# - modified March 2012 Andrey Kamaev andrey.kamaev@itseez.com
# - modified March 2012
# [~] fixed incorrect C compiler flags
# [~] fixed CMAKE_SYSTEM_PROCESSOR change on ANDROID_ABI change
# [+] improved toolchain loading speed
# [+] added assembler language support (.S)
# [+] allowed preset search paths and extra search suffixes
# - modified April 2012 Andrey Kamaev andrey.kamaev@itseez.com
# - modified April 2012
# [+] updated for NDK r7c
# [~] fixed most of problems with compiler/linker flags and caching
# [+] added option ANDROID_FUNCTION_LEVEL_LINKING
# ------------------------------------------------------------------------------
cmake_minimum_required( VERSION 2.6.3 )
@ -754,8 +759,8 @@ if( ARMEABI OR ARMEABI_V7A )
# extra arm-specific flags
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" )
elseif( X86 )
set( CMAKE_CXX_FLAGS "-ffunction-sections -funwind-tables" )
set( CMAKE_C_FLAGS "-ffunction-sections -funwind-tables" )
set( CMAKE_CXX_FLAGS "-funwind-tables" )
set( CMAKE_C_FLAGS "-funwind-tables" )
if( ANDROID_USE_STLPORT )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions" )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions" )
@ -817,14 +822,14 @@ endif()
#linker flags
list( APPEND ANDROID_SYSTEM_LIB_DIRS "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}" "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" )
set( LINKER_FLAGS "" )
set( ANDROID_LINKER_FLAGS "" )
#STL
if( ANDROID_USE_STLPORT )
if( EXISTS "${__stlLibPath}/libstlport_static.a" )
__COPY_IF_DIFFERENT( "${__stlLibPath}/libstlport_static.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
endif()
if( EXISTS "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
set( LINKER_FLAGS "${LINKER_FLAGS} -Wl,--start-group -lstlport_static" )
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--start-group -lstlport_static" )
endif()
else( ANDROID_USE_STLPORT )
if( EXISTS "${__stlLibPath}/libgnustl_static.a" )
@ -839,7 +844,7 @@ else( ANDROID_USE_STLPORT )
__COPY_IF_DIFFERENT( "${__stlLibPath}/libstdc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
endif()
if( EXISTS "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
set( LINKER_FLAGS "${LINKER_FLAGS} -lstdc++" )
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -lstdc++" )
endif()
#gcc exception & rtti support
@ -855,7 +860,7 @@ else( ANDROID_USE_STLPORT )
__COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
endif()
if( EXISTS "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
set( LINKER_FLAGS "${LINKER_FLAGS} -lsupc++" )
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -lsupc++" )
endif()
endif( ANDROID_USE_STLPORT )
@ -868,7 +873,7 @@ __INIT_VARIABLE( ANDROID_NO_UNDEFINED OBSOLETE_NO_UNDEFINED VALUES ON )
set( ANDROID_NO_UNDEFINED ${ANDROID_NO_UNDEFINED} CACHE BOOL "Show all undefined symbols as linker errors" FORCE )
mark_as_advanced( ANDROID_NO_UNDEFINED )
if( ANDROID_NO_UNDEFINED )
set( LINKER_FLAGS "-Wl,--no-undefined ${LINKER_FLAGS}" )
set( ANDROID_LINKER_FLAGS "-Wl,--no-undefined ${ANDROID_LINKER_FLAGS}" )
endif()
if (ANDROID_NDK MATCHES "-r[56].?$")
@ -877,16 +882,25 @@ if (ANDROID_NDK MATCHES "-r[56].?$")
else()
__INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES OFF )
endif()
set( ANDROID_SO_UNDEFINED ${ANDROID_SO_UNDEFINED} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" FORCE )
mark_as_advanced( ANDROID_SO_UNDEFINED )
if( ANDROID_SO_UNDEFINED )
set( LINKER_FLAGS "${LINKER_FLAGS} -Wl,-allow-shlib-undefined" )
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-allow-shlib-undefined" )
endif()
__INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING VALUES ON )
set( ANDROID_FUNCTION_LEVEL_LINKING ON CACHE BOOL "Allows or disallows undefined symbols in shared libraries" FORCE )
mark_as_advanced( ANDROID_FUNCTION_LEVEL_LINKING )
if( ANDROID_FUNCTION_LEVEL_LINKING )
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" )
set( ANDROID_LINKER_FLAGS "-Wl,--gc-sections ${ANDROID_LINKER_FLAGS}" )
endif()
if( ARMEABI_V7A )
# this is *required* to use the following linker flags that routes around
# a CPU bug in some Cortex-A8 implementations:
set( LINKER_FLAGS "-Wl,--fix-cortex-a8 ${LINKER_FLAGS}" )
set( ANDROID_LINKER_FLAGS "-Wl,--fix-cortex-a8 ${ANDROID_LINKER_FLAGS}" )
endif()
#cache flags
@ -896,17 +910,21 @@ set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "c++ Rele
set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "c Release flags" )
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "c++ Debug flags" )
set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}" CACHE STRING "c Debug flags" )
set( CMAKE_SHARED_LINKER_FLAGS "${LINKER_FLAGS}" CACHE STRING "linker flags" )
set( CMAKE_MODULE_LINKER_FLAGS "${LINKER_FLAGS}" CACHE STRING "linker flags" )
set( CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections -Wl,-z,nocopyreloc ${LINKER_FLAGS}" CACHE STRING "linker flags" )
set( CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "linker flags" )
set( CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "linker flags" )
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "linker flags" )
include_directories( SYSTEM ${ANDROID_SYSTEM_INCLUDE_DIRS} )
link_directories( ${ANDROID_SYSTEM_LIB_DIRS} )
#finish flags
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Extra Android falgs")
set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Extra Android compiler flags")
set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Extra Android linker flags")
set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
set( CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" )
set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" )
set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
#set these global flags for cmake client scripts to change behavior
set( ANDROID True )
@ -981,7 +999,7 @@ endmacro()
# export toolchain settings for the try_compile() command
if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
set( __toolchain_config "")
foreach( __var ANDROID_ABI ANDROID_FORCE_ARM_BUILD ANDROID_NATIVE_API_LEVEL ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_SET_OBSOLETE_VARIABLES LIBRARY_OUTPUT_PATH_ROOT ANDROID_USE_STLPORT ANDROID_FORBID_SYGWIN ANDROID_NDK ANDROID_STANDALONE_TOOLCHAIN )
foreach( __var ANDROID_ABI ANDROID_FORCE_ARM_BUILD ANDROID_NATIVE_API_LEVEL ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_SET_OBSOLETE_VARIABLES LIBRARY_OUTPUT_PATH_ROOT ANDROID_USE_STLPORT ANDROID_FORBID_SYGWIN ANDROID_NDK ANDROID_STANDALONE_TOOLCHAIN ANDROID_FUNCTION_LEVEL_LINKING )
if( DEFINED ${__var} )
set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" )\n" )
endif()
@ -1003,14 +1021,16 @@ endif()
# Variables controlling behavior or set by cmake toolchain:
# ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86"
# ANDROID_FORCE_ARM_BUILD : ON/OFF
# ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14 (depends on NDK version)
# ANDROID_NO_UNDEFINED : ON/OFF
# ANDROID_SO_UNDEFINED : OFF/ON (default depends on NDK version)
# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF
# LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
# ANDROID_USE_STLPORT : OFF/ON - EXPERIMENTAL!!!
# ANDROID_FORBID_SYGWIN : ON/OFF
# ANDROID_NO_UNDEFINED : ON/OFF
# ANDROID_SO_UNDEFINED : OFF/ON (default depends on NDK version)
# ANDROID_FUNCTION_LEVEL_LINKING : ON/OFF
# Variables that takes effect only at first run:
# ANDROID_FORCE_ARM_BUILD : ON/OFF
# LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
# Can be set only at the first run:
# ANDROID_NDK
# ANDROID_STANDALONE_TOOLCHAIN
@ -1036,6 +1056,7 @@ endif()
# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a" or "x86" depending on ANDROID_ABI
# ANDROID_ARCH_NAME : "arm" or "x86" depending on ANDROID_ABI
# TOOL_OS_SUFFIX : "" or ".exe" depending on host platform
# ANDROID_SYSROOT : path to the compiler sysroot
# ANDROID_SYSTEM_INCLUDE_DIRS
# ANDROID_SYSTEM_LIB_DIRS
# Obsolete:
@ -1045,7 +1066,6 @@ endif()
# ANDROID_COMPILER_VERSION : GCC version used
# ANDROID_CXX_FLAGS : C/C++ compiler flags required by Android platform
# ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI
# ANDROID_SYSROOT : path to the compiler sysroot
# ANDROID_TOOLCHAIN_NAME : "standalone", "arm-linux-androideabi-4.4.3" or "x86-4.4.3" or something similar.
# ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux"
# ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK)

@ -15,6 +15,10 @@ SET SCRIPTS_DIR=%cd%
IF EXIST .\wincfg.cmd CALL .\wincfg.cmd
POPD
:: inherit old names
IF NOT DEFINED CMAKE SET CMAKE=%CMAKE_EXE%
IF NOT DEFINED MAKE SET MAKE=%MAKE_EXE%
:: defaults
IF NOT DEFINED BUILD_DIR SET BUILD_DIR=build
IF NOT DEFINED ANDROID_ABI SET ANDROID_ABI=armeabi-v7a
@ -25,8 +29,8 @@ PUSHD .
IF NOT DEFINED ANDROID_NDK (ECHO. & ECHO You should set an environment variable ANDROID_NDK to the full path to your copy of Android NDK & GOTO end)
(CD "%ANDROID_NDK%") || (ECHO. & ECHO Directory "%ANDROID_NDK%" specified by ANDROID_NDK variable does not exist & GOTO end)
IF NOT EXIST "%CMAKE_EXE%" (ECHO. & ECHO You should set an environment variable CMAKE_EXE to the full path to cmake executable & GOTO end)
IF NOT EXIST "%MAKE_EXE%" (ECHO. & ECHO You should set an environment variable MAKE_EXE to the full path to native port of make executable & GOTO end)
IF NOT EXIST "%CMAKE%" (ECHO. & ECHO You should set an environment variable CMAKE to the full path to cmake executable & GOTO end)
IF NOT EXIST "%MAKE%" (ECHO. & ECHO You should set an environment variable MAKE to the full path to native port of make executable & GOTO end)
IF NOT %BUILD_JAVA_PART%==1 GOTO required_variables_checked
@ -42,6 +46,11 @@ IF NOT DEFINED JAVA_HOME (ECHO. & ECHO You should set an environment variable JA
:required_variables_checked
POPD
:: check for ninja
echo "%MAKE%"|findstr /i ninja >nul:
IF %errorlevel%==1 (SET BUILD_WITH_NINJA=0) ELSE (SET BUILD_WITH_NINJA=1)
IF %BUILD_WITH_NINJA%==1 (SET CMAKE_GENERATOR=Ninja) ELSE (SET CMAKE_GENERATOR=MinGW Makefiles)
:: create build dir
IF DEFINED REBUILD rmdir /S /Q "%BUILD_DIR%" 2>NUL
MKDIR "%BUILD_DIR%" 2>NUL
@ -53,16 +62,17 @@ ECHO ANDROID_ABI=%ANDROID_ABI%
ECHO.
IF NOT %BUILD_OPENCV%==1 GOTO other-cmake
:opencv-cmake
("%CMAKE_EXE%" -G"MinGW Makefiles" -DANDROID_ABI="%ANDROID_ABI%" -DCMAKE_TOOLCHAIN_FILE="%SOURCE_DIR%"\android.toolchain.cmake -DCMAKE_MAKE_PROGRAM="%MAKE_EXE%" %* "%SOURCE_DIR%\..") && GOTO cmakefin
("%CMAKE%" -G"%CMAKE_GENERATOR%" -DANDROID_ABI="%ANDROID_ABI%" -DCMAKE_TOOLCHAIN_FILE="%SOURCE_DIR%"\android.toolchain.cmake -DCMAKE_MAKE_PROGRAM="%MAKE%" %* "%SOURCE_DIR%\..") && GOTO cmakefin
ECHO. & ECHO cmake failed & GOTO end
:other-cmake
("%CMAKE_EXE%" -G"MinGW Makefiles" -DANDROID_ABI="%ANDROID_ABI%" -DOpenCV_DIR="%OPENCV_BUILD_DIR%" -DCMAKE_TOOLCHAIN_FILE="%OPENCV_BUILD_DIR%\..\android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM="%MAKE_EXE%" %* "%SOURCE_DIR%") && GOTO cmakefin
("%CMAKE%" -G"%CMAKE_GENERATOR%" -DANDROID_ABI="%ANDROID_ABI%" -DOpenCV_DIR="%OPENCV_BUILD_DIR%" -DCMAKE_TOOLCHAIN_FILE="%OPENCV_BUILD_DIR%\..\android.toolchain.cmake" -DCMAKE_MAKE_PROGRAM="%MAKE%" %* "%SOURCE_DIR%") && GOTO cmakefin
ECHO. & ECHO cmake failed & GOTO end
:cmakefin
:: run make
ECHO. & ECHO Building native libs...
("%MAKE_EXE%" -j %NUMBER_OF_PROCESSORS% VERBOSE=%VERBOSE%) || (ECHO. & ECHO make failed & GOTO end)
IF %BUILD_WITH_NINJA%==0 ("%MAKE%" -j %NUMBER_OF_PROCESSORS% VERBOSE=%VERBOSE%) || (ECHO. & ECHO make failed & GOTO end)
IF %BUILD_WITH_NINJA%==1 ("%MAKE%") || (ECHO. & ECHO ninja failed & GOTO end)
IF NOT %BUILD_JAVA_PART%==1 GOTO end
POPD && PUSHD %SOURCE_DIR%

@ -17,27 +17,6 @@ set(OPENCV_EXTRA_EXE_LINKER_FLAGS "")
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "")
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "")
if(MSVC)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS")
# 64-bit portability warnings, in MSVC80
if(MSVC80)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /Wp64")
endif()
if(BUILD_WITH_DEBUG_INFO)
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE} /debug")
endif()
# Remove unreferenced functions: function level linking
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /Gy")
if(NOT MSVC_VERSION LESS 1400)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /bigobj")
endif()
if(BUILD_WITH_DEBUG_INFO)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} /Zi")
endif()
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
# High level of warnings.
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -Wall")
@ -62,27 +41,27 @@ if(CMAKE_COMPILER_IS_GNUCXX)
# Other optimizations
if(ENABLE_OMIT_FRAME_POINTER)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -fomit-frame-pointer")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -fomit-frame-pointer")
else()
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -fno-omit-frame-pointer")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -fno-omit-frame-pointer")
endif()
if(ENABLE_FAST_MATH)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -ffast-math")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -ffast-math")
endif()
if(ENABLE_POWERPC)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -mcpu=G3 -mtune=G5")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mcpu=G3 -mtune=G5")
endif()
if(ENABLE_SSE)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -msse")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse")
endif()
if(ENABLE_SSE2)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -msse2")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse2")
endif()
# SSE3 and further should be disabled under MingW because it generates compiler errors
if(NOT MINGW)
if(ENABLE_SSE3)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -msse3")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse3")
endif()
if(${CMAKE_OPENCV_GCC_VERSION_NUM} GREATER 402)
@ -94,14 +73,14 @@ if(CMAKE_COMPILER_IS_GNUCXX)
if(HAVE_GCC42_OR_NEWER OR APPLE)
if(ENABLE_SSSE3)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -mssse3")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mssse3")
endif()
if(HAVE_GCC43_OR_NEWER)
if(ENABLE_SSE41)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -msse4.1")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse4.1")
endif()
if(ENABLE_SSE42)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -msse4.2")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse4.2")
endif()
endif()
endif()
@ -109,13 +88,22 @@ if(CMAKE_COMPILER_IS_GNUCXX)
if(X86 OR X86_64)
if(NOT APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -mfpmath=387")
if(ENABLE_SSE2)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mfpmath=sse")# !! important - be on the same wave with x64 compilers
else()
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mfpmath=387")
endif()
endif()
endif()
# Profiling?
if(ENABLE_PROFILING)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -pg -g")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -pg -g")
# turn off incompatible options
foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS_RELEASE)
string(REPLACE "-fomit-frame-pointer" "" ${flags} "${${flags}}")
string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}")
endforeach()
elseif(NOT APPLE AND NOT ANDROID)
# Remove unreferenced functions: function level linking
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -ffunction-sections")
@ -129,23 +117,50 @@ if(CMAKE_COMPILER_IS_GNUCXX)
endif()
if(MSVC)
# 64-bit MSVC compiler uses SSE/SSE2 by default
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS")
# 64-bit portability warnings, in MSVC80
if(MSVC80)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /Wp64")
endif()
if(BUILD_WITH_DEBUG_INFO)
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE} /debug")
endif()
# Remove unreferenced functions: function level linking
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /Gy")
if(NOT MSVC_VERSION LESS 1400)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /bigobj")
endif()
if(BUILD_WITH_DEBUG_INFO)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} /Zi")
endif()
if(NOT MSVC64)
# 64-bit MSVC compiler uses SSE/SSE2 by default
if(ENABLE_SSE)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} /arch:SSE")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /arch:SSE")
endif()
if(ENABLE_SSE2)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} /arch:SSE2")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /arch:SSE2")
endif()
endif()
if(ENABLE_SSE3)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} /arch:SSE3")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /arch:SSE3")
endif()
if(ENABLE_SSE4_1)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} /arch:SSE4.1")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /arch:SSE4.1")
endif()
if(ENABLE_SSE OR ENABLE_SSE2 OR ENABLE_SSE3 OR ENABLE_SSE4_1)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} /Oi")
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /Oi")
endif()
if(X86 OR X86_64)
if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND ENABLE_SSE2)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /fp:fast")# !! important - be on the same wave with x64 compilers
endif()
endif()
endif()

@ -39,7 +39,7 @@ find_host_program(ANDROID_EXECUTABLE
if(ANDROID_EXECUTABLE)
if(NOT ANDROID_SDK_DETECT_QUIET)
message(STATUS " Found android tool: ${ANDROID_EXECUTABLE}")
message(STATUS "Found android tool: ${ANDROID_EXECUTABLE}")
endif()
get_filename_component(ANDROID_SDK_TOOLS_PATH "${ANDROID_EXECUTABLE}" PATH)
@ -293,7 +293,7 @@ macro(add_android_project target path)
# put the final .apk to the OpenCV's bin folder
add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${android_proj_bin_dir}/bin/${target}-debug.apk" "${OpenCV_BINARY_DIR}/bin/${target}.apk")
if(INSTALL_ANDROID_EXAMPLES AND target MATCHES "^example-")
if(INSTALL_ANDROID_EXAMPLES AND "${target}" MATCHES "^example-")
install(FILES "${OpenCV_BINARY_DIR}/bin/${target}.apk" DESTINATION "bin" COMPONENT main)
endif()
endif()

@ -21,5 +21,5 @@ if(ANT_EXECUTABLE)
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" ANT_VERSION "${ANT_VERSION_FULL}")
set(ANT_VERSION "${ANT_VERSION}" CACHE INTERNAL "Detected ant vesion")
message(STATUS " Found apache ant ${ANT_VERSION}: ${ANT_EXECUTABLE}")
message(STATUS "Found apache ant ${ANT_VERSION}: ${ANT_EXECUTABLE}")
endif()

@ -5,12 +5,15 @@ if(CMAKE_CL_64)
set(MSVC64 1)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_COMPILER_IS_GNUCXX 1)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(CMAKE_COMPILER_IS_GNUC 1)
if(NOT APPLE)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_COMPILER_IS_GNUCXX 1)
unset(ENABLE_PRECOMPILED_HEADERS CACHE)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(CMAKE_COMPILER_IS_GNUC 1)
unset(ENABLE_PRECOMPILED_HEADERS CACHE)
endif()
endif()
# ----------------------------------------------------------------------------

@ -1,35 +1,44 @@
if(MSVC AND NOT PYTHON_EXECUTABLE)
# search for executable with the same bitness as resulting binaries
# standard FindPythonInterp always prefers executable from system path
foreach(_CURRENT_VERSION ${Python_ADDITIONAL_VERSIONS} 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0 1.6 1.5)
# this is really important because we are using the interpreter for numpy search and for choosing the install location
foreach(_CURRENT_VERSION ${Python_ADDITIONAL_VERSIONS} 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
find_host_program(PYTHON_EXECUTABLE
NAMES python${_CURRENT_VERSION} python
PATHS [HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath]
PATHS
[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath]
[HKEY_CURRENT_USER\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath]
NO_SYSTEM_ENVIRONMENT_PATH
)
endforeach()
endif()
find_host_package(PythonInterp)
find_host_package(PythonInterp 2.0)
unset(PYTHON_USE_NUMPY CACHE)
unset(HAVE_SPHINX CACHE)
if(PYTHON_EXECUTABLE)
if(PYTHON_VERSION_STRING)
set(PYTHON_VERSION_FULL "${PYTHON_VERSION_STRING}")
set(PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
else()
execute_process(COMMAND ${PYTHON_EXECUTABLE} --version
ERROR_VARIABLE PYTHON_VERSION_FULL
ERROR_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "[0-9]+.[0-9]+" PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_FULL}")
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" PYTHON_VERSION_FULL "${PYTHON_VERSION_FULL}")
endif()
if(NOT ANDROID AND NOT IOS)
find_host_package(PythonLibs)
find_host_package(PythonLibs ${PYTHON_VERSION_FULL})
# cmake 2.4 (at least on Ubuntu 8.04 (hardy)) don't define PYTHONLIBS_FOUND
if(NOT PYTHONLIBS_FOUND AND PYTHON_INCLUDE_PATH)
set(PYTHONLIBS_FOUND ON)
endif()
endif()
execute_process(COMMAND ${PYTHON_EXECUTABLE} --version
ERROR_VARIABLE PYTHON_VERSION_FULL
ERROR_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "[0-9]+.[0-9]+" PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_FULL}")
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" PYTHON_VERSION_FULL "${PYTHON_VERSION_FULL}")
if(NOT ANDROID AND NOT IOS)
if(CMAKE_HOST_UNIX)
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import *; print get_python_lib()"
@ -53,6 +62,9 @@ if(PYTHON_EXECUTABLE)
if(NOT EXISTS "${PYTHON_PATH}/Lib/site-packages")
unset(PYTHON_PATH)
get_filename_component(PYTHON_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${PYTHON_VERSION_MAJOR_MINOR}\\InstallPath]" ABSOLUTE)
if(NOT PYTHON_PATH)
get_filename_component(PYTHON_PATH "[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${PYTHON_VERSION_MAJOR_MINOR}\\InstallPath]" ABSOLUTE)
endif()
file(TO_CMAKE_PATH "${PYTHON_PATH}" PYTHON_PATH)
endif()
set(PYTHON_PACKAGES_PATH "${PYTHON_PATH}/Lib/site-packages")
@ -92,7 +104,7 @@ if(PYTHON_EXECUTABLE)
find_host_program(SPHINX_BUILD sphinx-build)
if(SPHINX_BUILD)
set(HAVE_SPHINX 1)
message(STATUS " Found Sphinx ${SPHINX_VERSION}: ${SPHINX_BUILD}")
message(STATUS "Found Sphinx ${SPHINX_VERSION}: ${SPHINX_BUILD}")
endif()
endif()
endif(BUILD_DOCS)

@ -8,16 +8,14 @@ endmacro()
if(BUILD_ZLIB)
unset_all(ZLIB_FOUND)
else()
if(ANDROID)
set(ZLIB_FOUND TRUE)
set(ZLIB_LIBRARY z)
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
set(ZLIB_INCLUDE_DIR "")
ocv_parse_header2(ZLIB "${ANDROID_SYSROOT}/usr/include/zlib.h" ZLIB_VERSION "")
else()
include(FindZLIB)
if(NOT ZLIB_VERSION_STRING)
ocv_parse_header2(ZLIB "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_VERSION "")
include(FindZLIB)
if(ZLIB_FOUND AND NOT ZLIB_VERSION_STRING)
ocv_parse_header2(ZLIB "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_VERSION "")
endif()
if(ZLIB_FOUND AND ANDROID)
if(ZLIB_LIBRARY STREQUAL "${ANDROID_SYSROOT}/usr/lib/libz.so")
set(ZLIB_LIBRARY z)
set(ZLIB_LIBRARIES z)
endif()
endif()
endif()
@ -100,7 +98,9 @@ if(WITH_JASPER AND NOT JASPER_FOUND)
set(JASPER_INCLUDE_DIR "${${JASPER_LIBRARY}_SOURCE_DIR}")
endif()
ocv_parse_header2(JASPER "${JASPER_INCLUDE_DIR}/jasper/jas_config.h" JAS_VERSION "")
if(NOT JASPER_VERSION_STRING)
ocv_parse_header2(JASPER "${JASPER_INCLUDE_DIR}/jasper/jas_config.h" JAS_VERSION "")
endif()
################### libpng - optional (should be searched after zlib)
if(WITH_PNG)

@ -509,7 +509,7 @@ macro(ocv_add_precompiled_headers the_target)
add_native_precompiled_header(${the_target} ${pch_header})
elseif(CMAKE_GENERATOR MATCHES Xcode)
add_native_precompiled_header(${the_target} ${pch_header})
elseif(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_GENERATOR MATCHES Makefiles)
elseif(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_GENERATOR MATCHES "Makefiles|Ninja")
add_precompiled_header(${the_target} ${pch_header})
endif()
endif()

@ -12,7 +12,7 @@ if(NOT COMMAND find_host_program)
endif()
#added include directories in such way that directories from the OpenCV source tree go first
macro(ocv_include_directories)
function(ocv_include_directories)
set(__add_before "")
foreach(dir ${ARGN})
get_filename_component(__abs_dir "${dir}" ABSOLUTE)
@ -23,7 +23,7 @@ macro(ocv_include_directories)
endif()
endforeach()
include_directories(BEFORE ${__add_before})
endmacro()
endfunction()
# Provides an option that the user can optionally select.
@ -113,6 +113,15 @@ function(ocv_output_status msg)
file(APPEND "${OPENCV_BUILD_INFO_FILE}" "\"${msg}\\n\"\n")
endfunction()
macro(ocv_finalize_status)
if(NOT OPENCV_SKIP_STATUS_FINALIZATION)
if(TARGET opencv_core)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${opencv_core_BINARY_DIR}/version_string.inc" OUTPUT_QUIET)
endif()
endif()
endmacro()
# Status report function.
# Automatically align right column and selects text based on condition.
# Usage:

@ -30,7 +30,7 @@
# Advanced variables:
# - OpenCV_SHARED
# - OpenCV_CONFIG_PATH
# - OpenCV_INSTALL_PATH
# - OpenCV_INSTALL_PATH (not set on Windows)
# - OpenCV_LIB_COMPONENTS
# - OpenCV_USE_MANGLED_PATHS
# - OpenCV_HAVE_ANDROID_CAMERA
@ -50,13 +50,15 @@ set(OpenCV_SHARED @BUILD_SHARED_LIBS@)
set(OpenCV_USE_MANGLED_PATHS @OpenCV_USE_MANGLED_PATHS_CONFIGCMAKE@)
# Extract the directory where *this* file has been installed (determined at cmake run-time)
get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(OpenCV_CONFIG_PATH "${CMAKE_CURRENT_LIST_FILE}" PATH CACHE)
# Get the absolute path with no ../.. relative marks, to eliminate implicit linker warnings
if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 2.8)
get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../.." ABSOLUTE)
else()
get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../.." REALPATH)
if(NOT WIN32)
# Get the absolute path with no ../.. relative marks, to eliminate implicit linker warnings
if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 2.8)
get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../.." ABSOLUTE)
else()
get_filename_component(OpenCV_INSTALL_PATH "${OpenCV_CONFIG_PATH}/../.." REALPATH)
endif()
endif()
# Presence of Android native camera wrappers
@ -75,10 +77,11 @@ include_directories(${OpenCV_INCLUDE_DIRS})
# ======================================================
# Provide the libs directories to the caller
set(OpenCV_LIB_DIR_OPT @OpenCV_LIB_DIRS_CONFIGCMAKE@)
set(OpenCV_LIB_DIR_DBG @OpenCV_LIB_DIRS_CONFIGCMAKE@)
set(OpenCV_3RDPARTY_LIB_DIR_OPT @OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE@)
set(OpenCV_3RDPARTY_LIB_DIR_DBG @OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE@)
set(OpenCV_LIB_DIR_OPT @OpenCV_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where release OpenCV libraries are located")
set(OpenCV_LIB_DIR_DBG @OpenCV_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where debug OpenCV libraries are located")
set(OpenCV_3RDPARTY_LIB_DIR_OPT @OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where release 3rdpaty OpenCV dependencies are located")
set(OpenCV_3RDPARTY_LIB_DIR_DBG @OpenCV_3RDPARTY_LIB_DIRS_CONFIGCMAKE@ CACHE PATH "Path where debug 3rdpaty OpenCV dependencies are located")
mark_as_advanced(FORCE OpenCV_LIB_DIR_OPT OpenCV_LIB_DIR_DBG OpenCV_3RDPARTY_LIB_DIR_OPT OpenCV_3RDPARTY_LIB_DIR_DBG OpenCV_CONFIG_PATH)
# ======================================================
# Version variables:

@ -30,7 +30,7 @@ div.documentwrapper {
}
div.bodywrapper {
margin: 0 0 0 230px;
margin: 0 0 0 270px;
}
div.body {
@ -85,7 +85,7 @@ div.related a {
div.sphinxsidebar {
word-wrap: break-word;
width: 240px;
width: 270px;
{%- if theme_stickysidebar|tobool %}
top: 30px;
margin: 0;

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -72,7 +72,7 @@ Building OpenCV from source using CMake, using the command line
cd ~/opencv
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX= /usr/local
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
#. Enter the created temporary directory (<cmake_binary_dir>) and proceed with:

@ -48,7 +48,7 @@ The really useful stuff of these is that you may create a rule package *once* an
:alt: Add a new Property Sheet
:align: center
Use for example the *OpenCV_Debug* name. Then by selecting the sheet :menuselection:`Right Click --> Properties`. In the following I will show to set the OpenCV rules locally, as I find unnecessary to pollute projects with custom rules that I do not use it. Go the C++ groups General entry and under the *"Additional Include Directories"* add the path to your OpenCV include.
Use for example the *OpenCV_Debug* name. Then by selecting the sheet :menuselection:`Right Click --> Properties`. In the following I will show to set the OpenCV rules locally, as I find unnecessary to pollute projects with custom rules that I do not use it. Go the C++ groups General entry and under the *"Additional Include Directories"* add the path to your OpenCV include. If you don't have *"C/C++"* group, you should add any .c/.cpp file to the project.
.. code-block:: bash
@ -177,4 +177,4 @@ Here I first changed my drive (if your project isn't on the OS local drive), nav
:alt: Visual Studio Command Line Arguments
:align: center
Specify here the name of the inputs and while you start your application from the Visual Studio enviroment you have automatic argument passing. In the next introductionary tutorial you'll see an in-depth explanation of the upper source code: :ref:`Display_Image`.
Specify here the name of the inputs and while you start your application from the Visual Studio enviroment you have automatic argument passing. In the next introductionary tutorial you'll see an in-depth explanation of the upper source code: :ref:`Display_Image`.

@ -18,9 +18,15 @@ If you read a jpg file, a 3 channel image is created by default. If you need a g
Mat img = imread(filename, 0);
.. note:: format of the file is determined by its content (first few bytes)
Save an image to a file: ::
Mat img = imwrite(filename);
imwrite(filename, img);
.. note:: format of the file is determined by its extension.
.. note:: use ``imdecode`` and ``imencode`` to read and write image from/to memory rather than a file.
XML/YAML
--------

@ -1990,7 +1990,8 @@ bool cv::findCirclesGrid( InputArray _image, Size patternSize,
bool isFound = false;
#define BE_QUIET 1
#if BE_QUIET
redirectError(quiet_error);
void* oldCbkData;
ErrorCallback oldCbk = redirectError(quiet_error, 0, &oldCbkData);
#endif
try
{
@ -2001,7 +2002,7 @@ bool cv::findCirclesGrid( InputArray _image, Size patternSize,
}
#if BE_QUIET
redirectError(0);
redirectError(oldCbk, oldCbkData);
#endif
if (isFound)
{

@ -166,13 +166,15 @@ bool CvLevMarq::update( const CvMat*& _param, CvMat*& matJ, CvMat*& _err )
errNorm = cvNorm( err, 0, CV_L2 );
if( errNorm > prevErrNorm )
{
lambdaLg10++;
step();
_param = param;
cvZero( err );
_err = err;
state = CHECK_ERR;
return true;
if( ++lambdaLg10 <= 16 )
{
step();
_param = param;
cvZero( err );
_err = err;
state = CHECK_ERR;
return true;
}
}
lambdaLg10 = MAX(lambdaLg10-1, -16);
@ -233,13 +235,15 @@ bool CvLevMarq::updateAlt( const CvMat*& _param, CvMat*& _JtJ, CvMat*& _JtErr, d
assert( state == CHECK_ERR );
if( errNorm > prevErrNorm )
{
lambdaLg10++;
step();
_param = param;
errNorm = 0;
_errNorm = &errNorm;
state = CHECK_ERR;
return true;
if( ++lambdaLg10 <= 16 )
{
step();
_param = param;
errNorm = 0;
_errNorm = &errNorm;
state = CHECK_ERR;
return true;
}
}
lambdaLg10 = MAX(lambdaLg10-1, -16);
@ -1758,7 +1762,7 @@ CV_IMPL double cvCalibrateCamera2( const CvMat* objectPoints,
if( tvecs )
{
src = cvMat( 3, 1, CV_64F, solver.param->data.db + NINTRINSIC + i*6 + 3 );
dst = cvMat( 3, 1, CV_MAT_TYPE(tvecs->type), tvecs->rows == 1 ?
dst = cvMat( 3, 1, CV_MAT_DEPTH(tvecs->type), tvecs->rows == 1 ?
tvecs->data.ptr + i*CV_ELEM_SIZE(tvecs->type) :
tvecs->data.ptr + tvecs->step*i );
cvConvert( &src, &dst );

@ -0,0 +1,44 @@
/*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.
// 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 "precomp.hpp"

@ -213,7 +213,7 @@ void CvHybridTracker::updateTrackerWithEM(Mat image) {
cv::Mat lbls;
EM em_model(1, EM::COV_MAT_SPHERICAL, TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 10000, 0.001));
em_model.train(cvarrToMat(samples), lbls);
em_model.train(cvarrToMat(samples), noArray(), lbls);
if(labels)
lbls.copyTo(cvarrToMat(labels));

@ -171,8 +171,49 @@ RotatedRect
-----------
.. ocv:class:: RotatedRect
Template class for rotated rectangles specified by the center, size, and the rotation angle in degrees.
The class represents rotated (i.e. not up-right) rectangles on a plane. Each rectangle is specified by the center point (mass center), length of each side (represented by cv::Size2f structure) and the rotation angle in degrees.
.. ocv:function:: RotatedRect::RotatedRect()
.. ocv:function:: RotatedRect::RotatedRect(const Point2f& center, const Size2f& size, float angle)
.. ocv:function:: RotatedRect::RotatedRect(const CvBox2D& box)
:param center: The rectangle mass center.
:param size: Width and height of the rectangle.
:param angle: The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc., the rectangle becomes an up-right rectangle.
:param box: The rotated rectangle parameters as the obsolete CvBox2D structure.
.. ocv:function:: void RotatedRect::points(Point2f* pts) const
.. ocv:function:: Rect RotatedRect::boundingRect() const
.. ocv:function:: RotatedRect::operator CvBox2D() const
:param pts: The points array for storing rectangle vertices.
The sample below demonstrates how to use RotatedRect:
::
Mat image(200, 200, CV_8UC3, Scalar(0));
RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0));
Rect brect = rRect.boundingRect();
rectangle(image, brect, Scalar(255,0,0));
imshow("rectangles", image);
waitKey(0);
.. image:: pics/rotatedrect.png
.. seealso::
:ocv:cfunc:`CamShift`,
:ocv:func:`fitEllipse`,
:ocv:func:`minAreaRect`,
:ocv:struct:`CvBox2D`
TermCriteria
------------
@ -1773,6 +1814,84 @@ To use ``Mat_`` for multi-channel images/matrices, pass ``Vec`` as a ``Mat_`` pa
img(i,j)[2] ^= (uchar)(i ^ j);
InputArray
----------
This is the proxy class for passing read-only input arrays into OpenCV functions. It is defined as ::
typedef const _InputArray& InputArray;
where ``_InputArray`` is a class that can be constructed from ``Mat``, ``Mat_<T>``, ``Matx<T, m, n>``, ``std::vector<T>``, ``std::vector<std::vector<T> >`` or ``std::vector<Mat>``. It can also be constructed from a matrix expression.
Since this is mostly implementation-level class, and its interface may change in future versions, we do not describe it in details. There are a few key things, though, that should be kept in mind:
* When you see in the reference manual or in OpenCV source code a function that takes ``InputArray``, it means that you can actually pass ``Mat``, ``Matx``, ``vector<T>`` etc. (see above the complete list).
* Optional input arguments: If some of the input arrays may be empty, pass ``cv::noArray()`` (or simply ``cv::Mat()`` as you probably did before).
* The class is designed solely for passing parameters. That is, normally you *should not* declare class members, local and global variables of this type.
* If you want to design your own function or a class method that can operate of arrays of multiple types, you can use ``InputArray`` (or ``OutputArray``) for the respective parameters. Inside a function you should use ``_InputArray::getMat()`` method to construct a matrix header for the array (without copying data). ``_InputArray::kind()`` can be used to distinguish ``Mat`` from ``vector<>`` etc., but normally it is not needed.
Here is how you can use a function that takes ``InputArray`` ::
std::vector<Point2f> vec;
// points or a circle
for( int i = 0; i < 30; i++ )
vec.push_back(Point2f((float)(100 + 30*cos(i*CV_PI*2/5)),
(float)(100 - 30*sin(i*CV_PI*2/5))));
cv::transform(vec, vec, cv::Matx23f(0.707, -0.707, 10, 0.707, 0.707, 20));
That is, we form an STL vector containing points, and apply in-place affine transformation to the vector using the 2x3 matrix created inline as ``Matx<float, 2, 3>`` instance.
Here is how such a function can be implemented (for simplicity, we implement a very specific case of it, according to the assertion statement inside) ::
void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m)
{
// get Mat headers for input arrays. This is O(1) operation,
// unless _src and/or _m are matrix expressions.
Mat src = _src.getMat(), m = _m.getMat();
CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) );
// [re]create the output array so that it has the proper size and type.
// In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize.
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();
for( int i = 0; i < src.rows; i++ )
for( int j = 0; j < src.cols; j++ )
{
Point2f pt = src.at<Point2f>(i, j);
dst.at<Point2f>(i, j) = Point2f(m.at<float>(0, 0)*pt.x +
m.at<float>(0, 1)*pt.y +
m.at<float>(0, 2),
m.at<float>(1, 0)*pt.x +
m.at<float>(1, 1)*pt.y +
m.at<float>(1, 2));
}
}
There is another related type, ``InputArrayOfArrays``, which is currently defined as a synonym for ``InputArray``: ::
typedef InputArray InputArrayOfArrays;
It denotes function arguments that are either vectors of vectors or vectors of matrices. A separate synonym is needed to generate Python/Java etc. wrappers properly. At the function implementation level their use is similar, but ``_InputArray::getMat(idx)`` should be used to get header for the idx-th component of the outer vector and ``_InputArray::size().area()`` should be used to find the number of components (vectors/matrices) of the outer vector.
OutputArray
-----------
This type is very similar to ``InputArray`` except that it is used for input/output and output function parameters. Just like with ``InputArray``, OpenCV users should not care about ``OutputArray``, they just pass ``Mat``, ``vector<T>`` etc. to the functions. The same limitation as for ``InputArray``: **Do not explicitly create OutputArray instances** applies here too.
If you want to make your function polymorphic (i.e. accept different arrays as output parameters), it is also not very difficult. Take the sample above as the reference. Note that ``_OutputArray::create()`` needs to be called before ``_OutputArray::getMat()``. This way you guarantee that the output array is properly allocated.
Optional output parameters. If you do not need certain output array to be computed and returned to you, pass ``cv::noArray()``, just like you would in the case of optional input array. At the implementation level, use ``_OutputArray::needed()`` to check if certain output array needs to be computed or not.
There are several synonyms for ``OutputArray`` that are used to assist automatic Python/Java/... wrapper generators: ::
typedef OutputArray OutputArrayOfArrays;
typedef OutputArray InputOutputArray;
typedef OutputArray InputOutputArrayOfArrays;
NAryMatIterator
---------------
@ -2189,3 +2308,160 @@ It simplifies notation of some operations. ::
M.ref(1, 2, 3) = M(4, 5, 6) + M(7, 8, 9);
Algorithm
---------
This is a base class for all more or less complex algorithms in OpenCV, especially for classes of algorithms, for which there can be multiple implementations. The examples are stereo correspondence (for which there are algorithms like block matching, semi-global block matching, graph-cut etc.), background subtraction (which can be done using mixture-of-gaussians models, codebook-based algorithm etc.), optical flow (block matching, Lucas-Kanade, Horn-Schunck etc.).
The class provides the following features for all derived classes:
* so called "virtual constructor". That is, each Algorithm derivative is registered at program start and you can get the list of registered algorithms and create instance of a particular algorithm by its name (see ``Algorithm::create``). If you plan to add your own algorithms, it is good practice to add a unique prefix to your algorithms to distinguish them from other algorithms.
* setting/retrieving algorithm parameters by name. If you used video capturing functionality from OpenCV highgui module, you are probably familar with ``cvSetCaptureProperty()``, ``cvGetCaptureProperty()``, ``VideoCapture::set()`` and ``VideoCapture::get()``. ``Algorithm`` provides similar method where instead of integer id's you specify the parameter names as text strings. See ``Algorithm::set`` and ``Algorithm::get`` for details.
* reading and writing parameters from/to XML or YAML files. Every Algorithm derivative can store all its parameters and then read them back. There is no need to re-implement it each time.
Here is example of SIFT use in your application via Algorithm interface: ::
#include "opencv2/opencv.hpp"
...
initModule_nonfree(); // to load SURF/SIFT etc.
Ptr<Feature2D> sift = Algorithm::create<Feature2D>("Feature2D.SIFT");
FileStorage fs("sift_params.xml", FileStorage::READ);
if( fs.isOpened() ) // if we have file with parameters, read them
{
sift.read(fs["sift_params"]);
fs.release();
}
else // else modify the parameters and store them; user can later edit the file to use different parameters
{
sift.set("contrastThreshold", 0.01f); // lower the contrast threshold, compared to the default value
{
WriteStructContext ws(fs, "sift_params", CV_NODE_MAP);
sift.write(fs);
}
}
Mat image = imread("myimage.png", 0), descriptors;
vector<KeyPoint> keypoints;
sift(image, noArray(), keypoints, descriptors);
Algorithm::get
--------------
Returns the algorithm parameter
.. ocv:function:: template<typename _Tp> typename ParamType<_Tp>::member_type get(const string& name) const
:param name: The parameter name.
The method returns value of the particular parameter. Since the compiler can not deduce the type of the returned parameter, you should specify it explicitly in angle brackets. Here are the allowed forms of get:
* myalgo.get<int>("param_name")
* myalgo.get<double>("param_name")
* myalgo.get<bool>("param_name")
* myalgo.get<string>("param_name")
* myalgo.get<Mat>("param_name")
* myalgo.get<vector<Mat> >("param_name")
* myalgo.get<Algorithm>("param_name") (it returns Ptr<Algorithm>).
In some cases the actual type of the parameter can be cast to the specified type, e.g. integer parameter can be cast to double, ``bool`` can be cast to ``int``. But "dangerous" transformations (string<->number, double->int, 1x1 Mat<->number, ...) are not performed and the method will throw an exception. In the case of ``Mat`` or ``vector<Mat>`` parameters the method does not clone the matrix data, so do not modify the matrices. Use ``Algorithm::set`` instead - slower, but more safe.
Algorithm::set
--------------
Sets the algorithm parameter
.. ocv:function:: void set(const string& name, int value)
.. ocv:function:: void set(const string& name, double value)
.. ocv:function:: void set(const string& name, bool value)
.. ocv:function:: void set(const string& name, const string& value)
.. ocv:function:: void set(const string& name, const Mat& value)
.. ocv:function:: void set(const string& name, const vector<Mat>& value)
.. ocv:function:: void set(const string& name, const Ptr<Algorithm>& value)
:param name: The parameter name.
:param value: The parameter value.
The method sets value of the particular parameter. Some of the algorithm parameters may be declared as read-only. If you try to set such a parameter, you will get exception with the corresponding error message.
Algorithm::write
----------------
Stores algorithm parameters in a file storage
.. ocv:function:: void write(FileStorage& fs) const
:param fs: File storage.
The method stores all the algorithm parameters (in alphabetic order) to the file storage. The method is virtual. If you define your own Algorithm derivative, your can override the method and store some extra information. However, it's rarely needed. Here are some examples:
* SIFT feature detector (from nonfree module). The class only stores algorithm parameters and no keypoints or their descriptors. Therefore, it's enough to store the algorithm parameters, which is what ``Algorithm::write()`` does. Therefore, there is no dedicated ``SIFT::write()``.
* Background subtractor (from video module). It has the algorithm parameters and also it has the current background model. However, the background model is not stored. First, it's rather big. Then, if you have stored the background model, it would likely become irrelevant on the next run (because of shifted camera, changed background, different lighting etc.). Therefore, ``BackgroundSubtractorMOG`` and ``BackgroundSubtractorMOG2`` also rely on the standard ``Algorithm::write()`` to store just the algorithm parameters.
* Expectation Maximization (from ml module). The algorithm finds mixture of gaussians that approximates user data best of all. In this case the model may be re-used on the next run to test new data against the trained statistical model. So EM needs to store the model. However, since the model is described by a few parameters that are available as read-only algorithm parameters (i.e. they are available via ``EM::get()``), EM also relies on ``Algorithm::write()`` to store both EM parameters and the model (represented by read-only algorithm parameters).
Algorithm::read
---------------
Reads algorithm parameters from a file storage
.. ocv:function:: void read(const FileNode& fn)
:param fn: File node of the file storage.
The method reads all the algorithm parameters from the specified node of a file storage. Similarly to ``Algorithm::write()``, if you implement an algorithm that needs to read some extra data and/or re-compute some internal data, you may override the method.
Algorithm::getList
------------------
Returns the list of registered algorithms
.. ocv:function:: void read(vector<string>& algorithms)
:param algorithms: The output vector of algorithm names.
This static method returns the list of registered algorithms in alphabetical order.
Algorithm::getList
------------------
Returns the list of registered algorithms
.. ocv:function:: void read(vector<string>& algorithms)
:param algorithms: The output vector of algorithm names.
This static method returns the list of registered algorithms in alphabetical order.
Algorithm::create
-----------------
Creates algorithm instance by name
.. ocv:function:: template<typename _Tp> Ptr<_Tp> create(const string& name)
:param name: The algorithm name, one of the names returned by ``Algorithm::getList()``.
This static method creates a new instance of the specified algorithm. If there is no such algorithm, the method will silently return null pointer (that can be checked by ``Ptr::empty()`` method). Also, you should specify the particular ``Algorithm`` subclass as ``_Tp`` (or simply ``Algorithm`` if you do not know it at that point). ::
Ptr<BackgroundSubtractor> bgfg = Algorithm::create<BackgroundSubtractor>("BackgroundSubtractor.MOG2");
.. note:: This is important note about seemingly mysterious behavior of ``Algorithm::create()`` when it returns NULL while it should not. The reason is simple - ``Algorithm::create()`` resides in OpenCV`s core module and the algorithms are implemented in other modules. If you create algorithms dynamically, C++ linker may decide to throw away the modules where the actual algorithms are implemented, since you do not call any functions from the modules. To avoid this problem, you need to call ``initModule_<modulename>();`` somewhere in the beginning of the program before ``Algorithm::create()``. For example, call ``initModule_nonfree()`` in order to use SURF/SIFT, call ``initModule_ml()`` to use expectation maximization etc.
Creating Own Algorithms
-----------------------
The above methods are usually enough for users. If you want to make your own algorithm, derived from ``Algorithm``, you should basically follow a few conventions and add a little semi-standard piece of code to your class:
* Make a class and specify ``Algorithm`` as its base class.
* The algorithm parameters should be the class members. See ``Algorithm::get()`` for the list of possible types of the parameters.
* Add public virtual method ``AlgorithmInfo* info() const;`` to your class.
* Add constructor function, ``AlgorithmInfo`` instance and implement the ``info()`` method. The simplest way is to take http://code.opencv.org/svn/opencv/trunk/opencv/modules/ml/src/ml_init.cpp as the reference and modify it according to the list of your parameters.
* Add some public function (e.g. ``initModule_<mymodule>()``) that calls info() of your algorithm and put it into the same source file as ``info()`` implementation. This is to force C++ linker to include this object file into the target application. See ``Algorithm::create()`` for details.

@ -195,6 +195,29 @@ Stores coordinates of a rectangle.
.. seealso:: :ocv:class:`Rect\_`
CvBox2D
------
.. ocv:struct:: CvBox2D
Stores coordinates of a rotated rectangle.
.. ocv:member:: CvPoint2D32f center
Center of the box
.. ocv:member:: CvSize2D32f size
Box width and height
.. ocv:member:: float angle
Angle between the horizontal axis and the first side (i.e. length) in degrees
.. seealso:: :ocv:class:`RotatedRect`
CvScalar
--------

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

@ -2020,6 +2020,15 @@ public:
};
typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
const uchar* src2, size_t step2,
uchar* dst, size_t step, Size sz,
void*);
CV_EXPORTS BinaryFunc getConvertFunc(int sdepth, int ddepth);
CV_EXPORTS BinaryFunc getConvertScaleFunc(int sdepth, int ddepth);
CV_EXPORTS BinaryFunc getCopyMaskFunc(size_t esz);
//! swaps two matrices
CV_EXPORTS void swap(Mat& a, Mat& b);
@ -2133,11 +2142,11 @@ CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx);
CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst);
CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst);
CV_EXPORTS_W void hconcat(InputArray src, OutputArray dst);
CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst);
CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst);
CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst);
CV_EXPORTS_W void vconcat(InputArray src, OutputArray dst);
CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst);
//! computes bitwise conjunction of the two arrays (dst = src1 & src2)
CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2,
@ -2205,6 +2214,9 @@ CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude);
//! checks that each matrix element is within the specified range.
CV_EXPORTS_W bool checkRange(InputArray a, bool quiet=true, CV_OUT Point* pos=0,
double minVal=-DBL_MAX, double maxVal=DBL_MAX);
//! converts NaN's to the given number
CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val=0);
//! implements generalized matrix product algorithm GEMM from BLAS
CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha,
InputArray src3, double gamma, OutputArray dst, int flags=0);
@ -4263,7 +4275,7 @@ template<typename _Tp> struct ParamType {};
/*!
Base class for high-level OpenCV algorithms
*/
class CV_EXPORTS Algorithm
class CV_EXPORTS_W Algorithm
{
public:
Algorithm();
@ -4272,13 +4284,22 @@ public:
template<typename _Tp> typename ParamType<_Tp>::member_type get(const string& name) const;
template<typename _Tp> typename ParamType<_Tp>::member_type get(const char* name) const;
void set(const string& name, int value);
void set(const string& name, double value);
void set(const string& name, bool value);
void set(const string& name, const string& value);
void set(const string& name, const Mat& value);
void set(const string& name, const vector<Mat>& value);
void set(const string& name, const Ptr<Algorithm>& value);
CV_WRAP int getInt(const string& name) const;
CV_WRAP double getDouble(const string& name) const;
CV_WRAP bool getBool(const string& name) const;
CV_WRAP string getString(const string& name) const;
CV_WRAP Mat getMat(const string& name) const;
CV_WRAP vector<Mat> getMatVector(const string& name) const;
CV_WRAP Ptr<Algorithm> getAlgorithm(const string& name) const;
CV_WRAP_AS(setInt) void set(const string& name, int value);
CV_WRAP_AS(setDouble) void set(const string& name, double value);
CV_WRAP_AS(setBool) void set(const string& name, bool value);
CV_WRAP_AS(setString) void set(const string& name, const string& value);
CV_WRAP_AS(setMat) void set(const string& name, const Mat& value);
CV_WRAP_AS(setMatVector) void set(const string& name, const vector<Mat>& value);
CV_WRAP_AS(setAlgorithm) void set(const string& name, const Ptr<Algorithm>& value);
void set(const char* name, int value);
void set(const char* name, double value);
@ -4288,10 +4309,10 @@ public:
void set(const char* name, const vector<Mat>& value);
void set(const char* name, const Ptr<Algorithm>& value);
string paramHelp(const string& name) const;
CV_WRAP string paramHelp(const string& name) const;
int paramType(const char* name) const;
int paramType(const string& name) const;
void getParams(vector<string>& names) const;
CV_WRAP int paramType(const string& name) const;
CV_WRAP void getParams(CV_OUT vector<string>& names) const;
virtual void write(FileStorage& fs) const;
@ -4301,8 +4322,8 @@ public:
typedef int (Algorithm::*Getter)() const;
typedef void (Algorithm::*Setter)(int);
static void getList(vector<string>& algorithms);
static Ptr<Algorithm> _create(const string& name);
CV_WRAP static void getList(CV_OUT vector<string>& algorithms);
CV_WRAP static Ptr<Algorithm> _create(const string& name);
template<typename _Tp> static Ptr<_Tp> create(const string& name);
virtual AlgorithmInfo* info() const /* TODO: make it = 0;*/ { return 0; }
@ -4312,10 +4333,10 @@ public:
class CV_EXPORTS AlgorithmInfo
{
public:
friend class Algorithm;
AlgorithmInfo(const string& name, Algorithm::Constructor create);
~AlgorithmInfo();
void get(const Algorithm* algo, const char* name, int argType, void* value) const;
void set(Algorithm* algo, const char* name, int argType, const void* value) const;
void addParam_(Algorithm& algo, const char* name, int argType,
void* value, bool readOnly,
Algorithm::Getter getter, Algorithm::Setter setter,
@ -4365,6 +4386,8 @@ public:
const string& help=string());
protected:
AlgorithmInfoData* data;
void set(Algorithm* algo, const char* name, int argType,
const void* value, bool force=false) const;
};

@ -1,161 +1,161 @@
/*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.
// 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 GpuMaterials 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_DevMem2D_HPP__
#define __OPENCV_CORE_DevMem2D_HPP__
#ifdef __cplusplus
#ifdef __CUDACC__
#define __CV_GPU_HOST_DEVICE__ __host__ __device__ __forceinline__
#else
#define __CV_GPU_HOST_DEVICE__
#endif
namespace cv
{
namespace gpu
{
// Simple lightweight structures that encapsulates information about an image on device.
// It is intended to pass to nvcc-compiled code. GpuMat depends on headers that nvcc can't compile
template <bool expr> struct StaticAssert;
template <> struct StaticAssert<true> {static __CV_GPU_HOST_DEVICE__ void check(){}};
template<typename T> struct DevPtr
{
typedef T elem_type;
typedef int index_type;
enum { elem_size = sizeof(elem_type) };
T* data;
__CV_GPU_HOST_DEVICE__ DevPtr() : data(0) {}
__CV_GPU_HOST_DEVICE__ DevPtr(T* data_) : data(data_) {}
__CV_GPU_HOST_DEVICE__ size_t elemSize() const { return elem_size; }
__CV_GPU_HOST_DEVICE__ operator T*() { return data; }
__CV_GPU_HOST_DEVICE__ operator const T*() const { return data; }
};
template<typename T> struct PtrSz : public DevPtr<T>
{
__CV_GPU_HOST_DEVICE__ PtrSz() : size(0) {}
__CV_GPU_HOST_DEVICE__ PtrSz(T* data_, size_t size_) : DevPtr<T>(data_), size(size_) {}
size_t size;
};
template<typename T> struct PtrStep : public DevPtr<T>
{
__CV_GPU_HOST_DEVICE__ PtrStep() : step(0) {}
__CV_GPU_HOST_DEVICE__ PtrStep(T* data_, size_t step_) : DevPtr<T>(data_), step(step_) {}
/** \brief stride between two consecutive rows in bytes. Step is stored always and everywhere in bytes!!! */
size_t step;
__CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr<T>::data + y * step); }
__CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr<T>::data + y * step); }
__CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; }
__CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; }
};
template <typename T> struct PtrStepSz : public PtrStep<T>
{
__CV_GPU_HOST_DEVICE__ PtrStepSz() : cols(0), rows(0) {}
__CV_GPU_HOST_DEVICE__ PtrStepSz(int rows_, int cols_, T* data_, size_t step_)
: PtrStep<T>(data_, step_), cols(cols_), rows(rows_) {}
int cols;
int rows;
};
template <typename T> struct DevMem2D_ : public PtrStepSz<T>
{
DevMem2D_() {}
DevMem2D_(int rows_, int cols_, T* data_, size_t step_) : PtrStepSz<T>(rows_, cols_, data_, step_) {}
template <typename U>
explicit DevMem2D_(const DevMem2D_<U>& d) : PtrStepSz<T>(d.rows, d.cols, (T*)d.data, d.step) {}
};
template<typename T> struct PtrElemStep_ : public PtrStep<T>
{
PtrElemStep_(const DevMem2D_<T>& mem) : PtrStep<T>(mem.data, mem.step)
{
StaticAssert<256 % sizeof(T) == 0>::check();
PtrStep<T>::step /= PtrStep<T>::elem_size;
}
__CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return PtrStep<T>::data + y * PtrStep<T>::step; }
__CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return PtrStep<T>::data + y * PtrStep<T>::step; }
__CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; }
__CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; }
};
template<typename T> struct PtrStep_ : public PtrStep<T>
{
PtrStep_() {}
PtrStep_(const DevMem2D_<T>& mem) : PtrStep<T>(mem.data, mem.step) {}
};
typedef DevMem2D_<unsigned char> DevMem2Db;
typedef DevMem2Db DevMem2D;
typedef DevMem2D_<float> DevMem2Df;
typedef DevMem2D_<int> DevMem2Di;
typedef PtrStep<unsigned char> PtrStepb;
typedef PtrStep<float> PtrStepf;
typedef PtrStep<int> PtrStepi;
typedef PtrElemStep_<unsigned char> PtrElemStep;
typedef PtrElemStep_<float> PtrElemStepf;
typedef PtrElemStep_<int> PtrElemStepi;
}
}
#endif // __cplusplus
#endif /* __OPENCV_GPU_DevMem2D_HPP__ */
/*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.
// 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 GpuMaterials 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_DevMem2D_HPP__
#define __OPENCV_CORE_DevMem2D_HPP__
#ifdef __cplusplus
#ifdef __CUDACC__
#define __CV_GPU_HOST_DEVICE__ __host__ __device__ __forceinline__
#else
#define __CV_GPU_HOST_DEVICE__
#endif
namespace cv
{
namespace gpu
{
// Simple lightweight structures that encapsulates information about an image on device.
// It is intended to pass to nvcc-compiled code. GpuMat depends on headers that nvcc can't compile
template <bool expr> struct StaticAssert;
template <> struct StaticAssert<true> {static __CV_GPU_HOST_DEVICE__ void check(){}};
template<typename T> struct DevPtr
{
typedef T elem_type;
typedef int index_type;
enum { elem_size = sizeof(elem_type) };
T* data;
__CV_GPU_HOST_DEVICE__ DevPtr() : data(0) {}
__CV_GPU_HOST_DEVICE__ DevPtr(T* data_) : data(data_) {}
__CV_GPU_HOST_DEVICE__ size_t elemSize() const { return elem_size; }
__CV_GPU_HOST_DEVICE__ operator T*() { return data; }
__CV_GPU_HOST_DEVICE__ operator const T*() const { return data; }
};
template<typename T> struct PtrSz : public DevPtr<T>
{
__CV_GPU_HOST_DEVICE__ PtrSz() : size(0) {}
__CV_GPU_HOST_DEVICE__ PtrSz(T* data_, size_t size_) : DevPtr<T>(data_), size(size_) {}
size_t size;
};
template<typename T> struct PtrStep : public DevPtr<T>
{
__CV_GPU_HOST_DEVICE__ PtrStep() : step(0) {}
__CV_GPU_HOST_DEVICE__ PtrStep(T* data_, size_t step_) : DevPtr<T>(data_), step(step_) {}
/** \brief stride between two consecutive rows in bytes. Step is stored always and everywhere in bytes!!! */
size_t step;
__CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr<T>::data + y * step); }
__CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr<T>::data + y * step); }
__CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; }
__CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; }
};
template <typename T> struct PtrStepSz : public PtrStep<T>
{
__CV_GPU_HOST_DEVICE__ PtrStepSz() : cols(0), rows(0) {}
__CV_GPU_HOST_DEVICE__ PtrStepSz(int rows_, int cols_, T* data_, size_t step_)
: PtrStep<T>(data_, step_), cols(cols_), rows(rows_) {}
int cols;
int rows;
};
template <typename T> struct DevMem2D_ : public PtrStepSz<T>
{
DevMem2D_() {}
DevMem2D_(int rows_, int cols_, T* data_, size_t step_) : PtrStepSz<T>(rows_, cols_, data_, step_) {}
template <typename U>
explicit DevMem2D_(const DevMem2D_<U>& d) : PtrStepSz<T>(d.rows, d.cols, (T*)d.data, d.step) {}
};
template<typename T> struct PtrElemStep_ : public PtrStep<T>
{
PtrElemStep_(const DevMem2D_<T>& mem) : PtrStep<T>(mem.data, mem.step)
{
StaticAssert<256 % sizeof(T) == 0>::check();
PtrStep<T>::step /= PtrStep<T>::elem_size;
}
__CV_GPU_HOST_DEVICE__ T* ptr(int y = 0) { return PtrStep<T>::data + y * PtrStep<T>::step; }
__CV_GPU_HOST_DEVICE__ const T* ptr(int y = 0) const { return PtrStep<T>::data + y * PtrStep<T>::step; }
__CV_GPU_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; }
__CV_GPU_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; }
};
template<typename T> struct PtrStep_ : public PtrStep<T>
{
PtrStep_() {}
PtrStep_(const DevMem2D_<T>& mem) : PtrStep<T>(mem.data, mem.step) {}
};
typedef DevMem2D_<unsigned char> DevMem2Db;
typedef DevMem2Db DevMem2D;
typedef DevMem2D_<float> DevMem2Df;
typedef DevMem2D_<int> DevMem2Di;
typedef PtrStep<unsigned char> PtrStepb;
typedef PtrStep<float> PtrStepf;
typedef PtrStep<int> PtrStepi;
typedef PtrElemStep_<unsigned char> PtrElemStep;
typedef PtrElemStep_<float> PtrElemStepf;
typedef PtrElemStep_<int> PtrElemStepi;
}
}
#endif // __cplusplus
#endif /* __OPENCV_GPU_DevMem2D_HPP__ */

@ -561,18 +561,28 @@ template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
template<typename _Tp> inline _Tp& Mat::at(int i0)
{
CV_DbgAssert( dims <= 2 && data && (size.p[0] == 1 || size.p[1] == 1) &&
(unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) &&
CV_DbgAssert( dims <= 2 && data &&
(unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
return *(_Tp*)(data + step.p[size.p[0]==1]*i0);
if( isContinuous() || size.p[0] == 1 )
return ((_Tp*)data)[i0];
if( size.p[1] == 1 )
return *(_Tp*)(data + step.p[0]*i0);
int i = i0/cols, j = i0 - i*cols;
return ((_Tp*)(data + step.p[0]*i))[j];
}
template<typename _Tp> inline const _Tp& Mat::at(int i0) const
{
CV_DbgAssert( dims <= 2 && data && (size.p[0] == 1 || size.p[1] == 1) &&
(unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) &&
CV_DbgAssert( dims <= 2 && data &&
(unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
return *(_Tp*)(data + step.p[size.p[0]==1]*i0);
if( isContinuous() || size.p[0] == 1 )
return ((const _Tp*)data)[i0];
if( size.p[1] == 1 )
return *(const _Tp*)(data + step.p[0]*i0);
int i = i0/cols, j = i0 - i*cols;
return ((const _Tp*)(data + step.p[0]*i))[j];
}
template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)

@ -52,7 +52,7 @@
#ifdef __cplusplus
/////// exchange-add operation for atomic operations on reference counters ///////
#ifdef __INTEL_COMPILER // atomic increment on the Intel(tm) compiler
#if defined __INTEL_COMPILER && !(defined WIN32 || defined _WIN32) // atomic increment on the linux version of the Intel(tm) compiler
#define CV_XADD(addr,delta) _InterlockedExchangeAdd(const_cast<void*>(reinterpret_cast<volatile void*>(addr)), delta)
#elif defined __GNUC__
@ -638,6 +638,14 @@ Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
}
template<typename _Tp, int m, int n> static inline
Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b)
{
Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp());
return reinterpret_cast<const Vec<_Tp, m>&>(c);
}
template<typename _Tp> static inline
Point_<_Tp> operator * (const Matx<_Tp, 2, 2>& a, const Point_<_Tp>& b)
{
@ -668,14 +676,23 @@ Matx<_Tp, 4, 1> operator * (const Matx<_Tp, 4, 4>& a, const Point3_<_Tp>& b)
return a*Matx<_Tp, 4, 1>(b.x, b.y, b.z, 1);
}
template<typename _Tp> static inline
Scalar operator * (const Matx<_Tp, 4, 4>& a, const Scalar& b)
{
return Scalar(a*Matx<_Tp, 4, 1>(b[0],b[1],b[2],b[3]));
}
Matx<double, 4, 1> c(Matx<double, 4, 4>(a), b, Matx_MatMulOp());
return reinterpret_cast<const Scalar&>(c);
}
static inline
Scalar operator * (const Matx<double, 4, 4>& a, const Scalar& b)
{
Matx<double, 4, 1> c(a, b, Matx_MatMulOp());
return reinterpret_cast<const Scalar&>(c);
}
template<typename _Tp, int m, int n> inline
Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
{

@ -317,16 +317,19 @@ CV_INLINE int cvRound( double value )
#endif
}
#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP)
#include "emmintrin.h"
#endif
CV_INLINE int cvFloor( double value )
{
#ifdef __GNUC__
int i = (int)value;
return i - (i > value);
#elif defined _MSC_VER && defined _M_X64
#if defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)
__m128d t = _mm_set_sd( value );
int i = _mm_cvtsd_si32(t);
return i - _mm_movemask_pd(_mm_cmplt_sd(t, _mm_cvtsi32_sd(t,i)));
#elif defined __GNUC__
int i = (int)value;
return i - (i > value);
#else
int i = cvRound(value);
Cv32suf diff;
@ -338,13 +341,13 @@ CV_INLINE int cvFloor( double value )
CV_INLINE int cvCeil( double value )
{
#ifdef __GNUC__
int i = (int)value;
return i + (i < value);
#elif defined _MSC_VER && defined _M_X64
#if defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)
__m128d t = _mm_set_sd( value );
int i = _mm_cvtsd_si32(t);
return i + _mm_movemask_pd(_mm_cmplt_sd(_mm_cvtsi32_sd(t,i), t));
#elif defined __GNUC__
int i = (int)value;
return i + (i < value);
#else
int i = cvRound(value);
Cv32suf diff;

@ -251,6 +251,41 @@ void Algorithm::set(const char* name, const Ptr<Algorithm>& value)
info()->set(this, name, ParamType<Algorithm>::type, &value);
}
int Algorithm::getInt(const string& name) const
{
return get<int>(name);
}
double Algorithm::getDouble(const string& name) const
{
return get<double>(name);
}
bool Algorithm::getBool(const string& name) const
{
return get<bool>(name);
}
string Algorithm::getString(const string& name) const
{
return get<string>(name);
}
Mat Algorithm::getMat(const string& name) const
{
return get<Mat>(name);
}
vector<Mat> Algorithm::getMatVector(const string& name) const
{
return get<vector<Mat> >(name);
}
Ptr<Algorithm> Algorithm::getAlgorithm(const string& name) const
{
return get<Algorithm>(name);
}
string Algorithm::paramHelp(const string& name) const
{
return info()->paramHelp(name.c_str());
@ -296,9 +331,9 @@ AlgorithmInfo::~AlgorithmInfo()
void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const
{
size_t i = 0, n = data->params.vec.size();
size_t i = 0, nparams = data->params.vec.size();
cv::write(fs, "name", algo->name());
for( i = 0; i < n; i++ )
for( i = 0; i < nparams; i++ )
{
const Param& p = data->params.vec[i].second;
const string& pname = data->params.vec[i].first;
@ -327,9 +362,10 @@ void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const
void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const
{
size_t i = 0, n = data->params.vec.size();
size_t i = 0, nparams = data->params.vec.size();
AlgorithmInfo* info = algo->info();
for( i = 0; i < n; i++ )
for( i = 0; i < nparams; i++ )
{
const Param& p = data->params.vec[i].second;
const string& pname = data->params.vec[i].first;
@ -337,31 +373,43 @@ void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const
if( n.empty() )
continue;
if( p.type == Param::INT )
algo->set(pname, (int)n);
{
int val = (int)n;
info->set(algo, pname.c_str(), p.type, &val, true);
}
else if( p.type == Param::BOOLEAN )
algo->set(pname, (int)n != 0);
{
bool val = (int)n != 0;
info->set(algo, pname.c_str(), p.type, &val, true);
}
else if( p.type == Param::REAL )
algo->set(pname, (double)n);
{
double val = (double)n;
info->set(algo, pname.c_str(), p.type, &val, true);
}
else if( p.type == Param::STRING )
algo->set(pname, (string)n);
{
string val = (string)n;
info->set(algo, pname.c_str(), p.type, &val, true);
}
else if( p.type == Param::MAT )
{
Mat m;
cv::read(n, m);
algo->set(pname, m);
info->set(algo, pname.c_str(), p.type, &m, true);
}
else if( p.type == Param::MAT_VECTOR )
{
vector<Mat> mv;
cv::read(n, mv);
algo->set(pname, mv);
info->set(algo, pname.c_str(), p.type, &mv, true);
}
else if( p.type == Param::ALGORITHM )
{
Ptr<Algorithm> nestedAlgo = Algorithm::_create((string)n["name"]);
CV_Assert( !nestedAlgo.empty() );
nestedAlgo->read(n);
algo->set(pname, nestedAlgo);
info->set(algo, pname.c_str(), p.type, &nestedAlgo, true);
}
else
CV_Error( CV_StsUnsupportedFormat, "unknown/unsupported parameter type");
@ -391,24 +439,24 @@ union GetSetParam
void (Algorithm::*set_mat_vector)(const vector<Mat>&);
void (Algorithm::*set_algo)(const Ptr<Algorithm>&);
};
void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const void* value) const
void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const void* value, bool force) const
{
const Param* p = findstr(data->params, name);
if( !p )
CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") );
if( p->readonly )
if( !force && p->readonly )
CV_Error_( CV_StsError, ("Parameter '%s' is readonly", name));
GetSetParam f;
f.set_int = p->setter;
if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL )
{
CV_Assert( p->type == Param::INT || p->type == Param::REAL || p->type == Param::BOOLEAN );
if( p->type == Param::INT )
{
int val = argType == Param::INT ? *(const int*)value :
@ -443,7 +491,7 @@ void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const vo
else if( argType == Param::STRING )
{
CV_Assert( p->type == Param::STRING );
const string& val = *(const string*)value;
if( p->setter )
(algo->*f.set_string)(val);
@ -453,7 +501,7 @@ void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const vo
else if( argType == Param::MAT )
{
CV_Assert( p->type == Param::MAT );
const Mat& val = *(const Mat*)value;
if( p->setter )
(algo->*f.set_mat)(val);
@ -463,7 +511,7 @@ void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const vo
else if( argType == Param::MAT_VECTOR )
{
CV_Assert( p->type == Param::MAT_VECTOR );
const vector<Mat>& val = *(const vector<Mat>*)value;
if( p->setter )
(algo->*f.set_mat_vector)(val);
@ -473,7 +521,7 @@ void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const vo
else if( argType == Param::ALGORITHM )
{
CV_Assert( p->type == Param::ALGORITHM );
const Ptr<Algorithm>& val = *(const Ptr<Algorithm>*)value;
if( p->setter )
(algo->*f.set_algo)(val);

@ -2186,6 +2186,28 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma
}
void patchNaNs( InputOutputArray _a, double _val )
{
Mat a = _a.getMat();
CV_Assert( a.depth() == CV_32F );
const Mat* arrays[] = {&a, 0};
int* ptrs[1];
NAryMatIterator it(arrays, (uchar**)ptrs);
size_t len = it.size*a.channels();
Cv32suf val;
val.f = (float)_val;
for( size_t i = 0; i < it.nplanes; i++, ++it )
{
int* tptr = ptrs[0];
for( size_t j = 0; j < len; j++ )
if( (tptr[j] & 0x7fffffff) > 0x7f800000 )
tptr[j] = val.i;
}
}
void exp(const float* src, float* dst, int n)
{
Exp_32f(src, dst, n);

@ -176,15 +176,6 @@ struct NoVec
extern volatile bool USE_SSE2;
typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
const uchar* src2, size_t step2,
uchar* dst, size_t step, Size sz,
void*);
BinaryFunc getConvertFunc(int sdepth, int ddepth);
BinaryFunc getConvertScaleFunc(int sdepth, int ddepth);
BinaryFunc getCopyMaskFunc(size_t esz);
enum { BLOCK_SIZE = 1024 };
#ifdef HAVE_IPP

@ -48,6 +48,10 @@
#include "precomp.hpp"
#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP)
#include "emmintrin.h"
#endif
namespace cv
{
@ -196,33 +200,54 @@ DEF_RANDI_FUNC(8s, schar)
DEF_RANDI_FUNC(16u, ushort)
DEF_RANDI_FUNC(16s, short)
DEF_RANDI_FUNC(32s, int)
static void randf_32f( float* arr, int len, uint64* state, const Vec2f* p, bool )
{
uint64 temp = *state;
int i;
int i = 0;
for( i = 0; i <= len - 4; i += 4 )
for( ; i <= len - 4; i += 4 )
{
float f0, f1;
temp = RNG_NEXT(temp);
f0 = (int)temp*p[i][0] + p[i][1];
temp = RNG_NEXT(temp);
f1 = (int)temp*p[i+1][0] + p[i+1][1];
arr[i] = f0; arr[i+1] = f1;
temp = RNG_NEXT(temp);
f0 = (int)temp*p[i+2][0] + p[i+2][1];
temp = RNG_NEXT(temp);
f1 = (int)temp*p[i+3][0] + p[i+3][1];
arr[i+2] = f0; arr[i+3] = f1;
float f[4];
f[0] = (float)(int)(temp = RNG_NEXT(temp));
f[1] = (float)(int)(temp = RNG_NEXT(temp));
f[2] = (float)(int)(temp = RNG_NEXT(temp));
f[3] = (float)(int)(temp = RNG_NEXT(temp));
// handwritten SSE is required not for performance but for numerical stability!
// both 32-bit gcc and MSVC compilers trend to generate double precision SSE
// while 64-bit compilers generate single precision SIMD instructions
// so manual vectorisation forces all compilers to the single precision
#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP)
__m128 q0 = _mm_loadu_ps((const float*)(p + i));
__m128 q1 = _mm_loadu_ps((const float*)(p + i + 2));
__m128 q01l = _mm_unpacklo_ps(q0, q1);
__m128 q01h = _mm_unpackhi_ps(q0, q1);
__m128 p0 = _mm_unpacklo_ps(q01l, q01h);
__m128 p1 = _mm_unpackhi_ps(q01l, q01h);
_mm_storeu_ps(arr + i, _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(f), p0), p1));
#else
arr[i+0] = f[0]*p[i+0][0] + p[i+0][1];
arr[i+1] = f[1]*p[i+1][0] + p[i+1][1];
arr[i+2] = f[2]*p[i+2][0] + p[i+2][1];
arr[i+3] = f[3]*p[i+3][0] + p[i+3][1];
#endif
}
for( ; i < len; i++ )
{
temp = RNG_NEXT(temp);
#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP)
_mm_store_ss(arr + i, _mm_add_ss(
_mm_mul_ss(_mm_set_ss((float)(int)temp), _mm_set_ss(p[i][0])),
_mm_set_ss(p[i][1]))
);
#else
arr[i] = (int)temp*p[i][0] + p[i][1];
#endif
}
*state = temp;

@ -834,7 +834,6 @@ float normL2Sqr_(const float* a, const float* b, int n)
}
else
#endif
//vz why do we need unroll here? no sse = no need to unroll
{
for( ; j <= n - 4; j += 4 )
{
@ -875,7 +874,6 @@ float normL1_(const float* a, const float* b, int n)
}
else
#endif
//vz no need to unroll here - if no sse
{
for( ; j <= n - 4; j += 4 )
{
@ -916,7 +914,6 @@ int normL1_(const uchar* a, const uchar* b, int n)
}
else
#endif
//vz why do we need unroll here? no sse = no unroll
{
for( ; j <= n - 4; j += 4 )
{
@ -965,6 +962,34 @@ static const uchar popCountTable4[] =
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
};
int normHamming(const uchar* a, int n)
{
int i = 0, result = 0;
#if CV_NEON
if (CPU_HAS_NEON_FEATURE)
{
uint32x4_t bits = vmovq_n_u32(0);
for (; i <= n - 16; i += 16) {
uint8x16_t A_vec = vld1q_u8 (a + i);
uint8x16_t bitsSet = vcntq_u8 (A_vec);
uint16x8_t bitSet8 = vpaddlq_u8 (bitsSet);
uint32x4_t bitSet4 = vpaddlq_u16 (bitSet8);
bits = vaddq_u32(bits, bitSet4);
}
uint64x2_t bitSet2 = vpaddlq_u32 (bits);
result = vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),0);
result += vgetq_lane_s32 (vreinterpretq_s32_u64(bitSet2),2);
}
else
#endif
for( ; i <= n - 4; i += 4 )
result += popCountTable[a[i]] + popCountTable[a[i+1]] +
popCountTable[a[i+2]] + popCountTable[a[i+3]];
for( ; i < n; i++ )
result += popCountTable[a[i]];
return result;
}
int normHamming(const uchar* a, const uchar* b, int n)
{
int i = 0, result = 0;
@ -995,6 +1020,27 @@ int normHamming(const uchar* a, const uchar* b, int n)
return result;
}
int normHamming(const uchar* a, int n, int cellSize)
{
if( cellSize == 1 )
return normHamming(a, n);
const uchar* tab = 0;
if( cellSize == 2 )
tab = popCountTable2;
else if( cellSize == 4 )
tab = popCountTable4;
else
CV_Error( CV_StsBadSize, "bad cell size (not 1, 2 or 4) in normHamming" );
int i = 0, result = 0;
#if CV_ENABLE_UNROLLED
for( ; i <= n - 4; i += 4 )
result += tab[a[i]] + tab[a[i+1]] + tab[a[i+2]] + tab[a[i+3]];
#endif
for( ; i < n; i++ )
result += tab[a[i]];
return result;
}
int normHamming(const uchar* a, const uchar* b, int n, int cellSize)
{
if( cellSize == 1 )
@ -1221,38 +1267,80 @@ double cv::norm( InputArray _src, int normType, InputArray _mask )
int depth = src.depth(), cn = src.channels();
normType &= 7;
CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 );
CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR ||
((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src.type() == CV_8U) );
if( depth == CV_32F && src.isContinuous() && mask.empty() )
if( src.isContinuous() && mask.empty() )
{
size_t len = src.total()*cn;
if( len == (size_t)(int)len )
{
const float* data = src.ptr<float>();
if( normType == NORM_L2 )
{
double result = 0;
GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1);
return std::sqrt(result);
}
if( normType == NORM_L1 )
if( depth == CV_32F )
{
double result = 0;
GET_OPTIMIZED(normL1_32f)(data, 0, &result, (int)len, 1);
return result;
const float* data = src.ptr<float>();
if( normType == NORM_L2 )
{
double result = 0;
GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1);
return std::sqrt(result);
}
if( normType == NORM_L2SQR )
{
double result = 0;
GET_OPTIMIZED(normL2_32f)(data, 0, &result, (int)len, 1);
return result;
}
if( normType == NORM_L1 )
{
double result = 0;
GET_OPTIMIZED(normL1_32f)(data, 0, &result, (int)len, 1);
return result;
}
if( normType == NORM_INF )
{
float result = 0;
GET_OPTIMIZED(normInf_32f)(data, 0, &result, (int)len, 1);
return result;
}
}
if( depth == CV_8U )
{
float result = 0;
GET_OPTIMIZED(normInf_32f)(data, 0, &result, (int)len, 1);
return result;
const uchar* data = src.ptr<uchar>();
if( normType == NORM_HAMMING )
return normHamming(data, (int)len);
if( normType == NORM_HAMMING2 )
return normHamming(data, (int)len, 2);
}
}
}
CV_Assert( mask.empty() || mask.type() == CV_8U );
if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
{
if( !mask.empty() )
{
Mat temp;
bitwise_and(src, mask, temp);
return norm(temp, normType);
}
int cellSize = normType == NORM_HAMMING ? 1 : 2;
const Mat* arrays[] = {&src, 0};
uchar* ptrs[1];
NAryMatIterator it(arrays, ptrs);
int total = (int)it.size;
int result = 0;
for( size_t i = 0; i < it.nplanes; i++, ++it )
result += normHamming(ptrs[0], total, cellSize);
return result;
}
NormFunc func = normTab[normType >> 1][depth];
CV_Assert( func != 0 );
@ -1269,7 +1357,7 @@ double cv::norm( InputArray _src, int normType, InputArray _mask )
NAryMatIterator it(arrays, ptrs);
int j, total = (int)it.size, blockSize = total, intSumBlockSize = 0, count = 0;
bool blockSum = (normType == NORM_L1 && depth <= CV_16S) ||
(normType == NORM_L2 && depth <= CV_8S);
((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S);
int isum = 0;
int *ibuf = &result.i;
size_t esz = 0;
@ -1328,38 +1416,72 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m
CV_Assert( src1.size == src2.size && src1.type() == src2.type() );
normType &= 7;
CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 );
CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR ||
((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) );
if( src1.depth() == CV_32F && src1.isContinuous() && src2.isContinuous() && mask.empty() )
if( src1.isContinuous() && src2.isContinuous() && mask.empty() )
{
size_t len = src1.total()*src1.channels();
if( len == (size_t)(int)len )
{
const float* data1 = src1.ptr<float>();
const float* data2 = src2.ptr<float>();
if( normType == NORM_L2 )
if( src1.depth() == CV_32F )
{
double result = 0;
GET_OPTIMIZED(normDiffL2_32f)(data1, data2, 0, &result, (int)len, 1);
return std::sqrt(result);
}
if( normType == NORM_L1 )
{
double result = 0;
GET_OPTIMIZED(normDiffL1_32f)(data1, data2, 0, &result, (int)len, 1);
return result;
}
{
float result = 0;
GET_OPTIMIZED(normDiffInf_32f)(data1, data2, 0, &result, (int)len, 1);
return result;
const float* data1 = src1.ptr<float>();
const float* data2 = src2.ptr<float>();
if( normType == NORM_L2 )
{
double result = 0;
GET_OPTIMIZED(normDiffL2_32f)(data1, data2, 0, &result, (int)len, 1);
return std::sqrt(result);
}
if( normType == NORM_L2SQR )
{
double result = 0;
GET_OPTIMIZED(normDiffL2_32f)(data1, data2, 0, &result, (int)len, 1);
return result;
}
if( normType == NORM_L1 )
{
double result = 0;
GET_OPTIMIZED(normDiffL1_32f)(data1, data2, 0, &result, (int)len, 1);
return result;
}
if( normType == NORM_INF )
{
float result = 0;
GET_OPTIMIZED(normDiffInf_32f)(data1, data2, 0, &result, (int)len, 1);
return result;
}
}
}
}
CV_Assert( mask.empty() || mask.type() == CV_8U );
if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
{
if( !mask.empty() )
{
Mat temp;
bitwise_xor(src1, src2, temp);
bitwise_and(temp, mask, temp);
return norm(temp, normType);
}
int cellSize = normType == NORM_HAMMING ? 1 : 2;
const Mat* arrays[] = {&src1, &src2, 0};
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs);
int total = (int)it.size;
int result = 0;
for( size_t i = 0; i < it.nplanes; i++, ++it )
result += normHamming(ptrs[0], ptrs[1], total, cellSize);
return result;
}
NormDiffFunc func = normDiffTab[normType >> 1][depth];
CV_Assert( func != 0 );
@ -1377,7 +1499,7 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m
NAryMatIterator it(arrays, ptrs);
int j, total = (int)it.size, blockSize = total, intSumBlockSize = 0, count = 0;
bool blockSum = (normType == NORM_L1 && depth <= CV_16S) ||
(normType == NORM_L2 && depth <= CV_8S);
((normType == NORM_L2 || normType == NORM_L2SQR) && depth <= CV_8S);
unsigned isum = 0;
unsigned *ibuf = &result.u;
size_t esz = 0;

@ -1186,8 +1186,12 @@ struct CountNonZeroOp : public BaseElemWiseOp
struct MeanStdDevOp : public BaseElemWiseOp
{
Scalar sqmeanRef;
int cn;
MeanStdDevOp() : BaseElemWiseOp(1, FIX_ALPHA+FIX_BETA+FIX_GAMMA+SUPPORT_MASK+SCALAR_OUTPUT, 1, 1, Scalar::all(0))
{
cn = 0;
context = 7;
};
void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
@ -1202,6 +1206,9 @@ struct MeanStdDevOp : public BaseElemWiseOp
cvtest::multiply(temp, temp, temp);
Scalar mean = cvtest::mean(src[0], mask);
Scalar sqmean = cvtest::mean(temp, mask);
sqmeanRef = sqmean;
cn = temp.channels();
for( int c = 0; c < 4; c++ )
sqmean[c] = std::sqrt(std::max(sqmean[c] - mean[c]*mean[c], 0.));
@ -1212,7 +1219,11 @@ struct MeanStdDevOp : public BaseElemWiseOp
}
double getMaxErr(int)
{
return 1e-6;
CV_Assert(cn > 0);
double err = sqmeanRef[0];
for(int i = 1; i < cn; ++i)
err = std::max(err, sqmeanRef[i]);
return 3e-7 * err;
}
};
@ -1226,7 +1237,20 @@ struct NormOp : public BaseElemWiseOp
};
int getRandomType(RNG& rng)
{
return cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 4);
int type = cvtest::randomType(rng, DEPTH_MASK_ALL_BUT_8S, 1, 4);
for(;;)
{
normType = rng.uniform(1, 8);
if( normType == NORM_INF || normType == NORM_L1 ||
normType == NORM_L2 || normType == NORM_L2SQR ||
normType == NORM_HAMMING || normType == NORM_HAMMING2 )
break;
}
if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
{
type = CV_8U;
}
return type;
}
void op(const vector<Mat>& src, Mat& dst, const Mat& mask)
{
@ -1242,7 +1266,6 @@ struct NormOp : public BaseElemWiseOp
}
void generateScalars(int, RNG& rng)
{
normType = 1 << rng.uniform(0, 3);
}
double getMaxErr(int)
{

@ -79,10 +79,12 @@ protected:
bool check_full(int type); // compex test for symmetric matrix
virtual void run (int) = 0; // main testing method
private:
protected:
float eps_val_32, eps_vec_32;
float eps_val_64, eps_vec_64;
int ntests;
bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index = -1, int high_index = -1);
bool check_pair_count(const cv::Mat& src, const cv::Mat& evalues, const cv::Mat& evectors, int low_index = -1, int high_index = -1);
bool check_pairs_order(const cv::Mat& eigen_values); // checking order of eigen values & vectors (it should be none up)
@ -140,8 +142,7 @@ Core_EigenTest_Scalar_64::~Core_EigenTest_Scalar_64() {}
void Core_EigenTest_Scalar_32::run(int)
{
const size_t MATRIX_COUNT = 500;
for (size_t i = 0; i < MATRIX_COUNT; ++i)
for (int i = 0; i < ntests; ++i)
{
float value = cv::randu<float>();
cv::Mat src(1, 1, CV_32FC1, Scalar::all((float)value));
@ -151,8 +152,7 @@ void Core_EigenTest_Scalar_32::run(int)
void Core_EigenTest_Scalar_64::run(int)
{
const size_t MATRIX_COUNT = 500;
for (size_t i = 0; i < MATRIX_COUNT; ++i)
for (int i = 0; i < ntests; ++i)
{
float value = cv::randu<float>();
cv::Mat src(1, 1, CV_64FC1, Scalar::all((double)value));
@ -163,7 +163,9 @@ void Core_EigenTest_Scalar_64::run(int)
void Core_EigenTest_32::run(int) { check_full(CV_32FC1); }
void Core_EigenTest_64::run(int) { check_full(CV_64FC1); }
Core_EigenTest::Core_EigenTest() : eps_val_32(1e-3f), eps_vec_32(1e-2f), eps_val_64(1e-4f), eps_vec_64(1e-3f) {}
Core_EigenTest::Core_EigenTest()
: eps_val_32(1e-3f), eps_vec_32(1e-2f),
eps_val_64(1e-4f), eps_vec_64(1e-3f), ntests(100) {}
Core_EigenTest::~Core_EigenTest() {}
bool Core_EigenTest::check_pair_count(const cv::Mat& src, const cv::Mat& evalues, int low_index, int high_index)
@ -382,14 +384,13 @@ bool Core_EigenTest::test_values(const cv::Mat& src)
bool Core_EigenTest::check_full(int type)
{
const int MATRIX_COUNT = 500;
const int MAX_DEGREE = 7;
srand((unsigned int)time(0));
for (int i = 1; i <= MATRIX_COUNT; ++i)
for (int i = 0; i < ntests; ++i)
{
int src_size = (int)(std::pow(2.0, (rand()%MAX_DEGREE+1)*1.0));
int src_size = (int)(std::pow(2.0, (rand()%MAX_DEGREE)+1.));
cv::Mat src(src_size, src_size, type);

@ -1802,6 +1802,7 @@ Core_MatrixTest( 1, 4, false, false, 1 ),
flags(0), have_u(false), have_v(false), symmetric(false), compact(false), vector_w(false)
{
test_case_count = 100;
max_log_array_size = 8;
test_array[TEMP].push_back(NULL);
test_array[TEMP].push_back(NULL);
test_array[TEMP].push_back(NULL);

@ -74,11 +74,17 @@ protected:
bool TestSparseMat();
bool TestVec();
bool TestMatxMultiplication();
bool TestSubMatAccess();
bool operations1();
void checkDiff(const Mat& m1, const Mat& m2, const string& s) { if (norm(m1, m2, NORM_INF) != 0) throw test_excep(s); }
void checkDiffF(const Mat& m1, const Mat& m2, const string& s) { if (norm(m1, m2, NORM_INF) > 1e-5) throw test_excep(s); }
void checkDiff(const Mat& m1, const Mat& m2, const string& s)
{
if (norm(m1, m2, NORM_INF) != 0) throw test_excep(s);
}
void checkDiffF(const Mat& m1, const Mat& m2, const string& s)
{
if (norm(m1, m2, NORM_INF) > 1e-5) throw test_excep(s);
}
};
CV_OperationsTest::CV_OperationsTest()
@ -438,6 +444,41 @@ bool CV_OperationsTest::SomeMatFunctions()
}
bool CV_OperationsTest::TestSubMatAccess()
{
try
{
Mat_<float> T_bs(4,4);
Vec3f cdir(1.f, 1.f, 0.f);
Vec3f ydir(1.f, 0.f, 1.f);
Vec3f fpt(0.1f, 0.7f, 0.2f);
T_bs.setTo(0);
T_bs(Range(0,3),Range(2,3)) = 1.0*Mat(cdir); // wierd OpenCV stuff, need to do multiply
T_bs(Range(0,3),Range(1,2)) = 1.0*Mat(ydir);
T_bs(Range(0,3),Range(0,1)) = 1.0*Mat(cdir.cross(ydir));
T_bs(Range(0,3),Range(3,4)) = 1.0*Mat(fpt);
T_bs(3,3) = 1.0;
//std::cout << "[Nav Grok] S frame =" << std::endl << T_bs << std::endl;
// set up display coords, really just the S frame
std::vector<float>coords;
for (int i=0; i<16; i++)
{
coords.push_back(T_bs(i));
//std::cout << T_bs1(i) << std::endl;
}
CV_Assert( norm(coords, T_bs.reshape(1,1), NORM_INF) == 0 );
}
catch (const test_excep& e)
{
ts->printf(cvtest::TS::LOG, "%s\n", e.s.c_str());
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return false;
}
return true;
}
bool CV_OperationsTest::TestTemplateMat()
{
try
@ -754,12 +795,35 @@ bool CV_OperationsTest::TestMatxMultiplication()
{
try
{
Matx33f mat(1, 0, 0, 0, 1, 0, 0, 0, 1); // Identity matrix
Matx33f mat(1, 1, 1, 0, 1, 1, 0, 0, 1); // Identity matrix
Point2f pt(3, 4);
Point3f res = mat * pt; // Correctly assumes homogeneous coordinates
if(res.x != 3.0) throw test_excep();
if(res.y != 4.0) throw test_excep();
if(res.z != 1.0) throw test_excep();
Vec3f res2 = mat*Vec3f(res.x, res.y, res.z);
if(res.x != 8.0) throw test_excep();
if(res.y != 5.0) throw test_excep();
if(res.z != 1.0) throw test_excep();
if(res2[0] != 14.0) throw test_excep();
if(res2[1] != 6.0) throw test_excep();
if(res2[2] != 1.0) throw test_excep();
Matx44f mat44f(1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1);
Matx44d mat44d(1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1);
Scalar s(4, 3, 2, 1);
Scalar sf = mat44f*s;
Scalar sd = mat44d*s;
if(sf[0] != 10.0) throw test_excep();
if(sf[1] != 6.0) throw test_excep();
if(sf[2] != 3.0) throw test_excep();
if(sf[3] != 1.0) throw test_excep();
if(sd[0] != 10.0) throw test_excep();
if(sd[1] != 6.0) throw test_excep();
if(sd[2] != 3.0) throw test_excep();
if(sd[3] != 1.0) throw test_excep();
}
catch(const test_excep&)
{
@ -877,6 +941,9 @@ void CV_OperationsTest::run( int /* start_from */)
if (!TestMatxMultiplication())
return;
if (!TestSubMatAccess())
return;
if (!operations1())
return;

@ -95,9 +95,9 @@ Creates a descriptor extractor by name.
The current implementation supports the following types of a descriptor extractor:
* ``"SIFT"`` -- :ocv:class:`SiftDescriptorExtractor`
* ``"SURF"`` -- :ocv:class:`SurfDescriptorExtractor`
* ``"ORB"`` -- :ocv:class:`OrbDescriptorExtractor`
* ``"SIFT"`` -- :ocv:class:`SIFT`
* ``"SURF"`` -- :ocv:class:`SURF`
* ``"ORB"`` -- :ocv:class:`ORB`
* ``"BRIEF"`` -- :ocv:class:`BriefDescriptorExtractor`
A combined format is also supported: descriptor extractor adapter name ( ``"Opponent"`` --
@ -105,107 +105,6 @@ A combined format is also supported: descriptor extractor adapter name ( ``"Oppo
for example: ``"OpponentSIFT"`` .
SiftDescriptorExtractor
-----------------------
.. ocv:class:: SiftDescriptorExtractor
Wrapping class for computing descriptors by using the
:ocv:class:`SIFT` class. ::
class SiftDescriptorExtractor : public DescriptorExtractor
{
public:
SiftDescriptorExtractor(
const SIFT::DescriptorParams& descriptorParams=SIFT::DescriptorParams(),
const SIFT::CommonParams& commonParams=SIFT::CommonParams() );
SiftDescriptorExtractor( double magnification, bool isNormalize=true,
bool recalculateAngles=true, int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
int angleMode=SIFT::CommonParams::FIRST_ANGLE );
virtual void read (const FileNode &fn);
virtual void write (FileStorage &fs) const;
virtual int descriptorSize() const;
virtual int descriptorType() const;
protected:
...
}
SurfDescriptorExtractor
-----------------------
.. ocv:class:: SurfDescriptorExtractor
Wrapping class for computing descriptors by using the
:ocv:class:`SURF` class. ::
class SurfDescriptorExtractor : public DescriptorExtractor
{
public:
SurfDescriptorExtractor( int nOctaves=4,
int nOctaveLayers=2, bool extended=false );
virtual void read (const FileNode &fn);
virtual void write (FileStorage &fs) const;
virtual int descriptorSize() const;
virtual int descriptorType() const;
protected:
...
}
OrbDescriptorExtractor
---------------------------
.. ocv:class:: OrbDescriptorExtractor
Wrapping class for computing descriptors by using the
:ocv:class:`ORB` class. ::
template<typename T>
class ORbDescriptorExtractor : public DescriptorExtractor
{
public:
OrbDescriptorExtractor( ORB::PatchSize patch_size );
virtual void read( const FileNode &fn );
virtual void write( FileStorage &fs ) const;
virtual int descriptorSize() const;
virtual int descriptorType() const;
protected:
...
}
CalonderDescriptorExtractor
---------------------------
.. ocv:class:: CalonderDescriptorExtractor
Wrapping class for computing descriptors by using the
:ocv:class:`RTreeClassifier` class. ::
template<typename T>
class CalonderDescriptorExtractor : public DescriptorExtractor
{
public:
CalonderDescriptorExtractor( const string& classifierFile );
virtual void read( const FileNode &fn );
virtual void write( FileStorage &fs ) const;
virtual int descriptorSize() const;
virtual int descriptorType() const;
protected:
...
}
OpponentColorDescriptorExtractor
--------------------------------
.. ocv:class:: OpponentColorDescriptorExtractor

@ -248,7 +248,7 @@ Creates a descriptor matcher of a given type with the default parameters (using
*
``BruteForce-Hamming``
*
``BruteForce-HammingLUT``
``BruteForce-Hamming(2)``
*
``FlannBased``
@ -256,102 +256,22 @@ Creates a descriptor matcher of a given type with the default parameters (using
BruteForceMatcher
BFMatcher
-----------------
.. ocv:class:: BruteForceMatcher
.. ocv:class::BFMatcher
Brute-force descriptor matcher. For each descriptor in the first set, this matcher finds the closest descriptor in the second set by trying each one. This descriptor matcher supports masking permissible matches of descriptor sets. ::
template<class Distance>
class BruteForceMatcher : public DescriptorMatcher
{
public:
BruteForceMatcher( Distance d = Distance() );
virtual ~BruteForceMatcher();
virtual bool isMaskSupported() const;
virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
...
}
BFMatcher::BFMatcher
--------------------
Brute-force matcher constructor.
For efficiency, ``BruteForceMatcher`` is used as a template parameterized with the distance type. For float descriptors, ``L2<float>`` is a common choice. The following distances are supported: ::
.. ocv:function:: BFMatcher::BFMatcher( int distanceType, bool crossCheck=false )
template<typename T>
struct Accumulator
{
typedef T Type;
};
template<> struct Accumulator<unsigned char> { typedef unsigned int Type; };
template<> struct Accumulator<unsigned short> { typedef unsigned int Type; };
template<> struct Accumulator<char> { typedef int Type; };
template<> struct Accumulator<short> { typedef int Type; };
/*
* Euclidean distance functor
*/
template<class T>
struct L2
{
typedef T ValueType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const;
};
:param distanceType: One of ``NORM_L1``, ``NORM_L2``, ``NORM_HAMMING``, ``NORM_HAMMING2``. ``L1`` and ``L2`` norms are preferable choices for SIFT and SURF descriptors, ``NORM_HAMMING`` should be used with ORB and BRIEF, ``NORM_HAMMING2`` should be used with ORB when ``WTA_K==3`` or ``4`` (see ORB::ORB constructor description).
/*
* Squared Euclidean distance functor
*/
template<class T>
struct SL2
{
typedef T ValueType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const;
};
// Note: in case of SL2 distance a parameter maxDistance in the method DescriptorMatcher::radiusMatch
// is a squared maximum distance in L2.
/*
* Manhattan distance (city block distance) functor
*/
template<class T>
struct CV_EXPORTS L1
{
typedef T ValueType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const;
};
/*
* Hamming distance functor
*/
struct HammingLUT
{
typedef unsigned char ValueType;
typedef int ResultType;
ResultType operator()( const unsigned char* a, const unsigned char* b,
int size ) const;
...
};
struct Hamming
{
typedef unsigned char ValueType;
typedef int ResultType;
ResultType operator()( const unsigned char* a, const unsigned char* b,
int size ) const;
};
:param crossCheck: If it is false, this is will be default BFMatcher behaviour when it finds the k nearest neighbors for each query descriptor. If ``crossCheck==true``, then the ``knnMatch()`` method with ``k=1`` will only return pairs ``(i,j)`` such that for ``i-th`` query descriptor the ``j-th`` descriptor in the matcher's collection is the nearest and vice versa, i.e. the ``BFMathcher`` will only return consistent pairs. Such technique usually produces best results with minimal number of outliers when there are enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper.
FlannBasedMatcher

@ -140,10 +140,10 @@ The following detector types are supported:
* ``"FAST"`` -- :ocv:class:`FastFeatureDetector`
* ``"STAR"`` -- :ocv:class:`StarFeatureDetector`
* ``"SIFT"`` -- :ocv:class:`SiftFeatureDetector`
* ``"SURF"`` -- :ocv:class:`SurfFeatureDetector`
* ``"ORB"`` -- :ocv:class:`OrbFeatureDetector`
* ``"MSER"`` -- :ocv:class:`MserFeatureDetector`
* ``"SIFT"`` -- :ocv:class:`SIFT` (nonfree module)
* ``"SURF"`` -- :ocv:class:`SURF` (nonfree module)
* ``"ORB"`` -- :ocv:class:`ORB`
* ``"MSER"`` -- :ocv:class:`MSER`
* ``"GFTT"`` -- :ocv:class:`GoodFeaturesToTrackDetector`
* ``"HARRIS"`` -- :ocv:class:`GoodFeaturesToTrackDetector` with Harris detector enabled
* ``"Dense"`` -- :ocv:class:`DenseFeatureDetector`
@ -250,67 +250,6 @@ Wrapping class for feature detection using the
...
};
SiftFeatureDetector
-------------------
.. ocv:class:: SiftFeatureDetector
Wrapping class for feature detection using the
:ocv:class:`SIFT` class. ::
class SiftFeatureDetector : public FeatureDetector
{
public:
SiftFeatureDetector(
const SIFT::DetectorParams& detectorParams=SIFT::DetectorParams(),
const SIFT::CommonParams& commonParams=SIFT::CommonParams() );
SiftFeatureDetector( double threshold, double edgeThreshold,
int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
int angleMode=SIFT::CommonParams::FIRST_ANGLE );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
SurfFeatureDetector
-------------------
.. ocv:class:: SurfFeatureDetector
Wrapping class for feature detection using the
:ocv:class:`SURF` class. ::
class SurfFeatureDetector : public FeatureDetector
{
public:
SurfFeatureDetector( double hessianThreshold = 400., int octaves = 3,
int octaveLayers = 4 );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
OrbFeatureDetector
-------------------
.. ocv:class:: OrbFeatureDetector
Wrapping class for feature detection using the
:ocv:class:`ORB` class. ::
class OrbFeatureDetector : public FeatureDetector
{
public:
OrbFeatureDetector( size_t n_features );
virtual void read( const FileNode& fn );
virtual void write( FileStorage& fs ) const;
protected:
...
};
DenseFeatureDetector
--------------------
.. ocv:class:: DenseFeatureDetector
@ -605,15 +544,3 @@ StarAdjuster
StarAdjuster(double initial_thresh = 30.0);
...
};
SurfAdjuster
------------
.. ocv:class:: SurfAdjuster
:ocv:class:`AdjusterAdapter` for :ocv:class:`SurfFeatureDetector`. This class adjusts the ``hessianThreshold`` of ``SurfFeatureDetector``. ::
class SurfAdjuster: public SurfAdjuster
{
SurfAdjuster();
...
};

@ -238,122 +238,6 @@ Clones the matcher.
but with empty train data.
OneWayDescriptorMatcher
-----------------------
.. ocv:class:: OneWayDescriptorMatcher
Wrapping class for computing, matching, and classifying descriptors using the
:ocv:class:`OneWayDescriptorBase` class. ::
class OneWayDescriptorMatcher : public GenericDescriptorMatcher
{
public:
class Params
{
public:
static const int POSE_COUNT = 500;
static const int PATCH_WIDTH = 24;
static const int PATCH_HEIGHT = 24;
static float GET_MIN_SCALE() { return 0.7f; }
static float GET_MAX_SCALE() { return 1.5f; }
static float GET_STEP_SCALE() { return 1.2f; }
Params( int poseCount = POSE_COUNT,
Size patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT),
string pcaFilename = string(),
string trainPath = string(), string trainImagesList = string(),
float minScale = GET_MIN_SCALE(), float maxScale = GET_MAX_SCALE(),
float stepScale = GET_STEP_SCALE() );
int poseCount;
Size patchSize;
string pcaFilename;
string trainPath;
string trainImagesList;
float minScale, maxScale, stepScale;
};
OneWayDescriptorMatcher( const Params& params=Params() );
virtual ~OneWayDescriptorMatcher();
void initialize( const Params& params, const Ptr<OneWayDescriptorBase>& base=Ptr<OneWayDescriptorBase>() );
// Clears keypoints stored in collection and OneWayDescriptorBase
virtual void clear();
virtual void train();
virtual bool isMaskSupported();
virtual void read( const FileNode &fn );
virtual void write( FileStorage& fs ) const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
...
};
FernDescriptorMatcher
---------------------
.. ocv:class:: FernDescriptorMatcher
Wrapping class for computing, matching, and classifying descriptors using the
:ocv:class:`FernClassifier` class. ::
class FernDescriptorMatcher : public GenericDescriptorMatcher
{
public:
class Params
{
public:
Params( int nclasses=0,
int patchSize=FernClassifier::PATCH_SIZE,
int signatureSize=FernClassifier::DEFAULT_SIGNATURE_SIZE,
int nstructs=FernClassifier::DEFAULT_STRUCTS,
int structSize=FernClassifier::DEFAULT_STRUCT_SIZE,
int nviews=FernClassifier::DEFAULT_VIEWS,
int compressionMethod=FernClassifier::COMPRESSION_NONE,
const PatchGenerator& patchGenerator=PatchGenerator() );
Params( const string& filename );
int nclasses;
int patchSize;
int signatureSize;
int nstructs;
int structSize;
int nviews;
int compressionMethod;
PatchGenerator patchGenerator;
string filename;
};
FernDescriptorMatcher( const Params& params=Params() );
virtual ~FernDescriptorMatcher();
virtual void clear();
virtual void train();
virtual bool isMaskSupported();
virtual void read( const FileNode &fn );
virtual void write( FileStorage& fs ) const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
...
};
VectorDescriptorMatcher
-----------------------
.. ocv:class:: VectorDescriptorMatcher

@ -7,7 +7,7 @@ FAST
--------
Detects corners using the FAST algorithm
.. ocv:function:: void FAST( const Mat& image, vector<KeyPoint>& keypoints, int threshold, bool nonmaxSupression=true )
.. ocv:function:: void FAST( InputArray image, vector<KeyPoint>& keypoints, int threshold, bool nonmaxSupression=true )
:param image: Image where keypoints (corners) are detected.
@ -17,7 +17,9 @@ Detects corners using the FAST algorithm
:param nonmaxSupression: If it is true, non-maximum suppression is applied to detected corners (keypoints).
Detects corners using the FAST algorithm by E. Rosten (*Machine Learning for High-speed Corner Detection*, 2006).
Detects corners using the FAST algorithm by [Rosten06]_.
.. [Rosten06] E. Rosten. Machine Learning for High-speed Corner Detection, 2006.
MSER
@ -46,533 +48,51 @@ The class encapsulates all the parameters of the MSER extraction algorithm (see
http://en.wikipedia.org/wiki/Maximally_stable_extremal_regions). Also see http://opencv.willowgarage.com/wiki/documentation/cpp/features2d/MSER for useful comments and parameters description.
StarDetector
------------
.. ocv:class:: StarDetector
Class implementing the ``Star`` keypoint detector, a modified version of the ``CenSurE`` keypoint detector described in [Agrawal08]_.
.. [Agrawal08] Agrawal, M. and Konolige, K. and Blas, M.R. "CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching", ECCV08, 2008
StarDetector::StarDetector
--------------------------
The Star Detector constructor
.. ocv:function:: StarDetector::StarDetector()
.. ocv:function:: StarDetector::StarDetector(int maxSize, int responseThreshold, int lineThresholdProjected, int lineThresholdBinarized, int suppressNonmaxSize)
.. ocv:pyfunction:: cv2.StarDetector(maxSize, responseThreshold, lineThresholdProjected, lineThresholdBinarized, suppressNonmaxSize) -> <StarDetector object>
:param maxSize: maximum size of the features. The following values are supported: 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128. In the case of a different value the result is undefined.
:param responseThreshold: threshold for the approximated laplacian, used to eliminate weak features. The larger it is, the less features will be retrieved
:param lineThresholdProjected: another threshold for the laplacian to eliminate edges
:param lineThresholdBinarized: yet another threshold for the feature size to eliminate edges. The larger the 2nd threshold, the more points you get.
StarDetector::operator()
------------------------
Finds keypoints in an image
.. ocv:function:: void StarDetector::operator()(const Mat& image, vector<KeyPoint>& keypoints)
.. ocv:pyfunction:: cv2.StarDetector.detect(image) -> keypoints
.. ocv:cfunction:: CvSeq* cvGetStarKeypoints( const CvArr* image, CvMemStorage* storage, CvStarDetectorParams params=cvStarDetectorParams() )
.. ocv:pyoldfunction:: cv.GetStarKeypoints(image, storage, params)-> keypoints
:param image: The input 8-bit grayscale image
:param keypoints: The output vector of keypoints
:param storage: The memory storage used to store the keypoints (OpenCV 1.x API only)
:param params: The algorithm parameters stored in ``CvStarDetectorParams`` (OpenCV 1.x API only)
ORB
----
---
.. ocv:class:: ORB
Class for extracting ORB features and descriptors from an image. ::
class ORB
{
public:
/** The patch sizes that can be used (only one right now) */
struct CommonParams
{
enum { DEFAULT_N_LEVELS = 3, DEFAULT_FIRST_LEVEL = 0};
/** default constructor */
CommonParams(float scale_factor = 1.2f, unsigned int n_levels = DEFAULT_N_LEVELS,
int edge_threshold = 31, unsigned int first_level = DEFAULT_FIRST_LEVEL);
void read(const FileNode& fn);
void write(FileStorage& fs) const;
/** Coefficient by which we divide the dimensions from one scale pyramid level to the next */
float scale_factor_;
/** The number of levels in the scale pyramid */
unsigned int n_levels_;
/** The level at which the image is given
* if 1, that means we will also look at the image scale_factor_ times bigger
*/
unsigned int first_level_;
/** How far from the boundary the points should be */
int edge_threshold_;
};
// constructor that initializes all the algorithm parameters
// n_features is the number of desired features
ORB(size_t n_features = 500, const CommonParams & detector_params = CommonParams());
// returns the number of elements in each descriptor (32 bytes)
int descriptorSize() const;
// detects keypoints using ORB
void operator()(const Mat& img, const Mat& mask,
vector<KeyPoint>& keypoints) const;
// detects ORB keypoints and computes the ORB descriptors for them;
// output vector "descriptors" stores elements of descriptors and has size
// equal descriptorSize()*keypoints.size() as each descriptor is
// descriptorSize() elements of this vector.
void operator()(const Mat& img, const Mat& mask,
vector<KeyPoint>& keypoints,
cv::Mat& descriptors,
bool useProvidedKeypoints=false) const;
};
The class implements ORB.
RandomizedTree
--------------
.. ocv:class:: RandomizedTree
Class containing a base structure for ``RTreeClassifier``. ::
class CV_EXPORTS RandomizedTree
{
public:
friend class RTreeClassifier;
RandomizedTree();
~RandomizedTree();
Class implementing the ORB (*oriented BRIEF*) keypoint detector and descriptor extractor, described in [RRKB11]_. The algorithm uses FAST in pyramids to detect stable keypoints, selects the strongest features using FAST or Harris response, finds their orientation using first-order moments and computes the descriptors using BRIEF (where the coordinates of random point pairs (or k-tuples) are rotated according to the measured orientation).
void train(std::vector<BaseKeypoint> const& base_set,
RNG &rng, int depth, int views,
size_t reduced_num_dim, int num_quant_bits);
void train(std::vector<BaseKeypoint> const& base_set,
RNG &rng, PatchGenerator &make_patch, int depth,
int views, size_t reduced_num_dim, int num_quant_bits);
.. [RRKB11] Ethan Rublee, Vincent Rabaud, Kurt Konolige, Gary R. Bradski: ORB: An efficient alternative to SIFT or SURF. ICCV 2011: 2564-2571.
// next two functions are EXPERIMENTAL
//(do not use unless you know exactly what you do)
static void quantizeVector(float *vec, int dim, int N, float bnds[2],
int clamp_mode=0);
static void quantizeVector(float *src, int dim, int N, float bnds[2],
uchar *dst);
// patch_data must be a 32x32 array (no row padding)
float* getPosterior(uchar* patch_data);
const float* getPosterior(uchar* patch_data) const;
uchar* getPosterior2(uchar* patch_data);
void read(const char* file_name, int num_quant_bits);
void read(std::istream &is, int num_quant_bits);
void write(const char* file_name) const;
void write(std::ostream &os) const;
int classes() { return classes_; }
int depth() { return depth_; }
void discardFloatPosteriors() { freePosteriors(1); }
inline void applyQuantization(int num_quant_bits)
{ makePosteriors2(num_quant_bits); }
private:
int classes_;
int depth_;
int num_leaves_;
std::vector<RTreeNode> nodes_;
float **posteriors_; // 16-byte aligned posteriors
uchar **posteriors2_; // 16-byte aligned posteriors
std::vector<int> leaf_counts_;
void createNodes(int num_nodes, RNG &rng);
void allocPosteriorsAligned(int num_leaves, int num_classes);
void freePosteriors(int which);
// which: 1=posteriors_, 2=posteriors2_, 3=both
void init(int classes, int depth, RNG &rng);
void addExample(int class_id, uchar* patch_data);
void finalize(size_t reduced_num_dim, int num_quant_bits);
int getIndex(uchar* patch_data) const;
inline float* getPosteriorByIndex(int index);
inline uchar* getPosteriorByIndex2(int index);
inline const float* getPosteriorByIndex(int index) const;
void convertPosteriorsToChar();
void makePosteriors2(int num_quant_bits);
void compressLeaves(size_t reduced_num_dim);
void estimateQuantPercForPosteriors(float perc[2]);
};
RandomizedTree::train
-------------------------
Trains a randomized tree using an input set of keypoints.
ORB::ORB
--------
The ORB constructor
.. ocv:function:: void train(std::vector<BaseKeypoint> const& base_set, RNG& rng, PatchGenerator& make_patch, int depth, int views, size_t reduced_num_dim, int num_quant_bits)
.. ocv:function:: ORB::ORB()
.. ocv:function:: void train(std::vector<BaseKeypoint> const& base_set, RNG& rng, PatchGenerator& make_patch, int depth, int views, size_t reduced_num_dim, int num_quant_bits)
.. ocv:function:: ORB::ORB(int nfeatures = 500, float scaleFactor = 1.2f, int nlevels = 8, int edgeThreshold = 31, int firstLevel = 0, int WTA_K=2, int scoreType=HARRIS_SCORE, int patchSize=31)
:param base_set: Vector of the ``BaseKeypoint`` type. It contains image keypoints used for training.
:param rng: Random-number generator used for training.
:param nfeatures: The maximum number of features to retain.
:param make_patch: Patch generator used for training.
:param scaleFactor: Pyramid decimation ratio, greater than 1. ``scaleFactor==2`` means the classical pyramid, where each next level has 4x less pixels than the previous, but such a big scale factor will degrade feature matching scores dramatically. On the other hand, too close to 1 scale factor will mean that to cover certain scale range you will need more pyramid levels and so the speed will suffer.
:param depth: Maximum tree depth.
:param views: Number of random views of each keypoint neighborhood to generate.
:param reduced_num_dim: Number of dimensions used in the compressed signature.
:param nlevels: The number of pyramid levels. The smallest level will have linear size equal to ``input_image_linear_size/pow(scaleFactor, nlevels)``.
:param num_quant_bits: Number of bits used for quantization.
RandomizedTree::read
------------------------
Reads a pre-saved randomized tree from a file or stream.
.. ocv:function:: read(const char* file_name, int num_quant_bits)
.. ocv:function:: read(std::istream &is, int num_quant_bits)
:param file_name: Name of the file that contains randomized tree data.
:param is: Input stream associated with the file that contains randomized tree data.
:param num_quant_bits: Number of bits used for quantization.
RandomizedTree::write
-------------------------
Writes the current randomized tree to a file or stream.
.. ocv:function:: void write(const char* file_name) const
.. ocv:function:: void write(std::ostream &os) const
:param file_name: Name of the file where randomized tree data is stored.
:param os: Output stream associated with the file where randomized tree data is stored.
RandomizedTree::applyQuantization
-------------------------------------
.. ocv:function:: void applyQuantization(int num_quant_bits)
Applies quantization to the current randomized tree.
:param num_quant_bits: Number of bits used for quantization.
RTreeNode
---------
.. ocv:class:: RTreeNode
Class containing a base structure for ``RandomizedTree``. ::
struct RTreeNode
{
short offset1, offset2;
RTreeNode() {}
RTreeNode(uchar x1, uchar y1, uchar x2, uchar y2)
: offset1(y1*PATCH_SIZE + x1),
offset2(y2*PATCH_SIZE + x2)
{}
//! Left child on 0, right child on 1
inline bool operator() (uchar* patch_data) const
{
return patch_data[offset1] > patch_data[offset2];
}
};
RTreeClassifier
---------------
.. ocv:class:: RTreeClassifier
Class containing ``RTreeClassifier``. It represents the Calonder descriptor originally introduced by Michael Calonder. ::
class CV_EXPORTS RTreeClassifier
{
public:
static const int DEFAULT_TREES = 48;
static const size_t DEFAULT_NUM_QUANT_BITS = 4;
RTreeClassifier();
void train(std::vector<BaseKeypoint> const& base_set,
RNG &rng,
int num_trees = RTreeClassifier::DEFAULT_TREES,
int depth = DEFAULT_DEPTH,
int views = DEFAULT_VIEWS,
size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
int num_quant_bits = DEFAULT_NUM_QUANT_BITS,
bool print_status = true);
void train(std::vector<BaseKeypoint> const& base_set,
RNG &rng,
PatchGenerator &make_patch,
int num_trees = RTreeClassifier::DEFAULT_TREES,
int depth = DEFAULT_DEPTH,
int views = DEFAULT_VIEWS,
size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM,
int num_quant_bits = DEFAULT_NUM_QUANT_BITS,
bool print_status = true);
// sig must point to a memory block of at least
//classes()*sizeof(float|uchar) bytes
void getSignature(IplImage *patch, uchar *sig);
void getSignature(IplImage *patch, float *sig);
void getSparseSignature(IplImage *patch, float *sig,
float thresh);
static int countNonZeroElements(float *vec, int n, double tol=1e-10);
static inline void safeSignatureAlloc(uchar **sig, int num_sig=1,
int sig_len=176);
static inline uchar* safeSignatureAlloc(int num_sig=1,
int sig_len=176);
inline int classes() { return classes_; }
inline int original_num_classes()
{ return original_num_classes_; }
void setQuantization(int num_quant_bits);
void discardFloatPosteriors();
void read(const char* file_name);
void read(std::istream &is);
void write(const char* file_name) const;
void write(std::ostream &os) const;
std::vector<RandomizedTree> trees_;
private:
int classes_;
int num_quant_bits_;
uchar **posteriors_;
ushort *ptemp_;
int original_num_classes_;
bool keep_floats_;
};
RTreeClassifier::train
--------------------------
Trains a randomized tree classifier using an input set of keypoints.
.. ocv:function:: void train(vector<BaseKeypoint> const& base_set, RNG& rng, int num_trees = RTreeClassifier::DEFAULT_TREES, int depth = DEFAULT_DEPTH, int views = DEFAULT_VIEWS, size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM, int num_quant_bits = DEFAULT_NUM_QUANT_BITS, bool print_status = true)
.. ocv:function:: void train(vector<BaseKeypoint> const& base_set, RNG& rng, PatchGenerator& make_patch, int num_trees = RTreeClassifier::DEFAULT_TREES, int depth = DEFAULT_DEPTH, int views = DEFAULT_VIEWS, size_t reduced_num_dim = DEFAULT_REDUCED_NUM_DIM, int num_quant_bits = DEFAULT_NUM_QUANT_BITS, bool print_status = true)
:param base_set: Vector of the ``BaseKeypoint`` type. It contains image keypoints used for training.
:param edgeThreshold: This is size of the border where the features are not detected. It should roughly match the ``patchSize`` parameter.
:param rng: Random-number generator used for training.
:param firstLevel: It should be 0 in the current implementation.
:param make_patch: Patch generator used for training.
:param WTA_K: The number of points that produce each element of the oriented BRIEF descriptor. The default value 2 means the BRIEF where we take a random point pair and compare their brightnesses, so we get 0/1 response. Other possible values are 3 and 4. For example, 3 means that we take 3 random points (of course, those point coordinates are random, but they are generated from the pre-defined seed, so each element of BRIEF descriptor is computed deterministically from the pixel rectangle), find point of maximum brightness and output index of the winner (0, 1 or 2). Such output will occupy 2 bits, and therefore it will need a special variant of Hamming distance, denoted as ``NORM_HAMMING2`` (2 bits per bin). When ``WTA_K=4``, we take 4 random points to compute each bin (that will also occupy 2 bits with possible values 0, 1, 2 or 3).
:param num_trees: Number of randomized trees used in ``RTreeClassificator`` .
:param scoreType: The default HARRIS_SCORE means that Harris algorithm is used to rank features (the score is written to ``KeyPoint::score`` and is used to retain best ``nfeatures`` features); FAST_SCORE is alternative value of the parameter that produces slightly less stable keypoints, but it is a little faster to compute.
:param depth: Maximum tree depth.
:param patchSize: size of the patch used by the oriented BRIEF descriptor. Of course, on smaller pyramid layers the perceived image area covered by a feature will be larger.
:param views: Number of random views of each keypoint neighborhood to generate.
ORB::operator()
---------------
Finds keypoints in an image and computes their descriptors
.. ocv:function:: void ORB::operator()(InputArray image, InputArray mask, vector<KeyPoint>& keypoints, OutputArray descriptors, bool useProvidedKeypoints=false ) const
:param reduced_num_dim: Number of dimensions used in the compressed signature.
:param image: The input 8-bit grayscale image.
:param num_quant_bits: Number of bits used for quantization.
:param mask: The operation mask.
:param print_status: Current status of training printed on the console.
RTreeClassifier::getSignature
---------------------------------
Returns a signature for an image patch.
.. ocv:function:: void getSignature(IplImage *patch, uchar *sig)
.. ocv:function:: void getSignature(IplImage *patch, float *sig)
:param patch: Image patch to calculate the signature for.
:param sig: Output signature (array dimension is ``reduced_num_dim)`` .
RTreeClassifier::getSparseSignature
---------------------------------------
Returns a sparse signature for an image patch
.. ocv:function:: void getSparseSignature(IplImage *patch, float *sig, float thresh)
:param patch: Image patch to calculate the signature for.
:param keypoints: The output vector of keypoints.
:param sig: Output signature (array dimension is ``reduced_num_dim)`` .
:param descriptors: The output descriptors. Pass ``cv::noArray()`` if you do not need it.
:param thresh: Threshold used for compressing the signature.
Returns a signature for an image patch similarly to ``getSignature`` but uses a threshold for removing all signature elements below the threshold so that the signature is compressed.
RTreeClassifier::countNonZeroElements
-----------------------------------------
Returns the number of non-zero elements in an input array.
.. ocv:function:: static int countNonZeroElements(float *vec, int n, double tol=1e-10)
:param vec: Input vector containing float elements.
:param n: Input vector size.
:param tol: Threshold used for counting elements. All elements less than ``tol`` are considered as zero elements.
RTreeClassifier::read
-------------------------
Reads a pre-saved ``RTreeClassifier`` from a file or stream.
.. ocv:function:: read(const char* file_name)
.. ocv:function:: read(std::istream& is)
:param file_name: Name of the file that contains randomized tree data.
:param is: Input stream associated with the file that contains randomized tree data.
RTreeClassifier::write
--------------------------
Writes the current ``RTreeClassifier`` to a file or stream.
.. ocv:function:: void write(const char* file_name) const
.. ocv:function:: void write(std::ostream &os) const
:param file_name: Name of the file where randomized tree data is stored.
:param os: Output stream associated with the file where randomized tree data is stored.
RTreeClassifier::setQuantization
------------------------------------
Applies quantization to the current randomized tree.
.. ocv:function:: void setQuantization(int num_quant_bits)
:param num_quant_bits: Number of bits used for quantization.
The example below demonstrates the usage of ``RTreeClassifier`` for matching the features. The features are extracted from the test and train images with SURF. Output is
:math:`best\_corr` and
:math:`best\_corr\_idx` arrays that keep the best probabilities and corresponding features indices for every train feature. ::
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq *objectKeypoints = 0, *objectDescriptors = 0;
CvSeq *imageKeypoints = 0, *imageDescriptors = 0;
CvSURFParams params = cvSURFParams(500, 1);
cvExtractSURF( test_image, 0, &imageKeypoints, &imageDescriptors,
storage, params );
cvExtractSURF( train_image, 0, &objectKeypoints, &objectDescriptors,
storage, params );
RTreeClassifier detector;
int patch_width = PATCH_SIZE;
iint patch_height = PATCH_SIZE;
vector<BaseKeypoint> base_set;
int i=0;
CvSURFPoint* point;
for (i=0;i<(n_points > 0 ? n_points : objectKeypoints->total);i++)
{
point=(CvSURFPoint*)cvGetSeqElem(objectKeypoints,i);
base_set.push_back(
BaseKeypoint(point->pt.x,point->pt.y,train_image));
}
//Detector training
RNG rng( cvGetTickCount() );
PatchGenerator gen(0,255,2,false,0.7,1.3,-CV_PI/3,CV_PI/3,
-CV_PI/3,CV_PI/3);
printf("RTree Classifier training...n");
detector.train(base_set,rng,gen,24,DEFAULT_DEPTH,2000,
(int)base_set.size(), detector.DEFAULT_NUM_QUANT_BITS);
printf("Donen");
float* signature = new float[detector.original_num_classes()];
float* best_corr;
int* best_corr_idx;
if (imageKeypoints->total > 0)
{
best_corr = new float[imageKeypoints->total];
best_corr_idx = new int[imageKeypoints->total];
}
for(i=0; i < imageKeypoints->total; i++)
{
point=(CvSURFPoint*)cvGetSeqElem(imageKeypoints,i);
int part_idx = -1;
float prob = 0.0f;
CvRect roi = cvRect((int)(point->pt.x) - patch_width/2,
(int)(point->pt.y) - patch_height/2,
patch_width, patch_height);
cvSetImageROI(test_image, roi);
roi = cvGetImageROI(test_image);
if(roi.width != patch_width || roi.height != patch_height)
{
best_corr_idx[i] = part_idx;
best_corr[i] = prob;
}
else
{
cvSetImageROI(test_image, roi);
IplImage* roi_image =
cvCreateImage(cvSize(roi.width, roi.height),
test_image->depth, test_image->nChannels);
cvCopy(test_image,roi_image);
detector.getSignature(roi_image, signature);
for (int j = 0; j< detector.original_num_classes();j++)
{
if (prob < signature[j])
{
part_idx = j;
prob = signature[j];
}
}
best_corr_idx[i] = part_idx;
best_corr[i] = prob;
if (roi_image)
cvReleaseImage(&roi_image);
}
cvResetImageROI(test_image);
}
:param useProvidedKeypoints: If it is true, then the method will use the provided vector of keypoints instead of detecting them.
..

@ -737,9 +737,11 @@ protected:
PixelTestFn test_fn_;
};
/****************************************************************************************\
* Distance *
* Distance *
\****************************************************************************************/
template<typename T>
struct CV_EXPORTS Accumulator
{
@ -757,9 +759,10 @@ template<> struct Accumulator<short> { typedef float Type; };
template<class T>
struct CV_EXPORTS SL2
{
enum { normType = NORM_L2SQR };
typedef T ValueType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const
{
return normL2Sqr<ValueType, ResultType>(a, b, size);
@ -772,9 +775,10 @@ struct CV_EXPORTS SL2
template<class T>
struct CV_EXPORTS L2
{
enum { normType = NORM_L2 };
typedef T ValueType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const
{
return (ResultType)sqrt((double)normL2Sqr<ValueType, ResultType>(a, b, size));
@ -787,9 +791,10 @@ struct CV_EXPORTS L2
template<class T>
struct CV_EXPORTS L1
{
enum { normType = NORM_L1 };
typedef T ValueType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const
{
return normL1<ValueType, ResultType>(a, b, size);
@ -802,9 +807,10 @@ struct CV_EXPORTS L1
*/
struct CV_EXPORTS Hamming
{
enum { normType = NORM_HAMMING };
typedef unsigned char ValueType;
typedef int ResultType;
/** this will count the bits in a ^ b
*/
ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const
@ -817,6 +823,7 @@ typedef Hamming HammingLUT;
template<int cellsize> struct CV_EXPORTS HammingMultilevel
{
enum { normType = NORM_HAMMING + (cellsize>1) };
typedef unsigned char ValueType;
typedef int ResultType;
@ -824,7 +831,7 @@ template<int cellsize> struct CV_EXPORTS HammingMultilevel
{
return normHamming(a, b, size, cellsize);
}
};
};
/****************************************************************************************\
* DMatch *

@ -96,10 +96,11 @@ void DescriptorExtractor::removeBorderKeypoints( vector<KeyPoint>& keypoints,
Ptr<DescriptorExtractor> DescriptorExtractor::create(const string& descriptorExtractorType)
{
if( descriptorExtractorType.find("Opponent") == 0)
if( descriptorExtractorType.find("Opponent") == 0 )
{
size_t pos = string("Opponent").size();
return DescriptorExtractor::create(descriptorExtractorType.substr(pos));
string type = descriptorExtractorType.substr(pos);
return new OpponentColorDescriptorExtractor(DescriptorExtractor::create(type));
}
return Algorithm::create<DescriptorExtractor>("Feature2D." + descriptorExtractorType);
@ -231,9 +232,9 @@ void OpponentColorDescriptorExtractor::computeImpl( const Mat& bgrImage, vector<
cp[1] < channelKeypoints[1].size() &&
cp[2] < channelKeypoints[2].size() )
{
const int maxInitIdx = std::max( channelKeypoints[0][idxs[0][cp[0]]].class_id,
std::max( channelKeypoints[1][idxs[1][cp[1]]].class_id,
channelKeypoints[2][idxs[2][cp[2]]].class_id ) );
const int maxInitIdx = std::max( 0, std::max( channelKeypoints[0][idxs[0][cp[0]]].class_id,
std::max( channelKeypoints[1][idxs[1][cp[1]]].class_id,
channelKeypoints[2][idxs[2][cp[2]]].class_id ) ) );
while( channelKeypoints[0][idxs[0][cp[0]]].class_id < maxInitIdx && cp[0] < channelKeypoints[0].size() ) { cp[0]++; }
while( channelKeypoints[1][idxs[1][cp[1]]].class_id < maxInitIdx && cp[1] < channelKeypoints[1].size() ) { cp[1]++; }

@ -144,40 +144,6 @@ void GFTTDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, co
}
}
static Algorithm* createGFTT() { return new GFTTDetector; }
static Algorithm* createHarris()
{
GFTTDetector* d = new GFTTDetector;
d->set("useHarris", true);
return d;
}
static AlgorithmInfo gftt_info("Feature2D.GFTT", createGFTT);
static AlgorithmInfo harris_info("Feature2D.HARRIS", createHarris);
AlgorithmInfo* GFTTDetector::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
GFTTDetector obj;
gftt_info.addParam(obj, "nfeatures", obj.nfeatures);
gftt_info.addParam(obj, "qualityLevel", obj.qualityLevel);
gftt_info.addParam(obj, "minDistance", obj.minDistance);
gftt_info.addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
gftt_info.addParam(obj, "k", obj.k);
harris_info.addParam(obj, "nfeatures", obj.nfeatures);
harris_info.addParam(obj, "qualityLevel", obj.qualityLevel);
harris_info.addParam(obj, "minDistance", obj.minDistance);
harris_info.addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
harris_info.addParam(obj, "k", obj.k);
initialized = true;
}
return &gftt_info;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
@ -215,29 +181,6 @@ void DenseFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypo
KeyPointsFilter::runByPixelsMask( keypoints, mask );
}
static Algorithm* createDense() { return new DenseFeatureDetector; }
static AlgorithmInfo dense_info("Feature2D.Dense", createDense);
AlgorithmInfo* DenseFeatureDetector::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
DenseFeatureDetector obj;
dense_info.addParam(obj, "initFeatureScale", obj.initFeatureScale);
dense_info.addParam(obj, "featureScaleLevels", obj.featureScaleLevels);
dense_info.addParam(obj, "featureScaleMul", obj.featureScaleMul);
dense_info.addParam(obj, "initXyStep", obj.initXyStep);
dense_info.addParam(obj, "initImgBound", obj.initImgBound);
dense_info.addParam(obj, "varyXyStepWithScale", obj.varyXyStepWithScale);
dense_info.addParam(obj, "varyImgBoundWithScale", obj.varyImgBoundWithScale);
initialized = true;
}
return &dense_info;
}
/*
* GridAdaptedFeatureDetector
@ -359,161 +302,6 @@ void PyramidAdaptedFeatureDetector::detectImpl( const Mat& image, vector<KeyPoin
if( !mask.empty() )
KeyPointsFilter::runByPixelsMask( keypoints, mask );
}
/////////////////////// AlgorithmInfo for various detector & descriptors ////////////////////////////
/* NOTE!!!
All the AlgorithmInfo-related stuff should be in the same file as initModule_features2d().
Otherwise, linker may throw away some seemingly unused stuff.
*/
static Algorithm* createBRIEF() { return new BriefDescriptorExtractor; }
static AlgorithmInfo& brief_info()
{
static AlgorithmInfo brief_info_var("Feature2D.BRIEF", createBRIEF);
return brief_info_var;
}
static AlgorithmInfo& brief_info_auto = brief_info();
AlgorithmInfo* BriefDescriptorExtractor::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
BriefDescriptorExtractor brief;
brief_info().addParam(brief, "bytes", brief.bytes_);
initialized = true;
}
return &brief_info();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static Algorithm* createFAST() { return new FastFeatureDetector; }
static AlgorithmInfo& fast_info()
{
static AlgorithmInfo fast_info_var("Feature2D.FAST", createFAST);
return fast_info_var;
}
static AlgorithmInfo& fast_info_auto = fast_info();
AlgorithmInfo* FastFeatureDetector::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
FastFeatureDetector obj;
fast_info().addParam(obj, "threshold", obj.threshold);
fast_info().addParam(obj, "nonmaxSuppression", obj.nonmaxSuppression);
initialized = true;
}
return &fast_info();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static Algorithm* createStarDetector() { return new StarDetector; }
static AlgorithmInfo& star_info()
{
static AlgorithmInfo star_info_var("Feature2D.STAR", createStarDetector);
return star_info_var;
}
static AlgorithmInfo& star_info_auto = star_info();
AlgorithmInfo* StarDetector::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
StarDetector obj;
star_info().addParam(obj, "maxSize", obj.maxSize);
star_info().addParam(obj, "responseThreshold", obj.responseThreshold);
star_info().addParam(obj, "lineThresholdProjected", obj.lineThresholdProjected);
star_info().addParam(obj, "lineThresholdBinarized", obj.lineThresholdBinarized);
star_info().addParam(obj, "suppressNonmaxSize", obj.suppressNonmaxSize);
initialized = true;
}
return &star_info();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static Algorithm* createMSER() { return new MSER; }
static AlgorithmInfo& mser_info()
{
static AlgorithmInfo mser_info_var("Feature2D.MSER", createMSER);
return mser_info_var;
}
static AlgorithmInfo& mser_info_auto = mser_info();
AlgorithmInfo* MSER::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
MSER obj;
mser_info().addParam(obj, "delta", obj.delta);
mser_info().addParam(obj, "minArea", obj.minArea);
mser_info().addParam(obj, "maxArea", obj.maxArea);
mser_info().addParam(obj, "maxVariation", obj.maxVariation);
mser_info().addParam(obj, "minDiversity", obj.minDiversity);
mser_info().addParam(obj, "maxEvolution", obj.maxEvolution);
mser_info().addParam(obj, "areaThreshold", obj.areaThreshold);
mser_info().addParam(obj, "minMargin", obj.minMargin);
mser_info().addParam(obj, "edgeBlurSize", obj.edgeBlurSize);
initialized = true;
}
return &mser_info();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static Algorithm* createORB() { return new ORB; }
static AlgorithmInfo& orb_info()
{
static AlgorithmInfo orb_info_var("Feature2D.ORB", createORB);
return orb_info_var;
}
static AlgorithmInfo& orb_info_auto = orb_info();
AlgorithmInfo* ORB::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
ORB obj;
orb_info().addParam(obj, "nFeatures", obj.nfeatures);
orb_info().addParam(obj, "scaleFactor", obj.scaleFactor);
orb_info().addParam(obj, "nLevels", obj.nlevels);
orb_info().addParam(obj, "firstLevel", obj.firstLevel);
orb_info().addParam(obj, "edgeThreshold", obj.edgeThreshold);
orb_info().addParam(obj, "patchSize", obj.patchSize);
orb_info().addParam(obj, "WTA_K", obj.WTA_K);
orb_info().addParam(obj, "scoreType", obj.scoreType);
initialized = true;
}
return &orb_info();
}
bool initModule_features2d(void)
{
Ptr<Algorithm> brief = createBRIEF(), orb = createORB(),
star = createStarDetector(), fastd = createFAST(), mser = createMSER();
return brief->info() != 0 && orb->info() != 0 && star->info() != 0 &&
fastd->info() != 0 && mser->info() != 0;
}
}

@ -0,0 +1,263 @@
/*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.
// 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 "precomp.hpp"
namespace cv
{
/////////////////////// AlgorithmInfo for various detector & descriptors ////////////////////////////
/* NOTE!!!
All the AlgorithmInfo-related stuff should be in the same file as initModule_features2d().
Otherwise, linker may throw away some seemingly unused stuff.
*/
static Algorithm* createBRIEF() { return new BriefDescriptorExtractor; }
static AlgorithmInfo& brief_info()
{
static AlgorithmInfo brief_info_var("Feature2D.BRIEF", createBRIEF);
return brief_info_var;
}
static AlgorithmInfo& brief_info_auto = brief_info();
AlgorithmInfo* BriefDescriptorExtractor::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
BriefDescriptorExtractor brief;
brief_info().addParam(brief, "bytes", brief.bytes_);
initialized = true;
}
return &brief_info();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static Algorithm* createFAST() { return new FastFeatureDetector; }
static AlgorithmInfo& fast_info()
{
static AlgorithmInfo fast_info_var("Feature2D.FAST", createFAST);
return fast_info_var;
}
static AlgorithmInfo& fast_info_auto = fast_info();
AlgorithmInfo* FastFeatureDetector::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
FastFeatureDetector obj;
fast_info().addParam(obj, "threshold", obj.threshold);
fast_info().addParam(obj, "nonmaxSuppression", obj.nonmaxSuppression);
initialized = true;
}
return &fast_info();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static Algorithm* createStarDetector() { return new StarDetector; }
static AlgorithmInfo& star_info()
{
static AlgorithmInfo star_info_var("Feature2D.STAR", createStarDetector);
return star_info_var;
}
static AlgorithmInfo& star_info_auto = star_info();
AlgorithmInfo* StarDetector::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
StarDetector obj;
star_info().addParam(obj, "maxSize", obj.maxSize);
star_info().addParam(obj, "responseThreshold", obj.responseThreshold);
star_info().addParam(obj, "lineThresholdProjected", obj.lineThresholdProjected);
star_info().addParam(obj, "lineThresholdBinarized", obj.lineThresholdBinarized);
star_info().addParam(obj, "suppressNonmaxSize", obj.suppressNonmaxSize);
initialized = true;
}
return &star_info();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static Algorithm* createMSER() { return new MSER; }
static AlgorithmInfo& mser_info()
{
static AlgorithmInfo mser_info_var("Feature2D.MSER", createMSER);
return mser_info_var;
}
static AlgorithmInfo& mser_info_auto = mser_info();
AlgorithmInfo* MSER::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
MSER obj;
mser_info().addParam(obj, "delta", obj.delta);
mser_info().addParam(obj, "minArea", obj.minArea);
mser_info().addParam(obj, "maxArea", obj.maxArea);
mser_info().addParam(obj, "maxVariation", obj.maxVariation);
mser_info().addParam(obj, "minDiversity", obj.minDiversity);
mser_info().addParam(obj, "maxEvolution", obj.maxEvolution);
mser_info().addParam(obj, "areaThreshold", obj.areaThreshold);
mser_info().addParam(obj, "minMargin", obj.minMargin);
mser_info().addParam(obj, "edgeBlurSize", obj.edgeBlurSize);
initialized = true;
}
return &mser_info();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static Algorithm* createORB() { return new ORB; }
static AlgorithmInfo& orb_info()
{
static AlgorithmInfo orb_info_var("Feature2D.ORB", createORB);
return orb_info_var;
}
static AlgorithmInfo& orb_info_auto = orb_info();
AlgorithmInfo* ORB::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
ORB obj;
orb_info().addParam(obj, "nFeatures", obj.nfeatures);
orb_info().addParam(obj, "scaleFactor", obj.scaleFactor);
orb_info().addParam(obj, "nLevels", obj.nlevels);
orb_info().addParam(obj, "firstLevel", obj.firstLevel);
orb_info().addParam(obj, "edgeThreshold", obj.edgeThreshold);
orb_info().addParam(obj, "patchSize", obj.patchSize);
orb_info().addParam(obj, "WTA_K", obj.WTA_K);
orb_info().addParam(obj, "scoreType", obj.scoreType);
initialized = true;
}
return &orb_info();
}
static Algorithm* createGFTT() { return new GFTTDetector; }
static Algorithm* createHarris()
{
GFTTDetector* d = new GFTTDetector;
d->set("useHarris", true);
return d;
}
static AlgorithmInfo gftt_info("Feature2D.GFTT", createGFTT);
static AlgorithmInfo harris_info("Feature2D.HARRIS", createHarris);
AlgorithmInfo* GFTTDetector::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
GFTTDetector obj;
gftt_info.addParam(obj, "nfeatures", obj.nfeatures);
gftt_info.addParam(obj, "qualityLevel", obj.qualityLevel);
gftt_info.addParam(obj, "minDistance", obj.minDistance);
gftt_info.addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
gftt_info.addParam(obj, "k", obj.k);
harris_info.addParam(obj, "nfeatures", obj.nfeatures);
harris_info.addParam(obj, "qualityLevel", obj.qualityLevel);
harris_info.addParam(obj, "minDistance", obj.minDistance);
harris_info.addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
harris_info.addParam(obj, "k", obj.k);
initialized = true;
}
return &gftt_info;
}
static Algorithm* createDense() { return new DenseFeatureDetector; }
static AlgorithmInfo dense_info("Feature2D.Dense", createDense);
AlgorithmInfo* DenseFeatureDetector::info() const
{
static volatile bool initialized = false;
if( !initialized )
{
DenseFeatureDetector obj;
dense_info.addParam(obj, "initFeatureScale", obj.initFeatureScale);
dense_info.addParam(obj, "featureScaleLevels", obj.featureScaleLevels);
dense_info.addParam(obj, "featureScaleMul", obj.featureScaleMul);
dense_info.addParam(obj, "initXyStep", obj.initXyStep);
dense_info.addParam(obj, "initImgBound", obj.initImgBound);
dense_info.addParam(obj, "varyXyStepWithScale", obj.varyXyStepWithScale);
dense_info.addParam(obj, "varyImgBoundWithScale", obj.varyImgBoundWithScale);
initialized = true;
}
return &dense_info;
}
bool initModule_features2d(void)
{
Ptr<Algorithm> brief = createBRIEF(), orb = createORB(),
star = createStarDetector(), fastd = createFAST(), mser = createMSER(),
dense = createDense(), gftt = createGFTT(), harris = createHarris();
return brief->info() != 0 && orb->info() != 0 && star->info() != 0 &&
fastd->info() != 0 && mser->info() != 0 && dense->info() != 0 &&
gftt->info() != 0 && harris->info() != 0;
}
}

@ -1,122 +0,0 @@
#include "test_precomp.hpp"
#if 0
using namespace cv;
class BruteForceMatcherTest : public cvtest::BaseTest
{
public:
BruteForceMatcherTest();
protected:
void run( int );
};
struct CV_EXPORTS L2Fake : public L2<float>
{
};
BruteForceMatcherTest::BruteForceMatcherTest() : cvtest::BaseTest( "BruteForceMatcher", "BruteForceMatcher::matchImpl")
{
support_testing_modes = cvtest::TS::TIMING_MODE;
}
void BruteForceMatcherTest::run( int )
{
const int dimensions = 64;
const int descriptorsNumber = 5000;
Mat train = Mat( descriptorsNumber, dimensions, CV_32FC1);
Mat query = Mat( descriptorsNumber, dimensions, CV_32FC1);
Mat permutation( 1, descriptorsNumber, CV_32SC1 );
for( int i=0;i<descriptorsNumber;i++ )
permutation.at<int>( 0, i ) = i;
//RNG rng = RNG( cvGetTickCount() );
RNG rng = RNG( *ts->get_rng() );
randShuffle( permutation, 1, &rng );
float boundary = 500.f;
for( int row=0;row<descriptorsNumber;row++ )
{
for( int col=0;col<dimensions;col++ )
{
int bit = rng( 2 );
train.at<float>( permutation.at<int>( 0, row ), col ) = bit*boundary + rng.uniform( 0.f, boundary );
query.at<float>( row, col ) = bit*boundary + rng.uniform( 0.f, boundary );
}
}
vector<DMatch> specMatches, genericMatches;
BruteForceMatcher<L2<float> > specMatcher;
BruteForceMatcher<L2Fake > genericMatcher;
int64 time0 = cvGetTickCount();
specMatcher.match( query, train, specMatches );
int64 time1 = cvGetTickCount();
genericMatcher.match( query, train, genericMatches );
int64 time2 = cvGetTickCount();
float specMatcherTime = float(time1 - time0)/(float)cvGetTickFrequency();
ts->printf( cvtest::TS::LOG, "Matching by matrix multiplication time s: %f, us per pair: %f\n",
specMatcherTime*1e-6, specMatcherTime/( descriptorsNumber*descriptorsNumber ) );
float genericMatcherTime = float(time2 - time1)/(float)cvGetTickFrequency();
ts->printf( cvtest::TS::LOG, "Matching without matrix multiplication time s: %f, us per pair: %f\n",
genericMatcherTime*1e-6, genericMatcherTime/( descriptorsNumber*descriptorsNumber ) );
if( (int)specMatches.size() != descriptorsNumber || (int)genericMatches.size() != descriptorsNumber )
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
for( int i=0;i<descriptorsNumber;i++ )
{
float epsilon = 0.01f;
bool isEquiv = fabs( specMatches[i].distance - genericMatches[i].distance ) < epsilon &&
specMatches[i].queryIdx == genericMatches[i].queryIdx &&
specMatches[i].trainIdx == genericMatches[i].trainIdx;
if( !isEquiv || specMatches[i].trainIdx != permutation.at<int>( 0, i ) )
{
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
break;
}
}
//Test mask
Mat mask( query.rows, train.rows, CV_8UC1 );
rng.fill( mask, RNG::UNIFORM, 0, 2 );
time0 = cvGetTickCount();
specMatcher.match( query, train, specMatches, mask );
time1 = cvGetTickCount();
genericMatcher.match( query, train, genericMatches, mask );
time2 = cvGetTickCount();
specMatcherTime = float(time1 - time0)/(float)cvGetTickFrequency();
ts->printf( cvtest::TS::LOG, "Matching by matrix multiplication time with mask s: %f, us per pair: %f\n",
specMatcherTime*1e-6, specMatcherTime/( descriptorsNumber*descriptorsNumber ) );
genericMatcherTime = float(time2 - time1)/(float)cvGetTickFrequency();
ts->printf( cvtest::TS::LOG, "Matching without matrix multiplication time with mask s: %f, us per pair: %f\n",
genericMatcherTime*1e-6, genericMatcherTime/( descriptorsNumber*descriptorsNumber ) );
if( specMatches.size() != genericMatches.size() )
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
for( size_t i=0;i<specMatches.size();i++ )
{
//float epsilon = 1e-2;
float epsilon = 10000000;
bool isEquiv = fabs( specMatches[i].distance - genericMatches[i].distance ) < epsilon &&
specMatches[i].queryIdx == genericMatches[i].queryIdx &&
specMatches[i].trainIdx == genericMatches[i].trainIdx;
if( !isEquiv )
{
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
break;
}
}
}
BruteForceMatcherTest taBruteForceMatcherTest;
#endif

@ -1059,13 +1059,6 @@ TEST( Features2d_DescriptorExtractor_BRIEF, regression )
test.safe_run();
}
/*TEST( Features2d_DescriptorExtractor_OpponentSIFT, regression )
{
CV_DescriptorExtractorTest<L2<float> > test( "descriptor-opponent-sift", 0.18f,
DescriptorExtractor::create("OpponentSIFT"), 8.06652f );
test.safe_run();
}*/
#if CV_SSE2
TEST( Features2d_DescriptorExtractor_Calonder_uchar, regression )
{

@ -7,6 +7,11 @@ static cvflann::IndexParams& get_params(const cv::flann::IndexParams& p)
return *(cvflann::IndexParams*)(p.params);
}
cv::flann::IndexParams::~IndexParams()
{
delete &get_params(*this);
}
namespace cv
{
@ -19,11 +24,6 @@ IndexParams::IndexParams()
{
params = new ::cvflann::IndexParams();
}
IndexParams::~IndexParams()
{
delete &get_params(*this);
}
template<typename T>
T getParam(const IndexParams& _p, const std::string& key, const T& defaultVal=T())

@ -1750,6 +1750,7 @@ public:
useInitialFlow = false;
minEigThreshold = 1e-4f;
getMinEigenVals = false;
isDeviceArch11_ = !DeviceInfo().supports(FEATURE_SET_COMPUTE_12);
}
void sparse(const GpuMat& prevImg, const GpuMat& nextImg, const GpuMat& prevPts, GpuMat& nextPts,
@ -1796,6 +1797,8 @@ private:
vector<GpuMat> uPyr_;
vector<GpuMat> vPyr_;
bool isDeviceArch11_;
};
@ -1812,6 +1815,7 @@ public:
polyN = 5;
polySigma = 1.1;
flags = 0;
isDeviceArch11_ = !DeviceInfo().supports(FEATURE_SET_COMPUTE_12);
}
int numLevels;
@ -1859,6 +1863,8 @@ private:
GpuMat frames_[2];
GpuMat pyrLevel_[2], M_, bufM_, R_[2], blurredFrame_[2];
std::vector<GpuMat> pyramid0_, pyramid1_;
bool isDeviceArch11_;
};

@ -433,6 +433,25 @@ namespace cv { namespace gpu { namespace device { namespace optflow_farneback
}
void boxFilter5Gpu_CC11(const DevMem2Df src, int ksizeHalf, DevMem2Df dst, cudaStream_t stream)
{
int height = src.rows / 5;
int width = src.cols;
dim3 block(128);
dim3 grid(divUp(width, block.x), divUp(height, block.y));
int smem = (block.x + 2*ksizeHalf) * 5 * block.y * sizeof(float);
float boxAreaInv = 1.f / ((1 + 2*ksizeHalf) * (1 + 2*ksizeHalf));
boxFilter5<<<grid, block, smem, stream>>>(height, width, src, ksizeHalf, boxAreaInv, dst);
cudaSafeCall(cudaGetLastError());
if (stream == 0)
cudaSafeCall(cudaDeviceSynchronize());
}
__constant__ float c_gKer[MAX_KSIZE_HALF + 1];
template <typename Border>
@ -575,14 +594,14 @@ namespace cv { namespace gpu { namespace device { namespace optflow_farneback
}
template <typename Border>
template <typename Border, int blockDimX>
void gaussianBlur5Caller(
const DevMem2Df src, int ksizeHalf, DevMem2Df dst, cudaStream_t stream)
{
int height = src.rows / 5;
int width = src.cols;
dim3 block(256);
dim3 block(blockDimX);
dim3 grid(divUp(width, block.x), divUp(height, block.y));
int smem = (block.x + 2*ksizeHalf) * 5 * block.y * sizeof(float);
Border b(height, width);
@ -603,12 +622,26 @@ namespace cv { namespace gpu { namespace device { namespace optflow_farneback
static const caller_t callers[] =
{
gaussianBlur5Caller<BrdReflect101<float> >,
gaussianBlur5Caller<BrdReplicate<float> >,
gaussianBlur5Caller<BrdReflect101<float>,256>,
gaussianBlur5Caller<BrdReplicate<float>,256>,
};
callers[borderMode](src, ksizeHalf, dst, stream);
}
}
void gaussianBlur5Gpu_CC11(
const DevMem2Df src, int ksizeHalf, DevMem2Df dst, int borderMode, cudaStream_t stream)
{
typedef void (*caller_t)(const DevMem2Df, int, DevMem2Df, cudaStream_t);
static const caller_t callers[] =
{
gaussianBlur5Caller<BrdReflect101<float>,128>,
gaussianBlur5Caller<BrdReplicate<float>,128>,
};
callers[borderMode](src, ksizeHalf, dst, stream);
}
}}}} // namespace cv { namespace gpu { namespace device { namespace optflow_farneback

@ -181,6 +181,7 @@ namespace cv { namespace gpu { namespace device
smem3[tid] = val3;
__syncthreads();
#if __CUDA_ARCH__ > 110
if (tid < 128)
{
smem1[tid] = val1 += smem1[tid + 128];
@ -188,6 +189,7 @@ namespace cv { namespace gpu { namespace device
smem3[tid] = val3 += smem3[tid + 128];
}
__syncthreads();
#endif
if (tid < 64)
{
@ -235,12 +237,14 @@ namespace cv { namespace gpu { namespace device
smem2[tid] = val2;
__syncthreads();
#if __CUDA_ARCH__ > 110
if (tid < 128)
{
smem1[tid] = val1 += smem1[tid + 128];
smem2[tid] = val2 += smem2[tid + 128];
}
__syncthreads();
#endif
if (tid < 64)
{
@ -279,11 +283,13 @@ namespace cv { namespace gpu { namespace device
smem1[tid] = val1;
__syncthreads();
#if __CUDA_ARCH__ > 110
if (tid < 128)
{
smem1[tid] = val1 += smem1[tid + 128];
}
__syncthreads();
#endif
if (tid < 64)
{
@ -310,9 +316,15 @@ namespace cv { namespace gpu { namespace device
__global__ void lkSparse(const PtrStepb I, const PtrStepb J, const PtrStep<short> dIdx, const PtrStep<short> dIdy,
const float2* prevPts, float2* nextPts, uchar* status, float* err, const int level, const int rows, const int cols)
{
#if __CUDA_ARCH__ <= 110
__shared__ float smem1[128];
__shared__ float smem2[128];
__shared__ float smem3[128];
#else
__shared__ float smem1[256];
__shared__ float smem2[256];
__shared__ float smem3[256];
#endif
const int tid = threadIdx.y * blockDim.x + threadIdx.x;

@ -172,11 +172,11 @@ static void add(float *res, const float *rhs, const int count, cudaStream_t stre
///////////////////////////////////////////////////////////////////////////////
__global__ void scaleVector(float *d_res, const float *d_src, float scale, const int len)
{
const int pos = blockIdx.x * blockDim.x + threadIdx.x;
if (pos >= len) return;
d_res[pos] = d_src[pos] * scale;
const int pos = blockIdx.x * blockDim.x + threadIdx.x;
if (pos >= len) return;
d_res[pos] = d_src[pos] * scale;
}
///////////////////////////////////////////////////////////////////////////////
@ -191,10 +191,10 @@ __global__ void scaleVector(float *d_res, const float *d_src, float scale, const
///////////////////////////////////////////////////////////////////////////////
static void ScaleVector(float *d_res, const float *d_src, float scale, const int len, cudaStream_t stream)
{
dim3 threads(256);
dim3 blocks(iDivUp(len, threads.x));
scaleVector<<<blocks, threads, 0, stream>>>(d_res, d_src, scale, len);
dim3 threads(256);
dim3 blocks(iDivUp(len, threads.x));
scaleVector<<<blocks, threads, 0, stream>>>(d_res, d_src, scale, len);
}
const int SOR_TILE_WIDTH = 32;
@ -1128,14 +1128,14 @@ NCVStatus NCVBroxOpticalFlow(const NCVBroxOpticalFlowDescriptor desc,
ncvAssertReturnNcvStat( nppiStResize_32f_C1R (ptrU->ptr(), srcSize, kLevelStride * sizeof (float), srcROI,
ptrUNew->ptr(), dstSize, ns * sizeof (float), dstROI, 1.0f/scale_factor, 1.0f/scale_factor, nppStBicubic) );
ScaleVector(ptrUNew->ptr(), ptrUNew->ptr(), 1.0f/scale_factor, ns * nh, stream);
ScaleVector(ptrUNew->ptr(), ptrUNew->ptr(), 1.0f/scale_factor, ns * nh, stream);
ncvAssertCUDALastErrorReturn(NCV_CUDA_ERROR);
ncvAssertReturnNcvStat( nppiStResize_32f_C1R (ptrV->ptr(), srcSize, kLevelStride * sizeof (float), srcROI,
ptrVNew->ptr(), dstSize, ns * sizeof (float), dstROI, 1.0f/scale_factor, 1.0f/scale_factor, nppStBicubic) );
ScaleVector(ptrVNew->ptr(), ptrVNew->ptr(), 1.0f/scale_factor, ns * nh, stream);
ScaleVector(ptrVNew->ptr(), ptrVNew->ptr(), 1.0f/scale_factor, ns * nh, stream);
ncvAssertCUDALastErrorReturn(NCV_CUDA_ERROR);
cv::gpu::device::swap<FloatVector*>(ptrU, ptrUNew);

@ -2508,7 +2508,7 @@ __global__ void resizeBicubic(NcvSize32u srcSize,
wsum += wx;
}
}
dst[(ix + dstROI.x)+ (iy + dstROI.y) * dstStep] = sum / wsum;
dst[(ix + dstROI.x)+ (iy + dstROI.y) * dstStep] = (!wsum)? 0 : sum / wsum;
}

@ -81,6 +81,8 @@ namespace cv { namespace gpu { namespace device { namespace optflow_farneback
void boxFilter5Gpu(const DevMem2Df src, int ksizeHalf, DevMem2Df dst, cudaStream_t stream);
void boxFilter5Gpu_CC11(const DevMem2Df src, int ksizeHalf, DevMem2Df dst, cudaStream_t stream);
void setGaussianBlurKernel(const float *gKer, int ksizeHalf);
void gaussianBlurGpu(
@ -89,6 +91,9 @@ namespace cv { namespace gpu { namespace device { namespace optflow_farneback
void gaussianBlur5Gpu(
const DevMem2Df src, int ksizeHalf, DevMem2Df dst, int borderType, cudaStream_t stream);
void gaussianBlur5Gpu_CC11(
const DevMem2Df src, int ksizeHalf, DevMem2Df dst, int borderType, cudaStream_t stream);
}}}} // namespace cv { namespace gpu { namespace device { namespace optflow_farneback
@ -167,7 +172,10 @@ void cv::gpu::FarnebackOpticalFlow::updateFlow_boxFilter(
const GpuMat& R0, const GpuMat& R1, GpuMat& flowx, GpuMat &flowy,
GpuMat& M, GpuMat &bufM, int blockSize, bool updateMatrices, Stream streams[])
{
device::optflow_farneback::boxFilter5Gpu(M, blockSize/2, bufM, S(streams[0]));
if (!isDeviceArch11_)
device::optflow_farneback::boxFilter5Gpu(M, blockSize/2, bufM, S(streams[0]));
else
device::optflow_farneback::boxFilter5Gpu_CC11(M, blockSize/2, bufM, S(streams[0]));
swap(M, bufM);
for (int i = 1; i < 5; ++i)
@ -183,8 +191,12 @@ void cv::gpu::FarnebackOpticalFlow::updateFlow_gaussianBlur(
const GpuMat& R0, const GpuMat& R1, GpuMat& flowx, GpuMat& flowy,
GpuMat& M, GpuMat &bufM, int blockSize, bool updateMatrices, Stream streams[])
{
device::optflow_farneback::gaussianBlur5Gpu(
M, blockSize/2, bufM, BORDER_REPLICATE_GPU, S(streams[0]));
if (!isDeviceArch11_)
device::optflow_farneback::gaussianBlur5Gpu(
M, blockSize/2, bufM, BORDER_REPLICATE_GPU, S(streams[0]));
else
device::optflow_farneback::gaussianBlur5Gpu_CC11(
M, blockSize/2, bufM, BORDER_REPLICATE_GPU, S(streams[0]));
swap(M, bufM);
device::optflow_farneback::updateFlowGpu(M, flowx, flowy, S(streams[0]));

@ -622,6 +622,9 @@ void cv::gpu::ORB_GPU::computeDescriptors(GpuMat& descriptors)
if (keyPointsCount_[level] == 0)
continue;
if (keyPointsCount_[level] == 0)
continue;
GpuMat descRange = descriptors.rowRange(offset, offset + keyPointsCount_[level]);
if (blurForDescriptor)

@ -1,499 +1,416 @@
/*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.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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 "precomp.hpp"
namespace {
//#define DUMP
/////////////////////////////////////////////////////////////////////////////////////////////////
// BroxOpticalFlow
#define BROX_OPTICAL_FLOW_DUMP_FILE "opticalflow/brox_optical_flow.bin"
#define BROX_OPTICAL_FLOW_DUMP_FILE_CC20 "opticalflow/brox_optical_flow_cc20.bin"
struct BroxOpticalFlow : testing::TestWithParam<cv::gpu::DeviceInfo>
{
cv::gpu::DeviceInfo devInfo;
virtual void SetUp()
{
devInfo = GetParam();
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(BroxOpticalFlow, Regression)
{
cv::Mat frame0 = readImageType("opticalflow/frame0.png", CV_32FC1);
ASSERT_FALSE(frame0.empty());
cv::Mat frame1 = readImageType("opticalflow/frame1.png", CV_32FC1);
ASSERT_FALSE(frame1.empty());
cv::gpu::BroxOpticalFlow brox(0.197f /*alpha*/, 50.0f /*gamma*/, 0.8f /*scale_factor*/,
10 /*inner_iterations*/, 77 /*outer_iterations*/, 10 /*solver_iterations*/);
cv::gpu::GpuMat u;
cv::gpu::GpuMat v;
brox(loadMat(frame0), loadMat(frame1), u, v);
#ifndef DUMP
std::string fname(cvtest::TS::ptr()->get_data_path());
if (devInfo.majorVersion() >= 2)
fname += BROX_OPTICAL_FLOW_DUMP_FILE_CC20;
else
fname += BROX_OPTICAL_FLOW_DUMP_FILE;
std::ifstream f(fname.c_str(), std::ios_base::binary);
int rows, cols;
f.read((char*)&rows, sizeof(rows));
f.read((char*)&cols, sizeof(cols));
cv::Mat u_gold(rows, cols, CV_32FC1);
for (int i = 0; i < u_gold.rows; ++i)
f.read(u_gold.ptr<char>(i), u_gold.cols * sizeof(float));
cv::Mat v_gold(rows, cols, CV_32FC1);
for (int i = 0; i < v_gold.rows; ++i)
f.read(v_gold.ptr<char>(i), v_gold.cols * sizeof(float));
EXPECT_MAT_NEAR(u_gold, u, 0);
EXPECT_MAT_NEAR(v_gold, v, 0);
#else
std::string fname(cvtest::TS::ptr()->get_data_path());
if (devInfo.majorVersion() >= 2)
fname += BROX_OPTICAL_FLOW_DUMP_FILE_CC20;
else
fname += BROX_OPTICAL_FLOW_DUMP_FILE;
std::ofstream f(fname.c_str(), std::ios_base::binary);
f.write((char*)&u.rows, sizeof(u.rows));
f.write((char*)&u.cols, sizeof(u.cols));
cv::Mat h_u(u);
cv::Mat h_v(v);
for (int i = 0; i < u.rows; ++i)
f.write(h_u.ptr<char>(i), u.cols * sizeof(float));
for (int i = 0; i < v.rows; ++i)
f.write(h_v.ptr<char>(i), v.cols * sizeof(float));
#endif
}
INSTANTIATE_TEST_CASE_P(GPU_Video, BroxOpticalFlow, ALL_DEVICES);
/////////////////////////////////////////////////////////////////////////////////////////////////
// GoodFeaturesToTrack
IMPLEMENT_PARAM_CLASS(MinDistance, double)
PARAM_TEST_CASE(GoodFeaturesToTrack, cv::gpu::DeviceInfo, MinDistance)
{
cv::gpu::DeviceInfo devInfo;
double minDistance;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
minDistance = GET_PARAM(1);
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(GoodFeaturesToTrack, Accuracy)
{
cv::Mat image = readImage("opticalflow/frame0.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(image.empty());
int maxCorners = 1000;
double qualityLevel = 0.01;
cv::gpu::GoodFeaturesToTrackDetector_GPU detector(maxCorners, qualityLevel, minDistance);
if (!supportFeature(devInfo, cv::gpu::GLOBAL_ATOMICS))
{
try
{
cv::gpu::GpuMat d_pts;
detector(loadMat(image), d_pts);
}
catch (const cv::Exception& e)
{
ASSERT_EQ(CV_StsNotImplemented, e.code);
}
}
else
{
cv::gpu::GpuMat d_pts;
detector(loadMat(image), d_pts);
std::vector<cv::Point2f> pts(d_pts.cols);
cv::Mat pts_mat(1, d_pts.cols, CV_32FC2, (void*)&pts[0]);
d_pts.download(pts_mat);
std::vector<cv::Point2f> pts_gold;
cv::goodFeaturesToTrack(image, pts_gold, maxCorners, qualityLevel, minDistance);
ASSERT_EQ(pts_gold.size(), pts.size());
size_t mistmatch = 0;
for (size_t i = 0; i < pts.size(); ++i)
{
cv::Point2i a = pts_gold[i];
cv::Point2i b = pts[i];
bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1;
if (!eq)
++mistmatch;
}
double bad_ratio = static_cast<double>(mistmatch) / pts.size();
ASSERT_LE(bad_ratio, 0.01);
}
}
INSTANTIATE_TEST_CASE_P(GPU_Video, GoodFeaturesToTrack, testing::Combine(
ALL_DEVICES,
testing::Values(MinDistance(0.0), MinDistance(3.0))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// PyrLKOpticalFlow
IMPLEMENT_PARAM_CLASS(UseGray, bool)
PARAM_TEST_CASE(PyrLKOpticalFlow, cv::gpu::DeviceInfo, UseGray)
{
cv::gpu::DeviceInfo devInfo;
bool useGray;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
useGray = GET_PARAM(1);
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(PyrLKOpticalFlow, Sparse)
{
cv::Mat frame0 = readImage("opticalflow/frame0.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
ASSERT_FALSE(frame0.empty());
cv::Mat frame1 = readImage("opticalflow/frame1.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
ASSERT_FALSE(frame1.empty());
cv::Mat gray_frame;
if (useGray)
gray_frame = frame0;
else
cv::cvtColor(frame0, gray_frame, cv::COLOR_BGR2GRAY);
std::vector<cv::Point2f> pts;
cv::goodFeaturesToTrack(gray_frame, pts, 1000, 0.01, 0.0);
cv::gpu::GpuMat d_pts;
cv::Mat pts_mat(1, (int)pts.size(), CV_32FC2, (void*)&pts[0]);
d_pts.upload(pts_mat);
cv::gpu::PyrLKOpticalFlow pyrLK;
cv::gpu::GpuMat d_nextPts;
cv::gpu::GpuMat d_status;
cv::gpu::GpuMat d_err;
pyrLK.sparse(loadMat(frame0), loadMat(frame1), d_pts, d_nextPts, d_status, &d_err);
std::vector<cv::Point2f> nextPts(d_nextPts.cols);
cv::Mat nextPts_mat(1, d_nextPts.cols, CV_32FC2, (void*)&nextPts[0]);
d_nextPts.download(nextPts_mat);
std::vector<unsigned char> status(d_status.cols);
cv::Mat status_mat(1, d_status.cols, CV_8UC1, (void*)&status[0]);
d_status.download(status_mat);
std::vector<float> err(d_err.cols);
cv::Mat err_mat(1, d_err.cols, CV_32FC1, (void*)&err[0]);
d_err.download(err_mat);
std::vector<cv::Point2f> nextPts_gold;
std::vector<unsigned char> status_gold;
std::vector<float> err_gold;
cv::calcOpticalFlowPyrLK(frame0, frame1, pts, nextPts_gold, status_gold, err_gold);
ASSERT_EQ(nextPts_gold.size(), nextPts.size());
ASSERT_EQ(status_gold.size(), status.size());
ASSERT_EQ(err_gold.size(), err.size());
size_t mistmatch = 0;
for (size_t i = 0; i < nextPts.size(); ++i)
{
if (status[i] != status_gold[i])
{
++mistmatch;
continue;
}
if (status[i])
{
cv::Point2i a = nextPts[i];
cv::Point2i b = nextPts_gold[i];
bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1;
float errdiff = std::abs(err[i] - err_gold[i]);
if (!eq || errdiff > 1e-1)
++mistmatch;
}
}
double bad_ratio = static_cast<double>(mistmatch) / nextPts.size();
ASSERT_LE(bad_ratio, 0.01);
}
INSTANTIATE_TEST_CASE_P(GPU_Video, PyrLKOpticalFlow, testing::Combine(
ALL_DEVICES,
testing::Values(UseGray(true), UseGray(false))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// FarnebackOpticalFlow
IMPLEMENT_PARAM_CLASS(PyrScale, double)
IMPLEMENT_PARAM_CLASS(PolyN, int)
CV_FLAGS(FarnebackOptFlowFlags, 0, cv::OPTFLOW_FARNEBACK_GAUSSIAN)
IMPLEMENT_PARAM_CLASS(UseInitFlow, bool)
PARAM_TEST_CASE(FarnebackOpticalFlow, cv::gpu::DeviceInfo, PyrScale, PolyN, FarnebackOptFlowFlags, UseInitFlow)
{
cv::gpu::DeviceInfo devInfo;
double pyrScale;
int polyN;
int flags;
bool useInitFlow;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
pyrScale = GET_PARAM(1);
polyN = GET_PARAM(2);
flags = GET_PARAM(3);
useInitFlow = GET_PARAM(4);
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(FarnebackOpticalFlow, Accuracy)
{
cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(frame0.empty());
cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(frame1.empty());
double polySigma = polyN <= 5 ? 1.1 : 1.5;
cv::gpu::FarnebackOpticalFlow calc;
calc.pyrScale = pyrScale;
calc.polyN = polyN;
calc.polySigma = polySigma;
calc.flags = flags;
cv::gpu::GpuMat d_flowx, d_flowy;
calc(loadMat(frame0), loadMat(frame1), d_flowx, d_flowy);
cv::Mat flow;
if (useInitFlow)
{
cv::Mat flowxy[] = {cv::Mat(d_flowx), cv::Mat(d_flowy)};
cv::merge(flowxy, 2, flow);
}
if (useInitFlow)
{
calc.flags |= cv::OPTFLOW_USE_INITIAL_FLOW;
calc(loadMat(frame0), loadMat(frame1), d_flowx, d_flowy);
}
cv::calcOpticalFlowFarneback(
frame0, frame1, flow, calc.pyrScale, calc.numLevels, calc.winSize,
calc.numIters, calc.polyN, calc.polySigma, calc.flags);
std::vector<cv::Mat> flowxy;
cv::split(flow, flowxy);
EXPECT_MAT_SIMILAR(flowxy[0], d_flowx, 0.1);
EXPECT_MAT_SIMILAR(flowxy[1], d_flowy, 0.1);
}
INSTANTIATE_TEST_CASE_P(GPU_Video, FarnebackOpticalFlow, testing::Combine(
ALL_DEVICES,
testing::Values(PyrScale(0.3), PyrScale(0.5), PyrScale(0.8)),
testing::Values(PolyN(5), PolyN(7)),
testing::Values(FarnebackOptFlowFlags(0), FarnebackOptFlowFlags(cv::OPTFLOW_FARNEBACK_GAUSSIAN)),
testing::Values(UseInitFlow(false), UseInitFlow(true))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// VideoWriter
#ifdef WIN32
PARAM_TEST_CASE(VideoWriter, cv::gpu::DeviceInfo, std::string)
{
cv::gpu::DeviceInfo devInfo;
std::string inputFile;
std::string outputFile;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
inputFile = GET_PARAM(1);
cv::gpu::setDevice(devInfo.deviceID());
inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "video/" + inputFile;
outputFile = inputFile.substr(0, inputFile.find('.')) + "_test.avi";
}
};
TEST_P(VideoWriter, Regression)
{
const double FPS = 25.0;
cv::VideoCapture reader(inputFile);
ASSERT_TRUE( reader.isOpened() );
cv::gpu::VideoWriter_GPU d_writer;
cv::Mat frame;
std::vector<cv::Mat> frames;
cv::gpu::GpuMat d_frame;
for (int i = 1; i < 10; ++i)
{
reader >> frame;
if (frame.empty())
break;
frames.push_back(frame.clone());
d_frame.upload(frame);
if (!d_writer.isOpened())
d_writer.open(outputFile, frame.size(), FPS);
d_writer.write(d_frame);
}
reader.release();
d_writer.close();
reader.open(outputFile);
ASSERT_TRUE( reader.isOpened() );
for (int i = 0; i < 5; ++i)
{
reader >> frame;
ASSERT_FALSE( frame.empty() );
}
}
INSTANTIATE_TEST_CASE_P(GPU_Video, VideoWriter, testing::Combine(
ALL_DEVICES,
testing::Values(std::string("VID00003-20100701-2204.mpg"), std::string("big_buck_bunny.mpg"))));
#endif // WIN32
/////////////////////////////////////////////////////////////////////////////////////////////////
// VideoReader
PARAM_TEST_CASE(VideoReader, cv::gpu::DeviceInfo, std::string)
{
cv::gpu::DeviceInfo devInfo;
std::string inputFile;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
inputFile = GET_PARAM(1);
cv::gpu::setDevice(devInfo.deviceID());
inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "video/" + inputFile;
}
};
TEST_P(VideoReader, Regression)
{
cv::gpu::VideoReader_GPU reader(inputFile);
ASSERT_TRUE( reader.isOpened() );
cv::gpu::GpuMat frame;
for (int i = 0; i < 5; ++i)
{
ASSERT_TRUE( reader.read(frame) );
ASSERT_FALSE( frame.empty() );
}
reader.close();
ASSERT_FALSE( reader.isOpened() );
}
INSTANTIATE_TEST_CASE_P(GPU_Video, VideoReader, testing::Combine(
ALL_DEVICES,
testing::Values(std::string("VID00003-20100701-2204.mpg"))));
} // namespace
/*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.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, 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 Intel Corporation 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 "precomp.hpp"
namespace {
//#define DUMP
/////////////////////////////////////////////////////////////////////////////////////////////////
// BroxOpticalFlow
#define BROX_OPTICAL_FLOW_DUMP_FILE "opticalflow/brox_optical_flow.bin"
#define BROX_OPTICAL_FLOW_DUMP_FILE_CC20 "opticalflow/brox_optical_flow_cc20.bin"
struct BroxOpticalFlow : testing::TestWithParam<cv::gpu::DeviceInfo>
{
cv::gpu::DeviceInfo devInfo;
virtual void SetUp()
{
devInfo = GetParam();
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(BroxOpticalFlow, Regression)
{
cv::Mat frame0 = readImageType("opticalflow/frame0.png", CV_32FC1);
ASSERT_FALSE(frame0.empty());
cv::Mat frame1 = readImageType("opticalflow/frame1.png", CV_32FC1);
ASSERT_FALSE(frame1.empty());
cv::gpu::BroxOpticalFlow brox(0.197f /*alpha*/, 50.0f /*gamma*/, 0.8f /*scale_factor*/,
10 /*inner_iterations*/, 77 /*outer_iterations*/, 10 /*solver_iterations*/);
cv::gpu::GpuMat u;
cv::gpu::GpuMat v;
brox(loadMat(frame0), loadMat(frame1), u, v);
#ifndef DUMP
std::string fname(cvtest::TS::ptr()->get_data_path());
if (devInfo.majorVersion() >= 2)
fname += BROX_OPTICAL_FLOW_DUMP_FILE_CC20;
else
fname += BROX_OPTICAL_FLOW_DUMP_FILE;
std::ifstream f(fname.c_str(), std::ios_base::binary);
int rows, cols;
f.read((char*)&rows, sizeof(rows));
f.read((char*)&cols, sizeof(cols));
cv::Mat u_gold(rows, cols, CV_32FC1);
for (int i = 0; i < u_gold.rows; ++i)
f.read(u_gold.ptr<char>(i), u_gold.cols * sizeof(float));
cv::Mat v_gold(rows, cols, CV_32FC1);
for (int i = 0; i < v_gold.rows; ++i)
f.read(v_gold.ptr<char>(i), v_gold.cols * sizeof(float));
EXPECT_MAT_NEAR(u_gold, u, 0);
EXPECT_MAT_NEAR(v_gold, v, 0);
#else
std::string fname(cvtest::TS::ptr()->get_data_path());
if (devInfo.majorVersion() >= 2)
fname += BROX_OPTICAL_FLOW_DUMP_FILE_CC20;
else
fname += BROX_OPTICAL_FLOW_DUMP_FILE;
std::ofstream f(fname.c_str(), std::ios_base::binary);
f.write((char*)&u.rows, sizeof(u.rows));
f.write((char*)&u.cols, sizeof(u.cols));
cv::Mat h_u(u);
cv::Mat h_v(v);
for (int i = 0; i < u.rows; ++i)
f.write(h_u.ptr<char>(i), u.cols * sizeof(float));
for (int i = 0; i < v.rows; ++i)
f.write(h_v.ptr<char>(i), v.cols * sizeof(float));
#endif
}
INSTANTIATE_TEST_CASE_P(GPU_Video, BroxOpticalFlow, ALL_DEVICES);
/////////////////////////////////////////////////////////////////////////////////////////////////
// GoodFeaturesToTrack
IMPLEMENT_PARAM_CLASS(MinDistance, double)
PARAM_TEST_CASE(GoodFeaturesToTrack, cv::gpu::DeviceInfo, MinDistance)
{
cv::gpu::DeviceInfo devInfo;
double minDistance;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
minDistance = GET_PARAM(1);
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(GoodFeaturesToTrack, Accuracy)
{
cv::Mat image = readImage("opticalflow/frame0.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(image.empty());
int maxCorners = 1000;
double qualityLevel = 0.01;
cv::gpu::GoodFeaturesToTrackDetector_GPU detector(maxCorners, qualityLevel, minDistance);
if (!supportFeature(devInfo, cv::gpu::GLOBAL_ATOMICS))
{
try
{
cv::gpu::GpuMat d_pts;
detector(loadMat(image), d_pts);
}
catch (const cv::Exception& e)
{
ASSERT_EQ(CV_StsNotImplemented, e.code);
}
}
else
{
cv::gpu::GpuMat d_pts;
detector(loadMat(image), d_pts);
std::vector<cv::Point2f> pts(d_pts.cols);
cv::Mat pts_mat(1, d_pts.cols, CV_32FC2, (void*)&pts[0]);
d_pts.download(pts_mat);
std::vector<cv::Point2f> pts_gold;
cv::goodFeaturesToTrack(image, pts_gold, maxCorners, qualityLevel, minDistance);
ASSERT_EQ(pts_gold.size(), pts.size());
size_t mistmatch = 0;
for (size_t i = 0; i < pts.size(); ++i)
{
cv::Point2i a = pts_gold[i];
cv::Point2i b = pts[i];
bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1;
if (!eq)
++mistmatch;
}
double bad_ratio = static_cast<double>(mistmatch) / pts.size();
ASSERT_LE(bad_ratio, 0.01);
}
}
INSTANTIATE_TEST_CASE_P(GPU_Video, GoodFeaturesToTrack, testing::Combine(
ALL_DEVICES,
testing::Values(MinDistance(0.0), MinDistance(3.0))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// PyrLKOpticalFlow
IMPLEMENT_PARAM_CLASS(UseGray, bool)
PARAM_TEST_CASE(PyrLKOpticalFlow, cv::gpu::DeviceInfo, UseGray)
{
cv::gpu::DeviceInfo devInfo;
bool useGray;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
useGray = GET_PARAM(1);
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(PyrLKOpticalFlow, Sparse)
{
cv::Mat frame0 = readImage("opticalflow/frame0.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
ASSERT_FALSE(frame0.empty());
cv::Mat frame1 = readImage("opticalflow/frame1.png", useGray ? cv::IMREAD_GRAYSCALE : cv::IMREAD_COLOR);
ASSERT_FALSE(frame1.empty());
cv::Mat gray_frame;
if (useGray)
gray_frame = frame0;
else
cv::cvtColor(frame0, gray_frame, cv::COLOR_BGR2GRAY);
std::vector<cv::Point2f> pts;
cv::goodFeaturesToTrack(gray_frame, pts, 1000, 0.01, 0.0);
cv::gpu::GpuMat d_pts;
cv::Mat pts_mat(1, (int)pts.size(), CV_32FC2, (void*)&pts[0]);
d_pts.upload(pts_mat);
cv::gpu::PyrLKOpticalFlow pyrLK;
cv::gpu::GpuMat d_nextPts;
cv::gpu::GpuMat d_status;
cv::gpu::GpuMat d_err;
pyrLK.sparse(loadMat(frame0), loadMat(frame1), d_pts, d_nextPts, d_status, &d_err);
std::vector<cv::Point2f> nextPts(d_nextPts.cols);
cv::Mat nextPts_mat(1, d_nextPts.cols, CV_32FC2, (void*)&nextPts[0]);
d_nextPts.download(nextPts_mat);
std::vector<unsigned char> status(d_status.cols);
cv::Mat status_mat(1, d_status.cols, CV_8UC1, (void*)&status[0]);
d_status.download(status_mat);
std::vector<float> err(d_err.cols);
cv::Mat err_mat(1, d_err.cols, CV_32FC1, (void*)&err[0]);
d_err.download(err_mat);
std::vector<cv::Point2f> nextPts_gold;
std::vector<unsigned char> status_gold;
std::vector<float> err_gold;
cv::calcOpticalFlowPyrLK(frame0, frame1, pts, nextPts_gold, status_gold, err_gold);
ASSERT_EQ(nextPts_gold.size(), nextPts.size());
ASSERT_EQ(status_gold.size(), status.size());
ASSERT_EQ(err_gold.size(), err.size());
size_t mistmatch = 0;
for (size_t i = 0; i < nextPts.size(); ++i)
{
if (status[i] != status_gold[i])
{
++mistmatch;
continue;
}
if (status[i])
{
cv::Point2i a = nextPts[i];
cv::Point2i b = nextPts_gold[i];
bool eq = std::abs(a.x - b.x) < 1 && std::abs(a.y - b.y) < 1;
float errdiff = std::abs(err[i] - err_gold[i]);
if (!eq || errdiff > 1e-1)
++mistmatch;
}
}
double bad_ratio = static_cast<double>(mistmatch) / nextPts.size();
ASSERT_LE(bad_ratio, 0.01);
}
INSTANTIATE_TEST_CASE_P(GPU_Video, PyrLKOpticalFlow, testing::Combine(
ALL_DEVICES,
testing::Values(UseGray(true), UseGray(false))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// FarnebackOpticalFlow
IMPLEMENT_PARAM_CLASS(PyrScale, double)
IMPLEMENT_PARAM_CLASS(PolyN, int)
CV_FLAGS(FarnebackOptFlowFlags, 0, cv::OPTFLOW_FARNEBACK_GAUSSIAN)
IMPLEMENT_PARAM_CLASS(UseInitFlow, bool)
PARAM_TEST_CASE(FarnebackOpticalFlow, cv::gpu::DeviceInfo, PyrScale, PolyN, FarnebackOptFlowFlags, UseInitFlow)
{
cv::gpu::DeviceInfo devInfo;
double pyrScale;
int polyN;
int flags;
bool useInitFlow;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
pyrScale = GET_PARAM(1);
polyN = GET_PARAM(2);
flags = GET_PARAM(3);
useInitFlow = GET_PARAM(4);
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(FarnebackOpticalFlow, Accuracy)
{
cv::Mat frame0 = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(frame0.empty());
cv::Mat frame1 = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(frame1.empty());
double polySigma = polyN <= 5 ? 1.1 : 1.5;
cv::gpu::FarnebackOpticalFlow calc;
calc.pyrScale = pyrScale;
calc.polyN = polyN;
calc.polySigma = polySigma;
calc.flags = flags;
cv::gpu::GpuMat d_flowx, d_flowy;
calc(loadMat(frame0), loadMat(frame1), d_flowx, d_flowy);
cv::Mat flow;
if (useInitFlow)
{
cv::Mat flowxy[] = {cv::Mat(d_flowx), cv::Mat(d_flowy)};
cv::merge(flowxy, 2, flow);
}
if (useInitFlow)
{
calc.flags |= cv::OPTFLOW_USE_INITIAL_FLOW;
calc(loadMat(frame0), loadMat(frame1), d_flowx, d_flowy);
}
cv::calcOpticalFlowFarneback(
frame0, frame1, flow, calc.pyrScale, calc.numLevels, calc.winSize,
calc.numIters, calc.polyN, calc.polySigma, calc.flags);
std::vector<cv::Mat> flowxy;
cv::split(flow, flowxy);
EXPECT_MAT_SIMILAR(flowxy[0], d_flowx, 0.1);
EXPECT_MAT_SIMILAR(flowxy[1], d_flowy, 0.1);
};
INSTANTIATE_TEST_CASE_P(GPU_Video, FarnebackOpticalFlow, testing::Combine(
ALL_DEVICES,
testing::Values(PyrScale(0.3), PyrScale(0.5), PyrScale(0.8)),
testing::Values(PolyN(5), PolyN(7)),
testing::Values(FarnebackOptFlowFlags(0), FarnebackOptFlowFlags(cv::OPTFLOW_FARNEBACK_GAUSSIAN)),
testing::Values(UseInitFlow(false), UseInitFlow(true))));
struct OpticalFlowNan : public BroxOpticalFlow {};
TEST_P(OpticalFlowNan, Regression)
{
cv::Mat frame0 = readImageType("opticalflow/frame0.png", CV_32FC1);
ASSERT_FALSE(frame0.empty());
cv::Mat r_frame0, r_frame1;
cv::resize(frame0, r_frame0, cv::Size(1380,1000));
cv::Mat frame1 = readImageType("opticalflow/frame1.png", CV_32FC1);
ASSERT_FALSE(frame1.empty());
cv::resize(frame1, r_frame1, cv::Size(1380,1000));
cv::gpu::BroxOpticalFlow brox(0.197f /*alpha*/, 50.0f /*gamma*/, 0.8f /*scale_factor*/,
5 /*inner_iterations*/, 150 /*outer_iterations*/, 10 /*solver_iterations*/);
cv::gpu::GpuMat u;
cv::gpu::GpuMat v;
brox(loadMat(r_frame0), loadMat(r_frame1), u, v);
cv::Mat h_u, h_v;
u.download(h_u);
v.download(h_v);
EXPECT_TRUE(cv::checkRange(h_u));
EXPECT_TRUE(cv::checkRange(h_v));
};
INSTANTIATE_TEST_CASE_P(GPU_Video, OpticalFlowNan, ALL_DEVICES);
} // namespace

@ -52,11 +52,7 @@ set(grfmt_srcs src/bitstrm.cpp ${grfmt_srcs})
source_group("Src\\grfmts" FILES ${grfmt_hdrs} ${grfmt_srcs})
if(NEW_FFMPEG)
set(highgui_hdrs src/precomp.hpp src/utils.hpp src/cap_ffmpeg_impl_v2.hpp)
else()
set(highgui_hdrs src/precomp.hpp src/utils.hpp src/cap_ffmpeg_impl.hpp)
endif()
set(highgui_hdrs src/precomp.hpp src/utils.hpp src/cap_ffmpeg_impl.hpp)
set(highgui_srcs
src/cap.cpp
@ -277,28 +273,30 @@ if(WIN32 AND WITH_FFMPEG)
endif()
set(ffmpeg_bare_name "opencv_ffmpeg${FFMPEG_SUFFIX}.dll")
set(ffmpeg_bare_name_ver "opencv_ffmpeg${OPENCV_DLLVERSION}${FFMPEG_SUFFIX}.dll")
set(ffmpeg_path "${OpenCV_SOURCE_DIR}/3rdparty/ffmpeg/${ffmpeg_bare_name}")
if(CMAKE_VERSION VERSION_GREATER "2.8.2")
add_custom_command(TARGET ${the_module} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/$<CONFIGURATION>/${ffmpeg_bare_name}"
COMMENT "Copying ${ffmpeg_path} to the output directory")
elseif(MSVC_IDE)
#if(MSVC AND CMAKE_VERSION VERSION_GREATER "2.8.2")
# add_custom_command(TARGET ${the_module} POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/$<CONFIGURATION>/${ffmpeg_bare_name_ver}"
# COMMENT "Copying ${ffmpeg_path} to the output directory")
#else
if(MSVC_IDE)
add_custom_command(TARGET ${the_module} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/Release/${ffmpeg_bare_name}"
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/Debug/${ffmpeg_bare_name}"
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/Release/${ffmpeg_bare_name_ver}"
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/Debug/${ffmpeg_bare_name_ver}"
COMMENT "Copying ${ffmpeg_path} to the output directory")
elseif(MSVC)
add_custom_command(TARGET ${the_module} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_BUILD_TYPE}/${ffmpeg_bare_name}"
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_BUILD_TYPE}/${ffmpeg_bare_name_ver}"
COMMENT "Copying ${ffmpeg_path} to the output directory")
else()
add_custom_command(TARGET ${the_module} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/${ffmpeg_bare_name}"
COMMAND ${CMAKE_COMMAND} -E copy "${ffmpeg_path}" "${EXECUTABLE_OUTPUT_PATH}/${ffmpeg_bare_name_ver}"
COMMENT "Copying ${ffmpeg_path} to the output directory")
endif()
install(FILES "${ffmpeg_path}" DESTINATION bin COMPONENT main)
install(FILES "${ffmpeg_path}" DESTINATION bin COMPONENT main RENAME "${ffmpeg_bare_name_ver}")
endif()
ocv_add_accuracy_tests()

@ -300,6 +300,7 @@ enum
CV_CAP_PVAPI =800, // PvAPI, Prosilica GigE SDK
CV_CAP_OPENNI =900, // OpenNI (for Kinect)
CV_CAP_OPENNI_ASUS =910, // OpenNI (for Asus Xtion)
CV_CAP_ANDROID =1000, // Android

@ -121,13 +121,27 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
#ifdef HAVE_VIDEOINPUT
CV_CAP_DSHOW,
#endif
#if 1
CV_CAP_IEEE1394, // identical to CV_CAP_DC1394
#endif
#ifdef HAVE_TYZX
CV_CAP_STEREO,
#endif
#ifdef HAVE_PVAPI
CV_CAP_PVAPI,
#endif
#if 1
CV_CAP_VFW, // identical to CV_CAP_V4L
#endif
#ifdef HAVE_MIL
CV_CAP_MIL,
#endif
#ifdef HAVE_QUICKTIME
CV_CAP_QT,
#endif
#ifdef HAVE_UNICAP
CV_CAP_UNICAP,
#endif
#ifdef HAVE_OPENNI
CV_CAP_OPENNI,
#endif
@ -137,7 +151,9 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
#ifdef HAVE_XIMEA
CV_CAP_XIAPI,
#endif
CV_CAP_AVFOUNDATION
#ifdef HAVE_AVFOUNDATION
CV_CAP_AVFOUNDATION,
#endif
-1
};
@ -153,142 +169,159 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
// try every possibly installed camera API
for (int i = 0; domains[i] >= 0; i++)
{
#if defined(HAVE_VIDEOINPUT) || defined(HAVE_TYZX) || defined(HAVE_VFW) || \
defined(HAVE_CAMV4L) || defined (HAVE_CAMV4L2) || defined(HAVE_GSTREAMER) || \
defined(HAVE_DC1394_2) || defined(HAVE_DC1394) || defined(HAVE_CMU1394) || \
defined(HAVE_GSTREAMER) || defined(HAVE_MIL) || defined(HAVE_QUICKTIME) || \
defined(HAVE_UNICAP) || defined(HAVE_PVAPI) || defined(HAVE_OPENNI) || defined(HAVE_ANDROID_NATIVE_CAMERA) || \
defined(HAVE_AVFOUNDATION)
#if defined(HAVE_VIDEOINPUT) || \
defined(HAVE_TYZX) || \
defined(HAVE_VFW) || \
defined(HAVE_LIBV4L) || \
(defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2)) || \
defined(HAVE_GSTREAMER) || \
defined(HAVE_DC1394_2) || \
defined(HAVE_DC1394) || \
defined(HAVE_CMU1394) || \
defined(HAVE_MIL) || \
defined(HAVE_QUICKTIME) || \
defined(HAVE_UNICAP) || \
defined(HAVE_PVAPI) || \
defined(HAVE_OPENNI) || \
defined(HAVE_XIMEA) || \
defined(HAVE_AVFOUNDATION) || \
defined(HAVE_ANDROID_NATIVE_CAMERA) || \
(0)
// local variable to memorize the captured device
CvCapture *capture;
#endif
#endif
switch (domains[i])
{
#ifdef HAVE_VIDEOINPUT
#ifdef HAVE_VIDEOINPUT
case CV_CAP_DSHOW:
capture = cvCreateCameraCapture_DShow (index);
if (capture)
return capture;
break;
#endif
#endif
#ifdef HAVE_TYZX
#ifdef HAVE_TYZX
case CV_CAP_STEREO:
capture = cvCreateCameraCapture_TYZX (index);
if (capture)
return capture;
break;
#endif
#endif
case CV_CAP_VFW:
#ifdef HAVE_VFW
#ifdef HAVE_VFW
capture = cvCreateCameraCapture_VFW (index);
if (capture)
return capture;
#endif
#if defined HAVE_LIBV4L || (defined (HAVE_CAMV4L) && defined (HAVE_CAMV4L2))
#endif
#if defined HAVE_LIBV4L || (defined (HAVE_CAMV4L) && defined (HAVE_CAMV4L2))
capture = cvCreateCameraCapture_V4L (index);
if (capture)
return capture;
#endif
#ifdef HAVE_GSTREAMER
#endif
#ifdef HAVE_GSTREAMER
capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, 0);
if (capture)
return capture;
capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L, 0);
if (capture)
return capture;
#endif
break;
#endif
break; //CV_CAP_VFW
case CV_CAP_FIREWIRE:
#ifdef HAVE_DC1394_2
#ifdef HAVE_DC1394_2
capture = cvCreateCameraCapture_DC1394_2 (index);
if (capture)
return capture;
#endif
#ifdef HAVE_DC1394
#endif
#ifdef HAVE_DC1394
capture = cvCreateCameraCapture_DC1394 (index);
if (capture)
return capture;
#endif
#ifdef HAVE_CMU1394
#endif
#ifdef HAVE_CMU1394
capture = cvCreateCameraCapture_CMU (index);
if (capture)
return capture;
#endif
/* Re-enable again when gstreamer 1394 support will land in the backend code
#ifdef HAVE_GSTREAMER
#endif
#if defined(HAVE_GSTREAMER) && 0
//Re-enable again when gstreamer 1394 support will land in the backend code
capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_1394, 0);
if (capture)
return capture;
#endif
*/
break;
#ifdef HAVE_MIL
#endif
break; //CV_CAP_FIREWIRE
#ifdef HAVE_MIL
case CV_CAP_MIL:
capture = cvCreateCameraCapture_MIL (index);
if (capture)
return capture;
break;
#endif
#endif
#ifdef HAVE_QUICKTIME
#ifdef HAVE_QUICKTIME
case CV_CAP_QT:
capture = cvCreateCameraCapture_QT (index);
if (capture)
return capture;
break;
#endif
#endif
#ifdef HAVE_UNICAP
#ifdef HAVE_UNICAP
case CV_CAP_UNICAP:
capture = cvCreateCameraCapture_Unicap (index);
if (capture)
return capture;
break;
#endif
#endif
#ifdef HAVE_PVAPI
#ifdef HAVE_PVAPI
case CV_CAP_PVAPI:
capture = cvCreateCameraCapture_PvAPI (index);
if (capture)
return capture;
break;
#endif
#endif
#ifdef HAVE_OPENNI
#ifdef HAVE_OPENNI
case CV_CAP_OPENNI:
capture = cvCreateCameraCapture_OpenNI (index);
if (capture)
return capture;
break;
#endif
#endif
#ifdef HAVE_ANDROID_NATIVE_CAMERA
#ifdef HAVE_ANDROID_NATIVE_CAMERA
case CV_CAP_ANDROID:
capture = cvCreateCameraCapture_Android (index);
if (capture)
return capture;
break;
#endif
#endif
#ifdef HAVE_XIMEA
#ifdef HAVE_XIMEA
case CV_CAP_XIAPI:
capture = cvCreateCameraCapture_XIMEA (index);
if (capture)
return capture;
break;
#endif
#endif
#ifdef HAVE_AVFOUNDATION
#ifdef HAVE_AVFOUNDATION
case CV_CAP_AVFOUNDATION:
capture = cvCreateCameraCapture_AVFoundation (index);
if (capture)
return capture;
break;
#endif
#endif
}
}
@ -307,30 +340,30 @@ CV_IMPL CvCapture * cvCreateFileCapture (const char * filename)
if (! result)
result = cvCreateFileCapture_FFMPEG_proxy (filename);
#ifdef HAVE_XINE
#ifdef HAVE_XINE
if (! result)
result = cvCreateFileCapture_XINE (filename);
#endif
#endif
#ifdef HAVE_GSTREAMER
#ifdef HAVE_GSTREAMER
if (! result)
result = cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename);
#endif
#endif
#ifdef HAVE_QUICKTIME
#ifdef HAVE_QUICKTIME
if (! result)
result = cvCreateFileCapture_QT (filename);
#endif
#endif
#ifdef HAVE_AVFOUNDATION
#ifdef HAVE_AVFOUNDATION
if (! result)
result = cvCreateFileCapture_AVFoundation (filename);
#endif
#endif
#ifdef HAVE_OPENNI
#ifdef HAVE_OPENNI
if (! result)
result = cvCreateFileCapture_OpenNI (filename);
#endif
#endif
if (! result)
result = cvCreateFileCapture_Images (filename);
@ -360,19 +393,21 @@ CV_IMPL CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc,
result = cvCreateVideoWriter_XINE(filename, fourcc, fps, frameSize, is_color);
#endif
*/
#ifdef HAVE_AVFOUNDATION
#ifdef HAVE_AVFOUNDATION
if (! result)
result = cvCreateVideoWriter_AVFoundation(filename, fourcc, fps, frameSize, is_color);
#endif
#endif
#ifdef HAVE_QUICKTIME
#ifdef HAVE_QUICKTIME
if(!result)
result = cvCreateVideoWriter_QT(filename, fourcc, fps, frameSize, is_color);
#endif
#ifdef HAVE_GSTREAMER
#endif
#ifdef HAVE_GSTREAMER
if (! result)
result = cvCreateVideoWriter_GStreamer(filename, fourcc, fps, frameSize, is_color);
#endif
#endif
if(!result)
result = cvCreateVideoWriter_Images(filename);

@ -969,6 +969,8 @@ IplImage* CvCaptureFile::retrieveFramePixelBuffer() {
CVPixelBufferUnlockBaseAddress(pixels, 0);
CVBufferRelease(pixels);
CMSampleBufferInvalidate(sampleBuffer);
CFRelease(sampleBuffer);
[localpool drain];
return bgr_image;

@ -69,6 +69,7 @@ icvInitFFMPEG(void)
{
#if defined WIN32 || defined _WIN32
const char* module_name = "opencv_ffmpeg"
CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION)
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__)
"_64"
#endif

File diff suppressed because it is too large Load Diff

@ -409,10 +409,11 @@ private:
class CvCapture_OpenNI : public CvCapture
{
public:
enum { DEVICE_DEFAULT=0, DEVICE_MS_KINECT=0, DEVICE_ASUS_XTION=1, DEVICE_MAX=1 };
static const int INVALID_PIXEL_VAL = 0;
static const int INVALID_COORDINATE_VAL = 0;
#ifdef HAVE_TBB
static const int DEFAULT_MAX_BUFFER_SIZE = 8;
#else
@ -516,14 +517,25 @@ XnMapOutputMode defaultMapOutputMode()
return mode;
}
CvCapture_OpenNI::CvCapture_OpenNI( int index )
{
int deviceType = DEVICE_DEFAULT;
XnStatus status;
isContextOpened = false;
maxBufferSize = DEFAULT_MAX_BUFFER_SIZE;
isCircleBuffer = DEFAULT_IS_CIRCLE_BUFFER;
maxTimeDuration = DEFAULT_MAX_TIME_DURATION;
if( index >= 10 )
{
deviceType = index / 10;
index %= 10;
}
if( deviceType > DEVICE_MAX )
return;
// Initialize and configure the context.
status = context.Init();
@ -620,6 +632,14 @@ CvCapture_OpenNI::CvCapture_OpenNI( int index )
CV_DbgAssert( imageGenerator.SetMapOutputMode(defaultMapOutputMode()) == XN_STATUS_OK );
}
if( deviceType == DEVICE_ASUS_XTION )
{
//ps/asus specific
imageGenerator.SetIntProperty("InputFormat", 1 /*XN_IO_IMAGE_FORMAT_YUV422*/);
imageGenerator.SetPixelFormat(XN_PIXEL_FORMAT_RGB24);
depthGenerator.SetIntProperty("RegistrationType", 1 /*XN_PROCESSING_HARDWARE*/);
}
// Start generating data.
status = context.StartGeneratingAll();
if( status != XN_STATUS_OK )

@ -126,7 +126,8 @@ void CvCaptureCAM_PvAPI::close()
// Stop the acquisition & free the camera
PvCommandRun(Camera.Handle, "AcquisitionStop");
PvCaptureEnd(Camera.Handle);
PvCameraClose(Camera.Handle);
PvCameraClose(Camera.Handle);
PvUnInitialize();
}
// Initialize camera input

@ -241,7 +241,8 @@ bool PngDecoder::readData( Mat& img )
png_set_palette_to_rgb( png_ptr );
if( m_color_type == PNG_COLOR_TYPE_GRAY && m_bit_depth < 8 )
#if PNG_LIBPNG_VER_MAJOR*100 + PNG_LIBPNG_VER_MINOR >= 104
#if (PNG_LIBPNG_VER_MAJOR*10000 + PNG_LIBPNG_VER_MINOR*100 + PNG_LIBPNG_VER_RELEASE >= 10209) || \
(PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR == 0 && PNG_LIBPNG_VER_RELEASE >= 18)
png_set_expand_gray_1_2_4_to_8( png_ptr );
#else
png_set_gray_1_2_4_to_8( png_ptr );

@ -49,6 +49,8 @@
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#ifdef HAVE_QT_OPENGL

@ -406,8 +406,10 @@ int CV_DrawingTest_C::checkLineIterator( Mat& _img )
return 0;
}
TEST(Highgui_Drawing_CPP, regression) { CV_DrawingTest_CPP test; test.safe_run(); }
TEST(Highgui_Drawing_C, regression) { CV_DrawingTest_C test; test.safe_run(); }
#ifdef HAVE_JPEG
TEST(Highgui_Drawing, cpp_regression) { CV_DrawingTest_CPP test; test.safe_run(); }
TEST(Highgui_Drawing, c_regression) { CV_DrawingTest_C test; test.safe_run(); }
#endif
class CV_FillConvexPolyTest : public cvtest::BaseTest
{
@ -441,4 +443,4 @@ protected:
}
};
TEST(Highgui_Drawing_FillConvexPoly, clipping) { CV_FillConvexPolyTest test; test.safe_run(); }
TEST(Highgui_Drawing, fillconvexpoly_clipping) { CV_FillConvexPolyTest test; test.safe_run(); }

@ -1,147 +1,176 @@
/*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.
// 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"
#include "opencv2/highgui/highgui.hpp"
#ifdef HAVE_FFMPEG
#include "ffmpeg_codecs.hpp"
using namespace cv;
using namespace std;
class CV_FFmpegWriteBigVideoTest : public cvtest::BaseTest
{
public:
void run(int)
{
const int img_r = 4096;
const int img_c = 4096;
const double fps0 = 15;
const double time_sec = 1;
const size_t n = sizeof(codec_bmp_tags)/sizeof(codec_bmp_tags[0]);
bool created = false;
for (size_t j = 0; j < n; ++j)
{
stringstream s; s << codec_bmp_tags[j].tag;
int tag = codec_bmp_tags[j].tag;
if( tag != MKTAG('H', '2', '6', '3') &&
tag != MKTAG('H', '2', '6', '1') &&
tag != MKTAG('D', 'I', 'V', 'X') &&
tag != MKTAG('D', 'X', '5', '0') &&
tag != MKTAG('X', 'V', 'I', 'D') &&
tag != MKTAG('m', 'p', '4', 'v') &&
tag != MKTAG('D', 'I', 'V', '3') &&
tag != MKTAG('W', 'M', 'V', '1') &&
tag != MKTAG('W', 'M', 'V', '2') &&
tag != MKTAG('M', 'P', 'E', 'G') &&
tag != MKTAG('M', 'J', 'P', 'G') &&
tag != MKTAG('j', 'p', 'e', 'g') &&
tag != 0 &&
tag != MKTAG('I', '4', '2', '0') &&
tag != MKTAG('Y', 'U', 'Y', '2') &&
tag != MKTAG('F', 'L', 'V', '1') )
continue;
const string filename = "output_"+s.str()+".avi";
try
{
double fps = fps0;
Size frame_s = Size(img_c, img_r);
if( tag == CV_FOURCC('H', '2', '6', '1') )
frame_s = Size(352, 288);
else if( tag == CV_FOURCC('H', '2', '6', '3') )
frame_s = Size(704, 576);
/*else if( tag == CV_FOURCC('M', 'J', 'P', 'G') ||
tag == CV_FOURCC('j', 'p', 'e', 'g') )
frame_s = Size(1920, 1080);*/
if( tag == CV_FOURCC('M', 'P', 'E', 'G') )
fps = 25;
VideoWriter writer(filename, tag, fps, frame_s);
if (writer.isOpened() == false)
{
ts->printf(ts->LOG, "\n\nFile name: %s\n", filename.c_str());
ts->printf(ts->LOG, "Codec id: %d Codec tag: %c%c%c%c\n", j,
tag & 255, (tag >> 8) & 255, (tag >> 16) & 255, (tag >> 24) & 255);
ts->printf(ts->LOG, "Error: cannot create video file.");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
}
else
{
Mat img(frame_s, CV_8UC3, Scalar::all(0));
const int coeff = cvRound(cv::min(frame_s.width, frame_s.height)/(fps0 * time_sec));
for (int i = 0 ; i < static_cast<int>(fps * time_sec); i++ )
{
//circle(img, Point2i(img_c / 2, img_r / 2), cv::min(img_r, img_c) / 2 * (i + 1), Scalar(255, 0, 0, 0), 2);
rectangle(img, Point2i(coeff * i, coeff * i), Point2i(coeff * (i + 1), coeff * (i + 1)),
Scalar::all(255 * (1.0 - static_cast<double>(i) / (fps * time_sec * 2) )), -1);
writer << img;
}
if (!created) created = true;
else remove(filename.c_str());
}
}
catch(...)
{
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
}
ts->set_failed_test_info(cvtest::TS::OK);
}
}
};
TEST(Highgui_FFmpeg_WriteBigVideo, regression) { CV_FFmpegWriteBigVideoTest test; test.safe_run(); }
#endif
/*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.
// 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"
#include "opencv2/highgui/highgui.hpp"
#ifdef HAVE_FFMPEG
#include "ffmpeg_codecs.hpp"
using namespace cv;
using namespace std;
class CV_FFmpegWriteBigVideoTest : public cvtest::BaseTest
{
public:
void run(int)
{
const int img_r = 4096;
const int img_c = 4096;
const double fps0 = 15;
const double time_sec = 1;
const size_t n = sizeof(codec_bmp_tags)/sizeof(codec_bmp_tags[0]);
bool created = false;
for (size_t j = 0; j < n; ++j)
{
stringstream s; s << codec_bmp_tags[j].tag;
int tag = codec_bmp_tags[j].tag;
if( tag != MKTAG('H', '2', '6', '3') &&
tag != MKTAG('H', '2', '6', '1') &&
//tag != MKTAG('D', 'I', 'V', 'X') &&
tag != MKTAG('D', 'X', '5', '0') &&
tag != MKTAG('X', 'V', 'I', 'D') &&
tag != MKTAG('m', 'p', '4', 'v') &&
//tag != MKTAG('D', 'I', 'V', '3') &&
//tag != MKTAG('W', 'M', 'V', '1') &&
//tag != MKTAG('W', 'M', 'V', '2') &&
tag != MKTAG('M', 'P', 'E', 'G') &&
tag != MKTAG('M', 'J', 'P', 'G') &&
//tag != MKTAG('j', 'p', 'e', 'g') &&
tag != 0 &&
tag != MKTAG('I', '4', '2', '0') &&
//tag != MKTAG('Y', 'U', 'Y', '2') &&
tag != MKTAG('F', 'L', 'V', '1') )
continue;
const string filename = "output_"+s.str()+".avi";
try
{
double fps = fps0;
Size frame_s = Size(img_c, img_r);
if( tag == CV_FOURCC('H', '2', '6', '1') )
frame_s = Size(352, 288);
else if( tag == CV_FOURCC('H', '2', '6', '3') )
frame_s = Size(704, 576);
/*else if( tag == CV_FOURCC('M', 'J', 'P', 'G') ||
tag == CV_FOURCC('j', 'p', 'e', 'g') )
frame_s = Size(1920, 1080);*/
if( tag == CV_FOURCC('M', 'P', 'E', 'G') )
fps = 25;
VideoWriter writer(filename, tag, fps, frame_s);
if (writer.isOpened() == false)
{
ts->printf(ts->LOG, "\n\nFile name: %s\n", filename.c_str());
ts->printf(ts->LOG, "Codec id: %d Codec tag: %c%c%c%c\n", j,
tag & 255, (tag >> 8) & 255, (tag >> 16) & 255, (tag >> 24) & 255);
ts->printf(ts->LOG, "Error: cannot create video file.");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
}
else
{
Mat img(frame_s, CV_8UC3, Scalar::all(0));
const int coeff = cvRound(cv::min(frame_s.width, frame_s.height)/(fps0 * time_sec));
for (int i = 0 ; i < static_cast<int>(fps * time_sec); i++ )
{
//circle(img, Point2i(img_c / 2, img_r / 2), cv::min(img_r, img_c) / 2 * (i + 1), Scalar(255, 0, 0, 0), 2);
rectangle(img, Point2i(coeff * i, coeff * i), Point2i(coeff * (i + 1), coeff * (i + 1)),
Scalar::all(255 * (1.0 - static_cast<double>(i) / (fps * time_sec * 2) )), -1);
writer << img;
}
if (!created) created = true;
else remove(filename.c_str());
}
}
catch(...)
{
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
}
ts->set_failed_test_info(cvtest::TS::OK);
}
}
};
TEST(Highgui_Video, ffmpeg_writebig) { CV_FFmpegWriteBigVideoTest test; test.safe_run(); }
class CV_FFmpegReadImageTest : public cvtest::BaseTest
{
public:
void run(int)
{
try
{
string filename = ts->get_data_path() + "../cv/features2d/tsukuba.png";
VideoCapture cap(filename);
Mat img0 = imread(filename, 1);
Mat img, img_next;
cap >> img;
cap >> img_next;
CV_Assert( !img0.empty() && !img.empty() && img_next.empty() );
double diff = norm(img0, img, CV_C);
CV_Assert( diff == 0 );
}
catch(...)
{
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
}
ts->set_failed_test_info(cvtest::TS::OK);
}
};
TEST(Highgui_Video, ffmpeg_image) { CV_FFmpegReadImageTest test; test.safe_run(); }
#endif

@ -55,12 +55,9 @@ public:
void CV_FramecountTest::run(int)
{
#if defined WIN32 || (defined __linux__ && !defined ANDROID) || (defined __APPLE__ && defined HAVE_FFMPEG)
#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP
const int time_sec = 5, fps = 25;
const string ext[] = {"avi", "mov", "mp4", "mpg", "wmv"};
const string ext[] = {"avi", "mov", "mp4"};
const size_t n = sizeof(ext)/sizeof(ext[0]);
@ -68,34 +65,31 @@ void CV_FramecountTest::run(int)
ts->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str());
int failed = 0;
Ptr<CvCapture> cap;
for (size_t i = 0; i < n; ++i)
{
int code = cvtest::TS::OK;
string file_path = src_dir+"video/big_buck_bunny."+ext[i];
printf("\nReading video file in %s...\n", file_path.c_str());
CvCapture *cap = cvCreateFileCapture(file_path.c_str());
if (!cap)
cap = cvCreateFileCapture(file_path.c_str());
if (cap.empty())
{
ts->printf(cvtest::TS::LOG, "\nFile information (video %d): \n\nName: big_buck_bunny.%s\nFAILED\n\n", i+1, ext[i].c_str());
ts->printf(cvtest::TS::LOG, "Error: cannot read source video file.\n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
failed++; continue;
return;
}
cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 0);
IplImage* frame; int FrameCount = -1;
//cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 0);
IplImage* frame; int FrameCount = 0;
do
for(;;)
{
FrameCount++;
frame = cvQueryFrame(cap);
if( !frame )
break;
FrameCount++;
}
while (frame);
int framecount = (int)cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_COUNT);
@ -105,30 +99,16 @@ void CV_FramecountTest::run(int)
"Frame count returned by cvGetCaptureProperty function: %d\n",
i+1, ext[i].c_str(), time_sec*fps, FrameCount, framecount);
code = FrameCount != time_sec*fps ? cvtest::TS::FAIL_INVALID_OUTPUT : FrameCount != framecount ? cvtest::TS::FAIL_INVALID_OUTPUT : code;
if (code)
if( (FrameCount != cvRound(time_sec*fps) ||
FrameCount != framecount) && ext[i] != "mpg" )
{
ts->printf(cvtest::TS::LOG, "FAILED\n");
ts->printf(cvtest::TS::LOG, "\nError: actual frame count and returned frame count are not matched.\n");
ts->set_failed_test_info(code);
failed++;
}
else
{
ts->printf(cvtest::TS::LOG, "OK\n");
ts->set_failed_test_info(ts->OK);
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
cvReleaseImage(&frame);
cvReleaseCapture(&cap);
}
ts->printf(cvtest::TS::LOG, "\nSuccessfull experiments: %d (%d%%)\n", n-failed, (n - failed)*100/n);
ts->printf(cvtest::TS::LOG, "Failed experiments: %d (%d%%)\n", failed, failed*100/n);
#endif
#endif
}
TEST(HighguiFramecount, regression) {CV_FramecountTest test; test.safe_run();}
#if BUILD_WITH_VIDEO_INPUT_SUPPORT
TEST(Highgui_Video, framecount) {CV_FramecountTest test; test.safe_run();}
#endif

@ -201,7 +201,13 @@ public:
}
};
TEST(Highgui_Grfmt_WriteBigImage, regression) { CV_GrfmtWriteBigImageTest test; test.safe_run(); }
TEST(Highgui_Grfmt_WriteSequenceImage, regression) { CV_GrfmtWriteSequenceImageTest test; test.safe_run(); }
TEST(GrfmtReadBMPRLE8, regression) { CV_GrfmtReadBMPRLE8Test test; test.safe_run(); }
#ifdef HAVE_PNG
TEST(Highgui_Image, write_big) { CV_GrfmtWriteBigImageTest test; test.safe_run(); }
#endif
#if defined(HAVE_PNG) && defined(HAVE_TIFF) && defined(HAVE_JPEG)
TEST(Highgui_Image, write_imageseq) { CV_GrfmtWriteSequenceImageTest test; test.safe_run(); }
#endif
TEST(Highgui_Image, read_bmp_rle8) { CV_GrfmtReadBMPRLE8Test test; test.safe_run(); }

@ -47,11 +47,11 @@
using namespace cv;
using namespace std;
enum NAVIGATION_METHOD {PROGRESSIVE, RANDOM};
class CV_VideoPositioningTest: public cvtest::BaseTest
{
public:
enum {PROGRESSIVE, RANDOM};
CV_VideoPositioningTest();
~CV_VideoPositioningTest();
virtual void run(int) = 0;
@ -122,17 +122,20 @@ void CV_VideoPositioningTest::run_test(int method)
ts->printf(cvtest::TS::LOG, "\n\nSource files directory: %s\n", (src_dir+"video/").c_str());
const string ext[] = {"avi", "mp4", "wmv"};
const string ext[] = {"avi", "mov", "mp4", "mpg"};
size_t n = sizeof(ext)/sizeof(ext[0]);
int n = (int)(sizeof(ext)/sizeof(ext[0]));
int failed_videos = 0;
for (size_t i = 0; i < n; ++i)
for (int i = 0; i < n; ++i)
{
// skip random positioning test in plain mpegs
if( method == RANDOM && ext[i] == "mpg" )
continue;
string file_path = src_dir + "video/big_buck_bunny." + ext[i];
printf("\nReading video file in %s...\n", file_path.c_str());
ts->printf(cvtest::TS::LOG, "\nReading video file in %s...\n", file_path.c_str());
CvCapture* cap = cvCreateFileCapture(file_path.c_str());
@ -186,20 +189,17 @@ void CV_VideoPositioningTest::run_test(int method)
ts->printf(cvtest::TS::LOG, "Required pos: %d\nReturned pos: %d\n", idx.at(j), val);
ts->printf(cvtest::TS::LOG, "Error: required and returned positions are not matched.\n");
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
if (!flag) flag = !flag;
flag = true;
}
if (flag) failed_iterations++;
if (flag)
{
failed_iterations++;
failed_videos++;
break;
}
}
ts->printf(cvtest::TS::LOG, "\nSuccessfull iterations: %d (%d%%)\n", idx.size()-failed_iterations, 100*(idx.size()-failed_iterations)/idx.size());
ts->printf(cvtest::TS::LOG, "Failed iterations: %d (%d%%)\n", failed_iterations, 100*failed_iterations/idx.size());
if (failed_frames||failed_positions)
{
ts->printf(cvtest::TS::LOG, "\nFAILED\n----------\n"); failed_videos++;
}
cvReleaseCapture(&cap);
}
@ -209,25 +209,15 @@ void CV_VideoPositioningTest::run_test(int method)
void CV_VideoProgressivePositioningTest::run(int)
{
#if defined WIN32 || (defined __linux__ && !defined ANDROID) || (defined __APPLE__ && defined HAVE_FFMPEG)
#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP
run_test(PROGRESSIVE);
#endif
#endif
}
void CV_VideoRandomPositioningTest::run(int)
{
#if defined WIN32 || (defined __linux__ && !defined ANDROID) || (defined __APPLE__ && defined HAVE_FFMPEG)
#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP
run_test(RANDOM);
#endif
#endif
}
TEST (HighguiPositioning, progressive) { CV_VideoProgressivePositioningTest test; test.safe_run(); }
TEST (HighguiPositioning, random) { CV_VideoRandomPositioningTest test; test.safe_run(); }
#if BUILD_WITH_VIDEO_INPUT_SUPPORT
TEST (Highgui_Video, seek_progressive) { CV_VideoProgressivePositioningTest test; test.safe_run(); }
TEST (Highgui_Video, seek_random) { CV_VideoRandomPositioningTest test; test.safe_run(); }
#endif

@ -10,4 +10,70 @@
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>
#if defined(HAVE_VIDEOINPUT) || \
defined(HAVE_TYZX) || \
defined(HAVE_VFW) || \
defined(HAVE_LIBV4L) || \
(defined(HAVE_CAMV4L) && defined(HAVE_CAMV4L2)) || \
defined(HAVE_GSTREAMER) || \
defined(HAVE_DC1394_2) || \
defined(HAVE_DC1394) || \
defined(HAVE_CMU1394) || \
defined(HAVE_MIL) || \
defined(HAVE_QUICKTIME) || \
defined(HAVE_UNICAP) || \
defined(HAVE_PVAPI) || \
defined(HAVE_OPENNI) || \
defined(HAVE_XIMEA) || \
defined(HAVE_AVFOUNDATION) || \
(0)
//defined(HAVE_ANDROID_NATIVE_CAMERA) || - enable after #1193
# define BUILD_WITH_CAMERA_SUPPORT 1
#else
# define BUILD_WITH_CAMERA_SUPPORT 0
#endif
#if defined(HAVE_XINE) || \
defined(HAVE_GSTREAMER) || \
defined(HAVE_QUICKTIME) || \
defined(HAVE_AVFOUNDATION) || \
/*defined(HAVE_OPENNI) || too specialized */ \
defined(HAVE_FFMPEG) || \
defined(WIN32) /* assume that we have ffmpeg */
# define BUILD_WITH_VIDEO_INPUT_SUPPORT 1
#else
# define BUILD_WITH_VIDEO_INPUT_SUPPORT 0
#endif
#if /*defined(HAVE_XINE) || */\
defined(HAVE_GSTREAMER) || \
defined(HAVE_QUICKTIME) || \
defined(HAVE_AVFOUNDATION) || \
defined(HAVE_FFMPEG) || \
defined(WIN32) /* assume that we have ffmpeg */
# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 1
#else
# define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 0
#endif
namespace cvtest
{
string fourccToString(int fourcc);
struct VideoFormat
{
VideoFormat() { fourcc = -1; }
VideoFormat(const string& _ext, int _fourcc) : ext(_ext), fourcc(_fourcc) {}
bool empty() const { return ext.empty(); }
string ext;
int fourcc;
};
extern const VideoFormat g_specific_fmt_list[];
}
#endif

@ -46,86 +46,75 @@
using namespace cv;
using namespace std;
namespace cvtest
{
string fourccToString(int fourcc)
{
return format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255);
}
const VideoFormat g_specific_fmt_list[] =
{
VideoFormat("avi", CV_FOURCC('X', 'V', 'I', 'D')),
VideoFormat("avi", CV_FOURCC('M', 'P', 'E', 'G')),
VideoFormat("avi", CV_FOURCC('M', 'J', 'P', 'G')),
//VideoFormat("avi", CV_FOURCC('I', 'Y', 'U', 'V')),
VideoFormat("mkv", CV_FOURCC('X', 'V', 'I', 'D')),
VideoFormat("mkv", CV_FOURCC('M', 'P', 'E', 'G')),
VideoFormat("mkv", CV_FOURCC('M', 'J', 'P', 'G')),
VideoFormat("mov", CV_FOURCC('m', 'p', '4', 'v')),
VideoFormat()
};
}
class CV_HighGuiTest : public cvtest::BaseTest
{
protected:
void ImageTest(const string& dir);
void VideoTest (const string& dir, int fourcc);
void VideoTest (const string& dir, const cvtest::VideoFormat& fmt);
void SpecificImageTest (const string& dir);
void SpecificVideoFileTest (const string& dir, const char codecchars[4]);
void SpecificVideoCameraTest (const string& dir, const char codecchars[4]);
void SpecificVideoTest (const string& dir, const cvtest::VideoFormat& fmt);
public:
CV_HighGuiTest();
~CV_HighGuiTest();
CV_HighGuiTest() {}
~CV_HighGuiTest() {}
virtual void run(int) = 0;
};
class CV_ImageTest : public CV_HighGuiTest
{
public:
CV_ImageTest();
~CV_ImageTest();
CV_ImageTest() {}
~CV_ImageTest() {}
void run(int);
};
class CV_SpecificImageTest : public CV_HighGuiTest
{
public:
CV_SpecificImageTest();
~CV_SpecificImageTest();
CV_SpecificImageTest() {}
~CV_SpecificImageTest() {}
void run(int);
};
class CV_VideoTest : public CV_HighGuiTest
{
public:
CV_VideoTest();
~CV_VideoTest();
CV_VideoTest() {}
~CV_VideoTest() {}
void run(int);
};
class CV_SpecificVideoFileTest : public CV_HighGuiTest
class CV_SpecificVideoTest : public CV_HighGuiTest
{
public:
CV_SpecificVideoFileTest();
~CV_SpecificVideoFileTest();
CV_SpecificVideoTest() {}
~CV_SpecificVideoTest() {}
void run(int);
};
class CV_SpecificVideoCameraTest : public CV_HighGuiTest
{
public:
CV_SpecificVideoCameraTest();
~CV_SpecificVideoCameraTest();
void run(int);
};
CV_HighGuiTest::CV_HighGuiTest() {}
CV_HighGuiTest::~CV_HighGuiTest() {}
CV_ImageTest::CV_ImageTest() : CV_HighGuiTest() {}
CV_VideoTest::CV_VideoTest() : CV_HighGuiTest() {}
CV_SpecificImageTest::CV_SpecificImageTest() : CV_HighGuiTest() {}
CV_SpecificVideoFileTest::CV_SpecificVideoFileTest() : CV_HighGuiTest() {}
CV_SpecificVideoCameraTest::CV_SpecificVideoCameraTest() : CV_HighGuiTest() {}
CV_ImageTest::~CV_ImageTest() {}
CV_VideoTest::~CV_VideoTest() {}
CV_SpecificImageTest::~CV_SpecificImageTest() {}
CV_SpecificVideoFileTest::~CV_SpecificVideoFileTest() {}
CV_SpecificVideoCameraTest::~CV_SpecificVideoCameraTest() {}
double PSNR(const Mat& m1, const Mat& m2)
{
Mat tmp;
absdiff( m1.reshape(1), m2.reshape(1), tmp);
multiply(tmp, tmp, tmp);
double MSE = 1.0/(tmp.cols * tmp.rows) * sum(tmp)[0];
return 20 * log10(255.0 / sqrt(MSE));
}
void CV_HighGuiTest::ImageTest(const string& dir)
{
@ -141,7 +130,26 @@ void CV_HighGuiTest::ImageTest(const string& dir)
return;
}
const string exts[] = {"png", "bmp", "tiff", "jpg", "jp2", "ppm", "ras" };
const string exts[] = {
#ifdef HAVE_PNG
"png",
#endif
#ifdef HAVE_TIFF
"tiff",
#endif
#ifdef HAVE_JPEG
"jpg",
#endif
#ifdef HAVE_JASPER
"jp2",
#endif
#ifdef HAVE_OPENEXR
"exr",
#endif
"bmp",
"ppm",
"ras"
};
const size_t ext_num = sizeof(exts)/sizeof(exts[0]);
for(size_t i = 0; i < ext_num; ++i)
@ -213,12 +221,13 @@ void CV_HighGuiTest::ImageTest(const string& dir)
ts->set_failed_test_info(ts->OK);
}
void CV_HighGuiTest::VideoTest(const string& dir, int fourcc)
void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt)
{
string src_file = dir + "../cv/shared/video_for_test.avi";
string tmp_name = "video.avi";
string tmp_name = format("video_%s.%s", cvtest::fourccToString(fmt.fourcc).c_str(), fmt.ext.c_str());
ts->printf(ts->LOG, "reading video : %s\n", src_file.c_str());
ts->printf(ts->LOG, "reading video : %s and converting it to %s\n", src_file.c_str(), tmp_name.c_str());
CvCapture* cap = cvCaptureFromFile(src_file.c_str());
@ -229,6 +238,7 @@ void CV_HighGuiTest::VideoTest(const string& dir, int fourcc)
}
CvVideoWriter* writer = 0;
vector<Mat> frames;
for(;;)
{
@ -236,13 +246,16 @@ void CV_HighGuiTest::VideoTest(const string& dir, int fourcc)
if (!img)
break;
frames.push_back(Mat(img).clone());
if (writer == 0)
{
writer = cvCreateVideoWriter(tmp_name.c_str(), fourcc, 24, cvGetSize(img));
writer = cvCreateVideoWriter(tmp_name.c_str(), fmt.fourcc, 24, cvGetSize(img));
if (writer == 0)
{
ts->printf(ts->LOG, "can't create writer (with fourcc : %d)\n", fourcc);
ts->printf(ts->LOG, "can't create writer (with fourcc : %d)\n",
cvtest::fourccToString(fmt.fourcc).c_str());
cvReleaseCapture( &cap );
ts->set_failed_test_info(ts->FAIL_MISMATCH);
return;
@ -255,8 +268,6 @@ void CV_HighGuiTest::VideoTest(const string& dir, int fourcc)
cvReleaseVideoWriter( &writer );
cvReleaseCapture( &cap );
cap = cvCaptureFromFile(src_file.c_str());
CvCapture *saved = cvCaptureFromFile(tmp_name.c_str());
if (!saved)
{
@ -266,25 +277,27 @@ void CV_HighGuiTest::VideoTest(const string& dir, int fourcc)
const double thresDbell = 20;
for(;;)
for(int i = 0;; i++)
{
IplImage* ipl = cvQueryFrame( cap );
IplImage* ipl1 = cvQueryFrame( saved );
if (!ipl || !ipl1)
if (!ipl1)
break;
Mat img(ipl);
Mat img = frames[i];
Mat img1(ipl1);
if (PSNR(img1, img) < thresDbell)
double psnr = PSNR(img1, img);
if (psnr < thresDbell)
{
printf("Too low psnr = %gdb\n", psnr);
imwrite("img.png", img);
imwrite("img1.png", img1);
ts->set_failed_test_info(ts->FAIL_MISMATCH);
break;
}
}
cvReleaseCapture( &cap );
cvReleaseCapture( &saved );
ts->printf(ts->LOG, "end test function : ImagesVideo \n");
@ -306,7 +319,7 @@ void CV_HighGuiTest::SpecificImageTest(const string& dir)
return;
}
cv::resize(image, image, cv::Size(968, 757), 0.0, 0.0, cv::INTER_CUBIC);
resize(image, image, Size(968, 757), 0.0, 0.0, INTER_CUBIC);
stringstream s_digit; s_digit << i;
@ -375,247 +388,99 @@ void CV_HighGuiTest::SpecificImageTest(const string& dir)
ts->set_failed_test_info(ts->OK);
}
void CV_HighGuiTest::SpecificVideoFileTest(const string& dir, const char codecchars[4])
void CV_HighGuiTest::SpecificVideoTest(const string& dir, const cvtest::VideoFormat& fmt)
{
const string exts[] = {"avi", "mov", "mpg", "wmv"};
const size_t n = sizeof(exts)/sizeof(exts[0]);
int fourcc0 = CV_FOURCC(codecchars[0], codecchars[1], codecchars[2], codecchars[3]);
for (size_t j = 0; j < n; ++j)
{
string ext = exts[j];
int fourcc = fourcc0;
string ext = fmt.ext;
int fourcc = fmt.fourcc;
if( (ext == "mov" && fourcc != CV_FOURCC('M', 'J', 'P', 'G')) ||
(ext == "mpg" && fourcc != CV_FOURCC('m', 'p', 'e', 'g')) ||
(ext == "wmv" && fourcc != CV_FOURCC('M', 'J', 'P', 'G')))
continue;
if( ext == "mov" )
fourcc = CV_FOURCC('m', 'p', '4', 'v');
string fourcc_str = format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255);
const string video_file = "video_" + fourcc_str + "." + ext;
Size frame_size(968 & -2, 757 & -2);
//Size frame_size(968 & -16, 757 & -16);
//Size frame_size(640, 480);
VideoWriter writer(video_file, fourcc, 25, frame_size, true);
if (!writer.isOpened())
{
VideoWriter writer(video_file, fourcc, 25, frame_size, true);
ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str());
ts->printf(ts->LOG, "Cannot create VideoWriter object with codec %s.\n", fourcc_str.c_str());
ts->set_failed_test_info(ts->FAIL_MISMATCH);
continue;
}
const size_t IMAGE_COUNT = 30;
for(size_t i = 0; i < IMAGE_COUNT; ++i)
{
stringstream s_digit;
if (i < 10) {s_digit << "0"; s_digit << i;}
else s_digit << i;
const string file_path = dir+"../python/images/QCIF_"+s_digit.str()+".bmp";
cv::Mat img = imread(file_path, CV_LOAD_IMAGE_COLOR);
if (img.empty())
{
ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str());
ts->printf(ts->LOG, "Error: cannot read frame from %s.\n", (ts->get_data_path()+"../python/images/QCIF_"+s_digit.str()+".bmp").c_str());
ts->printf(ts->LOG, "Continue creating the video file...\n");
ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA);
break;//continue;
}
cv::resize(img, img, frame_size, 0.0, 0.0, cv::INTER_CUBIC);
for (int k = 0; k < img.rows; ++k)
for (int l = 0; l < img.cols; ++l)
if (img.at<Vec3b>(k, l) == Vec3b::all(0))
img.at<Vec3b>(k, l) = Vec3b(0, 255, 0);
else img.at<Vec3b>(k, l) = Vec3b(0, 0, 255);
string fourcc_str = cvtest::fourccToString(fourcc);
const string video_file = "video_" + fourcc_str + "." + ext;
imwrite("QCIF_"+s_digit.str()+".bmp", img);
Size frame_size(968 & -2, 757 & -2);
VideoWriter writer(video_file, fourcc, 25, frame_size, true);
writer << img;
}
writer.release();
cv::VideoCapture cap(video_file);
if (!writer.isOpened())
{
// call it repeatedly for easier debugging
VideoWriter writer(video_file, fourcc, 25, frame_size, true);
ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str());
ts->printf(ts->LOG, "Cannot create VideoWriter object with codec %s.\n", fourcc_str.c_str());
ts->set_failed_test_info(ts->FAIL_MISMATCH);
return;
}
size_t FRAME_COUNT = (size_t)cap.get(CV_CAP_PROP_FRAME_COUNT);
const size_t IMAGE_COUNT = 30;
vector<Mat> images;
for( size_t i = 0; i < IMAGE_COUNT; ++i )
{
string file_path = format("%s../python/images/QCIF_%02d.bmp", dir.c_str(), i);
Mat img = imread(file_path, CV_LOAD_IMAGE_COLOR);
if (FRAME_COUNT != IMAGE_COUNT && ext != "mpg" )
if (img.empty())
{
ts->printf(ts->LOG, "\nFrame count checking for video_%s.%s...\n", fourcc_str.c_str(), ext.c_str());
ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str());
ts->printf(ts->LOG, "Required frame count: %d; Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT);
ts->printf(ts->LOG, "Error: Incorrect frame count in the video.\n");
ts->printf(ts->LOG, "Continue checking...\n");
ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY);
ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str());
ts->printf(ts->LOG, "Error: cannot read frame from %s.\n", file_path.c_str());
ts->printf(ts->LOG, "Continue creating the video file...\n");
ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA);
break;
}
//cap.set(CV_CAP_PROP_POS_FRAMES, -1);
for (int i = 0; i < (int)std::min<size_t>(FRAME_COUNT, IMAGE_COUNT)-1; i++)
{
cv::Mat frame; cap >> frame;
if (frame.empty())
{
ts->printf(ts->LOG, "\nVideo file directory: %s\n", ".");
ts->printf(ts->LOG, "File name: video_%s.%s\n", fourcc_str.c_str(), ext.c_str());
ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str());
ts->printf(ts->LOG, "Error: cannot read the next frame with index %d.\n", i+1);
ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA);
break;
}
stringstream s_digit;
if (i+1 < 10) {s_digit << "0"; s_digit << i+1;}
else s_digit << i+1;
cv::Mat img = imread("QCIF_"+s_digit.str()+".bmp", CV_LOAD_IMAGE_COLOR);
if (img.empty())
{
ts->printf(ts->LOG, "\nError: cannot read an image from %s.\n", ("QCIF_"+s_digit.str()+".bmp").c_str());
ts->set_failed_test_info(ts->FAIL_MISMATCH);
continue;
}
const double thresDbell = 40;
double psnr = PSNR(img, frame);
for (int k = 0; k < img.rows; ++k)
for (int l = 0; l < img.cols; ++l)
if (img.at<Vec3b>(k, l) == Vec3b::all(0))
img.at<Vec3b>(k, l) = Vec3b(0, 255, 0);
else img.at<Vec3b>(k, l) = Vec3b(0, 0, 255);
resize(img, img, frame_size, 0.0, 0.0, INTER_CUBIC);
if (psnr > thresDbell)
{
ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", fourcc_str.c_str(), ext.c_str());
ts->printf(ts->LOG, "Frame index: %d\n", i+1);
ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr);
ts->printf(ts->LOG, "Maximum allowed difference: %g\n", thresDbell);
ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n");
break;
}
}
images.push_back(img);
writer << img;
}
}
void CV_HighGuiTest::SpecificVideoCameraTest(const string& dir, const char codecchars[4])
{
const string ext[] = {"avi", "mov", "mp4", "mpg", "wmv"};
const size_t n = sizeof(ext)/sizeof(ext[0]);
const int IMAGE_COUNT = 125;
writer.release();
VideoCapture cap(video_file);
cv::VideoCapture cap(0);
size_t FRAME_COUNT = (size_t)cap.get(CV_CAP_PROP_FRAME_COUNT);
if (!cap.isOpened())
if (FRAME_COUNT != IMAGE_COUNT )
{
ts->printf(ts->LOG, "\nError: cannot start working with device.\n");
ts->set_failed_test_info(ts->OK);
ts->printf(ts->LOG, "\nFrame count checking for video_%s.%s...\n", fourcc_str.c_str(), ext.c_str());
ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str());
ts->printf(ts->LOG, "Required frame count: %d; Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT);
ts->printf(ts->LOG, "Error: Incorrect frame count in the video.\n");
ts->printf(ts->LOG, "Continue checking...\n");
ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY);
return;
}
for (size_t i = 0; i < n; ++i)
if ((ext[i]!="mp4")||(string(&codecchars[0], 4)!="IYUV"))
#if defined WIN32 || defined _WIN32
if (((ext[i]!="mov")||(string(&codecchars[0], 4)=="XVID"))&&(ext[i]!="mp4"))
#endif
for (int i = 0; (size_t)i < FRAME_COUNT; i++)
{
Mat frame; int framecount = 0;
cv::VideoWriter writer;
std::vector <cv::Mat> tmp_img(IMAGE_COUNT);
writer.open("video_"+string(&codecchars[0], 4)+"."+ext[i], CV_FOURCC(codecchars[0], codecchars[1], codecchars[2], codecchars[3]), 25, Size(968, 757), true);
if (!writer.isOpened())
Mat frame; cap >> frame;
if (frame.empty())
{
ts->printf(ts->LOG, "\nVideo file directory: %s\n", ".");
ts->printf(ts->LOG, "Video codec: %s\n", std::string(&codecchars[0], 4).c_str());
ts->printf(ts->LOG, "Error: cannot create VideoWriter object for video_%s.%s.\n", string(&codecchars[0]).c_str(), ext[i].c_str());
ts->set_failed_test_info(ts->FAIL_EXCEPTION);
continue;
}
for (;;)
{
cap >> frame;
if (frame.empty())
{
ts->printf(ts->LOG, "\nVideo file directory: %s\n", ".");
ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str());
ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str());
ts->printf(ts->LOG, "Error: cannot read next frame with index %d from the device.\n", framecount);
break;
}
cv::resize(frame, frame, Size(968, 757), 0, 0, INTER_CUBIC);
writer << frame; tmp_img[framecount] = frame;
framecount++;
if (framecount == IMAGE_COUNT) break;
ts->printf(ts->LOG, "File name: video_%s.%s\n", fourcc_str.c_str(), ext.c_str());
ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str());
ts->printf(ts->LOG, "Error: cannot read the next frame with index %d.\n", i+1);
ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA);
break;
}
cv::VideoCapture vcap(dir+"video_"+string(&codecchars[0], 4)+"."+ext[i]);
Mat img = images[i];
if (!vcap.isOpened())
{
ts->printf(ts->LOG, "\nVideo file directory: %s\n", ".");
ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str());
ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str());
ts->printf(ts->LOG, "Error: cannot open video file.\n");
continue;
}
const double thresDbell = 40;
double psnr = PSNR(img, frame);
int FRAME_COUNT = (int)vcap.get(CV_CAP_PROP_FRAME_COUNT);
if (FRAME_COUNT != IMAGE_COUNT)
if (psnr > thresDbell)
{
ts->printf(ts->LOG, "\nChecking frame count...\n");
ts->printf(ts->LOG, "Video file directory: %s\n", ".");
ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str());
ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str());
ts->printf(ts->LOG, "Required frame count: %d Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT);
ts->printf(ts->LOG, "Error: required and returned frame count are not matched.\n");
ts->printf(ts->LOG, "Continue checking...\n");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
}
cv::Mat img; framecount = 0;
vcap.set(CV_CAP_PROP_POS_FRAMES, 0);
for ( ; framecount < std::min<int>(FRAME_COUNT, IMAGE_COUNT); framecount++ )
{
vcap >> img;
if (img.empty())
{
ts->printf(ts->LOG, "\nVideo file directory: %s\n", ".");
ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str());
ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str());
ts->printf(ts->LOG, "Error: cannot read frame with index %d from the video.\n", framecount);
break;
}
const double thresDbell = 20;
double psnr = PSNR(img, tmp_img[framecount]);
if (psnr > thresDbell)
{
ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", string(&codecchars[0], 4).c_str(), ext[i].c_str());
ts->printf(ts->LOG, "Frame index: %d\n", framecount);
ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr);
ts->printf(ts->LOG, "Maximum allowed difference: %g\n", thresDbell);
ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n");
continue;
}
ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", fourcc_str.c_str(), ext.c_str());
ts->printf(ts->LOG, "Frame index: %d\n", i+1);
ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr);
ts->printf(ts->LOG, "Maximum allowed difference: %g\n", thresDbell);
ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n");
break;
}
}
}
@ -632,71 +497,33 @@ void CV_SpecificImageTest::run(int)
void CV_VideoTest::run(int)
{
#if defined WIN32 || (defined __linux__ && !defined ANDROID) || (defined __APPLE__ && defined HAVE_FFMPEG)
#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP
const char codecs[][4] = { {'I', 'Y', 'U', 'V'},
{'X', 'V', 'I', 'D'},
{'m', 'p', 'e', 'g'},
{'M', 'J', 'P', 'G'} };
printf("%s", ts->get_data_path().c_str());
int count = sizeof(codecs)/(4*sizeof(char));
for (int i = 0; i < count; ++i)
for (int i = 0; ; ++i)
{
VideoTest(ts->get_data_path(), CV_FOURCC(codecs[i][0], codecs[i][1], codecs[i][2], codecs[i][3]));
const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[i];
if( fmt.empty() )
break;
VideoTest(ts->get_data_path(), fmt);
}
#endif
#endif
}
void CV_SpecificVideoFileTest::run(int)
void CV_SpecificVideoTest::run(int)
{
#if defined WIN32 || (defined __linux__ && !defined ANDROID) || (defined __APPLE__ && defined HAVE_FFMPEG)
#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP
const char codecs[][4] = { {'m', 'p', 'e', 'g'},
{'X', 'V', 'I', 'D'},
{'M', 'J', 'P', 'G'},
{'I', 'Y', 'U', 'V'} };
int count = sizeof(codecs)/(4*sizeof(char));
for (int i = 0; i < count; ++i)
for (int i = 0; ; ++i)
{
SpecificVideoFileTest(ts->get_data_path(), codecs[i]);
const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[i];
if( fmt.empty() )
break;
SpecificVideoTest(ts->get_data_path(), fmt);
}
#endif
#endif
}
void CV_SpecificVideoCameraTest::run(int)
{
#if defined WIN32 || (defined __linux__ && !defined ANDROID)
#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP
const char codecs[][4] = { {'m', 'p', 'e', 'g'},
{'X', 'V', 'I', 'D'},
{'M', 'J', 'P', 'G'},
{'I', 'Y', 'U', 'V'} };
int count = sizeof(codecs)/(4*sizeof(char));
for (int i = 0; i < count; ++i)
{
SpecificVideoCameraTest(ts->get_data_path(), codecs[i]);
}
#endif
#ifdef HAVE_JPEG
TEST(Highgui_Image, regression) { CV_ImageTest test; test.safe_run(); }
#endif
}
TEST(Highgui_Image, regression) { CV_ImageTest test; test.safe_run(); }
#if BUILD_WITH_VIDEO_INPUT_SUPPORT && BUILD_WITH_VIDEO_OUTPUT_SUPPORT
TEST(Highgui_Video, regression) { CV_VideoTest test; test.safe_run(); }
TEST(Highgui_SpecificImage, regression) { CV_SpecificImageTest test; test.safe_run(); }
TEST(Highgui_SpecificVideoFile, regression) { CV_SpecificVideoFileTest test; test.safe_run(); }
TEST(Highgui_SpecificVideoCamera, regression) { CV_SpecificVideoCameraTest test; test.safe_run(); }
TEST(Highgui_Video, write_read) { CV_SpecificVideoTest test; test.safe_run(); }
#endif
TEST(Highgui_Image, write_read) { CV_SpecificImageTest test; test.safe_run(); }

@ -1,229 +1,180 @@
/*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.
// 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"
#include "opencv2/highgui/highgui.hpp"
#ifdef HAVE_FFMPEG
#include "ffmpeg_codecs.hpp"
using namespace cv;
using namespace std;
class CV_PositioningTest : public cvtest::BaseTest
{
public:
void CreateTestVideo(const string& format, int codec, int framecount = 125);
void run(int);
};
void CV_PositioningTest::CreateTestVideo(const string& format, int codec, int framecount)
{
stringstream s; s << codec;
//if( format == "mov" && codec == CV_FOURCC('m', 'p', 'e', 'g')
// putchar('$');
cv::VideoWriter writer("test_video_"+s.str()+"."+format, codec, 25, cv::Size(640, 480), false);
for (int i = 0; i < framecount; ++i)
{
cv::Mat mat(480, 640, CV_8UC1);
size_t n = 8, tmp = i;
vector<char> tmp_code; tmp_code.clear();
while ( tmp > 1 )
{
tmp_code.push_back(tmp%2);
tmp /= 2;
}
tmp_code.push_back(tmp);
vector<char> i_code;
for (size_t j = 0; j < n; ++j)
{
char val = j < n - tmp_code.size() ? 0 : tmp_code.at(n-1-j);
i_code.push_back(val);
}
const size_t w = 480/n;
for (size_t j = 0; j < n; ++j)
{
cv::Scalar color = i_code[j] ? 255 : 0;
rectangle(mat, Rect(0, w*j, 640, w), color, -1);
}
writer << mat;
}
}
void CV_PositioningTest::run(int)
{
#if defined WIN32 || (defined __linux__ && !defined ANDROID) || (defined __APPLE__ && defined HAVE_FFMPEG)
#if !defined HAVE_GSTREAMER || defined HAVE_GSTREAMER_APP
const string format[] = {"avi", "mov", "mp4", "mpg", "wmv", "3gp"};
const char codec[][4] = { {'X', 'V', 'I', 'D'},
{'m', 'p', 'e', 'g'},
{'M', 'J', 'P', 'G'} };
size_t n_format = sizeof(format)/sizeof(format[0]),
n_codec = sizeof(codec)/sizeof(codec[0]);
int n_frames = 256;
for (size_t i = 0; i < n_format; ++i)
for (size_t j = 0; j < n_codec; ++j)
{
CreateTestVideo(format[i], CV_FOURCC(codec[j][0], codec[j][1], codec[j][2], codec[j][3]), n_frames);
stringstream s; s << CV_FOURCC(codec[j][0], codec[j][1], codec[j][2], codec[j][3]); //codec_bmp_tags[j].tag;
const string file_path = "test_video_"+s.str()+"."+format[i];
bool error = false; int failed = 0;
cv::VideoCapture cap(file_path);
if (!cap.isOpened())
{
ts->printf(ts->LOG, "\n\nFile: %s\n", file_path.c_str());
ts->printf(ts->LOG, "\nVideo codec: %s\n", string(&codec[j][0], 4).c_str());
ts->printf(ts->LOG, "\nError: cannot read video file.");
ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA);
error = true;
}
cap.set(CV_CAP_PROP_POS_FRAMES, 0);
int N = cap.get(CV_CAP_PROP_FRAME_COUNT);
if (N != n_frames)
{
if (!error)
{
ts->printf(ts->LOG, "\n\nFile: %s\n", file_path.c_str());
ts->printf(ts->LOG, "\nVideo codec: %s\n", string(&codec[j][0], 4).c_str());
error = true;
}
ts->printf(ts->LOG, "\nError: returned frame count in clip is incorrect.\n");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
}
vector <int> idx;
RNG rng(N);
idx.clear();
for( int k = 0; k < N-1; k++ )
idx.push_back(rng.uniform(0, N));
idx.push_back(N-1);
std::swap(idx.at(rng.uniform(0, N-1)), idx.at(N-1));
for (int k = 0; k < N; ++k)
{
cap.set(CV_CAP_PROP_POS_FRAMES, (double)idx[k]);
cv::Mat img; cap.retrieve(img);
if (img.empty())
{
if (!error)
{
ts->printf(ts->LOG, "\n\nFile: %s\n", file_path.c_str());
ts->printf(ts->LOG, "\nVideo codec: %s\n", string(&codec[j][0], 4).c_str());
error = true;
}
ts->printf(ts->LOG, "\nError: cannot read a frame in position %d.\n", idx[k]);
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
}
const double thresh = 100;
const size_t n = 8, w = img.rows/n;
int index = 0, deg = n-1;
for (size_t l = 0; l < n; ++l)
{
cv::Mat mat = img.rowRange(w*l, w*(l+1)-1);
Scalar mat_mean = cv::mean(mat);
if (mat_mean[0] > thresh) index += (int)std::pow(2.0, 1.0*deg);
deg--;
}
if (index != idx[k])
{
if (!error)
{
ts->printf(ts->LOG, "\n\nFile: %s\n", file_path.c_str());
ts->printf(ts->LOG, "\nVideo codec: %s\n\n", string(&codec[j][0], 4).c_str());
error = true;
}
ts->printf(ts->LOG, "Required position: %d Returned position: %d\n", idx[k], index);
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
failed++;
}
}
if (!error) { ts->printf(ts->LOG, "\n\nFile: %s\n", file_path.c_str());
ts->printf(ts->LOG, "\nVideo codec: %s\n", string(&codec[j][0], 4).c_str()); }
const string status = failed ? "FAILED" : "OK";
ts->printf(ts->LOG, "\nSuccessfull iterations: %d(%d%%) Failed iterations: %d(%d%%) %s\n", N-failed, (N-failed)*100/N, failed, failed*100/N, status.c_str());
if( i < n_format-1 || j < n_codec-1 ) ts->printf(ts->LOG, "\n----------");
}
#endif
#endif
}
TEST(Highgui_Positioning, regression) { CV_PositioningTest test; test.safe_run(); }
#endif
/*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.
// 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"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;
class CV_PositioningTest : public cvtest::BaseTest
{
public:
CV_PositioningTest()
{
framesize = Size(640, 480);
}
Mat drawFrame(int i)
{
Mat mat = Mat::zeros(framesize, CV_8UC3);
mat = Scalar(fabs(cos(i*0.08)*255), fabs(sin(i*0.05)*255), i);
putText(mat, format("%03d", i), Point(10, 350), 0, 10, Scalar(128, 255, 255), 15);
return mat;
}
string getFilename(const cvtest::VideoFormat& fmt)
{
return format("test_video_%s.%s", cvtest::fourccToString(fmt.fourcc).c_str(), fmt.ext.c_str());
}
bool CreateTestVideo(const cvtest::VideoFormat& fmt, int framecount)
{
string filename = getFilename(fmt);
VideoWriter writer(filename, fmt.fourcc, 25, framesize, true);
if( !writer.isOpened() )
return false;
for (int i = 0; i < framecount; ++i)
{
Mat img = drawFrame(i);
writer << img;
}
return true;
}
void run(int)
{
int n_frames = 100;
for( int testcase = 0; ; testcase++ )
{
const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[testcase];
if( fmt.empty() )
break;
string filename = getFilename(fmt);
ts->printf(ts->LOG, "\nFile: %s\n", filename.c_str());
if( !CreateTestVideo(fmt, n_frames) )
{
ts->printf(ts->LOG, "\nError: cannot create video file");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
return;
}
VideoCapture cap(filename);
if (!cap.isOpened())
{
ts->printf(ts->LOG, "\nError: cannot read video file.");
ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA);
return;
}
int N0 = cap.get(CV_CAP_PROP_FRAME_COUNT);
cap.set(CV_CAP_PROP_POS_FRAMES, 0);
int N = cap.get(CV_CAP_PROP_FRAME_COUNT);
if (N != n_frames || N != N0)
{
ts->printf(ts->LOG, "\nError: returned frame count (N0=%d, N=%d) is different from the reference number %d\n", N0, N, n_frames);
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
return;
}
for (int k = 0; k < N; ++k)
{
int idx = theRNG().uniform(0, N);
if( !cap.set(CV_CAP_PROP_POS_FRAMES, idx) )
{
ts->printf(ts->LOG, "\nError: cannot seek to frame %d.\n", idx);
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
return;
}
int idx1 = (int)cap.get(CV_CAP_PROP_POS_FRAMES);
Mat img; cap >> img;
Mat img0 = drawFrame(idx);
if( idx != idx1 )
{
ts->printf(ts->LOG, "\nError: the current position (%d) after seek is different from specified (%d)\n",
idx1, idx);
ts->printf(ts->LOG, "Saving both frames ...\n");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
imwrite("opencv_test_highgui_postest_actual.png", img);
imwrite("opencv_test_highgui_postest_expected.png", img0);
return;
}
if (img.empty())
{
ts->printf(ts->LOG, "\nError: cannot read a frame at position %d.\n", idx);
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
return;
}
double err = PSNR(img, img0);
if( err < 20 )
{
ts->printf(ts->LOG, "The frame read after positioning to %d is incorrect (PSNR=%g)\n", idx, err);
ts->printf(ts->LOG, "Saving both frames ...\n");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
imwrite("opencv_test_highgui_postest_actual.png", img);
imwrite("opencv_test_highgui_postest_expected.png", img0);
return;
}
}
}
}
Size framesize;
};
#if BUILD_WITH_VIDEO_INPUT_SUPPORT && BUILD_WITH_VIDEO_OUTPUT_SUPPORT
TEST(Highgui_Video, seek_random_synthetic) { CV_PositioningTest test; test.safe_run(); }
#endif

@ -2,10 +2,8 @@ Geometric Image Transformations
===============================
.. highlight:: cpp
The functions in this section perform various geometrical transformations of 2D images. They do not change the image content but deform the pixel grid and map this deformed grid to the destination image. In fact, to avoid sampling artifacts, the mapping is done in the reverse order, from destination to the source. That is, for each pixel
:math:`(x, y)` of the destination image, the functions compute coordinates of the corresponding "donor" pixel in the source image and copy the pixel value:
The functions in this section perform various geometrical transformations of 2D images. They do not change the image content but deform the pixel grid and map this deformed grid to the destination image. In fact, to avoid sampling artifacts, the mapping is done in the reverse order, from destination to the source. That is, for each pixel :math:`(x, y)` of the destination image, the functions compute coordinates of the corresponding "donor" pixel in the source image and copy the pixel value:
.. math::
\texttt{dst} (x,y)= \texttt{src} (f_x(x,y), f_y(x,y))

@ -12,7 +12,6 @@ imgproc. Image Processing
miscellaneous_transformations
histograms
structural_analysis_and_shape_descriptors
planar_subdivisions
motion_analysis_and_object_tracking
feature_detection
object_detection

@ -632,7 +632,7 @@ Compares two shapes.
:param object2: Second contour or grayscale image.
:param method: Comparison method: ``CV_CONTOUR_MATCH_I1`` , \ ``CV_CONTOURS_MATCH_I2`` \
:param method: Comparison method: ``CV_CONTOURS_MATCH_I1`` , \ ``CV_CONTOURS_MATCH_I2`` \
or ``CV_CONTOURS_MATCH_I3`` (see the details below).
:param parameter: Method-specific parameter (not supported now).
@ -641,23 +641,23 @@ The function compares two shapes. All three implemented methods use the Hu invar
:ocv:func:`HuMoments` ) as follows (
:math:`A` denotes ``object1``,:math:`B` denotes ``object2`` ):
* method=CV\_CONTOUR\_MATCH\_I1
* method=CV_CONTOURS_MATCH_I1
.. math::
I_1(A,B) = \sum _{i=1...7} \left | \frac{1}{m^A_i} - \frac{1}{m^B_i} \right |
* method=CV\_CONTOUR\_MATCH\_I2
* method=CV_CONTOURS_MATCH_I2
.. math::
I_2(A,B) = \sum _{i=1...7} \left | m^A_i - m^B_i \right |
* method=CV\_CONTOUR\_MATCH\_I3
* method=CV_CONTOURS_MATCH_I3
.. math::
I_3(A,B) = \sum _{i=1...7} \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| }
I_3(A,B) = \max _{i=1...7} \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| }
where

@ -597,6 +597,9 @@ CV_EXPORTS_W void accumulateProduct( InputArray src1, InputArray src2,
CV_EXPORTS_W void accumulateWeighted( InputArray src, InputOutputArray dst,
double alpha, InputArray mask=noArray() );
//! computes PSNR image/video quality metric
CV_EXPORTS_W double PSNR(InputArray src1, InputArray src2);
CV_EXPORTS_W Point2d phaseCorrelate(InputArray src1, InputArray src2, InputArray window = noArray());
CV_EXPORTS_W void createHanningWindow(OutputArray dst, Size winSize, int type);

@ -89,7 +89,7 @@ PERF_TEST_P(Size_MatType_BorderType3x3, blur3x3,
TEST_CYCLE() blur(src, dst, Size(3,3), Point(-1,-1), btype);
SANITY_CHECK(dst);
SANITY_CHECK(dst, 1e-3);
}
PERF_TEST_P(Size_MatType_BorderType, gaussianBlur5x5,
@ -133,5 +133,5 @@ PERF_TEST_P(Size_MatType_BorderType, blur5x5,
TEST_CYCLE() blur(src, dst, Size(5,5), Point(-1,-1), btype);
SANITY_CHECK(dst);
SANITY_CHECK(dst, 1e-3);
}

@ -33,5 +33,5 @@ PERF_TEST_P(Img_BlockSize_ApertureSize_BorderType, cornerEigenValsAndVecs,
TEST_CYCLE() cornerEigenValsAndVecs(src, dst, blockSize, apertureSize, borderType);
SANITY_CHECK(dst);
SANITY_CHECK(dst, 2e-5);
}

@ -78,5 +78,5 @@ PERF_TEST_P( Size_MatType_OutMatDepth, integral_sqsum_tilted,
SANITY_CHECK(sum, 1e-6);
SANITY_CHECK(sqsum, 1e-6);
SANITY_CHECK(tilted, 1e-6);
SANITY_CHECK(tilted, 1e-6, tilted.depth() > CV_32S ? ERROR_RELATIVE : ERROR_ABSOLUTE);
}

@ -1965,12 +1965,14 @@ void cv::convexHull( InputArray _points, OutputArray _hull, bool clockwise, bool
void cv::convexityDefects( InputArray _points, InputArray _hull, OutputArray _defects )
{
Mat points = _points.getMat();
CV_Assert( points.isContinuous() && points.type() == CV_32SC2 );
int ptnum = points.checkVector(2, CV_32S);
CV_Assert( ptnum > 3 );
Mat hull = _hull.getMat();
CV_Assert( hull.checkVector(1, CV_32S) > 2 );
Ptr<CvMemStorage> storage = cvCreateMemStorage();
CvMat c_points = points, c_hull = hull;
CvSeq* seq = cvConvexityDefects(&c_points, &c_hull);
CvSeq* seq = cvConvexityDefects(&c_points, &c_hull, storage);
int i, n = seq->total;
if( n == 0 )
@ -1991,9 +1993,9 @@ void cv::convexityDefects( InputArray _points, InputArray _hull, OutputArray _de
int idx0 = (int)(d.start - ptorg);
int idx1 = (int)(d.end - ptorg);
int idx2 = (int)(d.depth_point - ptorg);
CV_Assert( 0 <= idx0 && idx0 < n );
CV_Assert( 0 <= idx1 && idx1 < n );
CV_Assert( 0 <= idx2 && idx2 < n );
CV_Assert( 0 <= idx0 && idx0 < ptnum );
CV_Assert( 0 <= idx1 && idx1 < ptnum );
CV_Assert( 0 <= idx2 && idx2 < ptnum );
CV_Assert( d.depth >= 0 );
int idepth = cvRound(d.depth*256);
defects.at<Vec4i>(i) = Vec4i(idx0, idx1, idx2, idepth);

@ -312,9 +312,7 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
ksize.width = 1;
}
#ifdef HAVE_TEGRA_OPTIMIZATION
if(tegra::box(src, dst, ksize, borderType))
return;
if ( tegra::boxFilter(src, dst, ksize, anchor, normalize, borderType) )
if ( tegra::box(src, dst, ksize, anchor, normalize, borderType) )
return;
#endif
@ -1441,6 +1439,7 @@ bilateralFilter_32f( const Mat& src, Mat& dst, int d,
// temporary copy of the image with borders for easy processing
Mat temp;
copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );
patchNaNs(temp);
// allocate lookup tables
vector<float> _space_weight(d*d);

@ -245,6 +245,15 @@ void cv::copyMakeBorder( InputArray _src, OutputArray _dst, int top, int bottom,
}
double cv::PSNR(InputArray _src1, InputArray _src2)
{
Mat src1 = _src1.getMat(), src2 = _src2.getMat();
CV_Assert( src1.depth() == CV_8U );
double diff = std::sqrt(norm(src1, src2, NORM_L2SQR)/(src1.total()*src1.channels()));
return 20*log10(255./(diff+DBL_EPSILON));
}
CV_IMPL void
cvCopyMakeBorder( const CvArr* srcarr, CvArr* dstarr, CvPoint offset,
int borderType, CvScalar value )

@ -6,7 +6,7 @@ if(NOT ANDROID OR NOT PYTHON_EXECUTABLE OR ANDROID_NATIVE_API_LEVEL LESS 8)
endif()
set(the_description "The java bindings")
ocv_add_module(java BINDINGS opencv_core opencv_imgproc OPTIONAL opencv_objdetect opencv_features2d opencv_video opencv_highgui opencv_ml opencv_calib3d opencv_photo)
ocv_add_module(java BINDINGS opencv_core opencv_imgproc OPTIONAL opencv_objdetect opencv_features2d opencv_video opencv_highgui opencv_ml opencv_calib3d opencv_photo opencv_nonfree)
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/cpp")
# get list of modules to wrap
@ -56,23 +56,25 @@ foreach(module ${OPENCV_JAVA_MODULES})
endforeach()
# first run (to get list of generated files)
file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out")
execute_process(COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_headers}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out"
OUTPUT_QUIET ERROR_QUIET)
file(GLOB_RECURSE ${module}_generated_java_sources RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/" "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/*.java")
ocv_list_add_prefix(${module}_generated_java_sources "${CMAKE_CURRENT_BINARY_DIR}/")
# second run (at build time)
add_custom_command(OUTPUT ${${module}_generated_java_sources} "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp"
COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_headers}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS "${GEN_JAVA}" "${HDR_PARSER}" ${module_headers})
list(APPEND java_hdr_deps ${module_headers})
list(APPEND generated_cpp_sources "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp")
list(APPEND generated_java_sources ${${module}_generated_java_sources})
if(module_headers)
file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out")
execute_process(COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_headers}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out"
OUTPUT_QUIET ERROR_QUIET)
file(GLOB_RECURSE ${module}_generated_java_sources RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/" "${CMAKE_CURRENT_BINARY_DIR}/gen_java_out/*.java")
ocv_list_add_prefix(${module}_generated_java_sources "${CMAKE_CURRENT_BINARY_DIR}/")
# second run (at build time)
add_custom_command(OUTPUT ${${module}_generated_java_sources} "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp"
COMMAND ${PYTHON_EXECUTABLE} "${GEN_JAVA}" "${HDR_PARSER}" ${module} ${module_headers}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS "${GEN_JAVA}" "${HDR_PARSER}" ${module_headers})
list(APPEND java_hdr_deps ${module_headers})
list(APPEND generated_cpp_sources "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp")
list(APPEND generated_java_sources ${${module}_generated_java_sources})
endif()
endforeach()
# get handwritten files used for wrappers generation
@ -183,12 +185,13 @@ if(ANDROID)
# manifest, jni, Eclipse project
file(GLOB_RECURSE android_lib_project_files RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/android/" "${CMAKE_CURRENT_SOURCE_DIR}/android/*")
list(REMOVE_ITEM android_lib_project_files "${ANDROID_MANIFEST_FILE}")
foreach(f ${android_lib_project_files})
if(NOT f MATCHES "\\.svn")
add_custom_command(
OUTPUT "${OpenCV_BINARY_DIR}/${f}"
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/android/${f}" "${OpenCV_BINARY_DIR}/${f}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/android/${f}"
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/android/${f}"
COMMENT "Generating ${f}"
)
@ -222,14 +225,17 @@ if(ANDROID)
android_get_compatible_target(lib_target_sdk_target ${ANDROID_NATIVE_API_LEVEL} ${ANDROID_SDK_TARGET})
add_custom_command(
OUTPUT ${lib_target_files}
OUTPUT ${lib_target_files} "${OpenCV_BINARY_DIR}/${ANDROID_MANIFEST_FILE}"
COMMAND ${CMAKE_COMMAND} -E remove ${lib_target_files}
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/android/${ANDROID_MANIFEST_FILE}" "${OpenCV_BINARY_DIR}/${ANDROID_MANIFEST_FILE}"
COMMAND ${ANDROID_EXECUTABLE} --silent create lib-project --path \"${OpenCV_BINARY_DIR}\" --target \"${lib_target_sdk_target}\" --name OpenCV --package org.opencv 2>\"${CMAKE_CURRENT_BINARY_DIR}/create_lib_project.log\"
MAIN_DEPENDENCY "${OpenCV_BINARY_DIR}/${ANDROID_MANIFEST_FILE}"
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/android/${ANDROID_MANIFEST_FILE}" "${OpenCV_BINARY_DIR}/${ANDROID_MANIFEST_FILE}"
MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/android/${ANDROID_MANIFEST_FILE}"
DEPENDS ${lib_proj_files}
COMMENT "Generating OpenCV Android library project. SDK target: ${lib_target_sdk_target}"
)
install(FILES "${OpenCV_BINARY_DIR}/${ANDROID_PROJECT_PROPERTIES_FILE}" DESTINATION . COMPONENT main)
install(FILES "${OpenCV_BINARY_DIR}/${ANDROID_MANIFEST_FILE}" DESTINATION . COMPONENT main)
if(ANT_EXECUTABLE AND ANDROID_TOOLS_Pkg_Revision GREATER 13)
# build the library project
@ -247,9 +253,7 @@ if(ANDROID)
list(APPEND lib_target_files "${OpenCV_BINARY_DIR}/bin/classes.jar")
endif()
add_custom_target(${lib_target}
SOURCES ${lib_proj_files} ${lib_target_files}
)
add_custom_target(${lib_target} SOURCES ${lib_proj_files} ${lib_target_files} "${OpenCV_BINARY_DIR}/${ANDROID_MANIFEST_FILE}")
add_dependencies(${lib_target} ${api_target})
add_dependencies(${the_module} ${lib_target})

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>OpenCV-2.4.beta</name>
<name>OpenCV-2.4.0</name>
<comment></comment>
<projects>
</projects>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv"
android:versionCode="1"
android:versionName="1.0">
android:versionCode="240"
android:versionName="2.4.0">
</manifest>

@ -23,10 +23,12 @@ public class UtilsTest extends OpenCVTestCase {
Bitmap bmp16 = BitmapFactory.decodeFile(OpenCVTestRunner.LENA_PATH, opt16);
Mat m16 = new Mat();
Utils.bitmapToMat(bmp16, m16);
assertTrue(m16.rows() == 512 && m16.cols() == 512 && m16.type() == CvType.CV_8UC4);
BitmapFactory.Options opt32 = new BitmapFactory.Options();
/*BitmapFactory.Options opt32 = new BitmapFactory.Options();
opt32.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bmp32 = BitmapFactory.decodeFile(OpenCVTestRunner.LENA_PATH, opt32);
Bitmap bmp32 = BitmapFactory.decodeFile(OpenCVTestRunner.LENA_PATH, opt32);*/
Bitmap bmp32 = bmp16.copy(Bitmap.Config.ARGB_8888, false);
Mat m32 = new Mat();
Utils.bitmapToMat(bmp32, m32);
@ -34,6 +36,7 @@ public class UtilsTest extends OpenCVTestCase {
double maxDiff = Core.norm(m16, m32, Core.NORM_INF);
Log.d("Bmp->Mat", "bmp16->Mat vs bmp32->Mat diff = " + maxDiff);
assertTrue(maxDiff <= 8 /* 8 == 2^8 / 2^5 */);
}

@ -4,6 +4,7 @@ import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDouble;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.MatOfPoint3f;
import org.opencv.core.Point;
@ -174,15 +175,17 @@ public class Calib3dTest extends OpenCVTestCase {
public void testFindChessboardCornersMatSizeMat() {
Size patternSize = new Size(9, 6);
Calib3d.findChessboardCorners(grayChess, patternSize, dst);
assertTrue(!dst.empty());
MatOfPoint2f corners = new MatOfPoint2f();
Calib3d.findChessboardCorners(grayChess, patternSize, corners);
assertTrue(!corners.empty());
}
public void testFindChessboardCornersMatSizeMatInt() {
Size patternSize = new Size(9, 6);
Calib3d.findChessboardCorners(grayChess, patternSize, dst, Calib3d.CALIB_CB_ADAPTIVE_THRESH + Calib3d.CALIB_CB_NORMALIZE_IMAGE
MatOfPoint2f corners = new MatOfPoint2f();
Calib3d.findChessboardCorners(grayChess, patternSize, corners, Calib3d.CALIB_CB_ADAPTIVE_THRESH + Calib3d.CALIB_CB_NORMALIZE_IMAGE
+ Calib3d.CALIB_CB_FAST_CHECK);
assertTrue(!dst.empty());
assertTrue(!corners.empty());
}
public void testFindCirclesGridDefaultMatSizeMat() {
@ -515,7 +518,7 @@ public class Calib3dTest extends OpenCVTestCase {
Mat rvec = new Mat();
Mat tvec = new Mat();
Calib3d.solvePnP(points3d, points2d, intrinsics, new Mat(), rvec, tvec);
Calib3d.solvePnP(points3d, points2d, intrinsics, new MatOfDouble(), rvec, tvec);
Mat truth_rvec = new Mat(3, 1, CvType.CV_64F);
truth_rvec.put(0, 0, 0, Math.PI / 2, 0);

@ -1284,14 +1284,14 @@ public class CoreTest extends OpenCVTestCase {
rgba0.setTo(new Scalar(10, 20, 30, 40));
List<Mat> src = Arrays.asList(rgba0);
List<Mat> dst = Arrays.asList(gray3, gray2, gray1, gray0, getMat(CvType.CV_8UC3, 0, 0, 0));
MatOfInt fromTo = new MatOfInt(1, new int[]
{ 3, 0,
MatOfInt fromTo = new MatOfInt(
3, 0,
3, 1,
2, 2,
0, 3,
2, 4,
1, 5,
0, 6 }
0, 6
);
Core.mixChannels(src, dst, fromTo);

@ -1,5 +1,7 @@
package org.opencv.test.core;
import java.util.Arrays;
import org.opencv.core.Core;
import org.opencv.core.CvException;
import org.opencv.core.CvType;
@ -11,8 +13,6 @@ import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.test.OpenCVTestCase;
import java.util.Arrays;
public class MatTest extends OpenCVTestCase {
public void testAdjustROI() {
@ -272,21 +272,72 @@ public class MatTest extends OpenCVTestCase {
assertEquals(5, Core.countNonZero(eye));
}
public void testGetIntInt() {
Mat src = new Mat(3, 3, CvType.CV_8U, new Scalar(2));
double[] actualArray = src.get(1, 1);
assertTrue(Arrays.equals(new double[] { 2 }, actualArray));
public Mat getTestMat(int size, int type) {
Mat m = new Mat(size, size, type);
final int ch = CvType.channels(type);
double buff[] = new double[size*size * ch];
for(int i=0; i<size; i++)
for(int j=0; j<size; j++)
for(int k=0; k<ch; k++) {
buff[i*size*ch + j*ch + k] = 100*i + 10*j + k;
}
m.put(0, 0, buff);
return m;
}
public void testGetIntInt_8U() {
Mat m = getTestMat(5, CvType.CV_8UC2);
// whole Mat
assertTrue(Arrays.equals(new double[] {0, 1}, m.get(0, 0)));
assertTrue(Arrays.equals(new double[] {240, 241}, m.get(2, 4)));
assertTrue(Arrays.equals(new double[] {255, 255}, m.get(4, 4)));
// sub-Mat
Mat sm = m.submat(2, 4, 3, 5);
assertTrue(Arrays.equals(new double[] {230, 231}, sm.get(0, 0)));
assertTrue(Arrays.equals(new double[] {255, 255}, sm.get(1, 1)));
}
public void testGetIntInt_32S() {
Mat m = getTestMat(5, CvType.CV_32SC3);
// whole Mat
assertTrue(Arrays.equals(new double[] {0, 1, 2}, m.get(0, 0)));
assertTrue(Arrays.equals(new double[] {240, 241, 242}, m.get(2, 4)));
assertTrue(Arrays.equals(new double[] {440, 441, 442}, m.get(4, 4)));
// sub-Mat
Mat sm = m.submat(2, 4, 3, 5);
assertTrue(Arrays.equals(new double[] {230, 231, 232}, sm.get(0, 0)));
assertTrue(Arrays.equals(new double[] {340, 341, 342}, sm.get(1, 1)));
}
public void testGetIntInt_64F() {
Mat m = getTestMat(5, CvType.CV_64FC1);
// whole Mat
assertTrue(Arrays.equals(new double[] {0}, m.get(0, 0)));
assertTrue(Arrays.equals(new double[] {240}, m.get(2, 4)));
assertTrue(Arrays.equals(new double[] {440}, m.get(4, 4)));
// sub-Mat
Mat sm = m.submat(2, 4, 3, 5);
assertTrue(Arrays.equals(new double[] {230}, sm.get(0, 0)));
assertTrue(Arrays.equals(new double[] {340}, sm.get(1, 1)));
}
public void testGetIntIntByteArray() {
Mat m = new Mat(5, 5, CvType.CV_8UC3, new Scalar(1, 2, 3));
Mat m = getTestMat(5, CvType.CV_8UC3);
byte[] goodData = new byte[9];
byte[] badData = new byte[7];
m.get(1, 1, goodData);
// whole Mat
int bytesNum = m.get(1, 1, goodData);
assertTrue(Arrays.equals(new byte[] { 1, 2, 3, 1, 2, 3, 1, 2, 3 }, goodData));
assertEquals(9, bytesNum);
assertTrue(Arrays.equals(new byte[] { 110, 111, 112, 120, 121, 122, (byte) 130, (byte) 131, (byte) 132 }, goodData));
try {
m.get(2, 2, badData);
@ -294,38 +345,105 @@ public class MatTest extends OpenCVTestCase {
} catch (UnsupportedOperationException e) {
// expected
}
// sub-Mat
Mat sm = m.submat(2, 4, 3, 5);
byte buff00[] = new byte[3];
bytesNum = sm.get(0, 0, buff00);
assertEquals(3, bytesNum);
assertTrue(Arrays.equals(new byte[] {(byte) 230, (byte) 231, (byte) 232}, buff00));
byte buff11[] = new byte[3];
bytesNum = sm.get(1, 1, buff11);
assertEquals(3, bytesNum);
assertTrue(Arrays.equals(new byte[] {(byte) 255, (byte) 255, (byte) 255}, buff11));
}
public void testGetIntIntDoubleArray() {
Mat src = new Mat(2, 2, CvType.CV_64F);
double[] doubleArray = { 1.0, 2.0, 3.0 };
int numOfBytes = src.get(0, 0, doubleArray);
assertEquals(24, numOfBytes);
}
Mat m = getTestMat(5, CvType.CV_64F);
double buff[] = new double[4];
// whole Mat
int bytesNum = m.get(1, 1, buff);
assertEquals(32, bytesNum);
assertTrue(Arrays.equals(new double[] { 110, 120, 130, 140 }, buff));
// sub-Mat
Mat sm = m.submat(2, 4, 3, 5);
double buff00[] = new double[2];
bytesNum = sm.get(0, 0, buff00);
assertEquals(16, bytesNum);
assertTrue(Arrays.equals(new double[] {230, 240}, buff00));
double buff11[] = new double[] {0, 0};
bytesNum = sm.get(1, 1, buff11);
assertEquals(8, bytesNum);
assertTrue(Arrays.equals(new double[] {340, 0}, buff11));
}
public void testGetIntIntFloatArray() {
Mat src = new Mat(2, 2, CvType.CV_32F);
float[] floatArray = { 3.0f, 1.0f, 4.0f };
Mat m = getTestMat(5, CvType.CV_32F);
float buff[] = new float[4];
// whole Mat
int bytesNum = m.get(1, 1, buff);
int numOfBytes = src.get(0, 0, floatArray);
assertEquals(12, numOfBytes);
assertEquals(16, bytesNum);
assertTrue(Arrays.equals(new float[] { 110, 120, 130, 140 }, buff));
// sub-Mat
Mat sm = m.submat(2, 4, 3, 5);
float buff00[] = new float[2];
bytesNum = sm.get(0, 0, buff00);
assertEquals(8, bytesNum);
assertTrue(Arrays.equals(new float[] {230, 240}, buff00));
float buff11[] = new float[] {0, 0};
bytesNum = sm.get(1, 1, buff11);
assertEquals(4, bytesNum);
assertTrue(Arrays.equals(new float[] {340, 0}, buff11));
}
public void testGetIntIntIntArray() {
Mat src = new Mat(2, 2, CvType.CV_32S);
int[] intArray = { 3, 1, 4, 7 };
int numOfBytes = src.get(0, 0, intArray);
assertEquals(16, numOfBytes);
Mat m = getTestMat(5, CvType.CV_32SC2);
int[] buff = new int[6];
// whole Mat
int bytesNum = m.get(1, 1, buff);
assertEquals(24, bytesNum);
assertTrue(Arrays.equals(new int[] { 110, 111, 120, 121, 130, 131 }, buff));
// sub-Mat
Mat sm = m.submat(2, 4, 3, 5);
int buff00[] = new int[4];
bytesNum = sm.get(0, 0, buff00);
assertEquals(16, bytesNum);
assertTrue(Arrays.equals(new int[] {230, 231, 240, 241}, buff00));
int buff11[] = new int[]{0, 0, 0, 0};
bytesNum = sm.get(1, 1, buff11);
assertEquals(8, bytesNum);
assertTrue(Arrays.equals(new int[] {340, 341, 0, 0}, buff11));
}
public void testGetIntIntShortArray() {
Mat src = new Mat(2, 2, CvType.CV_16U);
short[] data = { 3, 1, 4, 7 };
int numOfBytes = src.get(1, 1, data);
assertEquals(2, numOfBytes);
Mat m = getTestMat(5, CvType.CV_16SC2);
short[] buff = new short[6];
// whole Mat
int bytesNum = m.get(1, 1, buff);
assertEquals(12, bytesNum);
assertTrue(Arrays.equals(new short[] { 110, 111, 120, 121, 130, 131 }, buff));
// sub-Mat
Mat sm = m.submat(2, 4, 3, 5);
short buff00[] = new short[4];
bytesNum = sm.get(0, 0, buff00);
assertEquals(8, bytesNum);
assertTrue(Arrays.equals(new short[] {230, 231, 240, 241}, buff00));
short buff11[] = new short[]{0, 0, 0, 0};
bytesNum = sm.get(1, 1, buff11);
assertEquals(4, bytesNum);
assertTrue(Arrays.equals(new short[] {340, 341, 0, 0}, buff11));
}
public void testGetNativeObjAddr() {
@ -528,9 +646,33 @@ public class MatTest extends OpenCVTestCase {
}
public void testPutIntIntByteArray() {
Mat m = new Mat(5, 5, CvType.CV_8UC3);
byte[] bytes = new byte[] { 10, 20, 30, 40, 50, 60 };
m.put(1, 1, bytes);
Mat m = new Mat(5, 5, CvType.CV_8UC3, new Scalar(1, 2, 3));
Mat sm = m.submat(2, 4, 3, 5);
byte[] buff = new byte[] { 0, 0, 0, 0, 0, 0 };
byte[] buff0 = new byte[] { 10, 20, 30, 40, 50, 60 };
byte[] buff1 = new byte[] { -1, -2, -3, -4, -5, -6 };
int bytesNum = m.put(1, 2, buff0);
assertEquals(6, bytesNum);
bytesNum = m.get(1, 2, buff);
assertEquals(6, bytesNum);
assertTrue(Arrays.equals(buff, buff0));
bytesNum = sm.put(0, 0, buff1);
assertEquals(6, bytesNum);
bytesNum = sm.get(0, 0, buff);
assertEquals(6, bytesNum);
assertTrue(Arrays.equals(buff, buff1));
bytesNum = m.get(2, 3, buff);
assertEquals(6, bytesNum);
assertTrue(Arrays.equals(buff, buff1));
Mat m1 = m.row(1);
bytesNum = m1.get(0, 2, buff);
assertEquals(6, bytesNum);
assertTrue(Arrays.equals(buff, buff0));
try {
byte[] bytes2 = new byte[] { 10, 20, 30, 40, 50 };
@ -542,21 +684,41 @@ public class MatTest extends OpenCVTestCase {
}
public void testPutIntIntDoubleArray() {
Mat m = new Mat(5, 5, CvType.CV_8UC3);
m.put(1, 1, 10, 20, 30, 40, 50, 60);
try {
m.put(2, 2, 11, 22, 33, 44, 55);
fail("Expected UnsupportedOperationException (data.length % CvType.channels(t) != 0)");
} catch (UnsupportedOperationException e) {
// expected
}
Mat m = new Mat(5, 5, CvType.CV_8UC3, new Scalar(1, 2, 3));
Mat sm = m.submat(2, 4, 3, 5);
byte[] buff = new byte[] { 0, 0, 0, 0, 0, 0 };
int bytesNum = m.put(1, 2, 10, 20, 30, 40, 50, 60);
assertEquals(6, bytesNum);
bytesNum = m.get(1, 2, buff);
assertEquals(6, bytesNum);
assertTrue(Arrays.equals(buff, new byte[]{10, 20, 30, 40, 50, 60}));
bytesNum = sm.put(0, 0, 255, 254, 253, 252, 251, 250);
assertEquals(6, bytesNum);
bytesNum = sm.get(0, 0, buff);
assertEquals(6, bytesNum);
assertTrue(Arrays.equals(buff, new byte[]{-1, -2, -3, -4, -5, -6}));
bytesNum = m.get(2, 3, buff);
assertEquals(6, bytesNum);
assertTrue(Arrays.equals(buff, new byte[]{-1, -2, -3, -4, -5, -6}));
}
public void testPutIntIntFloatArray() {
Mat m = new Mat(5, 5, CvType.CV_32FC3);
Mat m = new Mat(5, 5, CvType.CV_32FC3, new Scalar(1, 2, 3));
float[] elements = new float[] { 10, 20, 30, 40, 50, 60 };
m.put(1, 1, elements);
int bytesNum = m.put(4, 3, elements);
assertEquals(elements.length * 4, bytesNum);
Mat m1 = m.row(4);
float buff[] = new float[3];
bytesNum = m1.get(0, 4, buff);
assertEquals(buff.length * 4, bytesNum);
assertTrue(Arrays.equals(new float[]{40, 50, 60}, buff));
assertArrayEquals(new double[]{10, 20, 30}, m.get(4, 3), EPS);
try {
float[] elements2 = new float[] { 10, 20, 30, 40, 50 };
@ -568,9 +730,18 @@ public class MatTest extends OpenCVTestCase {
}
public void testPutIntIntIntArray() {
Mat m = new Mat(5, 5, CvType.CV_32SC3);
Mat m = new Mat(5, 5, CvType.CV_32SC3, new Scalar(-1, -2, -3));
int[] elements = new int[] { 10, 20, 30, 40, 50, 60 };
m.put(1, 1, elements);
int bytesNum = m.put(0, 4, elements);
assertEquals(elements.length * 4, bytesNum);
Mat m1 = m.col(4);
int buff[] = new int[3];
bytesNum = m1.get(0, 0, buff);
assertEquals(buff.length * 4, bytesNum);
assertTrue(Arrays.equals(new int[]{10, 20, 30}, buff));
assertArrayEquals(new double[]{40, 50, 60}, m.get(1, 0), EPS);
try {
int[] elements2 = new int[] { 10, 20, 30, 40, 50 };
@ -582,9 +753,17 @@ public class MatTest extends OpenCVTestCase {
}
public void testPutIntIntShortArray() {
Mat m = new Mat(5, 5, CvType.CV_16SC3);
Mat m = new Mat(5, 5, CvType.CV_16SC3, new Scalar(-1, -2, -3));
short[] elements = new short[] { 10, 20, 30, 40, 50, 60 };
m.put(1, 1, elements);
int bytesNum = m.put(2, 3, elements);
assertEquals(elements.length * 2, bytesNum);
Mat m1 = m.col(3);
short buff[] = new short[3];
bytesNum = m1.get(2, 0, buff);
assertTrue(Arrays.equals(new short[]{10, 20, 30}, buff));
assertArrayEquals(new double[]{40, 50, 60}, m.get(2, 4), EPS);
try {
short[] elements2 = new short[] { 10, 20, 30, 40, 50 };
@ -692,6 +871,15 @@ public class MatTest extends OpenCVTestCase {
assertMatEqual(gray127, gray0);
}
public void testSetToScalarMask() {
Mat mask = gray0.clone();
mask.put(1, 1, 1, 2, 3);
gray0.setTo(new Scalar(1), mask);
assertEquals(3, Core.countNonZero(gray0));
Core.subtract(gray0, mask, gray0);
assertEquals(0, Core.countNonZero(gray0));
}
public void testSize() {
assertEquals(new Size(matSize, matSize), gray0.size());

@ -86,18 +86,11 @@ public class BruteForceDescriptorMatcherTest extends OpenCVTestCase {
matSize = 100;
truth = new DMatch[] {
/*
new DMatch(0, 0, 0, 0.643284f),
new DMatch(1, 1, 0, 0.92945856f),
new DMatch(2, 1, 0, 0.2841479f),
new DMatch(3, 1, 0, 0.9194034f),
new DMatch(4, 1, 0, 0.3006621f)
*/
new DMatch(0, 0, 0, 1.049694f),
new DMatch(1, 0, 0, 1.083795f),
new DMatch(2, 1, 0, 0.484352f),
new DMatch(3, 0, 0, 1.098605f),
new DMatch(4, 1, 0, 0.494587f)
new DMatch(0, 0, 0, 1.049694f),
new DMatch(1, 0, 0, 1.098605f),
new DMatch(2, 1, 0, 0.494587f),
new DMatch(3, 1, 0, 0.484352f),
new DMatch(4, 0, 0, 1.083795f)
};
super.setUp();
@ -183,6 +176,9 @@ public class BruteForceDescriptorMatcherTest extends OpenCVTestCase {
Log.d("knnMatch", "train = " + train);
Log.d("knnMatch", "query = " + query);
/*
Log.d("knnMatch", "train = " + train);
Log.d("knnMatch", "query = " + query);
matcher.add(train);
matcher.knnMatch(query, matches, k);
*/
@ -190,7 +186,7 @@ public class BruteForceDescriptorMatcherTest extends OpenCVTestCase {
for(int i = 0; i<matches.size(); i++)
{
MatOfDMatch vdm = matches.get(i);
Log.d("knn", "vdm["+i+"]="+vdm.dump());
//Log.d("knn", "vdm["+i+"]="+vdm.dump());
assertTrue(Math.min(k, train.rows()) >= vdm.total());
for(DMatch dm : vdm.toArray())
{

@ -189,9 +189,11 @@ public class BruteForceHammingLUTDescriptorMatcherTest extends OpenCVTestCase {
matcher.match(query, train, matches);
/*
OpenCVTestRunner.Log("matches found: " + matches.size());
for (DMatch m : matches.toArray())
OpenCVTestRunner.Log(m.toString());
*/
assertArrayDMatchEquals(truth, matches.toArray(), EPS);
}

@ -84,18 +84,11 @@ public class BruteForceL1DescriptorMatcherTest extends OpenCVTestCase {
matSize = 100;
truth = new DMatch[] {
/*
new DMatch(0, 0, 0, 3.175296f),
new DMatch(1, 1, 0, 3.5954158f),
new DMatch(2, 1, 0, 1.2537984f),
new DMatch(3, 1, 0, 3.5761614f),
new DMatch(4, 1, 0, 1.3250958f)
*/
new DMatch(0, 1, 0, 6.920234f),
new DMatch(1, 0, 0, 6.1294847f),
new DMatch(2, 1, 0, 2.6545324f),
new DMatch(3, 1, 0, 6.1675916f),
new DMatch(4, 1, 0, 2.679859f)
new DMatch(0, 1, 0, 6.9202342f),
new DMatch(1, 1, 0, 6.1675916f),
new DMatch(2, 1, 0, 2.6798589f),
new DMatch(3, 1, 0, 2.6545324f),
new DMatch(4, 0, 0, 6.1294847f)
};
super.setUp();
}

@ -89,18 +89,11 @@ public class BruteForceSL2DescriptorMatcherTest extends OpenCVTestCase {
matSize = 100;
truth = new DMatch[] {
/*
new DMatch(0, 0, 0, sqr(0.643284f)),
new DMatch(1, 1, 0, sqr(0.92945856f)),
new DMatch(2, 1, 0, sqr(0.2841479f)),
new DMatch(3, 1, 0, sqr(0.9194034f)),
new DMatch(4, 1, 0, sqr(0.3006621f))
*/
new DMatch(0, 0, 0, 1.1018577f),
new DMatch(1, 0, 0, 1.1746116f),
new DMatch(2, 1, 0, 0.23459719f),
new DMatch(3, 0, 0, 1.2069331f),
new DMatch(4, 1, 0, 0.2446168f)
new DMatch(1, 0, 0, 1.2069331f),
new DMatch(2, 1, 0, 0.2446168f),
new DMatch(3, 1, 0, 0.2345972f),
new DMatch(4, 0, 0, 1.1746116f)
};
super.setUp();

@ -158,18 +158,11 @@ public class FlannBasedDescriptorMatcherTest extends OpenCVTestCase {
matSize = 100;
truth = new DMatch[] {
/*
new DMatch(0, 0, 0, 0.643284f),
new DMatch(1, 1, 0, 0.92945856f),
new DMatch(2, 1, 0, 0.2841479f),
new DMatch(3, 1, 0, 0.9194034f),
new DMatch(4, 1, 0, 0.3006621f)
*/
new DMatch(0, 0, 0, 1.049694f),
new DMatch(1, 0, 0, 1.083795f),
new DMatch(2, 1, 0, 0.484352f),
new DMatch(3, 0, 0, 1.098605f),
new DMatch(4, 1, 0, 0.494587f)
new DMatch(1, 0, 0, 1.098605f),
new DMatch(2, 1, 0, 0.494587f),
new DMatch(3, 1, 0, 0.484352f),
new DMatch(4, 0, 0, 1.083795f)
};
super.setUp();

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save