diff --git a/CMakeLists.txt b/CMakeLists.txt index 6999ecb1ed..a2e04bb13b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,14 @@ project(OpenCV CXX C) include(cmake/OpenCVUtils.cmake REQUIRED) +# ---------------------------------------------------------------------------- +# Break in case of popular CMake configuration mistakes +# ---------------------------------------------------------------------------- +if(NOT CMAKE_SIZEOF_VOID_P GREATER 0) + message(FATAL_ERROR "CMake fails to deterimine the bitness of target platform. + Please check your CMake and compiler installation. If you are crosscompiling then ensure that your CMake toolchain file correctly sets the compiler details.") +endif() + # ---------------------------------------------------------------------------- # Detect compiler and target platform architecture # ---------------------------------------------------------------------------- @@ -109,6 +117,7 @@ OCV_OPTION(WITH_EIGEN "Include Eigen2/Eigen3 support" ON) OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" ON IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_GSTREAMER "Include Gstreamer support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_GTK "Include GTK support" ON IF (UNIX AND NOT APPLE AND NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_IMAGEIO "ImageIO support for OS X" OFF IF APPLE) OCV_OPTION(WITH_IPP "Include Intel IPP support" OFF IF (MSVC OR X86 OR X86_64) ) OCV_OPTION(WITH_JASPER "Include JPEG2K support" ON IF (NOT IOS) ) OCV_OPTION(WITH_JPEG "Include JPEG support" ON IF (NOT IOS) ) @@ -116,7 +125,7 @@ OCV_OPTION(WITH_OPENEXR "Include ILM support via OpenEXR" ON OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF IF (NOT ANDROID AND NOT IOS AND NOT APPLE) ) OCV_OPTION(WITH_OPENNI "Include OpenNI support" OFF IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_PNG "Include PNG support" ON IF (NOT IOS) ) -OCV_OPTION(WITH_PVAPI "Include Prosilica GigE support" ON IF (UNIX AND NOT ANDROID AND NOT IOS) ) +OCV_OPTION(WITH_PVAPI "Include Prosilica GigE support" ON IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_QT "Build with Qt Backend support" OFF IF (NOT ANDROID AND NOT IOS) ) OCV_OPTION(WITH_QUICKTIME "Use QuickTime for Video I/O insted of QTKit" OFF IF APPLE ) OCV_OPTION(WITH_TBB "Include Intel TBB support" OFF IF (NOT IOS) ) @@ -302,182 +311,281 @@ if(UNIX) include(cmake/OpenCVFindPkgConfig.cmake OPTIONAL) include(CheckFunctionExists) include(CheckIncludeFile) + + if(NOT APPLE) + CHECK_INCLUDE_FILE(alloca.h HAVE_ALLOCA_H) + CHECK_FUNCTION_EXISTS(alloca HAVE_ALLOCA) + CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) + CHECK_INCLUDE_FILE(pthread.h HAVE_LIBPTHREAD) + if(ANDROID) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m log) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} m pthread) + else() + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m pthread rt) + endif() + else() + add_definitions(-DHAVE_ALLOCA -DHAVE_ALLOCA_H -DHAVE_LIBPTHREAD -DHAVE_UNISTD_H) + endif() endif() include(cmake/OpenCVPCHSupport.cmake REQUIRED) include(cmake/OpenCVModule.cmake REQUIRED) # ---------------------------------------------------------------------------- -# Detect 3rd-party tools and libraries +# Detect 3rd-party image IO libraries # ---------------------------------------------------------------------------- - -# IO libraries include(cmake/OpenCVIOLibs.cmake REQUIRED) -#Graphic libraries -set(HAVE_OPENGL 0) -if(UNIX) - if(NOT APPLE) - if(WITH_GTK) - CHECK_MODULE(gtk+-2.0 HAVE_GTK) - CHECK_MODULE(gthread-2.0 HAVE_GTHREAD) - if(WITH_OPENGL) - CHECK_MODULE(gtkglext-1.0 HAVE_GTKGLEXT) - if(HAVE_GTKGLEXT) - find_package(OpenGL QUIET) - if(OPENGL_FOUND) - set(HAVE_OPENGL 1) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${OPENGL_LIBRARIES}) - ocv_include_directories(${OPENGL_INCLUDE_DIR}) - endif() - endif() - endif() +# ---------------------------------------------------------------------------- +# Detect 3rd-party GUI libraries +# ---------------------------------------------------------------------------- +# --- QT4 --- +ocv_clear_vars(HAVE_QT) +if(WITH_QT) + find_package(Qt4) + if(QT4_FOUND) + set(HAVE_QT TRUE) + add_definitions(-DHAVE_QT) #We need to define te macro this way, using cvconfig.h.cmake does not work + endif() +endif() + +# --- GTK --- +ocv_clear_vars(HAVE_GTK HAVE_GTHREAD HAVE_GTKGLEXT) +if(WITH_GTK AND NOT HAVE_QT) + CHECK_MODULE(gtk+-2.0 HAVE_GTK) + CHECK_MODULE(gthread-2.0 HAVE_GTHREAD) + if(WITH_OPENGL) + CHECK_MODULE(gtkglext-1.0 HAVE_GTKGLEXT) + endif() +endif() + +# --- OpenGl --- +ocv_clear_vars(HAVE_OPENGL HAVE_QT_OPENGL) +if(WITH_OPENGL) + if(WIN32 OR QT_QTOPENGL_FOUND OR HAVE_GTKGLEXT) + find_package (OpenGL QUIET) + if(OPENGL_FOUND) + set(HAVE_OPENGL TRUE) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${OPENGL_LIBRARIES}) + if(QT_QTOPENGL_FOUND) + set(HAVE_QT_OPENGL TRUE) + add_definitions(-DHAVE_QT_OPENGL) else() - set(HAVE_GTK FALSE) - set(HAVE_GTHREAD FALSE) - endif() - if(WITH_GSTREAMER) - CHECK_MODULE(gstreamer-base-0.10 HAVE_GSTREAMER) - CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER) - CHECK_MODULE(gstreamer-video-0.10 HAVE_GSTREAMER) - else() - set(HAVE_GSTREAMER FALSE) + ocv_include_directories(${OPENGL_INCLUDE_DIR}) endif() endif() + endif() +endif(WITH_OPENGL) - if(WITH_UNICAP) - CHECK_MODULE(libunicap HAVE_UNICAP_) - CHECK_MODULE(libucil HAVE_UNICAP_UCIL) - if(HAVE_UNICAP_ AND HAVE_UNICAP_UCIL) - set(HAVE_UNICAP 1) - endif() - else() - set(HAVE_UNICAP FALSE) - endif() +# ---------------------------------------------------------------------------- +# Detect 3rd-party video IO libraries +# ---------------------------------------------------------------------------- +# --- GStreamer --- +ocv_clear_vars(HAVE_GSTREAMER) +if(WITH_GSTREAMER) + CHECK_MODULE(gstreamer-base-0.10 HAVE_GSTREAMER) + if(HAVE_GSTREAMER) + CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER) + endif() + if(HAVE_GSTREAMER) + CHECK_MODULE(gstreamer-video-0.10 HAVE_GSTREAMER) + endif() +endif(WITH_GSTREAMER) - if(WITH_PVAPI) - find_path(PVAPI_INCLUDE_PATH "PvApi.h" - PATHS "/usr/local/include" "/usr/include" - DOC "The path to PvAPI header") - if(PVAPI_INCLUDE_PATH) - set(HAVE_PVAPI 1) +# --- unicap --- +ocv_clear_vars(HAVE_UNICAP) +if(WITH_UNICAP) + CHECK_MODULE(libunicap HAVE_UNICAP_) + CHECK_MODULE(libucil HAVE_UNICAP_UCIL) + if(HAVE_UNICAP_ AND HAVE_UNICAP_UCIL) + set(HAVE_UNICAP TRUE) + endif() +endif(WITH_UNICAP) + +# --- PvApi --- +ocv_clear_vars(HAVE_PVAPI) +if(WITH_PVAPI) + find_path(PVAPI_INCLUDE_PATH "PvApi.h" + PATHS "/usr/local/include" "/usr/include" + DOC "The path to PvAPI header") + if(PVAPI_INCLUDE_PATH) + set(HAVE_PVAPI TRUE) + endif() +endif(WITH_PVAPI) + +# --- Dc1394 --- +ocv_clear_vars(HAVE_DC1394 HAVE_DC1394_2) +if(WITH_1394) + CHECK_MODULE(libdc1394-2 HAVE_DC1394_2) + if(NOT HAVE_DC1394_2) + CHECK_MODULE(libdc1394 HAVE_DC1394) + endif() +endif(WITH_1394) + +# --- xine --- +ocv_clear_vars(HAVE_XINE) +if(WITH_XINE) + CHECK_MODULE(libxine HAVE_XINE) +endif(WITH_XINE) + +# --- V4L --- +ocv_clear_vars(HAVE_LIBV4L HAVE_CAMV4L HAVE_CAMV4L2) +if(WITH_V4L) + CHECK_MODULE(libv4l1 HAVE_LIBV4L) + CHECK_INCLUDE_FILE(linux/videodev.h HAVE_CAMV4L) + CHECK_INCLUDE_FILE(linux/videodev2.h HAVE_CAMV4L2) +endif(WITH_V4L) + +# --- OpenNI --- +ocv_clear_vars(HAVE_OPENNI HAVE_OPENNI_PRIME_SENSOR_MODULE) +if(WITH_OPENNI) + include(cmake/OpenCVFindOpenNI.cmake) +endif(WITH_OPENNI) + +# --- XIMEA --- +ocv_clear_vars(HAVE_XIMEA) +if(WITH_XIMEA) + include(cmake/OpenCVFindXimea.cmake) + if(XIMEA_FOUND) + set(HAVE_XIMEA TRUE) + endif() +endif(WITH_XIMEA) + +# --- FFMPEG --- +ocv_clear_vars(HAVE_FFMPEG HAVE_FFMPEG_CODEC HAVE_FFMPEG_FORMAT HAVE_FFMPEG_UTIL HAVE_FFMPEG_SWSCALE HAVE_GENTOO_FFMPEG HAVE_FFMPEG_FFMPEG) +if(WITH_FFMPEG) + if(WIN32) + include(3rdparty/ffmpeg/ffmpeg_version.cmake REQUIRED) + elseif(UNIX) + CHECK_MODULE(libavcodec HAVE_FFMPEG_CODEC) + CHECK_MODULE(libavformat HAVE_FFMPEG_FORMAT) + CHECK_MODULE(libavutil HAVE_FFMPEG_UTIL) + CHECK_MODULE(libswscale HAVE_FFMPEG_SWSCALE) + + CHECK_INCLUDE_FILE(libavformat/avformat.h HAVE_GENTOO_FFMPEG) + CHECK_INCLUDE_FILE(ffmpeg/avformat.h HAVE_FFMPEG_FFMPEG) + if(NOT HAVE_GENTOO_FFMPEG AND NOT HAVE_FFMPEG_FFMPEG) + if(EXISTS /usr/include/ffmpeg/libavformat/avformat.h OR HAVE_FFMPEG_SWSCALE) + set(HAVE_GENTOO_FFMPEG TRUE) endif() endif() + if(HAVE_FFMPEG_CODEC AND HAVE_FFMPEG_FORMAT AND HAVE_FFMPEG_UTIL AND HAVE_FFMPEG_SWSCALE) + set(HAVE_FFMPEG TRUE) + endif() - set(HAVE_FFMPEG 0) - if(WITH_FFMPEG) - CHECK_MODULE(libavcodec HAVE_FFMPEG_CODEC) - CHECK_MODULE(libavformat HAVE_FFMPEG_FORMAT) - CHECK_MODULE(libavutil HAVE_FFMPEG_UTIL) - CHECK_MODULE(libswscale HAVE_FFMPEG_SWSCALE) - CHECK_INCLUDE_FILE(libavformat/avformat.h HAVE_GENTOO_FFMPEG) - CHECK_INCLUDE_FILE(ffmpeg/avformat.h HAVE_FFMPEG_FFMPEG) - if(NOT HAVE_GENTOO_FFMPEG AND NOT HAVE_FFMPEG_FFMPEG) - if(EXISTS /usr/include/ffmpeg/libavformat/avformat.h OR HAVE_FFMPEG_SWSCALE) - set(HAVE_GENTOO_FFMPEG 1) - endif() - endif() - if(HAVE_FFMPEG_CODEC AND HAVE_FFMPEG_FORMAT AND HAVE_FFMPEG_UTIL) - if(HAVE_FFMPEG_SWSCALE) - set(HAVE_FFMPEG 1) - endif() - endif() - + if(HAVE_FFMPEG) # Find the bzip2 library because it is required on some systems FIND_LIBRARY(BZIP2_LIBRARIES NAMES bz2 bzip2) if(NOT BZIP2_LIBRARIES) # Do an other trial FIND_FILE(BZIP2_LIBRARIES NAMES libbz2.so.1 PATHS /lib) endif() - endif() - - if(WITH_1394) - CHECK_MODULE(libdc1394-2 HAVE_DC1394_2) - if(NOT HAVE_DC1394_2) - CHECK_MODULE(libdc1394 HAVE_DC1394) - endif() - else() - set(HAVE_DC1394_2 FALSE) - set(HAVE_DC1394 FALSE) - endif() - - if(NOT APPLE) - CHECK_INCLUDE_FILE(alloca.h HAVE_ALLOCA_H) - CHECK_FUNCTION_EXISTS(alloca HAVE_ALLOCA) - CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) - CHECK_INCLUDE_FILE(pthread.h HAVE_LIBPTHREAD) - - if(WITH_XINE) - CHECK_MODULE(libxine HAVE_XINE) - else() - set(HAVE_XINE FALSE) - endif() - if(WITH_V4L) - CHECK_MODULE(libv4l1 HAVE_LIBV4L) - CHECK_INCLUDE_FILE(linux/videodev.h HAVE_CAMV4L) - CHECK_INCLUDE_FILE(linux/videodev2.h HAVE_CAMV4L2) - else() - set(HAVE_LIBV4L FALSE) - set(HAVE_CAMV4L FALSE) - set(HAVE_CAMV4L2 FALSE) - endif() - - if(ANDROID) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m log) - elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR ${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} m pthread) - else() - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m pthread rt) - endif() - else() - add_definitions(-DHAVE_ALLOCA -DHAVE_ALLOCA_H -DHAVE_LIBPTHREAD -DHAVE_UNISTD_H) - endif() -endif() - -if(APPLE AND WITH_FFMPEG) - set(FFMPEG_DEFAULT_INCLUDE_DIRS "/usr/local/include/" "/usr/include/" "opt/include/") - - find_path(FFMPEG_INCLUDE_DIR "libavformat/avformat.h" PATHS ${FFMPEG_DEFAULT_INCLUDE_DIRS} DOC "The path to FFMPEG headers") - if(FFMPEG_INCLUDE_DIR) - set(HAVE_GENTOO_FFMPEG 1) - set(FFMPEG_LIB_DIR "${FFMPEG_INCLUDE_DIR}/../lib" CACHE PATH "Full path of FFMPEG library directory") - if(EXISTS "${FFMPEG_LIB_DIR}/libavcodec.a") - set(HAVE_FFMPEG_CODEC 1) - set(ALIASOF_libavcodec_VERSION "Unknown") - if(EXISTS "${FFMPEG_LIB_DIR}/libavformat.a") - set(HAVE_FFMPEG_FORMAT 1) - set(ALIASOF_libavformat_VERSION "Unknown") - if(EXISTS "${FFMPEG_LIB_DIR}/libavutil.a") - set(HAVE_FFMPEG_UTIL 1) - set(ALIASOF_libavutil_VERSION "Unknown") - if(EXISTS "${FFMPEG_LIB_DIR}/libswscale.a") - ocv_include_directories(${FFMPEG_INCLUDE_DIR}) - set(HAVE_FFMPEG_SWSCALE 1) - set(ALIASOF_libswscale_VERSION "Unknown") - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "${FFMPEG_LIB_DIR}/libavcodec.a" - "${FFMPEG_LIB_DIR}/libavformat.a" "${FFMPEG_LIB_DIR}/libavutil.a" - "${FFMPEG_LIB_DIR}/libswscale.a") - set(HAVE_FFMPEG 1) - endif() - endif() - endif() - endif() + endif(HAVE_FFMPEG) endif() -endif() -if(WIN32 AND WITH_FFMPEG) - include(3rdparty/ffmpeg/ffmpeg_version.cmake REQUIRED) -endif() + if(APPLE) + find_path(FFMPEG_INCLUDE_DIR "libavformat/avformat.h" + PATHS /usr/local /usr /opt + PATH_SUFFIXES include + DOC "The path to FFMPEG headers") + if(FFMPEG_INCLUDE_DIR) + set(HAVE_GENTOO_FFMPEG TRUE) + set(FFMPEG_LIB_DIR "${FFMPEG_INCLUDE_DIR}/../lib" CACHE PATH "Full path of FFMPEG library directory") + if(EXISTS "${FFMPEG_LIB_DIR}/libavcodec.a") + set(HAVE_FFMPEG_CODEC 1) + set(ALIASOF_libavcodec_VERSION "Unknown") + if(EXISTS "${FFMPEG_LIB_DIR}/libavformat.a") + set(HAVE_FFMPEG_FORMAT 1) + set(ALIASOF_libavformat_VERSION "Unknown") + if(EXISTS "${FFMPEG_LIB_DIR}/libavutil.a") + set(HAVE_FFMPEG_UTIL 1) + set(ALIASOF_libavutil_VERSION "Unknown") + if(EXISTS "${FFMPEG_LIB_DIR}/libswscale.a") + set(HAVE_FFMPEG_SWSCALE 1) + set(ALIASOF_libswscale_VERSION "Unknown") + set(HAVE_FFMPEG 1) + endif() + endif() + endif() + endif() + endif(FFMPEG_INCLUDE_DIR) + if(HAVE_FFMPEG) + set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "${FFMPEG_LIB_DIR}/libavcodec.a" + "${FFMPEG_LIB_DIR}/libavformat.a" "${FFMPEG_LIB_DIR}/libavutil.a" + "${FFMPEG_LIB_DIR}/libswscale.a") + ocv_include_directories(${FFMPEG_INCLUDE_DIR}) + endif() + endif(APPLE) +endif(WITH_FFMPEG) -#################### LATEX for dpf documentation ################## +# --- VideoInput --- +if(WITH_VIDEOINPUT) + # always have VideoInput on Windows + set(HAVE_VIDEOINPUT 1) +endif(WITH_VIDEOINPUT) + +# --- Extra HighGUI libs on Windows --- +if(WIN32) + list(APPEND HIGHGUI_LIBRARIES comctl32 gdi32 ole32) + if(MSVC) + list(APPEND HIGHGUI_LIBRARIES vfw32) + elseif(MINGW64) + list(APPEND HIGHGUI_LIBRARIES msvfw32 avifil32 avicap32 winmm) + elseif(MINGW) + list(APPEND HIGHGUI_LIBRARIES vfw32 winmm) + endif() +endif(WIN32) + + +# ---------------------------------------------------------------------------- +# Detect other 3rd-party libraries/tools +# ---------------------------------------------------------------------------- +# --- TBB --- +if(WITH_TBB) + include(cmake/OpenCVDetectTBB.cmake REQUIRED) +endif(WITH_TBB) + +# --- IPP --- +ocv_clear_vars(IPP_FOUND) +if(WITH_IPP) + include(cmake/OpenCVFindIPP.cmake) + if(IPP_FOUND) + add_definitions(-DHAVE_IPP) + ocv_include_directories(${IPP_INCLUDE_DIRS}) + link_directories(${IPP_LIBRARY_DIRS}) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${IPP_LIBRARIES}) + endif() +endif(WITH_IPP) + +# --- CUDA --- +if(WITH_CUDA) + include(cmake/OpenCVDetectCUDA.cmake REQUIRED) +endif(WITH_CUDA) + +# --- Eigen --- +if(WITH_EIGEN) + find_path(EIGEN_INCLUDE_PATH "Eigen/Core" + PATHS /usr/local /opt /usr ENV ProgramFiles ENV ProgramW6432 + PATH_SUFFIXES include/eigen3 include/eigen2 Eigen/include/eigen3 Eigen/include/eigen2 + DOC "The path to Eigen3/Eigen2 headers") + + if(EIGEN_INCLUDE_PATH) + ocv_include_directories(${EIGEN_INCLUDE_PATH}) + ocv_parse_header("${EIGEN_INCLUDE_PATH}/Eigen/src/Core/util/Macros.h" EIGEN_VERSION_LINES EIGEN_WORLD_VERSION EIGEN_MAJOR_VERSION EIGEN_MINOR_VERSION) + set(HAVE_EIGEN 1) + endif() +endif(WITH_EIGEN) + +# --- LATEX for pdf documentation --- if(BUILD_DOCS) include(cmake/OpenCVFindLATEX.cmake REQUIRED) -endif() +endif(BUILD_DOCS) -########################## Python Support ######################### +# --- Python Support --- include(cmake/OpenCVDetectPython.cmake REQUIRED) -########################### Java Support ########################## +# --- Java Support --- if(ANDROID) include(cmake/OpenCVDetectApacheAnt.cmake REQUIRED) include(cmake/OpenCVDetectAndroidSDK.cmake REQUIRED) @@ -485,7 +593,7 @@ if(ANDROID) if(NOT ANDROID_TOOLS_Pkg_Revision GREATER 13) message(WARNING "OpenCV requires Android SDK tools revision 14 or newer. Otherwise tests and samples will no be compiled.") endif() -endif() +endif(ANDROID) if(ANDROID AND ANDROID_EXECUTABLE AND ANT_EXECUTABLE AND (ANT_VERSION VERSION_GREATER 1.7) AND (ANDROID_TOOLS_Pkg_Revision GREATER 13)) SET(CAN_BUILD_ANDROID_PROJECTS TRUE) @@ -493,115 +601,6 @@ else() SET(CAN_BUILD_ANDROID_PROJECTS FALSE) endif() -############################### QT ################################ -set(HAVE_QT 0) -set(HAVE_QT_OPENGL 0) - -if(WITH_QT) - find_package(Qt4) - if(QT4_FOUND) - set(HAVE_QT 1) - add_definitions(-DHAVE_QT) #We need to define te macro this way, using cvconfig.h.cmake does not work - - if(WITH_OPENGL) - find_package (OpenGL QUIET) - if(QT_QTOPENGL_FOUND AND OPENGL_FOUND) - set(HAVE_OPENGL 1) - set(HAVE_QT_OPENGL 1) - add_definitions(-DHAVE_QT_OPENGL) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${OPENGL_LIBRARIES}) - endif() - endif() - endif() -endif() - -############################### TBB ################################ -if(WITH_TBB) - include(cmake/OpenCVDetectTBB.cmake REQUIRED) -endif() - -############################ Intel IPP ############################# -set(IPP_FOUND) - -if(WITH_IPP) - include(cmake/OpenCVFindIPP.cmake) -endif() - -if(IPP_FOUND) - add_definitions(-DHAVE_IPP) - ocv_include_directories(${IPP_INCLUDE_DIRS}) - link_directories(${IPP_LIBRARY_DIRS}) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${IPP_LIBRARIES}) -endif() - -############################### CUDA ################################ -if(WITH_CUDA) - include(cmake/OpenCVDetectCUDA.cmake REQUIRED) -endif() - -############################### OpenNI ################################ -set(HAVE_OPENNI FALSE) -set(HAVE_OPENNI_PRIME_SENSOR_MODULE FALSE) - -if(WITH_OPENNI) - include(cmake/OpenCVFindOpenNI.cmake) -endif() - -############################### XIMEA ################################ -set(HAVE_XIMEA FALSE) - -if(WITH_XIMEA) - include(cmake/OpenCVFindXimea.cmake) -endif() - -if(XIMEA_FOUND) - set(HAVE_XIMEA TRUE) -endif() - -############################## Eigen ############################## -if(WITH_EIGEN) - find_path(EIGEN_INCLUDE_PATH "Eigen/Core" - PATHS "/usr/local/include/eigen2" "/opt/include/eigen2" "/usr/include/eigen2" - "/usr/local/include/eigen3" "/opt/include/eigen3" "/usr/include/eigen3" - DOC "The path to Eigen2/Eigen3 headers") - if(EIGEN_INCLUDE_PATH) - ocv_include_directories(${EIGEN_INCLUDE_PATH}) - ocv_parse_header("${EIGEN_INCLUDE_PATH}/Eigen/src/Core/util/Macros.h" EIGEN_VERSION_LINES EIGEN_WORLD_VERSION EIGEN_MAJOR_VERSION EIGEN_MINOR_VERSION) - set(HAVE_EIGEN 1) - endif() -endif() - -################## Extra HighGUI libs on Windows ################### -if(WIN32) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} comctl32 gdi32 ole32) - - if(WITH_VIDEOINPUT) - set(HAVE_VIDEOINPUT 1) - endif() - - if(MSVC) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} vfw32) - endif() - - if(MINGW) - if(MINGW64) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} msvfw32 avifil32 avicap32 winmm) - else() - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} vfw32 winmm) - endif() - endif() - - if(WITH_OPENGL AND NOT HAVE_QT_OPENGL) - find_package(OpenGL QUIET) - - if(OPENGL_FOUND) - set(HAVE_OPENGL 1) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${OPENGL_LIBRARIES}) - ocv_include_directories(${OPENGL_INCLUDE_DIR}) - endif() - endif() -endif() - # ---------------------------------------------------------------------------- # Solution folders: @@ -667,12 +666,12 @@ if(OPENCV_SVNVERSION) status("Version control:" ${OPENCV_SVNVERSION}) endif() -#build platform +# ========================== build platform ========================== status("") status(" Platform:") status(" Host:" ${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_VERSION} ${CMAKE_HOST_SYSTEM_PROCESSOR}) if(CMAKE_CROSSCOMPILING) - status(" Target:" ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR}) + status(" Target:" ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR}) endif() status(" CMake:" ${CMAKE_VERSION}) status(" CMake generator:" ${CMAKE_GENERATOR}) @@ -687,7 +686,7 @@ if(NOT CMAKE_GENERATOR MATCHES "Xcode|Visual Studio") status(" Configuration:" ${CMAKE_BUILD_TYPE}) endif() -# C/C++ options +# ========================== C/C++ options ========================== status("") status(" C/C++:") status(" Built as dynamic libs?:" BUILD_SHARED_LIBS THEN YES ELSE NO) @@ -705,7 +704,7 @@ else() status(" Linker flags (Debug):" ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}) endif() -# OpenCV modules +# ========================== OpenCV modules ========================== status("") status(" OpenCV modules:") string(REPLACE "opencv_" "" OPENCV_MODULES_BUILD_ST "${OPENCV_MODULES_BUILD}") @@ -724,11 +723,11 @@ endforeach() string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_AUTO_ST "${OPENCV_MODULES_DISABLED_AUTO_ST}") status(" To be built:" OPENCV_MODULES_BUILD THEN ${OPENCV_MODULES_BUILD_ST} ELSE "-") -status(" Disabled by user:" OPENCV_MODULES_DISABLED_USER THEN ${OPENCV_MODULES_DISABLED_USER_ST} ELSE "-") +status(" Disabled:" OPENCV_MODULES_DISABLED_USER THEN ${OPENCV_MODULES_DISABLED_USER_ST} ELSE "-") status(" Disabled by dependency:" OPENCV_MODULES_DISABLED_AUTO THEN ${OPENCV_MODULES_DISABLED_AUTO_ST} ELSE "-") status(" Unavailable:" OPENCV_MODULES_DISABLED_FORCE THEN ${OPENCV_MODULES_DISABLED_FORCE_ST} ELSE "-") -# Android extra +# ========================== Android details ========================== if(ANDROID) status("") status(" Android: ") @@ -744,14 +743,17 @@ if(ANDROID) status(" ant:" ANT_EXECUTABLE THEN "${ANT_EXECUTABLE} (ver ${ANT_VERSION})" ELSE NO) endif() -#YV +# ========================== GUI ========================== status("") status(" GUI: ") -if (HAVE_QT) +if(HAVE_QT) status(" QT 4.x:" HAVE_QT THEN "YES (ver ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} ${QT_EDITION})" ELSE NO) status(" QT OpenGL support:" HAVE_QT_OPENGL THEN "YES (${QT_QTOPENGL_LIBRARY})" ELSE NO) else() + if(DEFINED WITH_QT) + status(" QT 4.x:" NO) + endif() if(WIN32) status(" Win32 UI:" YES) else() @@ -771,7 +773,7 @@ endif() status(" OpenGL support:" HAVE_OPENGL THEN "YES (${OPENGL_LIBRARIES})" ELSE NO) -# media +# ========================== MEDIA IO ========================== status("") status(" Media I/O: ") status(" ZLib:" BUILD_ZLIB THEN "build (ver ${ZLIB_VERSION_STRING})" ELSE "${ZLIB_LIBRARY} (ver ${ZLIB_VERSION_STRING})") @@ -802,82 +804,120 @@ else() endif() status(" OpenEXR:" WITH_OPENEXR AND OPENEXR_FOUND THEN "${OPENEXR_LIBRARIES} (ver ${OPENEXR_VERSION})" ELSE NO) -status(" OpenNI:" HAVE_OPENNI THEN "YES (ver ${OPENNI_VERSION_STRING}, build ${OPENNI_VERSION_BUILD})" ELSE NO) -status(" OpenNI PrimeSensor Modules:" - HAVE_OPENNI_PRIME_SENSOR_MODULE THEN "YES (${OPENNI_PRIME_SENSOR_MODULE})" ELSE NO) -if(WIN32) - status(" XIMEA:" HAVE_XIMEA THEN YES ELSE NO) -endif() -# video +# ========================== VIDEO IO ========================== status("") -if(UNIX AND NOT APPLE) - status(" Video I/O:") +status(" Video I/O:") + +if(DEFINED WITH_1394) status(" DC1394 1.x:" HAVE_DC1394 THEN "YES (ver ${ALIASOF_libdc1394_VERSION})" ELSE NO) status(" DC1394 2.x:" HAVE_DC1394_2 THEN "YES (ver ${ALIASOF_libdc1394-2_VERSION})" ELSE NO) - status(" GStreamer:" HAVE_GSTREAMER THEN "" ELSE NO) +endif(DEFINED WITH_1394) + +if(ANDROID) + if(HAVE_opencv_androidcamera) + status(" AndroidNativeCamera:" BUILD_ANDROID_CAMERA_WRAPPER + THEN "YES, build for Android${ANDROID_VERSION}" ELSE "YES, use prebuilt libraries") + else() + status(" AndroidNativeCamera:" "NO (native camera requires Android API level 8 or higher)") + endif() +endif() + +if(DEFINED WITH_AVFOUNDATION) + status(" AVFoundation:" WITH_AVFOUNDATION THEN YES ELSE NO) +endif(DEFINED WITH_AVFOUNDATION) + +if(DEFINED WITH_FFMPEG) + if(WIN32) + status(" FFMPEG:" WITH_FFMPEG THEN "YES (prebuilt binaries)" ELSE NO) + else() + status(" FFMPEG:" HAVE_FFMPEG THEN YES ELSE NO) + endif() + status(" codec:" HAVE_FFMPEG_CODEC THEN "YES (ver ${ALIASOF_libavcodec_VERSION})" ELSE NO) + status(" format:" HAVE_FFMPEG_FORMAT THEN "YES (ver ${ALIASOF_libavformat_VERSION})" ELSE NO) + status(" util:" HAVE_FFMPEG_UTIL THEN "YES (ver ${ALIASOF_libavutil_VERSION})" ELSE NO) + status(" swscale:" HAVE_FFMPEG_SWSCALE THEN "YES (ver ${ALIASOF_libswscale_VERSION})" ELSE NO) + status(" gentoo-style:" HAVE_GENTOO_FFMPEG THEN YES ELSE NO) +endif(DEFINED WITH_FFMPEG) + +if(DEFINED WITH_GSTREAMER) + status(" GStreamer:" HAVE_GSTREAMER THEN "" ELSE NO) if(HAVE_GSTREAMER) status(" base:" "YES (ver ${ALIASOF_gstreamer-base-0.10_VERSION})") status(" app:" "YES (ver ${ALIASOF_gstreamer-app-0.10_VERSION})") status(" video:" "YES (ver ${ALIASOF_gstreamer-video-0.10_VERSION})") endif() - status(" UniCap:" HAVE_UNICAP THEN "YES (ver ${ALIASOF_libunicap_VERSION})" ELSE NO) - status(" UniCap ucil:" HAVE_UNICAP_UCIL THEN "YES (ver ${ALIASOF_libucil_VERSION})" ELSE NO) - status(" PvAPI:" HAVE_PVAPI THEN YES ELSE NO) +endif(DEFINED WITH_GSTREAMER) + +if(DEFINED WITH_OPENNI) + status(" OpenNI:" HAVE_OPENNI THEN "YES (ver ${OPENNI_VERSION_STRING}, build ${OPENNI_VERSION_BUILD})" + ELSE NO) + status(" OpenNI PrimeSensor Modules:" HAVE_OPENNI_PRIME_SENSOR_MODULE + THEN "YES (${OPENNI_PRIME_SENSOR_MODULE})" ELSE NO) +endif(DEFINED WITH_OPENNI) + +if(DEFINED WITH_PVAPI) + status(" PvAPI:" HAVE_PVAPI THEN YES ELSE NO) +endif(DEFINED WITH_PVAPI) + +if(DEFINED WITH_QUICKTIME) + status(" QuickTime:" WITH_QUICKTIME THEN YES ELSE NO) + status(" QTKit:" WITH_QUICKTIME THEN NO ELSE YES) +endif(DEFINED WITH_QUICKTIME) + +if(DEFINED WITH_UNICAP) + status(" UniCap:" HAVE_UNICAP THEN "YES (ver ${ALIASOF_libunicap_VERSION})" ELSE NO) + status(" UniCap ucil:" HAVE_UNICAP_UCIL THEN "YES (ver ${ALIASOF_libucil_VERSION})" ELSE NO) +endif(DEFINED WITH_UNICAP) + +if(DEFINED WITH_V4L) if(HAVE_CAMV4L) set(HAVE_CAMV4L_STR "YES") else() set(HAVE_CAMV4L_STR "NO") endif() - if(HAVE_CAMV4L2) + if(HAVE_CAMV4L2) set(HAVE_CAMV4L2_STR "YES") else() set(HAVE_CAMV4L2_STR "NO") endif() - status(" V4L/V4L2:" HAVE_LIBV4L THEN "Using libv4l (ver ${ALIASOF_libv4l1_VERSION})" ELSE "${HAVE_CAMV4L_STR}/${HAVE_CAMV4L2_STR}") - status(" Xine:" HAVE_XINE THEN "YES (ver ${ALIASOF_libxine_VERSION})" ELSE NO) + status(" V4L/V4L2:" HAVE_LIBV4L THEN "Using libv4l (ver ${ALIASOF_libv4l1_VERSION})" + ELSE "${HAVE_CAMV4L_STR}/${HAVE_CAMV4L2_STR}") +endif(DEFINED WITH_V4L) - if(ANDROID) - if(HAVE_opencv_androidcamera) - status(" AndroidNativeCamera:" BUILD_ANDROID_CAMERA_WRAPPER THEN "YES, build for Android ${ANDROID_VERSION}" ELSE "YES, use prebuilt libraries") - else() - status(" AndroidNativeCamera:" "NO (native camera requires Android API level 8 or higher)") - endif() - endif() -elseif(APPLE) - if(NOT IOS) - status(" Video I/O:" WITH_QUICKTIME THEN QuickTime ELSE QTKit) - else() - status(" Video I/O: AVFoundation") - endif() -elseif(WIN32) - status(" Video I/O:" HAVE_VIDEOINPUT THEN DirectShow ELSE NO) -endif() +if(DEFINED WITH_VIDEOINPUT) + status(" DirectShow:" HAVE_VIDEOINPUT THEN YES ELSE NO) +endif(DEFINED WITH_VIDEOINPUT) -if(WIN32) - status(" FFMPEG:" WITH_FFMPEG THEN "YES (prebuilt binaries)" ELSE NO) -else() - status(" FFMPEG:" HAVE_FFMPEG THEN YES ELSE NO) -endif() -status(" codec:" HAVE_FFMPEG_CODEC THEN "YES (ver ${ALIASOF_libavcodec_VERSION})" ELSE NO) -status(" format:" HAVE_FFMPEG_FORMAT THEN "YES (ver ${ALIASOF_libavformat_VERSION})" ELSE NO) -status(" util:" HAVE_FFMPEG_UTIL THEN "YES (ver ${ALIASOF_libavutil_VERSION})" ELSE NO) -status(" swscale:" HAVE_FFMPEG_SWSCALE THEN "YES (ver ${ALIASOF_libswscale_VERSION})" ELSE NO) -status(" gentoo-style:" HAVE_GENTOO_FFMPEG THEN YES ELSE NO) +if(DEFINED WITH_XIMEA) + status(" XIMEA:" HAVE_XIMEA THEN YES ELSE NO) +endif(DEFINED WITH_XIMEA) -# Other third-party libraries +if(DEFINED WITH_XINE) + status(" Xine:" HAVE_XINE THEN "YES (ver ${ALIASOF_libxine_VERSION})" ELSE NO) +endif(DEFINED WITH_XINE) + +# ========================== Other third-party libraries ========================== status("") status(" Other third-party libraries:") -if(WITH_IPP AND IPP_FOUND) - status(" Use IPP:" "${IPP_LATEST_VERSION_STR} [${IPP_LATEST_VERSION_MAJOR}.${IPP_LATEST_VERSION_MINOR}.${IPP_LATEST_VERSION_BUILD}]") - status(" at:" "${IPP_ROOT_DIR}") -else() - status(" Use IPP:" WITH_IPP AND NOT IPP_FOUND THEN "IPP not found" ELSE NO) -endif() +if(DEFINED WITH_IPP) + if(WITH_IPP AND IPP_FOUND) + status(" Use IPP:" "${IPP_LATEST_VERSION_STR} [${IPP_LATEST_VERSION_MAJOR}.${IPP_LATEST_VERSION_MINOR}.${IPP_LATEST_VERSION_BUILD}]") + status(" at:" "${IPP_ROOT_DIR}") + else() + status(" Use IPP:" WITH_IPP AND NOT IPP_FOUND THEN "IPP not found" ELSE NO) + endif() +endif(DEFINED WITH_IPP) + +if(DEFINED WITH_TBB) + status(" Use TBB:" HAVE_TBB THEN "YES (ver ${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} interface ${TBB_INTERFACE_VERSION})" ELSE NO) +endif(DEFINED WITH_TBB) + +if(DEFINED WITH_CUDA) + status(" Use Cuda:" HAVE_CUDA THEN "YES (ver ${CUDA_VERSION_STRING})" ELSE NO) +endif(DEFINED WITH_CUDA) -status(" Use TBB:" HAVE_TBB THEN "YES (ver ${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR} interface ${TBB_INTERFACE_VERSION})" ELSE NO) -status(" Use Cuda:" HAVE_CUDA THEN "YES (ver ${CUDA_VERSION_STRING})" ELSE NO) status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO) if(HAVE_CUDA) @@ -891,7 +931,7 @@ if(HAVE_CUDA) status(" NVIDIA GPU features:" ${OPENCV_CUDA_ARCH_FEATURES}) endif() -# interfaces to other languages +# ========================== python ========================== status("") status(" Python:") status(" Interpreter:" PYTHON_EXECUTABLE THEN "${PYTHON_EXECUTABLE} (ver ${PYTHON_VERSION_FULL})" ELSE NO) @@ -905,12 +945,7 @@ if(BUILD_opencv_python) status(" packages path:" PYTHON_EXECUTABLE THEN "${PYTHON_PACKAGES_PATH}" ELSE "-") endif() -if(BUILD_opencv_java) - status("") - status(" Java:" HAVE_opencv_java THEN YES ELSE NO) -endif() - -# documentation +# ========================== documentation ========================== if(BUILD_DOCS) status("") status(" Documentation:") @@ -923,7 +958,7 @@ if(BUILD_DOCS) status(" PdfLaTeX compiler:" PDFLATEX_COMPILER THEN "${PDFLATEX_COMPILER}" ELSE NO) endif() -# samples and tests +# ========================== samples and tests ========================== status("") status(" Tests and samples:") status(" Tests:" BUILD_TESTS AND HAVE_opencv_ts THEN YES ELSE NO) @@ -931,11 +966,11 @@ status(" Performance tests:" BUILD_PERF_TESTS AND HAVE_opencv_ts THEN YES EL status(" Examples:" BUILD_EXAMPLES THEN YES ELSE NO) if(ANDROID) - status(" Android tests:" BUILD_TESTS AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO) - status(" Android examples:" BUILD_ANDROID_EXAMPLES THEN YES ELSE NO) + status(" Android tests:" BUILD_TESTS AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO) + status(" Android examples:" BUILD_ANDROID_EXAMPLES AND CAN_BUILD_ANDROID_PROJECTS THEN YES ELSE NO) endif() -#auxiliary +# ========================== auxiliary ========================== status("") status(" Install path:" "${CMAKE_INSTALL_PREFIX}") status("") diff --git a/cmake/OpenCVCompilerOptions.cmake b/cmake/OpenCVCompilerOptions.cmake index e84eb6c988..be58bc6bd6 100644 --- a/cmake/OpenCVCompilerOptions.cmake +++ b/cmake/OpenCVCompilerOptions.cmake @@ -1,3 +1,18 @@ +if(MINGW) + # mingw compiler is known to produce unstable SSE code with -O3 hence we are trying to use -O2 instead + if(CMAKE_COMPILER_IS_GNUCXX) + foreach(flags CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG) + string(REPLACE "-O3" "-O2" ${flags} "${${flags}}") + endforeach() + endif() + + if(CMAKE_COMPILER_IS_GNUCC) + foreach(flags CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_DEBUG) + string(REPLACE "-O3" "-O2" ${flags} "${${flags}}") + endforeach() + endif() +endif() + if(MSVC) if(CMAKE_CXX_FLAGS STREQUAL CMAKE_CXX_FLAGS_INIT) # override cmake default exception handling option @@ -14,18 +29,18 @@ set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "") set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "") if(MINGW) - # mingw compiler is known to produce unstable SSE code + # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40838 # here we are trying to workaround the problem include(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG(-mstackrealign HAVE_STACKREALIGN_FLAG) - if(HAVE_STACKREALIGN_FLAG) - set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mstackrealign") - else() +# CHECK_CXX_COMPILER_FLAG(-mstackrealign HAVE_STACKREALIGN_FLAG) + # if(HAVE_STACKREALIGN_FLAG) + # set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mstackrealign") + #else() CHECK_CXX_COMPILER_FLAG(-mpreferred-stack-boundary=2 HAVE_PREFERRED_STACKBOUNDARY_FLAG) if(HAVE_PREFERRED_STACKBOUNDARY_FLAG) set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mstackrealign") endif() - endif() + #endif() endif() if(CMAKE_COMPILER_IS_GNUCXX) diff --git a/cmake/OpenCVDetectAndroidSDK.cmake b/cmake/OpenCVDetectAndroidSDK.cmake index 12550fd545..bd6abc3f6a 100644 --- a/cmake/OpenCVDetectAndroidSDK.cmake +++ b/cmake/OpenCVDetectAndroidSDK.cmake @@ -8,7 +8,7 @@ file(TO_CMAKE_PATH "$ENV{HOME}" HOME_ENV_PATH) if(CMAKE_HOST_WIN32) set(ANDROID_SDK_OS windows) elseif(CMAKE_HOST_APPLE) - set(ANDROID_SDK_OS mac) + set(ANDROID_SDK_OS macosx) else() set(ANDROID_SDK_OS linux) endif() diff --git a/cmake/OpenCVDetectPython.cmake b/cmake/OpenCVDetectPython.cmake index 59513ad480..e66410d4b3 100644 --- a/cmake/OpenCVDetectPython.cmake +++ b/cmake/OpenCVDetectPython.cmake @@ -1,4 +1,4 @@ -if(MSVC AND NOT PYTHON_EXECUTABLE) +if(WIN32 AND NOT PYTHON_EXECUTABLE) # search for executable with the same bitness as resulting binaries # standard FindPythonInterp always prefers executable from system path # this is really important because we are using the interpreter for numpy search and for choosing the install location diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index 599404d37f..caeaa68071 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -11,7 +11,7 @@ if(NOT COMMAND find_host_program) endmacro() endif() -#added include directories in such way that directories from the OpenCV source tree go first +# adds include directories in such way that directories from the OpenCV source tree go first function(ocv_include_directories) set(__add_before "") foreach(dir ${ARGN}) @@ -25,6 +25,12 @@ function(ocv_include_directories) include_directories(BEFORE ${__add_before}) endfunction() +# clears all passed variables +macro(ocv_clear_vars) + foreach(_var ${ARGN}) + unset(${_var} CACHE) + endforeach() +endmacro() # Provides an option that the user can optionally select. # Can accept condition to control when option is available for user. @@ -352,10 +358,11 @@ macro(ocv_parse_header2 LIBNAME HDR_PATH VARNAME SCOPE) set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${SCOPE}) endif() else() - unset(${LIBNAME}_VERSION_MAJOR CACHE) - unset(${LIBNAME}_VERSION_MINOR CACHE) - unset(${LIBNAME}_VERSION_PATCH CACHE) - unset(${LIBNAME}_VERSION_TWEAK CACHE) - unset(${LIBNAME}_VERSION_STRING CACHE) + ocv_clear_vars(${LIBNAME}_VERSION_MAJOR + ${LIBNAME}_VERSION_MAJOR + ${LIBNAME}_VERSION_MINOR + ${LIBNAME}_VERSION_PATCH + ${LIBNAME}_VERSION_TWEAK + ${LIBNAME}_VERSION_STRING) endif() endmacro() diff --git a/modules/contrib/src/detection_based_tracker.cpp b/modules/contrib/src/detection_based_tracker.cpp index e5802b95b0..90392e30f0 100644 --- a/modules/contrib/src/detection_based_tracker.cpp +++ b/modules/contrib/src/detection_based_tracker.cpp @@ -107,12 +107,15 @@ class DetectionBasedTracker::SeparateDetectionWork DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork(DetectionBasedTracker& _detectionBasedTracker, const std::string& cascadeFilename) :detectionBasedTracker(_detectionBasedTracker), - cascadeInThread(cascadeFilename), + cascadeInThread(), isObjectDetectingReady(false), shouldObjectDetectingResultsBeForgot(false), stateThread(STATE_THREAD_STOPPED), timeWhenDetectingThreadStartedWork(-1) { + if(!cascadeInThread.load(cascadeFilename)) { + CV_Error(CV_StsBadArg, "DetectionBasedTracker::SeparateDetectionWork::SeparateDetectionWork: Cannot load a cascade from the file '"+cascadeFilename+"'"); + } int res=0; res=pthread_mutex_init(&mutex, NULL);//TODO: should be attributes? if (res) { @@ -439,14 +442,17 @@ DetectionBasedTracker::InnerParameters::InnerParameters() DetectionBasedTracker::DetectionBasedTracker(const std::string& cascadeFilename, const Parameters& params) :separateDetectionWork(), innerParameters(), - numTrackedSteps(0), - cascadeForTracking(cascadeFilename) + numTrackedSteps(0) { CV_Assert( (params.minObjectSize > 0) && (params.maxObjectSize >= 0) && (params.scaleFactor > 1.0) && (params.maxTrackLifetime >= 0) ); + if (!cascadeForTracking.load(cascadeFilename)) { + CV_Error(CV_StsBadArg, "DetectionBasedTracker::DetectionBasedTracker: Cannot load a cascade from the file '"+cascadeFilename+"'"); + } + parameters=params; separateDetectionWork=new SeparateDetectionWork(*this, cascadeFilename); diff --git a/modules/core/include/opencv2/core/internal.hpp b/modules/core/include/opencv2/core/internal.hpp index 6e1547d848..d0b3cd4ec7 100644 --- a/modules/core/include/opencv2/core/internal.hpp +++ b/modules/core/include/opencv2/core/internal.hpp @@ -233,6 +233,34 @@ CV_INLINE IppiSize ippiSize(int width, int height) } #endif + + #define CV_INIT_ALGORITHM(classname, algname, memberinit) \ + static Algorithm* create##classname() \ + { \ + return new classname; \ + } \ + \ + static AlgorithmInfo& classname##_info() \ + { \ + static AlgorithmInfo classname##_info_var(algname, create##classname); \ + return classname##_info_var; \ + } \ + \ + static AlgorithmInfo& classname##_info_auto = classname##_info(); \ + \ + AlgorithmInfo* classname::info() const \ + { \ + static volatile bool initialized = false; \ + \ + if( !initialized ) \ + { \ + initialized = true; \ + classname obj; \ + memberinit; \ + } \ + return &classname##_info(); \ + } + #endif /* maximal size of vector to run matrix operations on it inline (i.e. w/o ipp calls) */ diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 29234b073d..6b86cd7e43 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -322,7 +322,10 @@ inline Mat Mat::diag(const Mat& d) CV_Assert( d.cols == 1 || d.rows == 1 ); int len = d.rows + d.cols - 1; Mat m(len, len, d.type(), Scalar(0)), md = m.diag(); - d.copyTo(md); + if( d.cols == 1 ) + d.copyTo(md); + else + transpose(d, md); return m; } diff --git a/modules/features2d/src/features2d_init.cpp b/modules/features2d/src/features2d_init.cpp index 89d517fc1d..3312d9e915 100644 --- a/modules/features2d/src/features2d_init.cpp +++ b/modules/features2d/src/features2d_init.cpp @@ -51,208 +51,93 @@ namespace cv 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(); -} - +CV_INIT_ALGORITHM(BriefDescriptorExtractor, "Feature2D.BRIEF", + obj.info()->addParam(obj, "bytes", obj.bytes_)); /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static Algorithm* createORB() { return new ORB; } -static AlgorithmInfo& orb_info() -{ - static AlgorithmInfo orb_info_var("Feature2D.ORB", createORB); - return orb_info_var; -} +CV_INIT_ALGORITHM(FastFeatureDetector, "Feature2D.FAST", + obj.info()->addParam(obj, "threshold", obj.threshold); + obj.info()->addParam(obj, "nonmaxSuppression", obj.nonmaxSuppression)); -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); +CV_INIT_ALGORITHM(StarDetector, "Feature2D.STAR", + obj.info()->addParam(obj, "maxSize", obj.maxSize); + obj.info()->addParam(obj, "responseThreshold", obj.responseThreshold); + obj.info()->addParam(obj, "lineThresholdProjected", obj.lineThresholdProjected); + obj.info()->addParam(obj, "lineThresholdBinarized", obj.lineThresholdBinarized); + obj.info()->addParam(obj, "suppressNonmaxSize", obj.suppressNonmaxSize)); -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); +CV_INIT_ALGORITHM(MSER, "Feature2D.MSER", + obj.info()->addParam(obj, "delta", obj.delta); + obj.info()->addParam(obj, "minArea", obj.minArea); + obj.info()->addParam(obj, "maxArea", obj.maxArea); + obj.info()->addParam(obj, "maxVariation", obj.maxVariation); + obj.info()->addParam(obj, "minDiversity", obj.minDiversity); + obj.info()->addParam(obj, "maxEvolution", obj.maxEvolution); + obj.info()->addParam(obj, "areaThreshold", obj.areaThreshold); + obj.info()->addParam(obj, "minMargin", obj.minMargin); + obj.info()->addParam(obj, "edgeBlurSize", obj.edgeBlurSize)); -AlgorithmInfo* DenseFeatureDetector::info() const +/////////////////////////////////////////////////////////////////////////////////////////////////////////// + +CV_INIT_ALGORITHM(ORB, "Feature2D.ORB", + obj.info()->addParam(obj, "nFeatures", obj.nfeatures); + obj.info()->addParam(obj, "scaleFactor", obj.scaleFactor); + obj.info()->addParam(obj, "nLevels", obj.nlevels); + obj.info()->addParam(obj, "firstLevel", obj.firstLevel); + obj.info()->addParam(obj, "edgeThreshold", obj.edgeThreshold); + obj.info()->addParam(obj, "patchSize", obj.patchSize); + obj.info()->addParam(obj, "WTA_K", obj.WTA_K); + obj.info()->addParam(obj, "scoreType", obj.scoreType)); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// + +CV_INIT_ALGORITHM(GFTTDetector, "Feature2D.GFTT", + obj.info()->addParam(obj, "nfeatures", obj.nfeatures); + obj.info()->addParam(obj, "qualityLevel", obj.qualityLevel); + obj.info()->addParam(obj, "minDistance", obj.minDistance); + obj.info()->addParam(obj, "useHarrisDetector", obj.useHarrisDetector); + obj.info()->addParam(obj, "k", obj.k)); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class CV_EXPORTS HarrisDetector : public GFTTDetector { - 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; -} +public: + HarrisDetector( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1, + int blockSize=3, bool useHarrisDetector=true, double k=0.04 ) + : GFTTDetector( maxCorners, qualityLevel, minDistance, blockSize, useHarrisDetector, k ) {} + AlgorithmInfo* info() const; +}; + +CV_INIT_ALGORITHM(HarrisDetector, "Feature2D.HARRIS", + obj.info()->addParam(obj, "nfeatures", obj.nfeatures); + obj.info()->addParam(obj, "qualityLevel", obj.qualityLevel); + obj.info()->addParam(obj, "minDistance", obj.minDistance); + obj.info()->addParam(obj, "useHarrisDetector", obj.useHarrisDetector); + obj.info()->addParam(obj, "k", obj.k)); + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + +CV_INIT_ALGORITHM(DenseFeatureDetector, "Feature2D.Dense", + obj.info()->addParam(obj, "initFeatureScale", obj.initFeatureScale); + obj.info()->addParam(obj, "featureScaleLevels", obj.featureScaleLevels); + obj.info()->addParam(obj, "featureScaleMul", obj.featureScaleMul); + obj.info()->addParam(obj, "initXyStep", obj.initXyStep); + obj.info()->addParam(obj, "initImgBound", obj.initImgBound); + obj.info()->addParam(obj, "varyXyStepWithScale", obj.varyXyStepWithScale); + obj.info()->addParam(obj, "varyImgBoundWithScale", obj.varyImgBoundWithScale)); bool initModule_features2d(void) { - Ptr brief = createBRIEF(), orb = createORB(), - star = createStarDetector(), fastd = createFAST(), mser = createMSER(), - dense = createDense(), gftt = createGFTT(), harris = createHarris(); + Ptr brief = createBriefDescriptorExtractor(), orb = createORB(), + star = createStarDetector(), fastd = createFastFeatureDetector(), mser = createMSER(), + dense = createDenseFeatureDetector(), gftt = createGFTTDetector(), harris = createHarrisDetector(); return brief->info() != 0 && orb->info() != 0 && star->info() != 0 && fastd->info() != 0 && mser->info() != 0 && dense->info() != 0 && diff --git a/modules/highgui/CMakeLists.txt b/modules/highgui/CMakeLists.txt index a5ef22c89a..e683096497 100644 --- a/modules/highgui/CMakeLists.txt +++ b/modules/highgui/CMakeLists.txt @@ -7,52 +7,56 @@ ocv_add_module(highgui opencv_imgproc OPTIONAL opencv_androidcamera) # Jose Luis Blanco, 2008 # ---------------------------------------------------------------------------- -set(GRFMT_LIBS "") +ocv_clear_vars(GRFMT_LIBS) if(WITH_PNG OR WITH_TIFF OR WITH_OPENEXR) ocv_include_directories(${ZLIB_INCLUDE_DIR}) - set(GRFMT_LIBS ${GRFMT_LIBS} ${ZLIB_LIBRARIES}) + list(APPEND GRFMT_LIBS ${ZLIB_LIBRARIES}) endif() if(WITH_JPEG) add_definitions(-DHAVE_JPEG) ocv_include_directories(${JPEG_INCLUDE_DIR}) - set(GRFMT_LIBS ${GRFMT_LIBS} ${JPEG_LIBRARIES}) + list(APPEND GRFMT_LIBS ${JPEG_LIBRARIES}) endif() if(WITH_PNG) add_definitions(-DHAVE_PNG) add_definitions(${PNG_DEFINITIONS}) ocv_include_directories(${PNG_INCLUDE_DIR}) - set(GRFMT_LIBS ${GRFMT_LIBS} ${PNG_LIBRARIES}) + list(APPEND GRFMT_LIBS ${PNG_LIBRARIES}) endif() if(WITH_TIFF) add_definitions(-DHAVE_TIFF) ocv_include_directories(${TIFF_INCLUDE_DIR}) - set(GRFMT_LIBS ${GRFMT_LIBS} ${TIFF_LIBRARIES}) + list(APPEND GRFMT_LIBS ${TIFF_LIBRARIES}) endif() if(WITH_JASPER) add_definitions(-DHAVE_JASPER) ocv_include_directories(${JASPER_INCLUDE_DIR}) - set(GRFMT_LIBS ${GRFMT_LIBS} ${JASPER_LIBRARIES}) + list(APPEND GRFMT_LIBS ${JASPER_LIBRARIES}) endif() if(WITH_OPENEXR AND OPENEXR_FOUND) add_definitions(-DHAVE_OPENEXR) ocv_include_directories(${OPENEXR_INCLUDE_PATHS}) - set(GRFMT_LIBS ${GRFMT_LIBS} ${OPENEXR_LIBRARIES}) + list(APPEND GRFMT_LIBS ${OPENEXR_LIBRARIES}) endif() file(GLOB grfmt_hdrs src/grfmt*.hpp) file(GLOB grfmt_srcs src/grfmt*.cpp) -set(grfmt_hdrs src/bitstrm.hpp ${grfmt_hdrs}) -set(grfmt_srcs src/bitstrm.cpp ${grfmt_srcs}) +list(APPEND grfmt_hdrs src/bitstrm.hpp) +list(APPEND grfmt_srcs src/bitstrm.cpp) source_group("Src\\grfmts" FILES ${grfmt_hdrs} ${grfmt_srcs}) -set(highgui_hdrs src/precomp.hpp src/utils.hpp src/cap_ffmpeg_impl.hpp) +set(highgui_hdrs + src/precomp.hpp + src/utils.hpp + src/cap_ffmpeg_impl.hpp + ) set(highgui_srcs src/cap.cpp @@ -66,92 +70,138 @@ set(highgui_srcs file(GLOB highgui_ext_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") -#YV -if (HAVE_QT) +if(HAVE_QT) if (HAVE_QT_OPENGL) set(QT_USE_QTOPENGL TRUE) endif() - INCLUDE(${QT_USE_FILE}) + include(${QT_USE_FILE}) - SET(_RCCS_FILES src/window_QT.qrc) - QT4_ADD_RESOURCES(_RCC_OUTFILES ${_RCCS_FILES}) + QT4_ADD_RESOURCES(_RCC_OUTFILES src/window_QT.qrc) + QT4_WRAP_CPP(_MOC_OUTFILES src/window_QT.h) - SET(_MOC_HEADERS src/window_QT.h ) - QT4_WRAP_CPP(_MOC_OUTFILES ${_MOC_HEADERS}) - - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} ${QT_LIBRARIES} ${QT_QTTEST_LIBRARY}) - set(highgui_srcs ${highgui_srcs} src/window_QT.cpp ${_MOC_OUTFILES} ${_RCC_OUTFILES} ) + list(APPEND HIGHGUI_LIBRARIES ${QT_LIBRARIES} ${QT_QTTEST_LIBRARY}) + list(APPEND highgui_srcs src/window_QT.cpp ${_MOC_OUTFILES} ${_RCC_OUTFILES} ) +elseif(WIN32) + list(APPEND highgui_srcs src/window_w32.cpp) +elseif(HAVE_GTK) + list(APPEND highgui_srcs src/window_gtk.cpp) +elseif(APPLE) + if(WITH_CARBON) + add_definitions(-DHAVE_CARBON=1) + list(APPEND highgui_srcs src/window_carbon.cpp) + list(APPEND HIGHGUI_LIBRARIES "-framework Carbon" "-framework QuickTime") + elseif(NOT IOS) + add_definitions(-DHAVE_COCOA=1) + list(APPEND highgui_srcs src/window_cocoa.mm) + list(APPEND HIGHGUI_LIBRARIES "-framework Cocoa") + endif() endif() if(WIN32) - if(NOT HAVE_QT) - set(highgui_srcs ${highgui_srcs} src/window_w32.cpp) + list(APPEND highgui_srcs src/cap_vfw.cpp src/cap_cmu.cpp src/cap_dshow.cpp) +endif(WIN32) + +if(HAVE_XINE) + list(APPEND highgui_srcs src/cap_xine.cpp) +endif(HAVE_XINE) + +if(HAVE_DC1394_2) + list(APPEND highgui_srcs src/cap_dc1394_v2.cpp) +endif(HAVE_DC1394_2) + +if(HAVE_DC1394) + list(APPEND highgui_srcs src/cap_dc1394.cpp) +endif(HAVE_DC1394) + +if(HAVE_GSTREAMER) + list(APPEND highgui_srcs src/cap_gstreamer.cpp) +endif(HAVE_GSTREAMER) + +if(HAVE_UNICAP) + list(APPEND highgui_srcs src/cap_unicap.cpp) +endif(HAVE_UNICAP) + +if(HAVE_LIBV4L) + list(APPEND highgui_srcs src/cap_libv4l.cpp) +elseif(HAVE_CAMV4L OR HAVE_CAMV4L2) + list(APPEND highgui_srcs src/cap_v4l.cpp) +endif() + +if(HAVE_OPENNI) + list(APPEND highgui_srcs src/cap_openni.cpp) + ocv_include_directories(${OPENNI_INCLUDE_DIR}) + list(APPEND HIGHGUI_LIBRARIES ${OPENNI_LIBRARY}) +endif(HAVE_OPENNI) + +if(HAVE_opencv_androidcamera) + list(APPEND highgui_srcs src/cap_android.cpp) + add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA)#TODO: remove this line +endif(HAVE_opencv_androidcamera) + +if(HAVE_XIMEA) + list(APPEND highgui_srcs src/cap_ximea.cpp) + ocv_include_directories(${XIMEA_PATH}) + link_directories(${XIMEA_LIBRARY_DIR}) + list(APPEND HIGHGUI_LIBRARIES m3api) +endif(HAVE_XIMEA) + +if(HAVE_FFMPEG) + if(UNIX AND BZIP2_LIBRARIES) + list(APPEND HIGHGUI_LIBRARIES ${BZIP2_LIBRARIES}) endif() - set(highgui_srcs ${highgui_srcs} src/cap_vfw.cpp src/cap_cmu.cpp src/cap_dshow.cpp) - if(HAVE_MIL) - set(highgui_srcs ${highgui_srcs} src/cap_mil.cpp) + if(APPLE) + list(APPEND HIGHGUI_LIBRARIES "-framework VideoDecodeAcceleration") + endif() +endif(HAVE_FFMPEG) + +if(HAVE_PVAPI) + add_definitions(-DHAVE_PVAPI) + ocv_include_directories(${PVAPI_INCLUDE_PATH}) + if(X86) + set(PVAPI_SDK_SUBDIR x86) + elseif(X86_64) + set(PVAPI_SDK_SUBDIR x64) + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES arm) + set(PVAPI_SDK_SUBDIR arm) + endif() + if(PVAPI_SDK_SUBDIR AND CMAKE_COMPILER_IS_GNUCXX) + get_filename_component(PVAPI_EXPECTED_LIB_PATH "${PVAPI_INCLUDE_PATH}/../lib-pc/${PVAPI_SDK_SUBDIR}/${CMAKE_OPENCV_GCC_VERSION_MAJOR}.${CMAKE_OPENCV_GCC_VERSION_MINOR}" ABSOLUTE) + link_directories(${PVAPI_EXPECTED_LIB_PATH}) + endif() + set(highgui_srcs src/cap_pvapi.cpp ${highgui_srcs}) + set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} PvAPI) +endif() + +if(WITH_IMAGEIO) + add_definitions(-DHAVE_IMAGEIO=1) + if(IOS) + list(APPEND HIGHGUI_LIBRARIES "-framework ImageIO") + endif() + #TODO: check if need to link with some framework on OS X: -framework ApplicationServices ?? +endif(WITH_IMAGEIO) + +if(WITH_AVFOUNDATION) + add_definitions(-DHAVE_AVFOUNDATION=1) + list(APPEND highgui_srcs src/cap_avfoundation.mm) + list(APPEND HIGHGUI_LIBRARIES "-framework AVFoundation" "-framework QuartzCore") +elseif(APPLE) + add_definitions(-DHAVE_QUICKTIME=1) + if(WITH_QUICKTIME) + list(APPEND highgui_srcs src/cap_qt.cpp) + list(APPEND HIGHGUI_LIBRARIES "-framework Carbon" "-framework QuickTime" "-framework CoreFoundation" "-framework QuartzCore") + else() + list(APPEND highgui_srcs src/cap_qtkit.mm) + list(APPEND HIGHGUI_LIBRARIES "-framework QTKit" "-framework QuartzCore") endif() endif() +if(WIN32) + link_directories("${OpenCV_SOURCE_DIR}/3rdparty/lib") # for ffmpeg wrapper only + include_directories(AFTER "${OpenCV_SOURCE_DIR}/3rdparty/include") # for directshow in VS2005 and multi-monitor support on MinGW +endif() + if(UNIX) - if(NOT HAVE_QT) - if(HAVE_GTK) - set(highgui_srcs ${highgui_srcs} src/window_gtk.cpp) - endif() - endif() - - if(HAVE_XINE) - set(highgui_srcs ${highgui_srcs} src/cap_xine.cpp) - endif() - - if(HAVE_DC1394_2) - set(highgui_srcs ${highgui_srcs} src/cap_dc1394_v2.cpp) - endif() - - if(HAVE_DC1394) - set(highgui_srcs ${highgui_srcs} src/cap_dc1394.cpp) - endif() - - if(HAVE_FFMPEG) - if(BZIP2_LIBRARIES) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} ${BZIP2_LIBRARIES}) - endif() - endif() - - if(HAVE_PVAPI) - add_definitions(-DHAVE_PVAPI) - ocv_include_directories(${PVAPI_INCLUDE_PATH}) - if(X86) - set(PVAPI_SDK_SUBDIR x86) - elseif(X86_64) - set(PVAPI_SDK_SUBDIR x64) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES arm) - set(PVAPI_SDK_SUBDIR arm) - endif() - if(PVAPI_SDK_SUBDIR AND CMAKE_COMPILER_IS_GNUCXX) - get_filename_component(PVAPI_EXPECTED_LIB_PATH "${PVAPI_INCLUDE_PATH}/../lib-pc/${PVAPI_SDK_SUBDIR}/${CMAKE_OPENCV_GCC_VERSION_MAJOR}.${CMAKE_OPENCV_GCC_VERSION_MINOR}" ABSOLUTE) - link_directories(${PVAPI_EXPECTED_LIB_PATH}) - endif() - set(highgui_srcs src/cap_pvapi.cpp ${highgui_srcs}) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} PvAPI) - endif() - - if(HAVE_GSTREAMER) - set(highgui_srcs ${highgui_srcs} src/cap_gstreamer.cpp) - endif() - - if(HAVE_UNICAP) - set(highgui_srcs ${highgui_srcs} src/cap_unicap.cpp) - endif() - - if(HAVE_LIBV4L) - set(highgui_srcs ${highgui_srcs} src/cap_libv4l.cpp) - else() - if(HAVE_CAMV4L OR HAVE_CAMV4L2) - set(highgui_srcs ${highgui_srcs} src/cap_v4l.cpp) - endif() - endif() - + #these variables are set by CHECK_MODULE macro foreach(P ${HIGHGUI_INCLUDE_DIRS}) ocv_include_directories(${P}) endforeach() @@ -161,92 +211,12 @@ if(UNIX) endforeach() endif() -#OpenNI -if(WITH_OPENNI AND HAVE_OPENNI) - set(highgui_srcs ${highgui_srcs} src/cap_openni.cpp) - ocv_include_directories(${OPENNI_INCLUDE_DIR}) -endif() - -#YV -if(APPLE) - if (NOT IOS) - add_definitions(-DHAVE_QUICKTIME=1) - endif() - - if(NOT OPENCV_BUILD_3RDPARTY_LIBS) - add_definitions(-DHAVE_IMAGEIO=1) - endif() - - if (NOT HAVE_QT) - if(WITH_CARBON) - add_definitions(-DHAVE_CARBON=1) - set(highgui_srcs ${highgui_srcs} src/window_carbon.cpp) - else() - add_definitions(-DHAVE_COCOA=1) - set(highgui_srcs ${highgui_srcs} src/window_cocoa.mm) - endif() - endif() - - if(WITH_QUICKTIME) - set(highgui_srcs ${highgui_srcs} src/cap_qt.cpp) - else() - if(WITH_AVFOUNDATION) - add_definitions(-DHAVE_AVFOUNDATION=1) - set(highgui_srcs ${highgui_srcs} src/cap_avfoundation.mm) - else() - set(highgui_srcs ${highgui_srcs} src/cap_qtkit.mm) - endif() - endif() - - if(HAVE_FFMPEG) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "-framework VideoDecodeAcceleration") - endif() -endif(APPLE) - -if(HAVE_opencv_androidcamera) - set(highgui_srcs ${highgui_srcs} src/cap_android.cpp) - add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA)#TODO: remove this line -endif() - -if(HAVE_XIMEA AND XIMEA_FOUND) - set(highgui_srcs ${highgui_srcs} src/cap_ximea.cpp) - ocv_include_directories(${XIMEA_PATH}) - link_directories(${XIMEA_LIBRARY_DIR}) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} m3api) - set(highgui_srcs ${highgui_srcs} src/cap_ximea.cpp) -endif() - -if(OPENNI_LIBRARY) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} ${OPENNI_LIBRARY}) -endif() - -if(APPLE AND NOT IOS) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} bz2 "-framework Cocoa" "-framework QuartzCore") - if(WITH_CARBON) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "-framework Carbon") - endif() - if(NOT WITH_QUICKTIME) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "-framework QTKit") - endif() - if(WITH_CARBON OR WITH_QUICKTIME) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} "-framework QuickTime" "-framework CoreFoundation") - endif() -endif() - -if(IOS) - set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} bz2 "-framework QuartzCore" "-framework CoreFoundation" "-framework ImageIO" "-framework CoreGraphics" "-framework AVFoundation") -endif() - -if(WIN32) - link_directories("${OpenCV_SOURCE_DIR}/3rdparty/lib") - include_directories(AFTER "${OpenCV_SOURCE_DIR}/3rdparty/include") #for directshow -endif() - source_group("Src" FILES ${highgui_srcs} ${highgui_hdrs}) source_group("Include" FILES ${highgui_ext_hdrs}) ocv_set_module_sources(HEADERS ${highgui_ext_hdrs} SOURCES ${highgui_srcs} ${highgui_hdrs} ${grfmt_srcs} ${grfmt_hdrs}) ocv_module_include_directories() +ocv_list_unique(HIGHGUI_LIBRARIES) ocv_create_module(${GRFMT_LIBS} ${HIGHGUI_LIBRARIES}) if(BUILD_SHARED_LIBS) diff --git a/modules/highgui/src/window_w32.cpp b/modules/highgui/src/window_w32.cpp index bdee452c52..b97be0f7b7 100644 --- a/modules/highgui/src/window_w32.cpp +++ b/modules/highgui/src/window_w32.cpp @@ -48,6 +48,10 @@ #endif #define COMPILE_MULTIMON_STUBS // Required for multi-monitor support +#ifndef _MULTIMON_USE_SECURE_CRT +# define _MULTIMON_USE_SECURE_CRT 0 // some MinGW platforms have no strncpy_s +#endif + #if defined SM_CMONITORS && !defined MONITOR_DEFAULTTONEAREST # define MONITOR_DEFAULTTONULL 0x00000000 # define MONITOR_DEFAULTTOPRIMARY 0x00000001 @@ -974,6 +978,11 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) DWORD defStyle = WS_VISIBLE | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU; int len; CvRect rect; +#ifdef HAVE_OPENGL + bool useGl; + HDC hGLDC; + HGLRC hGLRC; +#endif cvInitSystem(0,0); @@ -1009,9 +1018,9 @@ CV_IMPL int cvNamedWindow( const char* name, int flags ) if (flags & CV_WINDOW_OPENGL) CV_ERROR( CV_OpenGlNotSupported, "Library was built without OpenGL support" ); #else - bool useGl = false; - HDC hGLDC = 0; - HGLRC hGLRC = 0; + useGl = false; + hGLDC = 0; + hGLRC = 0; if (flags & CV_WINDOW_OPENGL) createGlContext(hWnd, hGLDC, hGLRC, useGl); diff --git a/modules/imgproc/src/utils.cpp b/modules/imgproc/src/utils.cpp index 265022f19e..e7a9438857 100644 --- a/modules/imgproc/src/utils.cpp +++ b/modules/imgproc/src/utils.cpp @@ -224,7 +224,7 @@ void cv::copyMakeBorder( InputArray _src, OutputArray _dst, int top, int bottom, if(top == 0 && left == 0 && bottom == 0 && right == 0) { - if(src.data != dst.data) + if(src.data != dst.data || src.step != dst.step) src.copyTo(dst); return; } diff --git a/modules/ml/src/ml_init.cpp b/modules/ml/src/ml_init.cpp index 373a3776af..276f6f5d47 100644 --- a/modules/ml/src/ml_init.cpp +++ b/modules/ml/src/ml_init.cpp @@ -45,31 +45,14 @@ namespace cv { -static Algorithm* createEM() -{ - return new EM; -} -static AlgorithmInfo em_info("StatModel.EM", createEM); - -AlgorithmInfo* EM::info() const -{ - static volatile bool initialized = false; - if( !initialized ) - { - EM obj; - em_info.addParam(obj, "nclusters", obj.nclusters); - em_info.addParam(obj, "covMatType", obj.covMatType); - em_info.addParam(obj, "maxIters", obj.maxIters); - em_info.addParam(obj, "epsilon", obj.epsilon); - - em_info.addParam(obj, "weights", obj.weights, true); - em_info.addParam(obj, "means", obj.means, true); - em_info.addParam(obj, "covs", obj.covs, true); - - initialized = true; - } - return &em_info; -} +CV_INIT_ALGORITHM(EM, "StatModel.EM", + obj.info()->addParam(obj, "nclusters", obj.nclusters); + obj.info()->addParam(obj, "covMatType", obj.covMatType); + obj.info()->addParam(obj, "maxIters", obj.maxIters); + obj.info()->addParam(obj, "epsilon", obj.epsilon); + obj.info()->addParam(obj, "weights", obj.weights, true); + obj.info()->addParam(obj, "means", obj.means, true); + obj.info()->addParam(obj, "covs", obj.covs, true)); bool initModule_ml(void) { diff --git a/modules/nonfree/src/nonfree_init.cpp b/modules/nonfree/src/nonfree_init.cpp index 5a7a2dd28f..239e8576d9 100644 --- a/modules/nonfree/src/nonfree_init.cpp +++ b/modules/nonfree/src/nonfree_init.cpp @@ -46,65 +46,22 @@ namespace cv { /////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static Algorithm* createSURF() -{ - return new SURF; -} -static AlgorithmInfo& surf_info() -{ - static AlgorithmInfo surf_info_var("Feature2D.SURF", createSURF); - return surf_info_var; -} - -static AlgorithmInfo& surf_info_auto = surf_info(); - -AlgorithmInfo* SURF::info() const -{ - static volatile bool initialized = false; - if( !initialized ) - { - SURF obj; - surf_info().addParam(obj, "hessianThreshold", obj.hessianThreshold); - surf_info().addParam(obj, "nOctaves", obj.nOctaves); - surf_info().addParam(obj, "nOctaveLayers", obj.nOctaveLayers); - surf_info().addParam(obj, "extended", obj.extended); - surf_info().addParam(obj, "upright", obj.upright); - - initialized = true; - } - return &surf_info(); -} +CV_INIT_ALGORITHM(SURF, "Feature2D.SURF", + obj.info()->addParam(obj, "hessianThreshold", obj.hessianThreshold); + obj.info()->addParam(obj, "nOctaves", obj.nOctaves); + obj.info()->addParam(obj, "nOctaveLayers", obj.nOctaveLayers); + obj.info()->addParam(obj, "extended", obj.extended); + obj.info()->addParam(obj, "upright", obj.upright)); /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static Algorithm* createSIFT() { return new SIFT; } - -static AlgorithmInfo& sift_info() -{ - static AlgorithmInfo sift_info_var("Feature2D.SIFT", createSIFT); - return sift_info_var; -} - -static AlgorithmInfo& sift_info_auto = sift_info(); - -AlgorithmInfo* SIFT::info() const -{ - static volatile bool initialized = false; - if( !initialized ) - { - SIFT obj; - sift_info().addParam(obj, "nFeatures", obj.nfeatures); - sift_info().addParam(obj, "nOctaveLayers", obj.nOctaveLayers); - sift_info().addParam(obj, "contrastThreshold", obj.contrastThreshold); - sift_info().addParam(obj, "edgeThreshold", obj.edgeThreshold); - sift_info().addParam(obj, "sigma", obj.sigma); - - initialized = true; - } - return &sift_info(); -} +CV_INIT_ALGORITHM(SIFT, "Feature2D.SIFT", + obj.info()->addParam(obj, "nFeatures", obj.nfeatures); + obj.info()->addParam(obj, "nOctaveLayers", obj.nOctaveLayers); + obj.info()->addParam(obj, "contrastThreshold", obj.contrastThreshold); + obj.info()->addParam(obj, "edgeThreshold", obj.edgeThreshold); + obj.info()->addParam(obj, "sigma", obj.sigma)); /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/video/include/opencv2/video/tracking.hpp b/modules/video/include/opencv2/video/tracking.hpp index e3a895b446..75668d2289 100644 --- a/modules/video/include/opencv2/video/tracking.hpp +++ b/modules/video/include/opencv2/video/tracking.hpp @@ -304,7 +304,7 @@ enum }; //! constructs a pyramid which can be used as input for calcOpticalFlowPyrLK -CV_EXPORTS_W int buildOpticalFlowPyramid(InputArray _img, OutputArrayOfArrays pyramid, +CV_EXPORTS_W int buildOpticalFlowPyramid(InputArray img, OutputArrayOfArrays pyramid, Size winSize, int maxLevel, bool withDerivatives = true, int pyrBorder = BORDER_REFLECT_101, int derivBorder = BORDER_CONSTANT, bool tryReuseInputImage = true); diff --git a/modules/video/perf/perf_optflowpyrlk.cpp b/modules/video/perf/perf_optflowpyrlk.cpp index 75fcb926b8..2ef5f3c133 100644 --- a/modules/video/perf/perf_optflowpyrlk.cpp +++ b/modules/video/perf/perf_optflowpyrlk.cpp @@ -28,12 +28,12 @@ void FormTrackingPointsArray(vector& points, int width, int height, int } } -PERF_TEST_P(Path_Idx_Cn_NPoints_WSize, OpticalFlowPyrLK, testing::Combine( +PERF_TEST_P(Path_Idx_Cn_NPoints_WSize, OpticalFlowPyrLK_full, testing::Combine( testing::Values("cv/optflow/frames/VGA_%02d.png", "cv/optflow/frames/720p_%02d.jpg"), - testing::Range(0, 3), + testing::Range(1, 3), testing::Values(1, 3, 4), testing::Values(make_tuple(9, 9), make_tuple(15, 15)), - testing::Values(7, 11, 21, 25) + testing::Values(7, 11, 25) ) ) { @@ -48,6 +48,7 @@ PERF_TEST_P(Path_Idx_Cn_NPoints_WSize, OpticalFlowPyrLK, testing::Combine( int nPointsX = min(get<0>(get<3>(GetParam())), img1.cols); int nPointsY = min(get<1>(get<3>(GetParam())), img1.rows); int winSize = get<4>(GetParam()); + int maxLevel = 2; TermCriteria criteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 7, 0.001); int flags = 0; @@ -91,3 +92,120 @@ PERF_TEST_P(Path_Idx_Cn_NPoints_WSize, OpticalFlowPyrLK, testing::Combine( flags, minEigThreshold); } } + +typedef tr1::tuple, int, bool> Path_Idx_Cn_NPoints_WSize_Deriv_t; +typedef TestBaseWithParam Path_Idx_Cn_NPoints_WSize_Deriv; + +PERF_TEST_P(Path_Idx_Cn_NPoints_WSize_Deriv, OpticalFlowPyrLK_self, testing::Combine( + testing::Values("cv/optflow/frames/VGA_%02d.png", "cv/optflow/frames/720p_%02d.jpg"), + testing::Range(1, 3), + testing::Values(1, 3, 4), + testing::Values(make_tuple(9, 9), make_tuple(15, 15)), + testing::Values(7, 11, 25), + testing::Bool() + ) + ) +{ + string filename1 = getDataPath(cv::format(get<0>(GetParam()).c_str(), get<1>(GetParam()))); + string filename2 = getDataPath(cv::format(get<0>(GetParam()).c_str(), get<1>(GetParam()) + 1)); + Mat img1 = imread(filename1); + Mat img2 = imread(filename2); + if (img1.empty()) FAIL() << "Unable to load source image " << filename1; + if (img2.empty()) FAIL() << "Unable to load source image " << filename2; + + int cn = get<2>(GetParam()); + int nPointsX = min(get<0>(get<3>(GetParam())), img1.cols); + int nPointsY = min(get<1>(get<3>(GetParam())), img1.rows); + int winSize = get<4>(GetParam()); + bool withDerivatives = get<5>(GetParam()); + + int maxLevel = 2; + TermCriteria criteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 7, 0.001); + int flags = 0; + double minEigThreshold = 1e-4; + + Mat frame1, frame2; + switch(cn) + { + case 1: + cvtColor(img1, frame1, COLOR_BGR2GRAY, cn); + cvtColor(img2, frame2, COLOR_BGR2GRAY, cn); + break; + case 3: + frame1 = img1; + frame2 = img2; + break; + case 4: + cvtColor(img1, frame1, COLOR_BGR2BGRA, cn); + cvtColor(img2, frame2, COLOR_BGR2BGRA, cn); + break; + default: + FAIL() << "Unexpected number of channels: " << cn; + } + + vector inPoints; + vector outPoints; + vector status; + vector err; + + FormTrackingPointsArray(inPoints, frame1.cols, frame1.rows, nPointsX, nPointsY); + outPoints.resize(inPoints.size()); + status.resize(inPoints.size()); + err.resize(inPoints.size()); + + std::vector pyramid1, pyramid2; + + maxLevel = buildOpticalFlowPyramid(frame1, pyramid1, Size(winSize, winSize), maxLevel, withDerivatives); + maxLevel = buildOpticalFlowPyramid(frame2, pyramid2, Size(winSize, winSize), maxLevel, withDerivatives); + + declare.in(pyramid1, pyramid2, inPoints).out(outPoints); + + TEST_CYCLE() + { + calcOpticalFlowPyrLK(pyramid1, pyramid2, inPoints, outPoints, status, err, + Size(winSize, winSize), maxLevel, criteria, + flags, minEigThreshold); + } +} + +CV_ENUM(PyrBorderMode, BORDER_DEFAULT, BORDER_TRANSPARENT); +typedef tr1::tuple Path_Win_Deriv_Border_Reuse_t; +typedef TestBaseWithParam Path_Win_Deriv_Border_Reuse; + +PERF_TEST_P(Path_Win_Deriv_Border_Reuse, OpticalFlowPyrLK_pyr, testing::Combine( + testing::Values("cv/optflow/frames/720p_01.jpg"), + testing::Values(7, 11), + testing::Bool(), + testing::ValuesIn(PyrBorderMode::all()), + testing::Bool() + ) + ) +{ + string filename = getDataPath(get<0>(GetParam())); + Mat img = imread(filename); + Size winSize(get<1>(GetParam()), get<1>(GetParam())); + bool withDerivatives = get<2>(GetParam()); + int derivBorder = get<3>(GetParam()); + int pyrBorder = derivBorder; + if(derivBorder != BORDER_TRANSPARENT) + { + derivBorder = BORDER_CONSTANT; + pyrBorder = BORDER_REFLECT_101; + } + bool tryReuseInputImage = get<4>(GetParam()); + std::vector pyramid; + + img.adjustROI(winSize.height, winSize.height, winSize.width, winSize.width); + + int maxLevel = buildOpticalFlowPyramid(img, pyramid, winSize, 1000, withDerivatives, BORDER_CONSTANT, BORDER_CONSTANT, tryReuseInputImage); + + declare.in(img).out(pyramid); + + + TEST_CYCLE() + { + buildOpticalFlowPyramid(img, pyramid, winSize, maxLevel, withDerivatives, pyrBorder, derivBorder, tryReuseInputImage); + } + + SANITY_CHECK(pyramid); +} \ No newline at end of file diff --git a/modules/video/src/lkpyramid.cpp b/modules/video/src/lkpyramid.cpp index 0a4f44b620..52a23b2e20 100644 --- a/modules/video/src/lkpyramid.cpp +++ b/modules/video/src/lkpyramid.cpp @@ -41,17 +41,22 @@ #include "precomp.hpp" #include #include +#include "lkpyramid.hpp" -namespace cv +namespace { - -typedef short deriv_type; - -static void calcSharrDeriv(const Mat& src, Mat& dst) +static void calcSharrDeriv(const cv::Mat& src, cv::Mat& dst) { + using namespace cv; + using cv::detail::deriv_type; int rows = src.rows, cols = src.cols, cn = src.channels(), colsn = cols*cn, depth = src.depth(); CV_Assert(depth == CV_8U); dst.create(rows, cols, CV_MAKETYPE(DataType::depth, cn*2)); + + #ifdef HAVE_TEGRA_OPTIMIZATION + if (tegra::calcSharrDeriv(src, dst)) + return; +#endif int x, y, delta = (int)alignSize((cols + 2)*cn, 16); AutoBuffer _tempBuf(delta*2 + 64); @@ -127,373 +132,355 @@ static void calcSharrDeriv(const Mat& src, Mat& dst) } } +}//namespace -struct LKTrackerInvoker -{ - LKTrackerInvoker( const Mat& _prevImg, const Mat& _prevDeriv, const Mat& _nextImg, +cv::detail::LKTrackerInvoker::LKTrackerInvoker( + const Mat& _prevImg, const Mat& _prevDeriv, const Mat& _nextImg, const Point2f* _prevPts, Point2f* _nextPts, uchar* _status, float* _err, Size _winSize, TermCriteria _criteria, int _level, int _maxLevel, int _flags, float _minEigThreshold ) - { - prevImg = &_prevImg; - prevDeriv = &_prevDeriv; - nextImg = &_nextImg; - prevPts = _prevPts; - nextPts = _nextPts; - status = _status; - err = _err; - winSize = _winSize; - criteria = _criteria; - level = _level; - maxLevel = _maxLevel; - flags = _flags; - minEigThreshold = _minEigThreshold; - } +{ + prevImg = &_prevImg; + prevDeriv = &_prevDeriv; + nextImg = &_nextImg; + prevPts = _prevPts; + nextPts = _nextPts; + status = _status; + err = _err; + winSize = _winSize; + criteria = _criteria; + level = _level; + maxLevel = _maxLevel; + flags = _flags; + minEigThreshold = _minEigThreshold; +} + +void cv::detail::LKTrackerInvoker::operator()(const BlockedRange& range) const +{ + Point2f halfWin((winSize.width-1)*0.5f, (winSize.height-1)*0.5f); + const Mat& I = *prevImg; + const Mat& J = *nextImg; + const Mat& derivI = *prevDeriv; - void operator()(const BlockedRange& range) const + int j, cn = I.channels(), cn2 = cn*2; + cv::AutoBuffer _buf(winSize.area()*(cn + cn2)); + int derivDepth = DataType::depth; + + Mat IWinBuf(winSize, CV_MAKETYPE(derivDepth, cn), (deriv_type*)_buf); + Mat derivIWinBuf(winSize, CV_MAKETYPE(derivDepth, cn2), (deriv_type*)_buf + winSize.area()*cn); + + for( int ptidx = range.begin(); ptidx < range.end(); ptidx++ ) { - Point2f halfWin((winSize.width-1)*0.5f, (winSize.height-1)*0.5f); - const Mat& I = *prevImg; - const Mat& J = *nextImg; - const Mat& derivI = *prevDeriv; - - int j, cn = I.channels(), cn2 = cn*2; - cv::AutoBuffer _buf(winSize.area()*(cn + cn2)); - int derivDepth = DataType::depth; - - Mat IWinBuf(winSize, CV_MAKETYPE(derivDepth, cn), (deriv_type*)_buf); - Mat derivIWinBuf(winSize, CV_MAKETYPE(derivDepth, cn2), (deriv_type*)_buf + winSize.area()*cn); - - for( int ptidx = range.begin(); ptidx < range.end(); ptidx++ ) + Point2f prevPt = prevPts[ptidx]*(float)(1./(1 << level)); + Point2f nextPt; + if( level == maxLevel ) { - Point2f prevPt = prevPts[ptidx]*(float)(1./(1 << level)); - Point2f nextPt; - if( level == maxLevel ) - { - if( flags & OPTFLOW_USE_INITIAL_FLOW ) - nextPt = nextPts[ptidx]*(float)(1./(1 << level)); - else - nextPt = prevPt; - } + if( flags & OPTFLOW_USE_INITIAL_FLOW ) + nextPt = nextPts[ptidx]*(float)(1./(1 << level)); else - nextPt = nextPts[ptidx]*2.f; - nextPts[ptidx] = nextPt; - - Point2i iprevPt, inextPt; - prevPt -= halfWin; - iprevPt.x = cvFloor(prevPt.x); - iprevPt.y = cvFloor(prevPt.y); - - if( iprevPt.x < -winSize.width || iprevPt.x >= derivI.cols || - iprevPt.y < -winSize.height || iprevPt.y >= derivI.rows ) + nextPt = prevPt; + } + else + nextPt = nextPts[ptidx]*2.f; + nextPts[ptidx] = nextPt; + + Point2i iprevPt, inextPt; + prevPt -= halfWin; + iprevPt.x = cvFloor(prevPt.x); + iprevPt.y = cvFloor(prevPt.y); + + if( iprevPt.x < -winSize.width || iprevPt.x >= derivI.cols || + iprevPt.y < -winSize.height || iprevPt.y >= derivI.rows ) + { + if( level == 0 ) { - if( level == 0 ) - { - if( status ) - status[ptidx] = false; - if( err ) - err[ptidx] = 0; - } - continue; + if( status ) + status[ptidx] = false; + if( err ) + err[ptidx] = 0; } + continue; + } + + float a = prevPt.x - iprevPt.x; + float b = prevPt.y - iprevPt.y; + const int W_BITS = 14, W_BITS1 = 14; + const float FLT_SCALE = 1.f/(1 << 20); + int iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS)); + int iw01 = cvRound(a*(1.f - b)*(1 << W_BITS)); + int iw10 = cvRound((1.f - a)*b*(1 << W_BITS)); + int iw11 = (1 << W_BITS) - iw00 - iw01 - iw10; + + int dstep = (int)(derivI.step/derivI.elemSize1()); + int step = (int)(I.step/I.elemSize1()); + CV_Assert( step == (int)(J.step/J.elemSize1()) ); + float A11 = 0, A12 = 0, A22 = 0; + +#if CV_SSE2 + __m128i qw0 = _mm_set1_epi32(iw00 + (iw01 << 16)); + __m128i qw1 = _mm_set1_epi32(iw10 + (iw11 << 16)); + __m128i z = _mm_setzero_si128(); + __m128i qdelta_d = _mm_set1_epi32(1 << (W_BITS1-1)); + __m128i qdelta = _mm_set1_epi32(1 << (W_BITS1-5-1)); + __m128 qA11 = _mm_setzero_ps(), qA12 = _mm_setzero_ps(), qA22 = _mm_setzero_ps(); +#endif + + // extract the patch from the first image, compute covariation matrix of derivatives + int x, y; + for( y = 0; y < winSize.height; y++ ) + { + const uchar* src = (const uchar*)I.data + (y + iprevPt.y)*step + iprevPt.x*cn; + const deriv_type* dsrc = (const deriv_type*)derivI.data + (y + iprevPt.y)*dstep + iprevPt.x*cn2; - float a = prevPt.x - iprevPt.x; - float b = prevPt.y - iprevPt.y; - const int W_BITS = 14, W_BITS1 = 14; - const float FLT_SCALE = 1.f/(1 << 20); - int iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS)); - int iw01 = cvRound(a*(1.f - b)*(1 << W_BITS)); - int iw10 = cvRound((1.f - a)*b*(1 << W_BITS)); - int iw11 = (1 << W_BITS) - iw00 - iw01 - iw10; + deriv_type* Iptr = (deriv_type*)(IWinBuf.data + y*IWinBuf.step); + deriv_type* dIptr = (deriv_type*)(derivIWinBuf.data + y*derivIWinBuf.step); - int dstep = (int)(derivI.step/derivI.elemSize1()); - int step = (int)(I.step/I.elemSize1()); - CV_Assert( step == (int)(J.step/J.elemSize1()) ); - float A11 = 0, A12 = 0, A22 = 0; + x = 0; #if CV_SSE2 - __m128i qw0 = _mm_set1_epi32(iw00 + (iw01 << 16)); - __m128i qw1 = _mm_set1_epi32(iw10 + (iw11 << 16)); - __m128i z = _mm_setzero_si128(); - __m128i qdelta_d = _mm_set1_epi32(1 << (W_BITS1-1)); - __m128i qdelta = _mm_set1_epi32(1 << (W_BITS1-5-1)); - __m128 qA11 = _mm_setzero_ps(), qA12 = _mm_setzero_ps(), qA22 = _mm_setzero_ps(); + for( ; x <= winSize.width*cn - 4; x += 4, dsrc += 4*2, dIptr += 4*2 ) + { + __m128i v00, v01, v10, v11, t0, t1; + + v00 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x)), z); + v01 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + cn)), z); + v10 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + step)), z); + v11 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + step + cn)), z); + + t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0), + _mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1)); + t0 = _mm_srai_epi32(_mm_add_epi32(t0, qdelta), W_BITS1-5); + _mm_storel_epi64((__m128i*)(Iptr + x), _mm_packs_epi32(t0,t0)); + + v00 = _mm_loadu_si128((const __m128i*)(dsrc)); + v01 = _mm_loadu_si128((const __m128i*)(dsrc + cn2)); + v10 = _mm_loadu_si128((const __m128i*)(dsrc + dstep)); + v11 = _mm_loadu_si128((const __m128i*)(dsrc + dstep + cn2)); + + t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0), + _mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1)); + t1 = _mm_add_epi32(_mm_madd_epi16(_mm_unpackhi_epi16(v00, v01), qw0), + _mm_madd_epi16(_mm_unpackhi_epi16(v10, v11), qw1)); + t0 = _mm_srai_epi32(_mm_add_epi32(t0, qdelta_d), W_BITS1); + t1 = _mm_srai_epi32(_mm_add_epi32(t1, qdelta_d), W_BITS1); + v00 = _mm_packs_epi32(t0, t1); // Ix0 Iy0 Ix1 Iy1 ... + + _mm_storeu_si128((__m128i*)dIptr, v00); + t0 = _mm_srai_epi32(v00, 16); // Iy0 Iy1 Iy2 Iy3 + t1 = _mm_srai_epi32(_mm_slli_epi32(v00, 16), 16); // Ix0 Ix1 Ix2 Ix3 + + __m128 fy = _mm_cvtepi32_ps(t0); + __m128 fx = _mm_cvtepi32_ps(t1); + + qA22 = _mm_add_ps(qA22, _mm_mul_ps(fy, fy)); + qA12 = _mm_add_ps(qA12, _mm_mul_ps(fx, fy)); + qA11 = _mm_add_ps(qA11, _mm_mul_ps(fx, fx)); + } +#endif + + for( ; x < winSize.width*cn; x++, dsrc += 2, dIptr += 2 ) + { + int ival = CV_DESCALE(src[x]*iw00 + src[x+cn]*iw01 + + src[x+step]*iw10 + src[x+step+cn]*iw11, W_BITS1-5); + int ixval = CV_DESCALE(dsrc[0]*iw00 + dsrc[cn2]*iw01 + + dsrc[dstep]*iw10 + dsrc[dstep+cn2]*iw11, W_BITS1); + int iyval = CV_DESCALE(dsrc[1]*iw00 + dsrc[cn2+1]*iw01 + dsrc[dstep+1]*iw10 + + dsrc[dstep+cn2+1]*iw11, W_BITS1); + + Iptr[x] = (short)ival; + dIptr[0] = (short)ixval; + dIptr[1] = (short)iyval; + + A11 += (float)(ixval*ixval); + A12 += (float)(ixval*iyval); + A22 += (float)(iyval*iyval); + } + } + +#if CV_SSE2 + float CV_DECL_ALIGNED(16) A11buf[4], A12buf[4], A22buf[4]; + _mm_store_ps(A11buf, qA11); + _mm_store_ps(A12buf, qA12); + _mm_store_ps(A22buf, qA22); + A11 += A11buf[0] + A11buf[1] + A11buf[2] + A11buf[3]; + A12 += A12buf[0] + A12buf[1] + A12buf[2] + A12buf[3]; + A22 += A22buf[0] + A22buf[1] + A22buf[2] + A22buf[3]; +#endif + + A11 *= FLT_SCALE; + A12 *= FLT_SCALE; + A22 *= FLT_SCALE; + + float D = A11*A22 - A12*A12; + float minEig = (A22 + A11 - std::sqrt((A11-A22)*(A11-A22) + + 4.f*A12*A12))/(2*winSize.width*winSize.height); + + if( err && (flags & CV_LKFLOW_GET_MIN_EIGENVALS) != 0 ) + err[ptidx] = (float)minEig; + + if( minEig < minEigThreshold || D < FLT_EPSILON ) + { + if( level == 0 && status ) + status[ptidx] = false; + continue; + } + + D = 1.f/D; + + nextPt -= halfWin; + Point2f prevDelta; + + for( j = 0; j < criteria.maxCount; j++ ) + { + inextPt.x = cvFloor(nextPt.x); + inextPt.y = cvFloor(nextPt.y); + + if( inextPt.x < -winSize.width || inextPt.x >= J.cols || + inextPt.y < -winSize.height || inextPt.y >= J.rows ) + { + if( level == 0 && status ) + status[ptidx] = false; + break; + } + + a = nextPt.x - inextPt.x; + b = nextPt.y - inextPt.y; + iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS)); + iw01 = cvRound(a*(1.f - b)*(1 << W_BITS)); + iw10 = cvRound((1.f - a)*b*(1 << W_BITS)); + iw11 = (1 << W_BITS) - iw00 - iw01 - iw10; + float b1 = 0, b2 = 0; +#if CV_SSE2 + qw0 = _mm_set1_epi32(iw00 + (iw01 << 16)); + qw1 = _mm_set1_epi32(iw10 + (iw11 << 16)); + __m128 qb0 = _mm_setzero_ps(), qb1 = _mm_setzero_ps(); #endif - // extract the patch from the first image, compute covariation matrix of derivatives - int x, y; for( y = 0; y < winSize.height; y++ ) { - const uchar* src = (const uchar*)I.data + (y + iprevPt.y)*step + iprevPt.x*cn; - const deriv_type* dsrc = (const deriv_type*)derivI.data + (y + iprevPt.y)*dstep + iprevPt.x*cn2; - - deriv_type* Iptr = (deriv_type*)(IWinBuf.data + y*IWinBuf.step); - deriv_type* dIptr = (deriv_type*)(derivIWinBuf.data + y*derivIWinBuf.step); + const uchar* Jptr = (const uchar*)J.data + (y + inextPt.y)*step + inextPt.x*cn; + const deriv_type* Iptr = (const deriv_type*)(IWinBuf.data + y*IWinBuf.step); + const deriv_type* dIptr = (const deriv_type*)(derivIWinBuf.data + y*derivIWinBuf.step); x = 0; #if CV_SSE2 - for( ; x <= winSize.width*cn - 4; x += 4, dsrc += 4*2, dIptr += 4*2 ) + for( ; x <= winSize.width*cn - 8; x += 8, dIptr += 8*2 ) { - __m128i v00, v01, v10, v11, t0, t1; + __m128i diff0 = _mm_loadu_si128((const __m128i*)(Iptr + x)), diff1; + __m128i v00 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x)), z); + __m128i v01 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + cn)), z); + __m128i v10 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + step)), z); + __m128i v11 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + step + cn)), z); - v00 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x)), z); - v01 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + cn)), z); - v10 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + step)), z); - v11 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(const int*)(src + x + step + cn)), z); - - t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0), - _mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1)); + __m128i t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0), + _mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1)); + __m128i t1 = _mm_add_epi32(_mm_madd_epi16(_mm_unpackhi_epi16(v00, v01), qw0), + _mm_madd_epi16(_mm_unpackhi_epi16(v10, v11), qw1)); t0 = _mm_srai_epi32(_mm_add_epi32(t0, qdelta), W_BITS1-5); - _mm_storel_epi64((__m128i*)(Iptr + x), _mm_packs_epi32(t0,t0)); - - v00 = _mm_loadu_si128((const __m128i*)(dsrc)); - v01 = _mm_loadu_si128((const __m128i*)(dsrc + cn2)); - v10 = _mm_loadu_si128((const __m128i*)(dsrc + dstep)); - v11 = _mm_loadu_si128((const __m128i*)(dsrc + dstep + cn2)); - - t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0), - _mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1)); - t1 = _mm_add_epi32(_mm_madd_epi16(_mm_unpackhi_epi16(v00, v01), qw0), - _mm_madd_epi16(_mm_unpackhi_epi16(v10, v11), qw1)); - t0 = _mm_srai_epi32(_mm_add_epi32(t0, qdelta_d), W_BITS1); - t1 = _mm_srai_epi32(_mm_add_epi32(t1, qdelta_d), W_BITS1); - v00 = _mm_packs_epi32(t0, t1); // Ix0 Iy0 Ix1 Iy1 ... - - _mm_storeu_si128((__m128i*)dIptr, v00); - t0 = _mm_srai_epi32(v00, 16); // Iy0 Iy1 Iy2 Iy3 - t1 = _mm_srai_epi32(_mm_slli_epi32(v00, 16), 16); // Ix0 Ix1 Ix2 Ix3 - - __m128 fy = _mm_cvtepi32_ps(t0); - __m128 fx = _mm_cvtepi32_ps(t1); - - qA22 = _mm_add_ps(qA22, _mm_mul_ps(fy, fy)); - qA12 = _mm_add_ps(qA12, _mm_mul_ps(fx, fy)); - qA11 = _mm_add_ps(qA11, _mm_mul_ps(fx, fx)); + t1 = _mm_srai_epi32(_mm_add_epi32(t1, qdelta), W_BITS1-5); + diff0 = _mm_subs_epi16(_mm_packs_epi32(t0, t1), diff0); + diff1 = _mm_unpackhi_epi16(diff0, diff0); + diff0 = _mm_unpacklo_epi16(diff0, diff0); // It0 It0 It1 It1 ... + v00 = _mm_loadu_si128((const __m128i*)(dIptr)); // Ix0 Iy0 Ix1 Iy1 ... + v01 = _mm_loadu_si128((const __m128i*)(dIptr + 8)); + v10 = _mm_mullo_epi16(v00, diff0); + v11 = _mm_mulhi_epi16(v00, diff0); + v00 = _mm_unpacklo_epi16(v10, v11); + v10 = _mm_unpackhi_epi16(v10, v11); + qb0 = _mm_add_ps(qb0, _mm_cvtepi32_ps(v00)); + qb1 = _mm_add_ps(qb1, _mm_cvtepi32_ps(v10)); + v10 = _mm_mullo_epi16(v01, diff1); + v11 = _mm_mulhi_epi16(v01, diff1); + v00 = _mm_unpacklo_epi16(v10, v11); + v10 = _mm_unpackhi_epi16(v10, v11); + qb0 = _mm_add_ps(qb0, _mm_cvtepi32_ps(v00)); + qb1 = _mm_add_ps(qb1, _mm_cvtepi32_ps(v10)); } #endif - for( ; x < winSize.width*cn; x++, dsrc += 2, dIptr += 2 ) + for( ; x < winSize.width*cn; x++, dIptr += 2 ) { - int ival = CV_DESCALE(src[x]*iw00 + src[x+cn]*iw01 + - src[x+step]*iw10 + src[x+step+cn]*iw11, W_BITS1-5); - int ixval = CV_DESCALE(dsrc[0]*iw00 + dsrc[cn2]*iw01 + - dsrc[dstep]*iw10 + dsrc[dstep+cn2]*iw11, W_BITS1); - int iyval = CV_DESCALE(dsrc[1]*iw00 + dsrc[cn2+1]*iw01 + dsrc[dstep+1]*iw10 + - dsrc[dstep+cn2+1]*iw11, W_BITS1); - - Iptr[x] = (short)ival; - dIptr[0] = (short)ixval; - dIptr[1] = (short)iyval; - - A11 += (float)(ixval*ixval); - A12 += (float)(ixval*iyval); - A22 += (float)(iyval*iyval); + int diff = CV_DESCALE(Jptr[x]*iw00 + Jptr[x+cn]*iw01 + + Jptr[x+step]*iw10 + Jptr[x+step+cn]*iw11, + W_BITS1-5) - Iptr[x]; + b1 += (float)(diff*dIptr[0]); + b2 += (float)(diff*dIptr[1]); } } #if CV_SSE2 - float CV_DECL_ALIGNED(16) A11buf[4], A12buf[4], A22buf[4]; - _mm_store_ps(A11buf, qA11); - _mm_store_ps(A12buf, qA12); - _mm_store_ps(A22buf, qA22); - A11 += A11buf[0] + A11buf[1] + A11buf[2] + A11buf[3]; - A12 += A12buf[0] + A12buf[1] + A12buf[2] + A12buf[3]; - A22 += A22buf[0] + A22buf[1] + A22buf[2] + A22buf[3]; + float CV_DECL_ALIGNED(16) bbuf[4]; + _mm_store_ps(bbuf, _mm_add_ps(qb0, qb1)); + b1 += bbuf[0] + bbuf[2]; + b2 += bbuf[1] + bbuf[3]; #endif + + b1 *= FLT_SCALE; + b2 *= FLT_SCALE; - A11 *= FLT_SCALE; - A12 *= FLT_SCALE; - A22 *= FLT_SCALE; + Point2f delta( (float)((A12*b2 - A22*b1) * D), + (float)((A12*b1 - A11*b2) * D)); + //delta = -delta; - float D = A11*A22 - A12*A12; - float minEig = (A22 + A11 - std::sqrt((A11-A22)*(A11-A22) + - 4.f*A12*A12))/(2*winSize.width*winSize.height); + nextPt += delta; + nextPts[ptidx] = nextPt + halfWin; - if( err && (flags & CV_LKFLOW_GET_MIN_EIGENVALS) != 0 ) - err[ptidx] = (float)minEig; + if( delta.ddot(delta) <= criteria.epsilon ) + break; - if( minEig < minEigThreshold || D < FLT_EPSILON ) + if( j > 0 && std::abs(delta.x + prevDelta.x) < 0.01 && + std::abs(delta.y + prevDelta.y) < 0.01 ) { - if( level == 0 && status ) + nextPts[ptidx] -= delta*0.5f; + break; + } + prevDelta = delta; + } + + if( status[ptidx] && err && level == 0 && (flags & CV_LKFLOW_GET_MIN_EIGENVALS) == 0 ) + { + Point2f nextPt = nextPts[ptidx] - halfWin; + Point inextPt; + + inextPt.x = cvFloor(nextPt.x); + inextPt.y = cvFloor(nextPt.y); + + if( inextPt.x < -winSize.width || inextPt.x >= J.cols || + inextPt.y < -winSize.height || inextPt.y >= J.rows ) + { + if( status ) status[ptidx] = false; continue; } - D = 1.f/D; + float a = nextPt.x - inextPt.x; + float b = nextPt.y - inextPt.y; + iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS)); + iw01 = cvRound(a*(1.f - b)*(1 << W_BITS)); + iw10 = cvRound((1.f - a)*b*(1 << W_BITS)); + iw11 = (1 << W_BITS) - iw00 - iw01 - iw10; + float errval = 0.f; - nextPt -= halfWin; - Point2f prevDelta; - - for( j = 0; j < criteria.maxCount; j++ ) + for( y = 0; y < winSize.height; y++ ) { - inextPt.x = cvFloor(nextPt.x); - inextPt.y = cvFloor(nextPt.y); + const uchar* Jptr = (const uchar*)J.data + (y + inextPt.y)*step + inextPt.x*cn; + const deriv_type* Iptr = (const deriv_type*)(IWinBuf.data + y*IWinBuf.step); - if( inextPt.x < -winSize.width || inextPt.x >= J.cols || - inextPt.y < -winSize.height || inextPt.y >= J.rows ) + for( x = 0; x < winSize.width*cn; x++ ) { - if( level == 0 && status ) - status[ptidx] = false; - break; + int diff = CV_DESCALE(Jptr[x]*iw00 + Jptr[x+cn]*iw01 + + Jptr[x+step]*iw10 + Jptr[x+step+cn]*iw11, + W_BITS1-5) - Iptr[x]; + errval += std::abs((float)diff); } - - a = nextPt.x - inextPt.x; - b = nextPt.y - inextPt.y; - iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS)); - iw01 = cvRound(a*(1.f - b)*(1 << W_BITS)); - iw10 = cvRound((1.f - a)*b*(1 << W_BITS)); - iw11 = (1 << W_BITS) - iw00 - iw01 - iw10; - float b1 = 0, b2 = 0; -#if CV_SSE2 - qw0 = _mm_set1_epi32(iw00 + (iw01 << 16)); - qw1 = _mm_set1_epi32(iw10 + (iw11 << 16)); - __m128 qb0 = _mm_setzero_ps(), qb1 = _mm_setzero_ps(); -#endif - - for( y = 0; y < winSize.height; y++ ) - { - const uchar* Jptr = (const uchar*)J.data + (y + inextPt.y)*step + inextPt.x*cn; - const deriv_type* Iptr = (const deriv_type*)(IWinBuf.data + y*IWinBuf.step); - const deriv_type* dIptr = (const deriv_type*)(derivIWinBuf.data + y*derivIWinBuf.step); - - x = 0; - -#if CV_SSE2 - for( ; x <= winSize.width*cn - 8; x += 8, dIptr += 8*2 ) - { - __m128i diff0 = _mm_loadu_si128((const __m128i*)(Iptr + x)), diff1; - __m128i v00 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x)), z); - __m128i v01 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + cn)), z); - __m128i v10 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + step)), z); - __m128i v11 = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(Jptr + x + step + cn)), z); - - __m128i t0 = _mm_add_epi32(_mm_madd_epi16(_mm_unpacklo_epi16(v00, v01), qw0), - _mm_madd_epi16(_mm_unpacklo_epi16(v10, v11), qw1)); - __m128i t1 = _mm_add_epi32(_mm_madd_epi16(_mm_unpackhi_epi16(v00, v01), qw0), - _mm_madd_epi16(_mm_unpackhi_epi16(v10, v11), qw1)); - t0 = _mm_srai_epi32(_mm_add_epi32(t0, qdelta), W_BITS1-5); - t1 = _mm_srai_epi32(_mm_add_epi32(t1, qdelta), W_BITS1-5); - diff0 = _mm_subs_epi16(_mm_packs_epi32(t0, t1), diff0); - diff1 = _mm_unpackhi_epi16(diff0, diff0); - diff0 = _mm_unpacklo_epi16(diff0, diff0); // It0 It0 It1 It1 ... - v00 = _mm_loadu_si128((const __m128i*)(dIptr)); // Ix0 Iy0 Ix1 Iy1 ... - v01 = _mm_loadu_si128((const __m128i*)(dIptr + 8)); - v10 = _mm_mullo_epi16(v00, diff0); - v11 = _mm_mulhi_epi16(v00, diff0); - v00 = _mm_unpacklo_epi16(v10, v11); - v10 = _mm_unpackhi_epi16(v10, v11); - qb0 = _mm_add_ps(qb0, _mm_cvtepi32_ps(v00)); - qb1 = _mm_add_ps(qb1, _mm_cvtepi32_ps(v10)); - v10 = _mm_mullo_epi16(v01, diff1); - v11 = _mm_mulhi_epi16(v01, diff1); - v00 = _mm_unpacklo_epi16(v10, v11); - v10 = _mm_unpackhi_epi16(v10, v11); - qb0 = _mm_add_ps(qb0, _mm_cvtepi32_ps(v00)); - qb1 = _mm_add_ps(qb1, _mm_cvtepi32_ps(v10)); - } -#endif - - for( ; x < winSize.width*cn; x++, dIptr += 2 ) - { - int diff = CV_DESCALE(Jptr[x]*iw00 + Jptr[x+cn]*iw01 + - Jptr[x+step]*iw10 + Jptr[x+step+cn]*iw11, - W_BITS1-5) - Iptr[x]; - b1 += (float)(diff*dIptr[0]); - b2 += (float)(diff*dIptr[1]); - } - } - -#if CV_SSE2 - float CV_DECL_ALIGNED(16) bbuf[4]; - _mm_store_ps(bbuf, _mm_add_ps(qb0, qb1)); - b1 += bbuf[0] + bbuf[2]; - b2 += bbuf[1] + bbuf[3]; -#endif - - b1 *= FLT_SCALE; - b2 *= FLT_SCALE; - - Point2f delta( (float)((A12*b2 - A22*b1) * D), - (float)((A12*b1 - A11*b2) * D)); - //delta = -delta; - - nextPt += delta; - nextPts[ptidx] = nextPt + halfWin; - - if( delta.ddot(delta) <= criteria.epsilon ) - break; - - if( j > 0 && std::abs(delta.x + prevDelta.x) < 0.01 && - std::abs(delta.y + prevDelta.y) < 0.01 ) - { - nextPts[ptidx] -= delta*0.5f; - break; - } - prevDelta = delta; - } - - if( status[ptidx] && err && level == 0 && (flags & CV_LKFLOW_GET_MIN_EIGENVALS) == 0 ) - { - Point2f nextPt = nextPts[ptidx] - halfWin; - Point inextPt; - - inextPt.x = cvFloor(nextPt.x); - inextPt.y = cvFloor(nextPt.y); - - if( inextPt.x < -winSize.width || inextPt.x >= J.cols || - inextPt.y < -winSize.height || inextPt.y >= J.rows ) - { - if( status ) - status[ptidx] = false; - continue; - } - - float a = nextPt.x - inextPt.x; - float b = nextPt.y - inextPt.y; - iw00 = cvRound((1.f - a)*(1.f - b)*(1 << W_BITS)); - iw01 = cvRound(a*(1.f - b)*(1 << W_BITS)); - iw10 = cvRound((1.f - a)*b*(1 << W_BITS)); - iw11 = (1 << W_BITS) - iw00 - iw01 - iw10; - float errval = 0.f; - - for( y = 0; y < winSize.height; y++ ) - { - const uchar* Jptr = (const uchar*)J.data + (y + inextPt.y)*step + inextPt.x*cn; - const deriv_type* Iptr = (const deriv_type*)(IWinBuf.data + y*IWinBuf.step); - - for( x = 0; x < winSize.width*cn; x++ ) - { - int diff = CV_DESCALE(Jptr[x]*iw00 + Jptr[x+cn]*iw01 + - Jptr[x+step]*iw10 + Jptr[x+step+cn]*iw11, - W_BITS1-5) - Iptr[x]; - errval += std::abs((float)diff); - } - } - err[ptidx] = errval * 1.f/(32*winSize.width*cn*winSize.height); } + err[ptidx] = errval * 1.f/(32*winSize.width*cn*winSize.height); } } - - const Mat* prevImg; - const Mat* nextImg; - const Mat* prevDeriv; - const Point2f* prevPts; - Point2f* nextPts; - uchar* status; - float* err; - Size winSize; - TermCriteria criteria; - int level; - int maxLevel; - int flags; - float minEigThreshold; -}; - } - - + int cv::buildOpticalFlowPyramid(InputArray _img, OutputArrayOfArrays pyramid, Size winSize, int maxLevel, bool withDerivatives, int pyrBorder, int derivBorder, bool tryReuseInputImage) { @@ -503,7 +490,7 @@ int cv::buildOpticalFlowPyramid(InputArray _img, OutputArrayOfArrays pyramid, Si pyramid.create(1, (maxLevel + 1) * pyrstep, 0 /*type*/, -1, true, 0); - int derivType = CV_MAKETYPE(DataType::depth, img.channels() * 2); + int derivType = CV_MAKETYPE(DataType::depth, img.channels() * 2); //level 0 bool lvl0IsSet = false; @@ -597,12 +584,8 @@ void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg, TermCriteria criteria, int flags, double minEigThreshold ) { -#ifdef HAVE_TEGRA_OPTIMIZATION - if (tegra::calcOpticalFlowPyrLK(_prevImg, _nextImg, _prevPts, _nextPts, _status, _err, winSize, maxLevel, criteria, flags, minEigThreshold)) - return; -#endif Mat prevPtsMat = _prevPts.getMat(); - const int derivDepth = DataType::depth; + const int derivDepth = DataType::depth; CV_Assert( maxLevel >= 0 && winSize.width > 2 && winSize.height > 2 ); @@ -744,6 +727,12 @@ void cv::calcOpticalFlowPyrLK( InputArray _prevImg, InputArray _nextImg, CV_Assert(prevPyr[level * lvlStep1].size() == nextPyr[level * lvlStep2].size()); CV_Assert(prevPyr[level * lvlStep1].type() == nextPyr[level * lvlStep2].type()); +#ifdef HAVE_TEGRA_OPTIMIZATION + typedef tegra::LKTrackerInvoker LKTrackerInvoker; +#else + typedef cv::detail::LKTrackerInvoker LKTrackerInvoker; +#endif + parallel_for(BlockedRange(0, npoints), LKTrackerInvoker(prevPyr[level * lvlStep1], derivI, nextPyr[level * lvlStep2], prevPts, nextPts, status, err, diff --git a/modules/video/src/lkpyramid.hpp b/modules/video/src/lkpyramid.hpp new file mode 100644 index 0000000000..03a51af375 --- /dev/null +++ b/modules/video/src/lkpyramid.hpp @@ -0,0 +1,36 @@ +#pragma once + +namespace cv +{ +namespace detail +{ + + typedef short deriv_type; + + struct LKTrackerInvoker + { + LKTrackerInvoker( const Mat& _prevImg, const Mat& _prevDeriv, const Mat& _nextImg, + const Point2f* _prevPts, Point2f* _nextPts, + uchar* _status, float* _err, + Size _winSize, TermCriteria _criteria, + int _level, int _maxLevel, int _flags, float _minEigThreshold ); + + void operator()(const BlockedRange& range) const; + + const Mat* prevImg; + const Mat* nextImg; + const Mat* prevDeriv; + const Point2f* prevPts; + Point2f* nextPts; + uchar* status; + float* err; + Size winSize; + TermCriteria criteria; + int level; + int maxLevel; + int flags; + float minEigThreshold; + }; + +}// namespace detail +}// namespace cv \ No newline at end of file diff --git a/modules/video/src/video_init.cpp b/modules/video/src/video_init.cpp index e60f4fc97d..159f3075c7 100644 --- a/modules/video/src/video_init.cpp +++ b/modules/video/src/video_init.cpp @@ -47,72 +47,24 @@ namespace cv /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static Algorithm* createMOG() -{ - return new BackgroundSubtractorMOG; -} - -static AlgorithmInfo& mog_info() -{ - static AlgorithmInfo mog_info_var("BackgroundSubtractor.MOG", createMOG); - return mog_info_var; -} - -static AlgorithmInfo& mog_info_auto = mog_info(); - -AlgorithmInfo* BackgroundSubtractorMOG::info() const -{ - static volatile bool initialized = false; - if( !initialized ) - { - BackgroundSubtractorMOG obj; - - mog_info().addParam(obj, "history", obj.history); - mog_info().addParam(obj, "nmixtures", obj.nmixtures); - mog_info().addParam(obj, "backgroundRatio", obj.backgroundRatio); - mog_info().addParam(obj, "noiseSigma", obj.noiseSigma); - - initialized = true; - } - return &mog_info(); -} +CV_INIT_ALGORITHM(BackgroundSubtractorMOG, "BackgroundSubtractor.MOG", + obj.info()->addParam(obj, "history", obj.history); + obj.info()->addParam(obj, "nmixtures", obj.nmixtures); + obj.info()->addParam(obj, "backgroundRatio", obj.backgroundRatio); + obj.info()->addParam(obj, "noiseSigma", obj.noiseSigma)); /////////////////////////////////////////////////////////////////////////////////////////////////////////// -static Algorithm* createMOG2() -{ - return new BackgroundSubtractorMOG2; -} - -static AlgorithmInfo& mog2_info() -{ - static AlgorithmInfo mog2_info_var("BackgroundSubtractor.MOG2", createMOG2); - return mog2_info_var; -} - -static AlgorithmInfo& mog2_info_auto = mog2_info(); - -AlgorithmInfo* BackgroundSubtractorMOG2::info() const -{ - static volatile bool initialized = false; - if( !initialized ) - { - BackgroundSubtractorMOG2 obj; - - mog2_info().addParam(obj, "history", obj.history); - mog2_info().addParam(obj, "varThreshold", obj.varThreshold); - mog2_info().addParam(obj, "detectShadows", obj.bShadowDetection); - - initialized = true; - } - return &mog2_info(); -} +CV_INIT_ALGORITHM(BackgroundSubtractorMOG2, "BackgroundSubtractor.MOG2", + obj.info()->addParam(obj, "history", obj.history); + obj.info()->addParam(obj, "varThreshold", obj.varThreshold); + obj.info()->addParam(obj, "detectShadows", obj.bShadowDetection)); /////////////////////////////////////////////////////////////////////////////////////////////////////////// bool initModule_video(void) { - Ptr mog = createMOG(), mog2 = createMOG2(); + Ptr mog = createBackgroundSubtractorMOG(), mog2 = createBackgroundSubtractorMOG2(); return mog->info() != 0 && mog2->info() != 0; } diff --git a/samples/cpp/bagofwords_classification.cpp b/samples/cpp/bagofwords_classification.cpp index 7ea03c6eed..a8f9a50939 100644 --- a/samples/cpp/bagofwords_classification.cpp +++ b/samples/cpp/bagofwords_classification.cpp @@ -1,6 +1,7 @@ #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/features2d/features2d.hpp" +#include "opencv2/nonfree/nonfree.hpp" #include "opencv2/ml/ml.hpp" #include @@ -2515,6 +2516,8 @@ int main(int argc, char** argv) return -1; } + cv::initModule_nonfree(); + const string vocPath = argv[1], resPath = argv[2]; // Read or set default parameters diff --git a/samples/cpp/descriptor_extractor_matcher.cpp b/samples/cpp/descriptor_extractor_matcher.cpp index ce48220109..cb4d2ff238 100644 --- a/samples/cpp/descriptor_extractor_matcher.cpp +++ b/samples/cpp/descriptor_extractor_matcher.cpp @@ -2,6 +2,7 @@ #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/features2d/features2d.hpp" +#include "opencv2/nonfree/nonfree.hpp" #include @@ -235,6 +236,9 @@ int main(int argc, char** argv) help(argv); return -1; } + + cv::initModule_nonfree(); + bool isWarpPerspective = argc == 7; double ransacReprojThreshold = -1; if( !isWarpPerspective )