Merged the trunk r8589:8653 - all changes related to build warnings

This commit is contained in:
Andrey Kamaev 2012-06-15 13:04:17 +00:00
parent 73c152abc4
commit bd0e0b5800
438 changed files with 20374 additions and 19674 deletions

View File

@ -7,31 +7,24 @@ project(${JASPER_LIBRARY})
add_definitions(-DEXCLUDE_MIF_SUPPORT -DEXCLUDE_PNM_SUPPORT -DEXCLUDE_BMP_SUPPORT -DEXCLUDE_RAS_SUPPORT -DEXCLUDE_JPG_SUPPORT -DEXCLUDE_PGX_SUPPORT) add_definitions(-DEXCLUDE_MIF_SUPPORT -DEXCLUDE_PNM_SUPPORT -DEXCLUDE_BMP_SUPPORT -DEXCLUDE_RAS_SUPPORT -DEXCLUDE_JPG_SUPPORT -DEXCLUDE_PGX_SUPPORT)
# List of C++ files:
ocv_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) ocv_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# The .cpp files:
file(GLOB lib_srcs *.c) file(GLOB lib_srcs *.c)
file(GLOB lib_hdrs *.h) file(GLOB lib_hdrs *.h)
file(GLOB lib_ext_hdrs jasper/*.h) file(GLOB lib_ext_hdrs jasper/*.h)
# ---------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------
# Define the library target: # Define the library target:
# ---------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------
add_library(${JASPER_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs} ${lib_ext_hdrs}) add_library(${JASPER_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs} ${lib_ext_hdrs})
if(MSVC) if(MSVC)
if(NOT ENABLE_NOISY_WARNINGS)
string(REPLACE "/W3" "/W0" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
string(REPLACE "/W4" "/W0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
add_definitions(-DJAS_WIN_MSVC_BUILD) add_definitions(-DJAS_WIN_MSVC_BUILD)
endif() endif()
if(CMAKE_COMPILER_IS_GNUCXX) ocv_warnings_disable(CMAKE_C_FLAGS -Wno-implicit-function-declaration -Wno-uninitialized -Wmissing-prototypes -Wmissing-declarations -Wunused -Wshadow
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-uninitialized") /wd4013 /wd4018 /wd4715 /wd4244 /wd4101 /wd4267)
endif()
if(UNIX) if(UNIX)
if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC)
@ -39,21 +32,17 @@ if(UNIX)
endif() endif()
endif() endif()
if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-implicit-function-declaration -Wno-unused")
endif()
set_target_properties(${JASPER_LIBRARY} set_target_properties(${JASPER_LIBRARY}
PROPERTIES PROPERTIES
OUTPUT_NAME ${JASPER_LIBRARY} OUTPUT_NAME ${JASPER_LIBRARY}
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}"
) )
if(ENABLE_SOLUTION_FOLDERS) if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${JASPER_LIBRARY} PROPERTIES FOLDER "3rdparty") set_target_properties(${JASPER_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif() endif()
if(NOT BUILD_SHARED_LIBS) if(NOT BUILD_SHARED_LIBS)
install(TARGETS ${JASPER_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main) install(TARGETS ${JASPER_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main)
endif() endif()

View File

@ -4,24 +4,17 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
project(${JPEG_LIBRARY}) project(${JPEG_LIBRARY})
# List of C++ files:
ocv_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) ocv_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# The .cpp files:
file(GLOB lib_srcs *.c) file(GLOB lib_srcs *.c)
file(GLOB lib_hdrs *.h) file(GLOB lib_hdrs *.h)
# ---------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------
# Define the library target: # Define the library target:
# ---------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------
add_library(${JPEG_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs}) add_library(${JPEG_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs})
if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
endif()
if(UNIX) if(UNIX)
if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
@ -32,16 +25,18 @@ if(CMAKE_COMPILER_IS_GNUCXX)
set_source_files_properties(jcdctmgr.c PROPERTIES COMPILE_FLAGS "-O1") set_source_files_properties(jcdctmgr.c PROPERTIES COMPILE_FLAGS "-O1")
endif() endif()
ocv_warnings_disable(CMAKE_C_FLAGS -Wcast-align -Wshadow)
set_target_properties(${JPEG_LIBRARY} set_target_properties(${JPEG_LIBRARY}
PROPERTIES OUTPUT_NAME ${JPEG_LIBRARY} PROPERTIES OUTPUT_NAME ${JPEG_LIBRARY}
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH} ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}
) )
if(ENABLE_SOLUTION_FOLDERS) if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${JPEG_LIBRARY} PROPERTIES FOLDER "3rdparty") set_target_properties(${JPEG_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif() endif()
if(NOT BUILD_SHARED_LIBS) if(NOT BUILD_SHARED_LIBS)
install(TARGETS ${JPEG_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main) install(TARGETS ${JPEG_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main)
endif() endif()

View File

@ -4,39 +4,35 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
project(${PNG_LIBRARY}) project(${PNG_LIBRARY})
# List of C++ files:
ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" ${ZLIB_INCLUDE_DIR}) ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" ${ZLIB_INCLUDE_DIR})
file(GLOB lib_srcs *.c) file(GLOB lib_srcs *.c)
file(GLOB lib_hdrs *.h) file(GLOB lib_hdrs *.h)
# ---------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------
# Define the library target: # Define the library target:
# ---------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------
add_library(${PNG_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs}) add_library(${PNG_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs})
if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
endif()
if(UNIX) if(UNIX)
if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC) if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
endif() endif()
endif() endif()
ocv_warnings_disable(CMAKE_C_FLAGS -Wcast-align)
set_target_properties(${PNG_LIBRARY} set_target_properties(${PNG_LIBRARY}
PROPERTIES OUTPUT_NAME ${PNG_LIBRARY} PROPERTIES OUTPUT_NAME ${PNG_LIBRARY}
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}"
) )
if(ENABLE_SOLUTION_FOLDERS) if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${PNG_LIBRARY} PROPERTIES FOLDER "3rdparty") set_target_properties(${PNG_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif() endif()
if(NOT BUILD_SHARED_LIBS) if(NOT BUILD_SHARED_LIBS)
install(TARGETS ${PNG_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main) install(TARGETS ${PNG_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main)
endif() endif()

View File

@ -26,7 +26,6 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tif_config.h.cmakein"
ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" ${ZLIB_INCLUDE_DIR}) ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" ${ZLIB_INCLUDE_DIR})
# List of C++ files:
set(lib_srcs set(lib_srcs
tif_aux.c tif_aux.c
tif_close.c tif_close.c
@ -91,10 +90,9 @@ if(WIN32)
list(APPEND lib_srcs tif_win32.c) list(APPEND lib_srcs tif_win32.c)
endif(WIN32) endif(WIN32)
if(MSVC AND NOT ENABLE_NOISY_WARNINGS) ocv_warnings_disable(CMAKE_C_FLAGS -Wno-unused-but-set-variable -Wmissing-prototypes -Wmissing-declarations -Wundef
string(REPLACE "/W4" "/W0" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") -Wcast-align -Wshadow -Wno-maybe-uninitialized -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast)
string(REPLACE "/W4" "/W0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations /wd4100 /wd4244 /wd4706 /wd4127 /wd4701 /wd4018 /wd4267 /wd4306 /wd4305 /wd4312 /wd4311)
endif()
if(UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR CV_ICC)) if(UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR CV_ICC))
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
@ -104,15 +102,15 @@ add_library(${TIFF_LIBRARY} STATIC ${lib_srcs})
target_link_libraries(${TIFF_LIBRARY} ${ZLIB_LIBRARIES}) target_link_libraries(${TIFF_LIBRARY} ${ZLIB_LIBRARIES})
set_target_properties(${TIFF_LIBRARY} set_target_properties(${TIFF_LIBRARY}
PROPERTIES PROPERTIES
OUTPUT_NAME "${TIFF_LIBRARY}" OUTPUT_NAME "${TIFF_LIBRARY}"
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}"
) )
if(ENABLE_SOLUTION_FOLDERS) if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${TIFF_LIBRARY} PROPERTIES FOLDER "3rdparty") set_target_properties(${TIFF_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif() endif()
if(NOT BUILD_SHARED_LIBS) if(NOT BUILD_SHARED_LIBS)
install(TARGETS ${TIFF_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main) install(TARGETS ${TIFF_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main)

View File

@ -143,7 +143,7 @@
/* Signed 64-bit type formatter */ /* Signed 64-bit type formatter */
/* Unsigned 64-bit type formatter */ /* Unsigned 64-bit type formatter */
#ifdef _MSC_VER #if defined _MSC_VER || defined __MINGW__ || defined __MINGW32__
# define TIFF_UINT64_FORMAT "%I64u" # define TIFF_UINT64_FORMAT "%I64u"
# define TIFF_SSIZE_FORMAT "%Iu" # define TIFF_SSIZE_FORMAT "%Iu"
#else #else

View File

@ -72,7 +72,7 @@ if(NOT EXISTS "${tbb_tarball}")
file(REMOVE "${tbb_tarball}") file(REMOVE "${tbb_tarball}")
message(FATAL_ERROR "Downloaded TBB source tarball has invalid MD5 hash: ${tbb_local_md5} (expected: ${tbb_md5})") message(FATAL_ERROR "Downloaded TBB source tarball has invalid MD5 hash: ${tbb_local_md5} (expected: ${tbb_md5})")
endif() endif()
if(EXISTS "${tbb_src_dir}") if(EXISTS "${tbb_src_dir}")
file(REMOVE_RECURSE "${tbb_src_dir}") file(REMOVE_RECURSE "${tbb_src_dir}")
endif() endif()
@ -119,18 +119,21 @@ endif()
add_library(tbb STATIC ${lib_srcs} ${lib_hdrs} "${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h" "${CMAKE_CURRENT_SOURCE_DIR}/${tbb_version_file}") add_library(tbb STATIC ${lib_srcs} ${lib_hdrs} "${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h" "${CMAKE_CURRENT_SOURCE_DIR}/${tbb_version_file}")
target_link_libraries(tbb c m dl) target_link_libraries(tbb c m dl)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -include \"${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h\"") ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wmissing-declarations)
string(REPLACE "-Werror=non-virtual-dtor" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include \"${CMAKE_CURRENT_SOURCE_DIR}/android_additional.h\"")
set_target_properties(tbb set_target_properties(tbb
PROPERTIES OUTPUT_NAME tbb PROPERTIES OUTPUT_NAME tbb
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}" DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/${OPENCV_LIB_INSTALL_PATH}"
) )
if(ENABLE_SOLUTION_FOLDERS) if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(tbb PROPERTIES FOLDER "3rdparty") set_target_properties(tbb PROPERTIES FOLDER "3rdparty")
endif() endif()
if(NOT BUILD_SHARED_LIBS) if(NOT BUILD_SHARED_LIBS)
install(TARGETS tbb ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main) install(TARGETS tbb ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main)
endif() endif()

View File

@ -6,4 +6,4 @@
"TBB: BUILD_GLIBC Unknown" ENDL \ "TBB: BUILD_GLIBC Unknown" ENDL \
"TBB: BUILD_LD Unknown" ENDL \ "TBB: BUILD_LD Unknown" ENDL \
"TBB: BUILD_TARGET Unknown" ENDL \ "TBB: BUILD_TARGET Unknown" ENDL \
"TBB: BUILD_COMMAND use cv::getBuildInformation() for details" ENDL \ "TBB: BUILD_COMMAND use cv::getBuildInformation() for details" ENDL

View File

@ -6,4 +6,4 @@
#N": BUILD_GLIBC Unknown" ENDL \ #N": BUILD_GLIBC Unknown" ENDL \
#N": BUILD_LD Unknown" ENDL \ #N": BUILD_LD Unknown" ENDL \
#N": BUILD_TARGET Unknown" ENDL \ #N": BUILD_TARGET Unknown" ENDL \
#N": BUILD_COMMAND use cv::getBuildInformation() for details" ENDL \ #N": BUILD_COMMAND use cv::getBuildInformation() for details" ENDL

View File

@ -5,19 +5,10 @@
project(${ZLIB_LIBRARY} C) project(${ZLIB_LIBRARY} C)
include(CheckTypeSize)
include(CheckFunctionExists) include(CheckFunctionExists)
include(CheckIncludeFile) include(CheckIncludeFile)
include(CheckCSourceCompiles) include(CheckCSourceCompiles)
#
# Check to see if we have large file support
#
check_type_size(off64_t OFF64_T)
if(HAVE_OFF64_T)
add_definitions(-D_LARGEFILE64_SOURCE=1)
endif()
# #
# Check for fseeko # Check for fseeko
# #
@ -82,9 +73,7 @@ if(UNIX)
endif() endif()
endif() endif()
if(MSVC AND NOT ENABLE_NOISY_WARNINGS) ocv_warnings_disable(CMAKE_C_FLAGS /wd4013 -Wattributes -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4013")
endif()
set_target_properties(${ZLIB_LIBRARY} PROPERTIES set_target_properties(${ZLIB_LIBRARY} PROPERTIES
OUTPUT_NAME ${ZLIB_LIBRARY} OUTPUT_NAME ${ZLIB_LIBRARY}
@ -95,7 +84,7 @@ set_target_properties(${ZLIB_LIBRARY} PROPERTIES
if(ENABLE_SOLUTION_FOLDERS) if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${ZLIB_LIBRARY} PROPERTIES FOLDER "3rdparty") set_target_properties(${ZLIB_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif() endif()
if(NOT BUILD_SHARED_LIBS) if(NOT BUILD_SHARED_LIBS)
install(TARGETS ${ZLIB_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main) install(TARGETS ${ZLIB_LIBRARY} ARCHIVE DESTINATION share/OpenCV/3rdparty/${OPENCV_LIB_INSTALL_PATH} COMPONENT main)
endif() endif()

View File

@ -410,10 +410,18 @@ typedef uLong FAR uLongf;
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations * equivalently requesting no 64-bit operations
*/ */
#if -_LARGEFILE64_SOURCE - -1 == 1 #if defined _LARGEFILE64_SOURCE && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE # undef _LARGEFILE64_SOURCE
#endif #endif
#ifndef _LFS64_LARGEFILE
# define _LFS64_LARGEFILE 0
#endif
#ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 0
#endif
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
# define Z_LARGE # define Z_LARGE
#endif #endif

View File

@ -188,6 +188,8 @@ OCV_OPTION(ENABLE_SSE42 "Enable SSE4.2 instructions"
OCV_OPTION(ENABLE_NOISY_WARNINGS "Show all warnings even if they are too noisy" OFF ) OCV_OPTION(ENABLE_NOISY_WARNINGS "Show all warnings even if they are too noisy" OFF )
OCV_OPTION(OPENCV_WARNINGS_ARE_ERRORS "Treat warnings as errors" OFF ) OCV_OPTION(OPENCV_WARNINGS_ARE_ERRORS "Treat warnings as errors" OFF )
OCV_OPTION(OPENCV_CAN_BREAK_BINARY_COMPATIBILITY "Allow changes breaking binary compatibility with OpenCV 2.4.0" OFF )
# uncategorized options # uncategorized options
# =================================================== # ===================================================
OCV_OPTION(CMAKE_VERBOSE "Verbose mode" OFF ) OCV_OPTION(CMAKE_VERBOSE "Verbose mode" OFF )
@ -286,13 +288,13 @@ endif()
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# OpenCV compiler and linker options # OpenCV compiler and linker options
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
include(cmake/OpenCVCompilerOptions.cmake REQUIRED)
# In case of Makefiles if the user does not setup CMAKE_BUILD_TYPE, assume it's Release: # In case of Makefiles if the user does not setup CMAKE_BUILD_TYPE, assume it's Release:
if(CMAKE_GENERATOR MATCHES "Makefiles|Ninja" AND "${CMAKE_BUILD_TYPE}" STREQUAL "") if(CMAKE_GENERATOR MATCHES "Makefiles|Ninja" AND "${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif() endif()
include(cmake/OpenCVCompilerOptions.cmake REQUIRED)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# Use statically or dynamically linked CRT? # Use statically or dynamically linked CRT?
@ -328,6 +330,15 @@ if(UNIX)
endif() endif()
endif() endif()
#
# Check to see if we have large file support (needed by zlib)
#
include(CheckTypeSize)
check_type_size(off64_t OFF64_T)
if(HAVE_OFF64_T)
add_definitions(-D_LARGEFILE64_SOURCE=1)
endif()
include(cmake/OpenCVPCHSupport.cmake REQUIRED) include(cmake/OpenCVPCHSupport.cmake REQUIRED)
include(cmake/OpenCVModule.cmake REQUIRED) include(cmake/OpenCVModule.cmake REQUIRED)
@ -471,6 +482,7 @@ else()
status(" Linker flags (Release):" ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}) status(" Linker flags (Release):" ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_RELEASE})
status(" Linker flags (Debug):" ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}) status(" Linker flags (Debug):" ${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS_DEBUG})
endif() endif()
status(" Precompiled headers:" PCHSupport_FOUND AND ENABLE_PRECOMPILED_HEADERS THEN YES ELSE NO)
# ========================== OpenCV modules ========================== # ========================== OpenCV modules ==========================
status("") status("")
@ -560,7 +572,7 @@ if(WITH_TIFF)
if(TIFF_VERSION_STRING AND TIFF_FOUND) if(TIFF_VERSION_STRING AND TIFF_FOUND)
status(" TIFF:" "${TIFF_LIBRARY} (ver ${TIFF_VERSION} - ${TIFF_VERSION_STRING})") status(" TIFF:" "${TIFF_LIBRARY} (ver ${TIFF_VERSION} - ${TIFF_VERSION_STRING})")
else() else()
status(" TIFF:" TIFF_FOUND THEN "${TIFF_LIBRARY} (ver ${TIFF_VERSION})" ELSE "build (ver ${TIFF_VERSION})") status(" TIFF:" TIFF_FOUND THEN "${TIFF_LIBRARY} (ver ${TIFF_VERSION})" ELSE "build (ver ${TIFF_VERSION} - ${TIFF_VERSION_STRING})")
endif() endif()
else() else()
status(" TIFF:" "NO") status(" TIFF:" "NO")

View File

@ -42,6 +42,9 @@
#ifndef __CVCOMMON_H_ #ifndef __CVCOMMON_H_
#define __CVCOMMON_H_ #define __CVCOMMON_H_
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "cxcore.h" #include "cxcore.h"
#include "cv.h" #include "cv.h"
#include "cxmisc.h" #include "cxmisc.h"

File diff suppressed because it is too large Load Diff

View File

@ -394,7 +394,7 @@ void icvSaveStageHaarClassifier( CvIntHaarClassifier* classifier, FILE* file )
CvIntHaarClassifier* icvLoadCARTStageHaarClassifierF( FILE* file, int step ) static CvIntHaarClassifier* icvLoadCARTStageHaarClassifierF( FILE* file, int step )
{ {
CvStageHaarClassifier* ptr = NULL; CvStageHaarClassifier* ptr = NULL;
@ -525,9 +525,9 @@ float icvEvalTreeCascadeClassifierFilter( CvIntHaarClassifier* classifier, sum_t
sum_type* tilted, float normfactor ) sum_type* tilted, float normfactor )
{ {
CvTreeCascadeNode* ptr; CvTreeCascadeNode* ptr;
CvTreeCascadeClassifier* tree; //CvTreeCascadeClassifier* tree;
tree = (CvTreeCascadeClassifier*) classifier; //tree = (CvTreeCascadeClassifier*) classifier;

View File

@ -108,7 +108,7 @@ CvBackgroundData* cvbgdata = NULL;
/* /*
* get sum image offsets for <rect> corner points * get sum image offsets for <rect> corner points
* step - row step (measured in image pixels!) of sum image * step - row step (measured in image pixels!) of sum image
*/ */
#define CV_SUM_OFFSETS( p0, p1, p2, p3, rect, step ) \ #define CV_SUM_OFFSETS( p0, p1, p2, p3, rect, step ) \
@ -122,7 +122,7 @@ CvBackgroundData* cvbgdata = NULL;
(p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height); (p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height);
/* /*
* get tilted image offsets for <rect> corner points * get tilted image offsets for <rect> corner points
* step - row step (measured in image pixels!) of tilted image * step - row step (measured in image pixels!) of tilted image
*/ */
#define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step ) \ #define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step ) \
@ -154,7 +154,7 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
{ {
CvIntHaarFeatures* features = NULL; CvIntHaarFeatures* features = NULL;
CvTHaarFeature haarFeature; CvTHaarFeature haarFeature;
CvMemStorage* storage = NULL; CvMemStorage* storage = NULL;
CvSeq* seq = NULL; CvSeq* seq = NULL;
CvSeqWriter writer; CvSeqWriter writer;
@ -169,10 +169,11 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
int dx = 0; int dx = 0;
int dy = 0; int dy = 0;
#if 0
float factor = 1.0F; float factor = 1.0F;
factor = ((float) winsize.width) * winsize.height / (24 * 24); factor = ((float) winsize.width) * winsize.height / (24 * 24);
#if 0
s0 = (int) (s0 * factor); s0 = (int) (s0 * factor);
s1 = (int) (s1 * factor); s1 = (int) (s1 * factor);
s2 = (int) (s2 * factor); s2 = (int) (s2 * factor);
@ -252,7 +253,7 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
CV_WRITE_SEQ_ELEM( haarFeature, writer ); CV_WRITE_SEQ_ELEM( haarFeature, writer );
} }
} }
// haar_y4 // haar_y4
if ( (x+dx <= winsize.width ) && (y+dy*4 <= winsize.height) ) { if ( (x+dx <= winsize.width ) && (y+dy*4 <= winsize.height) ) {
if (dx*4*dy < s0) continue; if (dx*4*dy < s0) continue;
@ -277,7 +278,7 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
} }
} }
if (mode != 0 /*BASIC*/) { if (mode != 0 /*BASIC*/) {
// point // point
if ( (x+dx*3 <= winsize.width) && (y+dy*3 <= winsize.height) ) { if ( (x+dx*3 <= winsize.width) && (y+dy*3 <= winsize.height) ) {
if (dx*9*dy < s0) continue; if (dx*9*dy < s0) continue;
@ -289,12 +290,12 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
} }
} }
} }
if (mode == 2 /*ALL*/) { if (mode == 2 /*ALL*/) {
// tilted haar_x2 (x, y, w, h, b, weight) // tilted haar_x2 (x, y, w, h, b, weight)
if ( (x+2*dx <= winsize.width) && (y+2*dx+dy <= winsize.height) && (x-dy>= 0) ) { if ( (x+2*dx <= winsize.width) && (y+2*dx+dy <= winsize.height) && (x-dy>= 0) ) {
if (dx*2*dy < s1) continue; if (dx*2*dy < s1) continue;
if (!symmetric || (x <= (winsize.width / 2) )) { if (!symmetric || (x <= (winsize.width / 2) )) {
haarFeature = cvHaarFeature( "tilted_haar_x2", haarFeature = cvHaarFeature( "tilted_haar_x2",
x, y, dx*2, dy, -1, x, y, dx*2, dy, -1,
@ -302,11 +303,11 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
CV_WRITE_SEQ_ELEM( haarFeature, writer ); CV_WRITE_SEQ_ELEM( haarFeature, writer );
} }
} }
// tilted haar_y2 (x, y, w, h, b, weight) // tilted haar_y2 (x, y, w, h, b, weight)
if ( (x+dx <= winsize.width) && (y+dx+2*dy <= winsize.height) && (x-2*dy>= 0) ) { if ( (x+dx <= winsize.width) && (y+dx+2*dy <= winsize.height) && (x-2*dy>= 0) ) {
if (dx*2*dy < s1) continue; if (dx*2*dy < s1) continue;
if (!symmetric || (x <= (winsize.width / 2) )) { if (!symmetric || (x <= (winsize.width / 2) )) {
haarFeature = cvHaarFeature( "tilted_haar_y2", haarFeature = cvHaarFeature( "tilted_haar_y2",
x, y, dx, 2*dy, -1, x, y, dx, 2*dy, -1,
@ -314,11 +315,11 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
CV_WRITE_SEQ_ELEM( haarFeature, writer ); CV_WRITE_SEQ_ELEM( haarFeature, writer );
} }
} }
// tilted haar_x3 (x, y, w, h, b, weight) // tilted haar_x3 (x, y, w, h, b, weight)
if ( (x+3*dx <= winsize.width) && (y+3*dx+dy <= winsize.height) && (x-dy>= 0) ) { if ( (x+3*dx <= winsize.width) && (y+3*dx+dy <= winsize.height) && (x-dy>= 0) ) {
if (dx*3*dy < s2) continue; if (dx*3*dy < s2) continue;
if (!symmetric || (x <= (winsize.width / 2) )) { if (!symmetric || (x <= (winsize.width / 2) )) {
haarFeature = cvHaarFeature( "tilted_haar_x3", haarFeature = cvHaarFeature( "tilted_haar_x3",
x, y, dx*3, dy, -1, x, y, dx*3, dy, -1,
@ -326,11 +327,11 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
CV_WRITE_SEQ_ELEM( haarFeature, writer ); CV_WRITE_SEQ_ELEM( haarFeature, writer );
} }
} }
// tilted haar_y3 (x, y, w, h, b, weight) // tilted haar_y3 (x, y, w, h, b, weight)
if ( (x+dx <= winsize.width) && (y+dx+3*dy <= winsize.height) && (x-3*dy>= 0) ) { if ( (x+dx <= winsize.width) && (y+dx+3*dy <= winsize.height) && (x-3*dy>= 0) ) {
if (dx*3*dy < s2) continue; if (dx*3*dy < s2) continue;
if (!symmetric || (x <= (winsize.width / 2) )) { if (!symmetric || (x <= (winsize.width / 2) )) {
haarFeature = cvHaarFeature( "tilted_haar_y3", haarFeature = cvHaarFeature( "tilted_haar_y3",
x, y, dx, 3*dy, -1, x, y, dx, 3*dy, -1,
@ -338,12 +339,12 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
CV_WRITE_SEQ_ELEM( haarFeature, writer ); CV_WRITE_SEQ_ELEM( haarFeature, writer );
} }
} }
// tilted haar_x4 (x, y, w, h, b, weight) // tilted haar_x4 (x, y, w, h, b, weight)
if ( (x+4*dx <= winsize.width) && (y+4*dx+dy <= winsize.height) && (x-dy>= 0) ) { if ( (x+4*dx <= winsize.width) && (y+4*dx+dy <= winsize.height) && (x-dy>= 0) ) {
if (dx*4*dy < s3) continue; if (dx*4*dy < s3) continue;
if (!symmetric || (x <= (winsize.width / 2) )) { if (!symmetric || (x <= (winsize.width / 2) )) {
haarFeature = cvHaarFeature( "tilted_haar_x4", haarFeature = cvHaarFeature( "tilted_haar_x4",
@ -353,11 +354,11 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
CV_WRITE_SEQ_ELEM( haarFeature, writer ); CV_WRITE_SEQ_ELEM( haarFeature, writer );
} }
} }
// tilted haar_y4 (x, y, w, h, b, weight) // tilted haar_y4 (x, y, w, h, b, weight)
if ( (x+dx <= winsize.width) && (y+dx+4*dy <= winsize.height) && (x-4*dy>= 0) ) { if ( (x+dx <= winsize.width) && (y+dx+4*dy <= winsize.height) && (x-4*dy>= 0) ) {
if (dx*4*dy < s3) continue; if (dx*4*dy < s3) continue;
if (!symmetric || (x <= (winsize.width / 2) )) { if (!symmetric || (x <= (winsize.width / 2) )) {
haarFeature = cvHaarFeature( "tilted_haar_y4", haarFeature = cvHaarFeature( "tilted_haar_y4",
x, y, dx, 4*dy, -1, x, y, dx, 4*dy, -1,
@ -365,10 +366,10 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
CV_WRITE_SEQ_ELEM( haarFeature, writer ); CV_WRITE_SEQ_ELEM( haarFeature, writer );
} }
} }
/* /*
// tilted point // tilted point
if ( (x+dx*3 <= winsize.width - 1) && (y+dy*3 <= winsize.height - 1) && (x-3*dy>= 0)) { if ( (x+dx*3 <= winsize.width - 1) && (y+dy*3 <= winsize.height - 1) && (x-3*dy>= 0)) {
if (dx*9*dy < 36) continue; if (dx*9*dy < 36) continue;
@ -395,10 +396,10 @@ CvIntHaarFeatures* icvCreateIntHaarFeatures( CvSize winsize,
features->winsize = winsize; features->winsize = winsize;
cvCvtSeqToArray( seq, (CvArr*) features->feature ); cvCvtSeqToArray( seq, (CvArr*) features->feature );
cvReleaseMemStorage( &storage ); cvReleaseMemStorage( &storage );
icvConvertToFastHaarFeature( features->feature, features->fastfeature, icvConvertToFastHaarFeature( features->feature, features->fastfeature,
features->count, (winsize.width + 1) ); features->count, (winsize.width + 1) );
return features; return features;
} }
@ -438,7 +439,7 @@ void icvConvertToFastHaarFeature( CvTHaarFeature* haarFeature,
fastHaarFeature[i].rect[j].p3, fastHaarFeature[i].rect[j].p3,
haarFeature[i].rect[j].r, step ) haarFeature[i].rect[j].r, step )
} }
} }
else else
{ {
@ -469,15 +470,15 @@ static
CvHaarTrainigData* icvCreateHaarTrainingData( CvSize winsize, int maxnumsamples ) CvHaarTrainigData* icvCreateHaarTrainingData( CvSize winsize, int maxnumsamples )
{ {
CvHaarTrainigData* data; CvHaarTrainigData* data;
CV_FUNCNAME( "icvCreateHaarTrainingData" ); CV_FUNCNAME( "icvCreateHaarTrainingData" );
__BEGIN__; __BEGIN__;
data = NULL; data = NULL;
uchar* ptr = NULL; uchar* ptr = NULL;
size_t datasize = 0; size_t datasize = 0;
datasize = sizeof( CvHaarTrainigData ) + datasize = sizeof( CvHaarTrainigData ) +
/* sum and tilted */ /* sum and tilted */
( 2 * (winsize.width + 1) * (winsize.height + 1) * sizeof( sum_type ) + ( 2 * (winsize.width + 1) * (winsize.height + 1) * sizeof( sum_type ) +
@ -548,7 +549,7 @@ void icvGetTrainingDataCallback( CvMat* mat, CvMat* sampleIdx, CvMat*,
int j = 0; int j = 0;
float val = 0.0F; float val = 0.0F;
float normfactor = 0.0F; float normfactor = 0.0F;
CvHaarTrainingData* training_data; CvHaarTrainingData* training_data;
CvIntHaarFeatures* haar_features; CvIntHaarFeatures* haar_features;
@ -639,7 +640,7 @@ void icvGetTrainingDataCallback( CvMat* mat, CvMat* sampleIdx, CvMat*,
#if 0 /*def CV_VERBOSE*/ #if 0 /*def CV_VERBOSE*/
if( first % 5000 == 0 ) if( first % 5000 == 0 )
{ {
fprintf( stderr, "%3d%%\r", (int) (100.0 * first / fprintf( stderr, "%3d%%\r", (int) (100.0 * first /
haar_features->count) ); haar_features->count) );
fflush( stderr ); fflush( stderr );
} }
@ -692,7 +693,7 @@ void icvPrecalculate( CvHaarTrainingData* data, CvIntHaarFeatures* haarFeatures,
t_data = *data->valcache; t_data = *data->valcache;
t_idx = *data->idxcache; t_idx = *data->idxcache;
t_portion = MIN( portion, (numprecalculated - first) ); t_portion = MIN( portion, (numprecalculated - first) );
/* indices */ /* indices */
t_idx.rows = t_portion; t_idx.rows = t_portion;
t_idx.data.ptr = data->idxcache->data.ptr + first * ((size_t)t_idx.step); t_idx.data.ptr = data->idxcache->data.ptr + first * ((size_t)t_idx.step);
@ -766,7 +767,7 @@ void icvSplitIndicesCallback( int compidx, float threshold,
{ {
if( cvEvalFastHaarFeature( fastfeature, if( cvEvalFastHaarFeature( fastfeature,
(sum_type*) (data->sum.data.ptr + i * data->sum.step), (sum_type*) (data->sum.data.ptr + i * data->sum.step),
(sum_type*) (data->tilted.data.ptr + i * data->tilted.step) ) (sum_type*) (data->tilted.data.ptr + i * data->tilted.step) )
< threshold * data->normfactor.data.fl[i] ) < threshold * data->normfactor.data.fl[i] )
{ {
(*left)->data.fl[(*left)->cols++] = (float) i; (*left)->data.fl[(*left)->cols++] = (float) i;
@ -792,7 +793,7 @@ void icvSplitIndicesCallback( int compidx, float threshold,
index = (int) *((float*) (idxdata + i * idxstep)); index = (int) *((float*) (idxdata + i * idxstep));
if( cvEvalFastHaarFeature( fastfeature, if( cvEvalFastHaarFeature( fastfeature,
(sum_type*) (data->sum.data.ptr + index * data->sum.step), (sum_type*) (data->sum.data.ptr + index * data->sum.step),
(sum_type*) (data->tilted.data.ptr + index * data->tilted.step) ) (sum_type*) (data->tilted.data.ptr + index * data->tilted.step) )
< threshold * data->normfactor.data.fl[index] ) < threshold * data->normfactor.data.fl[index] )
{ {
(*left)->data.fl[(*left)->cols++] = (float) index; (*left)->data.fl[(*left)->cols++] = (float) index;
@ -858,7 +859,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
float sum_stage = 0.0F; float sum_stage = 0.0F;
float threshold = 0.0F; float threshold = 0.0F;
float falsealarm = 0.0F; float falsealarm = 0.0F;
//CvMat* sampleIdx = NULL; //CvMat* sampleIdx = NULL;
CvMat* trimmedIdx; CvMat* trimmedIdx;
//float* idxdata = NULL; //float* idxdata = NULL;
@ -871,7 +872,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
int idx; int idx;
int numsamples; int numsamples;
int numtrimmed; int numtrimmed;
CvCARTHaarClassifier* classifier; CvCARTHaarClassifier* classifier;
CvSeq* seq = NULL; CvSeq* seq = NULL;
CvMemStorage* storage = NULL; CvMemStorage* storage = NULL;
@ -885,7 +886,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
printf( "| N |%%SMP|F| ST.THR | HR | FA | EXP. ERR|\n" ); printf( "| N |%%SMP|F| ST.THR | HR | FA | EXP. ERR|\n" );
printf( "+----+----+-+---------+---------+---------+---------+\n" ); printf( "+----+----+-+---------+---------+---------+---------+\n" );
#endif /* CV_VERBOSE */ #endif /* CV_VERBOSE */
n = haarFeatures->count; n = haarFeatures->count;
m = data->sum.rows; m = data->sum.rows;
numsamples = (sampleIdx) ? MAX( sampleIdx->rows, sampleIdx->cols ) : m; numsamples = (sampleIdx) ? MAX( sampleIdx->rows, sampleIdx->cols ) : m;
@ -909,7 +910,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
trainParams.userdata = &userdata; trainParams.userdata = &userdata;
eval = cvMat( 1, m, CV_32FC1, cvAlloc( sizeof( float ) * m ) ); eval = cvMat( 1, m, CV_32FC1, cvAlloc( sizeof( float ) * m ) );
storage = cvCreateMemStorage(); storage = cvCreateMemStorage();
seq = cvCreateSeq( 0, sizeof( *seq ), sizeof( classifier ), storage ); seq = cvCreateSeq( 0, sizeof( *seq ), sizeof( classifier ), storage );
@ -919,7 +920,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
num_splits = 0; num_splits = 0;
sumalpha = 0.0F; sumalpha = 0.0F;
do do
{ {
#ifdef CV_VERBOSE #ifdef CV_VERBOSE
int v_wt = 0; int v_wt = 0;
@ -947,12 +948,12 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
num_splits += classifier->count; num_splits += classifier->count;
cart->release( (CvClassifier**) &cart ); cart->release( (CvClassifier**) &cart );
if( symmetric && (seq->total % 2) ) if( symmetric && (seq->total % 2) )
{ {
float normfactor = 0.0F; float normfactor = 0.0F;
CvStumpClassifier* stump; CvStumpClassifier* stump;
/* flip haar features */ /* flip haar features */
for( i = 0; i < classifier->count; i++ ) for( i = 0; i < classifier->count; i++ )
{ {
@ -961,9 +962,9 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
for( j = 0; j < CV_HAAR_FEATURE_MAX && for( j = 0; j < CV_HAAR_FEATURE_MAX &&
classifier->feature[i].rect[j].weight != 0.0F; j++ ) classifier->feature[i].rect[j].weight != 0.0F; j++ )
{ {
classifier->feature[i].rect[j].r.x = data->winsize.width - classifier->feature[i].rect[j].r.x = data->winsize.width -
classifier->feature[i].rect[j].r.x - classifier->feature[i].rect[j].r.x -
classifier->feature[i].rect[j].r.width; classifier->feature[i].rect[j].r.width;
} }
} }
else else
@ -975,7 +976,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
for( j = 0; j < CV_HAAR_FEATURE_MAX && for( j = 0; j < CV_HAAR_FEATURE_MAX &&
classifier->feature[i].rect[j].weight != 0.0F; j++ ) classifier->feature[i].rect[j].weight != 0.0F; j++ )
{ {
classifier->feature[i].rect[j].r.x = data->winsize.width - classifier->feature[i].rect[j].r.x = data->winsize.width -
classifier->feature[i].rect[j].r.x; classifier->feature[i].rect[j].r.x;
CV_SWAP( classifier->feature[i].rect[j].r.width, CV_SWAP( classifier->feature[i].rect[j].r.width,
classifier->feature[i].rect[j].r.height, tmp ); classifier->feature[i].rect[j].r.height, tmp );
@ -1010,7 +1011,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
weakTrainVals, 0, 0, 0, trimmedIdx, weakTrainVals, 0, 0, 0, trimmedIdx,
&(data->weights), &(data->weights),
trainParams.stumpTrainParams ); trainParams.stumpTrainParams );
classifier->threshold[i] = stump->threshold; classifier->threshold[i] = stump->threshold;
if( classifier->left[i] <= 0 ) if( classifier->left[i] <= 0 )
{ {
@ -1021,8 +1022,8 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
classifier->val[-classifier->right[i]] = stump->right; classifier->val[-classifier->right[i]] = stump->right;
} }
stump->release( (CvClassifier**) &stump ); stump->release( (CvClassifier**) &stump );
} }
stumpTrainParams.getTrainData = icvGetTrainingDataCallback; stumpTrainParams.getTrainData = icvGetTrainingDataCallback;
@ -1040,7 +1041,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
cvReleaseMat( &trimmedIdx ); cvReleaseMat( &trimmedIdx );
trimmedIdx = NULL; trimmedIdx = NULL;
} }
for( i = 0; i < numsamples; i++ ) for( i = 0; i < numsamples; i++ )
{ {
idx = icvGetIdxAt( sampleIdx, i ); idx = icvGetIdxAt( sampleIdx, i );
@ -1054,10 +1055,10 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
alpha = cvBoostNextWeakClassifier( &eval, &data->cls, weakTrainVals, alpha = cvBoostNextWeakClassifier( &eval, &data->cls, weakTrainVals,
&data->weights, trainer ); &data->weights, trainer );
sumalpha += alpha; sumalpha += alpha;
for( i = 0; i <= classifier->count; i++ ) for( i = 0; i <= classifier->count; i++ )
{ {
if( boosttype == CV_RABCLASS ) if( boosttype == CV_RABCLASS )
{ {
classifier->val[i] = cvLogRatio( classifier->val[i] ); classifier->val[i] = cvLogRatio( classifier->val[i] );
} }
@ -1077,7 +1078,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
for( j = 0; j < seq->total; j++ ) for( j = 0; j < seq->total; j++ )
{ {
classifier = *((CvCARTHaarClassifier**) cvGetSeqElem( seq, j )); classifier = *((CvCARTHaarClassifier**) cvGetSeqElem( seq, j ));
eval.data.fl[numpos] += classifier->eval( eval.data.fl[numpos] += classifier->eval(
(CvIntHaarClassifier*) classifier, (CvIntHaarClassifier*) classifier,
(sum_type*) (data->sum.data.ptr + idx * data->sum.step), (sum_type*) (data->sum.data.ptr + idx * data->sum.step),
(sum_type*) (data->tilted.data.ptr + idx * data->tilted.step), (sum_type*) (data->tilted.data.ptr + idx * data->tilted.step),
@ -1163,7 +1164,7 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
fflush( stdout ); fflush( stdout );
} }
#endif /* CV_VERBOSE */ #endif /* CV_VERBOSE */
} while( falsealarm > maxfalsealarm && (!maxsplits || (num_splits < maxsplits) ) ); } while( falsealarm > maxfalsealarm && (!maxsplits || (num_splits < maxsplits) ) );
cvBoostEndTraining( &trainer ); cvBoostEndTraining( &trainer );
@ -1177,12 +1178,12 @@ CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
threshold ); threshold );
cvCvtSeqToArray( seq, (CvArr*) stage->classifier ); cvCvtSeqToArray( seq, (CvArr*) stage->classifier );
} }
/* CLEANUP */ /* CLEANUP */
cvReleaseMemStorage( &storage ); cvReleaseMemStorage( &storage );
cvReleaseMat( &weakTrainVals ); cvReleaseMat( &weakTrainVals );
cvFree( &(eval.data.ptr) ); cvFree( &(eval.data.ptr) );
return (CvIntHaarClassifier*) stage; return (CvIntHaarClassifier*) stage;
} }
@ -1192,7 +1193,7 @@ CvBackgroundData* icvCreateBackgroundData( const char* filename, CvSize winsize
{ {
CvBackgroundData* data = NULL; CvBackgroundData* data = NULL;
const char* dir = NULL; const char* dir = NULL;
char full[PATH_MAX]; char full[PATH_MAX];
char* imgfilename = NULL; char* imgfilename = NULL;
size_t datasize = 0; size_t datasize = 0;
@ -1202,7 +1203,7 @@ CvBackgroundData* icvCreateBackgroundData( const char* filename, CvSize winsize
int len = 0; int len = 0;
assert( filename != NULL ); assert( filename != NULL );
dir = strrchr( filename, '\\' ); dir = strrchr( filename, '\\' );
if( dir == NULL ) if( dir == NULL )
{ {
@ -1223,7 +1224,7 @@ CvBackgroundData* icvCreateBackgroundData( const char* filename, CvSize winsize
{ {
count = 0; count = 0;
datasize = 0; datasize = 0;
/* count */ /* count */
while( !feof( input ) ) while( !feof( input ) )
{ {
@ -1257,11 +1258,11 @@ CvBackgroundData* icvCreateBackgroundData( const char* filename, CvSize winsize
while( !feof( input ) ) while( !feof( input ) )
{ {
*imgfilename = '\0'; *imgfilename = '\0';
if( !fgets( imgfilename, PATH_MAX - (int)(imgfilename - full) - 1, input )) if( !fgets( imgfilename, PATH_MAX - (int)(imgfilename - full) - 1, input ))
break; break;
len = (int)strlen( imgfilename ); len = (int)strlen( imgfilename );
if( len > 0 && imgfilename[len-1] == '\n' ) if( len > 0 && imgfilename[len-1] == '\n' )
imgfilename[len-1] = 0, len--; imgfilename[len-1] = 0, len--;
if( len > 0 ) if( len > 0 )
{ {
if( (*imgfilename) == '#' ) continue; /* comment */ if( (*imgfilename) == '#' ) continue; /* comment */
@ -1351,14 +1352,14 @@ void icvGetNextFromBackgroundData( CvBackgroundData* data,
{ {
round = data->round; round = data->round;
//#ifdef CV_VERBOSE //#ifdef CV_VERBOSE
// printf( "Open background image: %s\n", data->filename[data->last] ); // printf( "Open background image: %s\n", data->filename[data->last] );
//#endif /* CV_VERBOSE */ //#endif /* CV_VERBOSE */
data->last = rand() % data->count; data->last = rand() % data->count;
data->last %= data->count; data->last %= data->count;
img = cvLoadImage( data->filename[data->last], 0 ); img = cvLoadImage( data->filename[data->last], 0 );
if( !img ) if( !img )
continue; continue;
data->round += data->last / data->count; data->round += data->last / data->count;
data->round = data->round % (data->winsize.width * data->winsize.height); data->round = data->round % (data->winsize.width * data->winsize.height);
@ -1368,7 +1369,7 @@ void icvGetNextFromBackgroundData( CvBackgroundData* data,
offset.x = MIN( offset.x, img->width - data->winsize.width ); offset.x = MIN( offset.x, img->width - data->winsize.width );
offset.y = MIN( offset.y, img->height - data->winsize.height ); offset.y = MIN( offset.y, img->height - data->winsize.height );
if( img != NULL && img->depth == IPL_DEPTH_8U && img->nChannels == 1 && if( img != NULL && img->depth == IPL_DEPTH_8U && img->nChannels == 1 &&
offset.x >= 0 && offset.y >= 0 ) offset.x >= 0 && offset.y >= 0 )
{ {
@ -1403,7 +1404,7 @@ void icvGetNextFromBackgroundData( CvBackgroundData* data,
reader->scale = MAX( reader->scale = MAX(
((float) data->winsize.width + reader->point.x) / ((float) reader->src.cols), ((float) data->winsize.width + reader->point.x) / ((float) reader->src.cols),
((float) data->winsize.height + reader->point.y) / ((float) reader->src.rows) ); ((float) data->winsize.height + reader->point.y) / ((float) reader->src.rows) );
reader->img = cvMat( (int) (reader->scale * reader->src.rows + 0.5F), reader->img = cvMat( (int) (reader->scale * reader->src.rows + 0.5F),
(int) (reader->scale * reader->src.cols + 0.5F), (int) (reader->scale * reader->src.cols + 0.5F),
CV_8UC1, (void*) cvAlloc( datasize ) ); CV_8UC1, (void*) cvAlloc( datasize ) );
@ -1576,11 +1577,11 @@ void icvGetAuxImages( CvMat* img, CvMat* sum, CvMat* tilted,
sum_type valsum = 0; sum_type valsum = 0;
sqsum_type valsqsum = 0; sqsum_type valsqsum = 0;
double area = 0.0; double area = 0.0;
cvIntegral( img, sum, sqsum, tilted ); cvIntegral( img, sum, sqsum, tilted );
normrect = cvRect( 1, 1, img->cols - 2, img->rows - 2 ); normrect = cvRect( 1, 1, img->cols - 2, img->rows - 2 );
CV_SUM_OFFSETS( p0, p1, p2, p3, normrect, img->cols + 1 ) CV_SUM_OFFSETS( p0, p1, p2, p3, normrect, img->cols + 1 )
area = normrect.width * normrect.height; area = normrect.width * normrect.height;
valsum = ((sum_type*) (sum->data.ptr))[p0] - ((sum_type*) (sum->data.ptr))[p1] valsum = ((sum_type*) (sum->data.ptr))[p0] - ((sum_type*) (sum->data.ptr))[p1]
- ((sum_type*) (sum->data.ptr))[p2] + ((sum_type*) (sum->data.ptr))[p3]; - ((sum_type*) (sum->data.ptr))[p2] + ((sum_type*) (sum->data.ptr))[p3];
@ -1621,28 +1622,28 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
int i = 0; int i = 0;
ccounter_t getcount = 0; ccounter_t getcount = 0;
ccounter_t thread_getcount = 0; ccounter_t thread_getcount = 0;
ccounter_t consumed_count; ccounter_t consumed_count;
ccounter_t thread_consumed_count; ccounter_t thread_consumed_count;
/* private variables */ /* private variables */
CvMat img; CvMat img;
CvMat sum; CvMat sum;
CvMat tilted; CvMat tilted;
CvMat sqsum; CvMat sqsum;
sum_type* sumdata; sum_type* sumdata;
sum_type* tilteddata; sum_type* tilteddata;
float* normfactor; float* normfactor;
/* end private variables */ /* end private variables */
assert( data != NULL ); assert( data != NULL );
assert( first + count <= data->maxnum ); assert( first + count <= data->maxnum );
assert( cascade != NULL ); assert( cascade != NULL );
assert( callback != NULL ); assert( callback != NULL );
// if( !cvbgdata ) return 0; this check needs to be done in the callback for BG // if( !cvbgdata ) return 0; this check needs to be done in the callback for BG
CCOUNTER_SET_ZERO(getcount); CCOUNTER_SET_ZERO(getcount);
CCOUNTER_SET_ZERO(thread_getcount); CCOUNTER_SET_ZERO(thread_getcount);
CCOUNTER_SET_ZERO(consumed_count); CCOUNTER_SET_ZERO(consumed_count);
@ -1691,14 +1692,14 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
normfactor = data->normfactor.data.fl + i; normfactor = data->normfactor.data.fl + i;
sum.data.ptr = (uchar*) sumdata; sum.data.ptr = (uchar*) sumdata;
tilted.data.ptr = (uchar*) tilteddata; tilted.data.ptr = (uchar*) tilteddata;
icvGetAuxImages( &img, &sum, &tilted, &sqsum, normfactor ); icvGetAuxImages( &img, &sum, &tilted, &sqsum, normfactor );
if( cascade->eval( cascade, sumdata, tilteddata, *normfactor ) != 0.0F ) if( cascade->eval( cascade, sumdata, tilteddata, *normfactor ) != 0.0F )
{ {
CCOUNTER_INC(thread_getcount); CCOUNTER_INC(thread_getcount);
break; break;
} }
} }
#ifdef CV_VERBOSE #ifdef CV_VERBOSE
if( (i - first) % 500 == 0 ) if( (i - first) % 500 == 0 )
{ {
@ -1720,7 +1721,7 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
CCOUNTER_ADD(consumed_count, thread_consumed_count); CCOUNTER_ADD(consumed_count, thread_consumed_count);
} }
} /* omp parallel */ } /* omp parallel */
if( consumed != NULL ) if( consumed != NULL )
{ {
*consumed = (int)consumed_count; *consumed = (int)consumed_count;
@ -1731,7 +1732,7 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
/* *acceptance_ratio = ((double) count) / consumed_count; */ /* *acceptance_ratio = ((double) count) / consumed_count; */
*acceptance_ratio = CCOUNTER_DIV(count, consumed_count); *acceptance_ratio = CCOUNTER_DIV(count, consumed_count);
} }
return static_cast<int>(getcount); return static_cast<int>(getcount);
} }
@ -1791,7 +1792,7 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
// CV_SQSUM_MAT_TYPE, // CV_SQSUM_MAT_TYPE,
// cvAlloc( sizeof( sqsum_type ) * (data->winsize.height + 1) // cvAlloc( sizeof( sqsum_type ) * (data->winsize.height + 1)
// * (data->winsize.width + 1) ) ); // * (data->winsize.width + 1) ) );
// //
// #ifdef CV_OPENMP // #ifdef CV_OPENMP
// #pragma omp for schedule(static, 1) // #pragma omp for schedule(static, 1)
// #endif /* CV_OPENMP */ // #endif /* CV_OPENMP */
@ -1800,7 +1801,7 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
// for( ; ; ) // for( ; ; )
// { // {
// icvGetBackgroundImage( cvbgdata, cvbgreader, &img ); // icvGetBackgroundImage( cvbgdata, cvbgreader, &img );
// //
// CCOUNTER_INC(thread_consumed_count); // CCOUNTER_INC(thread_consumed_count);
// //
// sumdata = (sum_type*) (data->sum.data.ptr + i * data->sum.step); // sumdata = (sum_type*) (data->sum.data.ptr + i * data->sum.step);
@ -1808,7 +1809,7 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
// normfactor = data->normfactor.data.fl + i; // normfactor = data->normfactor.data.fl + i;
// sum.data.ptr = (uchar*) sumdata; // sum.data.ptr = (uchar*) sumdata;
// tilted.data.ptr = (uchar*) tilteddata; // tilted.data.ptr = (uchar*) tilteddata;
// icvGetAuxImages( &img, &sum, &tilted, &sqsum, normfactor ); // icvGetAuxImages( &img, &sum, &tilted, &sqsum, normfactor );
// if( cascade->eval( cascade, sumdata, tilteddata, *normfactor ) != 0.0F ) // if( cascade->eval( cascade, sumdata, tilteddata, *normfactor ) != 0.0F )
// { // {
// break; // break;
@ -1822,7 +1823,7 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
// fflush( stderr ); // fflush( stderr );
// } // }
//#endif /* CV_VERBOSE */ //#endif /* CV_VERBOSE */
// //
// } // }
// //
// cvFree( &(img.data.ptr) ); // cvFree( &(img.data.ptr) );
@ -1842,7 +1843,7 @@ int icvGetHaarTrainingData( CvHaarTrainingData* data, int first, int count,
// /* *acceptance_ratio = ((double) count) / consumed_count; */ // /* *acceptance_ratio = ((double) count) / consumed_count; */
// *acceptance_ratio = CCOUNTER_DIV(count, consumed_count); // *acceptance_ratio = CCOUNTER_DIV(count, consumed_count);
// } // }
// //
// return count; // return count;
//} //}
@ -1853,24 +1854,24 @@ int icvGetHaarTraininDataFromVecCallback( CvMat* img, void* userdata )
int c = 0; int c = 0;
assert( img->rows * img->cols == ((CvVecFile*) userdata)->vecsize ); assert( img->rows * img->cols == ((CvVecFile*) userdata)->vecsize );
size_t elements_read = fread( &tmp, sizeof( tmp ), 1, ((CvVecFile*) userdata)->input ); size_t elements_read = fread( &tmp, sizeof( tmp ), 1, ((CvVecFile*) userdata)->input );
CV_Assert(elements_read == 1); CV_Assert(elements_read == 1);
elements_read = fread( ((CvVecFile*) userdata)->vector, sizeof( short ), elements_read = fread( ((CvVecFile*) userdata)->vector, sizeof( short ),
((CvVecFile*) userdata)->vecsize, ((CvVecFile*) userdata)->input ); ((CvVecFile*) userdata)->vecsize, ((CvVecFile*) userdata)->input );
CV_Assert(elements_read == (size_t)((CvVecFile*) userdata)->vecsize); CV_Assert(elements_read == (size_t)((CvVecFile*) userdata)->vecsize);
if( feof( ((CvVecFile*) userdata)->input ) || if( feof( ((CvVecFile*) userdata)->input ) ||
(((CvVecFile*) userdata)->last)++ >= ((CvVecFile*) userdata)->count ) (((CvVecFile*) userdata)->last)++ >= ((CvVecFile*) userdata)->count )
{ {
return 0; return 0;
} }
for( r = 0; r < img->rows; r++ ) for( r = 0; r < img->rows; r++ )
{ {
for( c = 0; c < img->cols; c++ ) for( c = 0; c < img->cols; c++ )
{ {
CV_MAT_ELEM( *img, uchar, r, c ) = CV_MAT_ELEM( *img, uchar, r, c ) =
(uchar) ( ((CvVecFile*) userdata)->vector[r * img->cols + c] ); (uchar) ( ((CvVecFile*) userdata)->vector[r * img->cols + c] );
} }
} }
@ -1878,14 +1879,14 @@ int icvGetHaarTraininDataFromVecCallback( CvMat* img, void* userdata )
return 1; return 1;
} }
int icvGetHaarTrainingDataFromBGCallback ( CvMat* img, void* /*userdata*/ ) static int icvGetHaarTrainingDataFromBGCallback ( CvMat* img, void* /*userdata*/ )
{ {
if (! cvbgdata) if (! cvbgdata)
return 0; return 0;
if (! cvbgreader) if (! cvbgreader)
return 0; return 0;
// just in case icvGetBackgroundImage is not thread-safe ... // just in case icvGetBackgroundImage is not thread-safe ...
#ifdef CV_OPENMP #ifdef CV_OPENMP
#pragma omp critical (get_background_image_callback) #pragma omp critical (get_background_image_callback)
@ -1893,7 +1894,7 @@ int icvGetHaarTrainingDataFromBGCallback ( CvMat* img, void* /*userdata*/ )
{ {
icvGetBackgroundImage( cvbgdata, cvbgreader, img ); icvGetBackgroundImage( cvbgdata, cvbgreader, img );
} }
return 1; return 1;
} }
@ -1902,7 +1903,7 @@ int icvGetHaarTrainingDataFromBGCallback ( CvMat* img, void* /*userdata*/ )
* Get training data from .vec file * Get training data from .vec file
*/ */
static static
int icvGetHaarTrainingDataFromVec( CvHaarTrainingData* data, int first, int count, int icvGetHaarTrainingDataFromVec( CvHaarTrainingData* data, int first, int count,
CvIntHaarClassifier* cascade, CvIntHaarClassifier* cascade,
const char* filename, const char* filename,
int* consumed ) int* consumed )
@ -1914,8 +1915,8 @@ int icvGetHaarTrainingDataFromVec( CvHaarTrainingData* data, int first, int coun
__BEGIN__; __BEGIN__;
CvVecFile file; CvVecFile file;
short tmp = 0; short tmp = 0;
file.input = NULL; file.input = NULL;
if( filename ) file.input = fopen( filename, "rb" ); if( filename ) file.input = fopen( filename, "rb" );
@ -1967,8 +1968,8 @@ int icvGetHaarTrainingDataFromBG( CvHaarTrainingData* data, int first, int count
if (filename) if (filename)
{ {
CvVecFile file; CvVecFile file;
short tmp = 0; short tmp = 0;
file.input = NULL; file.input = NULL;
if( filename ) file.input = fopen( filename, "rb" ); if( filename ) file.input = fopen( filename, "rb" );
@ -2009,7 +2010,7 @@ int icvGetHaarTrainingDataFromBG( CvHaarTrainingData* data, int first, int count
void cvCreateCascadeClassifier( const char* dirname, void cvCreateCascadeClassifier( const char* dirname,
const char* vecfilename, const char* vecfilename,
const char* bgfilename, const char* bgfilename,
int npos, int nneg, int nstages, int npos, int nneg, int nstages,
int numprecalculated, int numprecalculated,
int numsplits, int numsplits,
@ -2048,7 +2049,7 @@ void cvCreateCascadeClassifier( const char* dirname,
cascade = (CvCascadeHaarClassifier*) icvCreateCascadeHaarClassifier( nstages ); cascade = (CvCascadeHaarClassifier*) icvCreateCascadeHaarClassifier( nstages );
cascade->count = 0; cascade->count = 0;
if( icvInitBackgroundReaders( bgfilename, winsize ) ) if( icvInitBackgroundReaders( bgfilename, winsize ) )
{ {
data = icvCreateHaarTrainingData( winsize, npos + nneg ); data = icvCreateHaarTrainingData( winsize, npos + nneg );
@ -2061,7 +2062,7 @@ void cvCreateCascadeClassifier( const char* dirname,
for( i = 0; i < nstages; i++, cascade->count++ ) for( i = 0; i < nstages; i++, cascade->count++ )
{ {
sprintf( stagename, "%s%d/%s", dirname, i, CV_STAGE_CART_FILE_NAME ); sprintf( stagename, "%s%d/%s", dirname, i, CV_STAGE_CART_FILE_NAME );
cascade->classifier[i] = cascade->classifier[i] =
icvLoadCARTStageHaarClassifier( stagename, winsize.width + 1 ); icvLoadCARTStageHaarClassifier( stagename, winsize.width + 1 );
if( !icvMkDir( stagename ) ) if( !icvMkDir( stagename ) )
@ -2129,7 +2130,7 @@ void cvCreateCascadeClassifier( const char* dirname,
data->sum.rows = data->tilted.rows = poscount + negcount; data->sum.rows = data->tilted.rows = poscount + negcount;
data->normfactor.cols = data->weights.cols = data->cls.cols = data->normfactor.cols = data->weights.cols = data->cls.cols =
poscount + negcount; poscount + negcount;
posweight = (equalweights) ? 1.0F / (poscount + negcount) : (0.5F / poscount); posweight = (equalweights) ? 1.0F / (poscount + negcount) : (0.5F / poscount);
negweight = (equalweights) ? 1.0F / (poscount + negcount) : (0.5F / negcount); negweight = (equalweights) ? 1.0F / (poscount + negcount) : (0.5F / negcount);
for( j = 0; j < poscount; j++ ) for( j = 0; j < poscount; j++ )
@ -2169,7 +2170,7 @@ void cvCreateCascadeClassifier( const char* dirname,
file = fopen( stagename, "w" ); file = fopen( stagename, "w" );
if( file != NULL ) if( file != NULL )
{ {
cascade->classifier[i]->save( cascade->classifier[i]->save(
(CvIntHaarClassifier*) cascade->classifier[i], file ); (CvIntHaarClassifier*) cascade->classifier[i], file );
fclose( file ); fclose( file );
} }
@ -2190,15 +2191,15 @@ void cvCreateCascadeClassifier( const char* dirname,
{ {
char xml_path[1024]; char xml_path[1024];
int len = (int)strlen(dirname); int len = (int)strlen(dirname);
CvHaarClassifierCascade* cascade = 0; CvHaarClassifierCascade* cascade1 = 0;
strcpy( xml_path, dirname ); strcpy( xml_path, dirname );
if( xml_path[len-1] == '\\' || xml_path[len-1] == '/' ) if( xml_path[len-1] == '\\' || xml_path[len-1] == '/' )
len--; len--;
strcpy( xml_path + len, ".xml" ); strcpy( xml_path + len, ".xml" );
cascade = cvLoadHaarClassifierCascade( dirname, cvSize(winwidth,winheight) ); cascade1 = cvLoadHaarClassifierCascade( dirname, cvSize(winwidth,winheight) );
if( cascade ) if( cascade1 )
cvSave( xml_path, cascade ); cvSave( xml_path, cascade1 );
cvReleaseHaarClassifierCascade( &cascade ); cvReleaseHaarClassifierCascade( &cascade1 );
} }
} }
else else
@ -2207,7 +2208,7 @@ void cvCreateCascadeClassifier( const char* dirname,
printf( "FAILED TO INITIALIZE BACKGROUND READERS\n" ); printf( "FAILED TO INITIALIZE BACKGROUND READERS\n" );
#endif /* CV_VERBOSE */ #endif /* CV_VERBOSE */
} }
/* CLEAN UP */ /* CLEAN UP */
icvDestroyBackgroundReaders(); icvDestroyBackgroundReaders();
cascade->release( (CvIntHaarClassifier**) &cascade ); cascade->release( (CvIntHaarClassifier**) &cascade );
@ -2215,7 +2216,7 @@ void cvCreateCascadeClassifier( const char* dirname,
/* tree cascade classifier */ /* tree cascade classifier */
int icvNumSplits( CvStageHaarClassifier* stage ) static int icvNumSplits( CvStageHaarClassifier* stage )
{ {
int i; int i;
int num; int num;
@ -2229,7 +2230,7 @@ int icvNumSplits( CvStageHaarClassifier* stage )
return num; return num;
} }
void icvSetNumSamples( CvHaarTrainingData* training_data, int num ) static void icvSetNumSamples( CvHaarTrainingData* training_data, int num )
{ {
assert( num <= training_data->maxnum ); assert( num <= training_data->maxnum );
@ -2238,7 +2239,7 @@ void icvSetNumSamples( CvHaarTrainingData* training_data, int num )
training_data->cls.cols = training_data->weights.cols = num; training_data->cls.cols = training_data->weights.cols = num;
} }
void icvSetWeightsAndClasses( CvHaarTrainingData* training_data, static void icvSetWeightsAndClasses( CvHaarTrainingData* training_data,
int num1, float weight1, float cls1, int num1, float weight1, float cls1,
int num2, float weight2, float cls2 ) int num2, float weight2, float cls2 )
{ {
@ -2258,7 +2259,7 @@ void icvSetWeightsAndClasses( CvHaarTrainingData* training_data,
} }
} }
CvMat* icvGetUsedValues( CvHaarTrainingData* training_data, static CvMat* icvGetUsedValues( CvHaarTrainingData* training_data,
int start, int num, int start, int num,
CvIntHaarFeatures* haar_features, CvIntHaarFeatures* haar_features,
CvStageHaarClassifier* stage ) CvStageHaarClassifier* stage )
@ -2302,7 +2303,7 @@ CvMat* icvGetUsedValues( CvHaarTrainingData* training_data,
} }
total = last + 1; total = last + 1;
CV_CALL( ptr = cvCreateMat( num, total, CV_32FC1 ) ); CV_CALL( ptr = cvCreateMat( num, total, CV_32FC1 ) );
#ifdef CV_OPENMP #ifdef CV_OPENMP
#pragma omp parallel for #pragma omp parallel for
@ -2351,7 +2352,7 @@ typedef struct CvSplit
void cvCreateTreeCascadeClassifier( const char* dirname, void cvCreateTreeCascadeClassifier( const char* dirname,
const char* vecfilename, const char* vecfilename,
const char* bgfilename, const char* bgfilename,
int npos, int nneg, int nstages, int npos, int nneg, int nstages,
int numprecalculated, int numprecalculated,
int numsplits, int numsplits,
@ -2425,11 +2426,11 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
sprintf( stage_name, "%s/", dirname ); sprintf( stage_name, "%s/", dirname );
suffix = stage_name + strlen( stage_name ); suffix = stage_name + strlen( stage_name );
if (! bg_vecfile) if (! bg_vecfile)
if( !icvInitBackgroundReaders( bgfilename, winsize ) && nstages > 0 ) if( !icvInitBackgroundReaders( bgfilename, winsize ) && nstages > 0 )
CV_ERROR( CV_StsError, "Unable to read negative images" ); CV_ERROR( CV_StsError, "Unable to read negative images" );
if( nstages > 0 ) if( nstages > 0 )
{ {
/* width-first search in the tree */ /* width-first search in the tree */
@ -2438,7 +2439,7 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
CvSplit* first_split; CvSplit* first_split;
CvSplit* last_split; CvSplit* last_split;
CvSplit* cur_split; CvSplit* cur_split;
CvTreeCascadeNode* parent; CvTreeCascadeNode* parent;
CvTreeCascadeNode* cur_node; CvTreeCascadeNode* cur_node;
CvTreeCascadeNode* last_node; CvTreeCascadeNode* last_node;
@ -2447,7 +2448,7 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
parent = leaves; parent = leaves;
leaves = NULL; leaves = NULL;
do do
{ {
int best_clusters; /* best selected number of clusters */ int best_clusters; /* best selected number of clusters */
float posweight, negweight; float posweight, negweight;
double leaf_fa_rate; double leaf_fa_rate;
@ -2501,7 +2502,6 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
{ {
CvTreeCascadeNode* single_cluster; CvTreeCascadeNode* single_cluster;
CvTreeCascadeNode* multiple_clusters; CvTreeCascadeNode* multiple_clusters;
CvSplit* cur_split;
int single_num; int single_num;
icvSetNumSamples( training_data, poscount + negcount ); icvSetNumSamples( training_data, poscount + negcount );
@ -2536,7 +2536,7 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
multiple_clusters = NULL; multiple_clusters = NULL;
printf( "Number of used features: %d\n", single_num ); printf( "Number of used features: %d\n", single_num );
if( maxtreesplits >= 0 ) if( maxtreesplits >= 0 )
{ {
max_clusters = MIN( max_clusters, maxtreesplits - total_splits + 1 ); max_clusters = MIN( max_clusters, maxtreesplits - total_splits + 1 );
@ -2594,7 +2594,7 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
printf( "Clusters are too small. Clustering aborted.\n" ); printf( "Clusters are too small. Clustering aborted.\n" );
break; break;
} }
cur_num = 0; cur_num = 0;
cur_node = last_node = NULL; cur_node = last_node = NULL;
for( cluster = 0; (cluster < k) && (cur_num < best_num); cluster++ ) for( cluster = 0; (cluster < k) && (cur_num < best_num); cluster++ )
@ -2674,18 +2674,19 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
} /* try different number of clusters */ } /* try different number of clusters */
cvReleaseMat( &vals ); cvReleaseMat( &vals );
CV_CALL( cur_split = (CvSplit*) cvAlloc( sizeof( *cur_split ) ) ); CvSplit* curSplit;
CV_ZERO_OBJ( cur_split ); CV_CALL( curSplit = (CvSplit*) cvAlloc( sizeof( *curSplit ) ) );
CV_ZERO_OBJ( curSplit );
if( last_split ) last_split->next = cur_split;
else first_split = cur_split;
last_split = cur_split;
cur_split->single_cluster = single_cluster; if( last_split ) last_split->next = curSplit;
cur_split->multiple_clusters = multiple_clusters; else first_split = curSplit;
cur_split->num_clusters = best_clusters; last_split = curSplit;
cur_split->parent = parent;
cur_split->single_multiple_ratio = (float) single_num / best_num; curSplit->single_cluster = single_cluster;
curSplit->multiple_clusters = multiple_clusters;
curSplit->num_clusters = best_clusters;
curSplit->parent = parent;
curSplit->single_multiple_ratio = (float) single_num / best_num;
} }
if( parent ) parent = parent->next_same_level; if( parent ) parent = parent->next_same_level;
@ -2734,7 +2735,7 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
? last_split->multiple_clusters : last_split->single_cluster; ? last_split->multiple_clusters : last_split->single_cluster;
parent = last_split->parent; parent = last_split->parent;
if( parent ) parent->child = cur_node; if( parent ) parent->child = cur_node;
/* connect leaves via next_same_level and save them */ /* connect leaves via next_same_level and save them */
for( ; cur_node; cur_node = cur_node->next ) for( ; cur_node; cur_node = cur_node->next )
{ {
@ -2768,14 +2769,14 @@ void cvCreateTreeCascadeClassifier( const char* dirname,
printf( "\nParent node: %s\n", buf ); printf( "\nParent node: %s\n", buf );
printf( "Chosen number of splits: %d\n\n", (last_split->multiple_clusters) printf( "Chosen number of splits: %d\n\n", (last_split->multiple_clusters)
? (last_split->num_clusters - 1) : 0 ); ? (last_split->num_clusters - 1) : 0 );
cur_split = last_split; cur_split = last_split;
last_split = last_split->next; last_split = last_split->next;
cvFree( &cur_split ); cvFree( &cur_split );
} /* for each split point */ } /* for each split point */
printf( "Total number of splits: %d\n", total_splits ); printf( "Total number of splits: %d\n", total_splits );
if( !(tcc->root) ) tcc->root = leaves; if( !(tcc->root) ) tcc->root = leaves;
CV_CALL( icvPrintTreeCascade( tcc->root ) ); CV_CALL( icvPrintTreeCascade( tcc->root ) );
@ -2903,7 +2904,7 @@ void cvCreateTrainingSamples( const char* filename,
inverse = (rand() > (RAND_MAX/2)); inverse = (rand() > (RAND_MAX/2));
} }
icvPlaceDistortedSample( &sample, inverse, maxintensitydev, icvPlaceDistortedSample( &sample, inverse, maxintensitydev,
maxxangle, maxyangle, maxzangle, maxxangle, maxyangle, maxzangle,
0 /* nonzero means placing image without cut offs */, 0 /* nonzero means placing image without cut offs */,
0.0 /* nozero adds random shifting */, 0.0 /* nozero adds random shifting */,
0.0 /* nozero adds random scaling */, 0.0 /* nozero adds random scaling */,
@ -2931,13 +2932,13 @@ void cvCreateTrainingSamples( const char* filename,
cvFree( &(sample.data.ptr) ); cvFree( &(sample.data.ptr) );
fclose( output ); fclose( output );
} /* if( output != NULL ) */ } /* if( output != NULL ) */
icvEndSampleDistortion( &data ); icvEndSampleDistortion( &data );
} }
#ifdef CV_VERBOSE #ifdef CV_VERBOSE
printf( "\r \r" ); printf( "\r \r" );
#endif /* CV_VERBOSE */ #endif /* CV_VERBOSE */
} }
@ -2986,7 +2987,7 @@ void cvCreateTestSamples( const char* infoname,
{ {
cvNamedWindow( "Image", CV_WINDOW_AUTOSIZE ); cvNamedWindow( "Image", CV_WINDOW_AUTOSIZE );
} }
info = fopen( infoname, "w" ); info = fopen( infoname, "w" );
strcpy( fullname, infoname ); strcpy( fullname, infoname );
filename = strrchr( fullname, '\\' ); filename = strrchr( fullname, '\\' );
@ -3008,7 +3009,7 @@ void cvCreateTestSamples( const char* infoname,
for( i = 0; i < count; i++ ) for( i = 0; i < count; i++ )
{ {
icvGetNextFromBackgroundData( cvbgdata, cvbgreader ); icvGetNextFromBackgroundData( cvbgdata, cvbgreader );
maxscale = MIN( 0.7F * cvbgreader->src.cols / winwidth, maxscale = MIN( 0.7F * cvbgreader->src.cols / winwidth,
0.7F * cvbgreader->src.rows / winheight ); 0.7F * cvbgreader->src.rows / winheight );
if( maxscale < 1.0F ) continue; if( maxscale < 1.0F ) continue;
@ -3025,14 +3026,14 @@ void cvCreateTestSamples( const char* infoname,
inverse = (rand() > (RAND_MAX/2)); inverse = (rand() > (RAND_MAX/2));
} }
icvPlaceDistortedSample( &win, inverse, maxintensitydev, icvPlaceDistortedSample( &win, inverse, maxintensitydev,
maxxangle, maxyangle, maxzangle, maxxangle, maxyangle, maxzangle,
1, 0.0, 0.0, &data ); 1, 0.0, 0.0, &data );
sprintf( filename, "%04d_%04d_%04d_%04d_%04d.jpg", sprintf( filename, "%04d_%04d_%04d_%04d_%04d.jpg",
(i + 1), x, y, width, height ); (i + 1), x, y, width, height );
if( info ) if( info )
{ {
fprintf( info, "%s %d %d %d %d %d\n", fprintf( info, "%s %d %d %d %d %d\n",
filename, 1, x, y, width, height ); filename, 1, x, y, width, height );

View File

@ -83,7 +83,7 @@
* cij - coeffs[i][j], coeffs[2][2] = 1 * cij - coeffs[i][j], coeffs[2][2] = 1
* (ui, vi) - rectangle vertices * (ui, vi) - rectangle vertices
*/ */
void cvGetPerspectiveTransform( CvSize src_size, double quad[4][2], static void cvGetPerspectiveTransform( CvSize src_size, double quad[4][2],
double coeffs[3][3] ) double coeffs[3][3] )
{ {
//CV_FUNCNAME( "cvWarpPerspective" ); //CV_FUNCNAME( "cvWarpPerspective" );
@ -130,7 +130,7 @@ void cvGetPerspectiveTransform( CvSize src_size, double quad[4][2],
} }
/* Warps source into destination by a perspective transform */ /* Warps source into destination by a perspective transform */
void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] ) static void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] )
{ {
CV_FUNCNAME( "cvWarpPerspective" ); CV_FUNCNAME( "cvWarpPerspective" );
@ -323,8 +323,6 @@ void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] )
int i00, i10, i01, i11; int i00, i10, i01, i11;
i00 = i10 = i01 = i11 = (int) fill_value; i00 = i10 = i01 = i11 = (int) fill_value;
double i = fill_value;
/* linear interpolation using 2x2 neighborhood */ /* linear interpolation using 2x2 neighborhood */
if( isrc_x >= 0 && isrc_x <= src_size.width && if( isrc_x >= 0 && isrc_x <= src_size.width &&
isrc_y >= 0 && isrc_y <= src_size.height ) isrc_y >= 0 && isrc_y <= src_size.height )
@ -349,9 +347,8 @@ void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] )
double i0 = i00 + (i10 - i00)*delta_x; double i0 = i00 + (i10 - i00)*delta_x;
double i1 = i01 + (i11 - i01)*delta_x; double i1 = i01 + (i11 - i01)*delta_x;
i = i0 + (i1 - i0)*delta_y;
((uchar*)(dst_data + y * dst_step))[x] = (uchar) i; ((uchar*)(dst_data + y * dst_step))[x] = (uchar) (i0 + (i1 - i0)*delta_y);
} }
x_min += k_left; x_min += k_left;
x_max += k_right; x_max += k_right;

View File

@ -44,6 +44,9 @@
* *
* Measure performance of classifier * Measure performance of classifier
*/ */
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "cv.h" #include "cv.h"
#include "highgui.h" #include "highgui.h"
@ -211,7 +214,7 @@ int main( int argc, char* argv[] )
totaltime = 0.0; totaltime = 0.0;
if( info != NULL ) if( info != NULL )
{ {
int x, y, width, height; int x, y;
IplImage* img; IplImage* img;
int hits, missed, falseAlarms; int hits, missed, falseAlarms;
int totalHits, totalMissed, totalFalseAlarms; int totalHits, totalMissed, totalFalseAlarms;
@ -246,11 +249,12 @@ int main( int argc, char* argv[] )
ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) ); ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) );
for( i = 0; i < refcount; i++ ) for( i = 0; i < refcount; i++ )
{ {
error = (fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4); int w, h;
error = (fscanf( info, "%d %d %d %d", &x, &y, &w, &h ) != 4);
if( error ) break; if( error ) break;
ref[i].x = 0.5F * width + x; ref[i].x = 0.5F * w + x;
ref[i].y = 0.5F * height + y; ref[i].y = 0.5F * h + y;
ref[i].width = sqrtf( 0.5F * (width * width + height * height) ); ref[i].width = sqrtf( 0.5F * (w * w + h * h) );
ref[i].found = 0; ref[i].found = 0;
ref[i].neghbors = 0; ref[i].neghbors = 0;
} }

View File

@ -1,3 +1,6 @@
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "HOGfeatures.h" #include "HOGfeatures.h"
#include "cascadeclassifier.h" #include "cascadeclassifier.h"
@ -54,7 +57,7 @@ void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) con
features[featIdx].write( fs, componentIdx ); features[featIdx].write( fs, componentIdx );
fs << "}"; fs << "}";
} }
fs << "]"; fs << "]";
} }
void CvHOGEvaluator::generateFeatures() void CvHOGEvaluator::generateFeatures()
@ -85,11 +88,11 @@ void CvHOGEvaluator::generateFeatures()
} }
} }
w = 4*t; w = 4*t;
h = 2*t; h = 2*t;
for (x = 0; x <= winSize.width - w; x += blockStep.width) for (x = 0; x <= winSize.width - w; x += blockStep.width)
{ {
for (y = 0; y <= winSize.height - h; y += blockStep.height) for (y = 0; y <= winSize.height - h; y += blockStep.height)
{ {
features.push_back(Feature(offset, x, y, 2*t, t)); features.push_back(Feature(offset, x, y, 2*t, t));
} }
} }
@ -136,7 +139,7 @@ void CvHOGEvaluator::Feature::write(FileStorage &fs) const
// int cellIdx = featComponent / N_BINS; // int cellIdx = featComponent / N_BINS;
// int binIdx = featComponent % N_BINS; // int binIdx = featComponent % N_BINS;
// //
// fs << CC_RECTS << "[:" << rect[cellIdx].x << rect[cellIdx].y << // fs << CC_RECTS << "[:" << rect[cellIdx].x << rect[cellIdx].y <<
// rect[cellIdx].width << rect[cellIdx].height << binIdx << "]"; // rect[cellIdx].width << rect[cellIdx].height << binIdx << "]";
//} //}
@ -144,7 +147,7 @@ void CvHOGEvaluator::Feature::write(FileStorage &fs) const
//All block is nessesary for block normalization //All block is nessesary for block normalization
void CvHOGEvaluator::Feature::write(FileStorage &fs, int featComponentIdx) const void CvHOGEvaluator::Feature::write(FileStorage &fs, int featComponentIdx) const
{ {
fs << CC_RECT << "[:" << rect[0].x << rect[0].y << fs << CC_RECT << "[:" << rect[0].x << rect[0].y <<
rect[0].width << rect[0].height << featComponentIdx << "]"; rect[0].width << rect[0].height << featComponentIdx << "]";
} }
@ -228,7 +231,7 @@ void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, M
memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) ); memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) );
histBuf += histStep + 1; histBuf += histStep + 1;
for( y = 0; y < qangle.rows; y++ ) for( y = 0; y < qangle.rows; y++ )
{ {
histBuf[-1] = 0.f; histBuf[-1] = 0.f;
float strSum = 0.f; float strSum = 0.f;
for( x = 0; x < qangle.cols; x++ ) for( x = 0; x < qangle.cols; x++ )

View File

@ -1,3 +1,6 @@
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "boost.h" #include "boost.h"
#include "cascadeclassifier.h" #include "cascadeclassifier.h"
#include <queue> #include <queue>
@ -139,7 +142,7 @@ static CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, b
//----------------------------- CascadeBoostParams ------------------------------------------------- //----------------------------- CascadeBoostParams -------------------------------------------------
CvCascadeBoostParams::CvCascadeBoostParams() : minHitRate( 0.995F), maxFalseAlarm( 0.5F ) CvCascadeBoostParams::CvCascadeBoostParams() : minHitRate( 0.995F), maxFalseAlarm( 0.5F )
{ {
boost_type = CvBoost::GENTLE; boost_type = CvBoost::GENTLE;
use_surrogates = use_1se_rule = truncate_pruned_tree = false; use_surrogates = use_1se_rule = truncate_pruned_tree = false;
} }
@ -157,7 +160,7 @@ CvCascadeBoostParams::CvCascadeBoostParams( int _boostType,
void CvCascadeBoostParams::write( FileStorage &fs ) const void CvCascadeBoostParams::write( FileStorage &fs ) const
{ {
String boostTypeStr = boost_type == CvBoost::DISCRETE ? CC_DISCRETE_BOOST : String boostTypeStr = boost_type == CvBoost::DISCRETE ? CC_DISCRETE_BOOST :
boost_type == CvBoost::REAL ? CC_REAL_BOOST : boost_type == CvBoost::REAL ? CC_REAL_BOOST :
boost_type == CvBoost::LOGIT ? CC_LOGIT_BOOST : boost_type == CvBoost::LOGIT ? CC_LOGIT_BOOST :
boost_type == CvBoost::GENTLE ? CC_GENTLE_BOOST : String(); boost_type == CvBoost::GENTLE ? CC_GENTLE_BOOST : String();
@ -197,7 +200,7 @@ bool CvCascadeBoostParams::read( const FileNode &node )
void CvCascadeBoostParams::printDefaults() const void CvCascadeBoostParams::printDefaults() const
{ {
cout << "--boostParams--" << endl; cout << "--boostParams--" << endl;
cout << " [-bt <{" << CC_DISCRETE_BOOST << ", " cout << " [-bt <{" << CC_DISCRETE_BOOST << ", "
<< CC_REAL_BOOST << ", " << CC_REAL_BOOST << ", "
<< CC_LOGIT_BOOST ", " << CC_LOGIT_BOOST ", "
<< CC_GENTLE_BOOST << "(default)}>]" << endl; << CC_GENTLE_BOOST << "(default)}>]" << endl;
@ -210,7 +213,7 @@ void CvCascadeBoostParams::printDefaults() const
void CvCascadeBoostParams::printAttrs() const void CvCascadeBoostParams::printAttrs() const
{ {
String boostTypeStr = boost_type == CvBoost::DISCRETE ? CC_DISCRETE_BOOST : String boostTypeStr = boost_type == CvBoost::DISCRETE ? CC_DISCRETE_BOOST :
boost_type == CvBoost::REAL ? CC_REAL_BOOST : boost_type == CvBoost::REAL ? CC_REAL_BOOST :
boost_type == CvBoost::LOGIT ? CC_LOGIT_BOOST : boost_type == CvBoost::LOGIT ? CC_LOGIT_BOOST :
boost_type == CvBoost::GENTLE ? CC_GENTLE_BOOST : String(); boost_type == CvBoost::GENTLE ? CC_GENTLE_BOOST : String();
@ -259,7 +262,7 @@ bool CvCascadeBoostParams::scanAttr( const String prmName, const String val)
else else
res = false; res = false;
return res; return res;
} }
CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_idx ) CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_idx )
@ -440,7 +443,7 @@ CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _fea
set_params( _params ); set_params( _params );
max_c_count = MAX( 2, featureEvaluator->getMaxCatCount() ); max_c_count = MAX( 2, featureEvaluator->getMaxCatCount() );
var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 ); var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 );
if ( featureEvaluator->getMaxCatCount() > 0 ) if ( featureEvaluator->getMaxCatCount() > 0 )
{ {
numPrecalcIdx = 0; numPrecalcIdx = 0;
cat_var_count = var_count; cat_var_count = var_count;
@ -448,7 +451,7 @@ CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _fea
for( int vi = 0; vi < var_count; vi++ ) for( int vi = 0; vi < var_count; vi++ )
{ {
var_type->data.i[vi] = vi; var_type->data.i[vi] = vi;
} }
} }
else else
{ {
@ -457,8 +460,8 @@ CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _fea
for( int vi = 1; vi <= var_count; vi++ ) for( int vi = 1; vi <= var_count; vi++ )
{ {
var_type->data.i[vi-1] = -vi; var_type->data.i[vi-1] = -vi;
} }
} }
var_type->data.i[var_count] = cat_var_count; var_type->data.i[var_count] = cat_var_count;
var_type->data.i[var_count+1] = cat_var_count+1; var_type->data.i[var_count+1] = cat_var_count+1;
@ -467,7 +470,7 @@ CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _fea
treeBlockSize = MAX(treeBlockSize + BlockSizeDelta, MinBlockSize); treeBlockSize = MAX(treeBlockSize + BlockSizeDelta, MinBlockSize);
tree_storage = cvCreateMemStorage( treeBlockSize ); tree_storage = cvCreateMemStorage( treeBlockSize );
node_heap = cvCreateSet( 0, sizeof(node_heap[0]), sizeof(CvDTreeNode), tree_storage ); node_heap = cvCreateSet( 0, sizeof(node_heap[0]), sizeof(CvDTreeNode), tree_storage );
split_heap = cvCreateSet( 0, sizeof(split_heap[0]), maxSplitSize, tree_storage ); split_heap = cvCreateSet( 0, sizeof(split_heap[0]), maxSplitSize, tree_storage );
} }
CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator, CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator,
@ -477,15 +480,15 @@ CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _fea
{ {
setData( _featureEvaluator, _numSamples, _precalcValBufSize, _precalcIdxBufSize, _params ); setData( _featureEvaluator, _numSamples, _precalcValBufSize, _precalcIdxBufSize, _params );
} }
void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluator, void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluator,
int _numSamples, int _numSamples,
int _precalcValBufSize, int _precalcIdxBufSize, int _precalcValBufSize, int _precalcIdxBufSize,
const CvDTreeParams& _params ) const CvDTreeParams& _params )
{ {
int* idst = 0; int* idst = 0;
unsigned short* udst = 0; unsigned short* udst = 0;
clear(); clear();
shared = true; shared = true;
have_labels = true; have_labels = true;
@ -503,16 +506,16 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
_resp = featureEvaluator->getCls(); _resp = featureEvaluator->getCls();
responses = &_resp; responses = &_resp;
// TODO: check responses: elements must be 0 or 1 // TODO: check responses: elements must be 0 or 1
if( _precalcValBufSize < 0 || _precalcIdxBufSize < 0) if( _precalcValBufSize < 0 || _precalcIdxBufSize < 0)
CV_Error( CV_StsOutOfRange, "_numPrecalcVal and _numPrecalcIdx must be positive or 0" ); CV_Error( CV_StsOutOfRange, "_numPrecalcVal and _numPrecalcIdx must be positive or 0" );
var_count = var_all = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize(); var_count = var_all = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize();
sample_count = _numSamples; sample_count = _numSamples;
is_buf_16u = false; is_buf_16u = false;
if (sample_count < 65536) if (sample_count < 65536)
is_buf_16u = true; is_buf_16u = true;
numPrecalcVal = min( cvRound((double)_precalcValBufSize*1048576. / (sizeof(float)*sample_count)), var_count ); numPrecalcVal = min( cvRound((double)_precalcValBufSize*1048576. / (sizeof(float)*sample_count)), var_count );
numPrecalcIdx = min( cvRound((double)_precalcIdxBufSize*1048576. / numPrecalcIdx = min( cvRound((double)_precalcIdxBufSize*1048576. /
@ -522,8 +525,8 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
valCache.create( numPrecalcVal, sample_count, CV_32FC1 ); valCache.create( numPrecalcVal, sample_count, CV_32FC1 );
var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 ); var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 );
if ( featureEvaluator->getMaxCatCount() > 0 ) if ( featureEvaluator->getMaxCatCount() > 0 )
{ {
numPrecalcIdx = 0; numPrecalcIdx = 0;
cat_var_count = var_count; cat_var_count = var_count;
@ -531,7 +534,7 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
for( int vi = 0; vi < var_count; vi++ ) for( int vi = 0; vi < var_count; vi++ )
{ {
var_type->data.i[vi] = vi; var_type->data.i[vi] = vi;
} }
} }
else else
{ {
@ -540,14 +543,14 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
for( int vi = 1; vi <= var_count; vi++ ) for( int vi = 1; vi <= var_count; vi++ )
{ {
var_type->data.i[vi-1] = -vi; var_type->data.i[vi-1] = -vi;
} }
} }
var_type->data.i[var_count] = cat_var_count; var_type->data.i[var_count] = cat_var_count;
var_type->data.i[var_count+1] = cat_var_count+1; var_type->data.i[var_count+1] = cat_var_count+1;
work_var_count = ( cat_var_count ? 0 : numPrecalcIdx ) + 1/*cv_lables*/; work_var_count = ( cat_var_count ? 0 : numPrecalcIdx ) + 1/*cv_lables*/;
buf_size = (work_var_count + 1) * sample_count/*sample_indices*/; buf_size = (work_var_count + 1) * sample_count/*sample_indices*/;
buf_count = 2; buf_count = 2;
if ( is_buf_16u ) if ( is_buf_16u )
buf = cvCreateMat( buf_count, buf_size, CV_16UC1 ); buf = cvCreateMat( buf_count, buf_size, CV_16UC1 );
else else
@ -556,7 +559,7 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
cat_count = cvCreateMat( 1, cat_var_count + 1, CV_32SC1 ); cat_count = cvCreateMat( 1, cat_var_count + 1, CV_32SC1 );
// precalculate valCache and set indices in buf // precalculate valCache and set indices in buf
precalculate(); precalculate();
// now calculate the maximum size of split, // now calculate the maximum size of split,
// create memory storage that will keep nodes and splits of the decision tree // create memory storage that will keep nodes and splits of the decision tree
@ -574,7 +577,7 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
tempBlockSize = MAX( tempBlockSize + BlockSizeDelta, MinBlockSize ); tempBlockSize = MAX( tempBlockSize + BlockSizeDelta, MinBlockSize );
temp_storage = cvCreateMemStorage( tempBlockSize ); temp_storage = cvCreateMemStorage( tempBlockSize );
nv_heap = cvCreateSet( 0, sizeof(*nv_heap), nvSize, temp_storage ); nv_heap = cvCreateSet( 0, sizeof(*nv_heap), nvSize, temp_storage );
data_root = new_node( 0, sample_count, 0, 0 ); data_root = new_node( 0, sample_count, 0, 0 );
// set sample labels // set sample labels
@ -617,7 +620,7 @@ void CvCascadeBoostTrainData::free_train_data()
const int* CvCascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsBuf) const int* CvCascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsBuf)
{ {
int nodeSampleCount = n->sample_count; int nodeSampleCount = n->sample_count;
int rStep = CV_IS_MAT_CONT( responses->type ) ? 1 : responses->step / CV_ELEM_SIZE( responses->type ); int rStep = CV_IS_MAT_CONT( responses->type ) ? 1 : responses->step / CV_ELEM_SIZE( responses->type );
int* sampleIndicesBuf = labelsBuf; // int* sampleIndicesBuf = labelsBuf; //
@ -626,7 +629,7 @@ const int* CvCascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* label
{ {
int sidx = sampleIndices[si]; int sidx = sampleIndices[si];
labelsBuf[si] = (int)responses->data.fl[sidx*rStep]; labelsBuf[si] = (int)responses->data.fl[sidx*rStep];
} }
return labelsBuf; return labelsBuf;
} }
@ -643,9 +646,9 @@ const int* CvCascadeBoostTrainData::get_cv_labels( CvDTreeNode* n, int* labels_b
void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf, void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf,
const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf ) const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf )
{ {
int nodeSampleCount = n->sample_count; int nodeSampleCount = n->sample_count;
const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf); const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf);
if ( vi < numPrecalcIdx ) if ( vi < numPrecalcIdx )
{ {
if( !is_buf_16u ) if( !is_buf_16u )
@ -659,7 +662,7 @@ void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* o
*sortedIndices = sortedIndicesBuf; *sortedIndices = sortedIndicesBuf;
} }
if( vi < numPrecalcVal ) if( vi < numPrecalcVal )
{ {
for( int i = 0; i < nodeSampleCount; i++ ) for( int i = 0; i < nodeSampleCount; i++ )
@ -705,10 +708,10 @@ void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* o
ordValuesBuf[i] = (&sampleValues[0])[sortedIndicesBuf[i]]; ordValuesBuf[i] = (&sampleValues[0])[sortedIndicesBuf[i]];
*sortedIndices = sortedIndicesBuf; *sortedIndices = sortedIndicesBuf;
} }
*ordValues = ordValuesBuf; *ordValues = ordValuesBuf;
} }
const int* CvCascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf ) const int* CvCascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf )
{ {
int nodeSampleCount = n->sample_count; int nodeSampleCount = n->sample_count;
@ -739,8 +742,8 @@ const int* CvCascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, in
float CvCascadeBoostTrainData::getVarValue( int vi, int si ) float CvCascadeBoostTrainData::getVarValue( int vi, int si )
{ {
if ( vi < numPrecalcVal && !valCache.empty() ) if ( vi < numPrecalcVal && !valCache.empty() )
return valCache.at<float>( vi, si ); return valCache.at<float>( vi, si );
return (*featureEvaluator)( vi, si ); return (*featureEvaluator)( vi, si );
} }
@ -858,7 +861,7 @@ CvDTreeNode* CvCascadeBoostTree::predict( int sampleIdx ) const
CvDTreeNode* node = root; CvDTreeNode* node = root;
if( !node ) if( !node )
CV_Error( CV_StsError, "The tree has not been trained yet" ); CV_Error( CV_StsError, "The tree has not been trained yet" );
if ( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount() == 0 ) // ordered if ( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount() == 0 ) // ordered
{ {
while( node->left ) while( node->left )
@ -946,7 +949,7 @@ void CvCascadeBoostTree::read( const FileNode &node, CvBoost* _ensemble,
int maxCatCount = ((CvCascadeBoostTrainData*)_data)->featureEvaluator->getMaxCatCount(); int maxCatCount = ((CvCascadeBoostTrainData*)_data)->featureEvaluator->getMaxCatCount();
int subsetN = (maxCatCount + 31)/32; int subsetN = (maxCatCount + 31)/32;
int step = 3 + ( maxCatCount>0 ? subsetN : 1 ); int step = 3 + ( maxCatCount>0 ? subsetN : 1 );
queue<CvDTreeNode*> internalNodesQueue; queue<CvDTreeNode*> internalNodesQueue;
FileNodeIterator internalNodesIt, leafValsuesIt; FileNodeIterator internalNodesIt, leafValsuesIt;
CvDTreeNode* prntNode, *cldNode; CvDTreeNode* prntNode, *cldNode;
@ -986,11 +989,11 @@ void CvCascadeBoostTree::read( const FileNode &node, CvBoost* _ensemble,
{ {
prntNode->right = cldNode = data->new_node( 0, 0, 0, 0 ); prntNode->right = cldNode = data->new_node( 0, 0, 0, 0 );
*leafValsuesIt >> cldNode->value; leafValsuesIt--; *leafValsuesIt >> cldNode->value; leafValsuesIt--;
cldNode->parent = prntNode; cldNode->parent = prntNode;
} }
else else
{ {
prntNode->right = internalNodesQueue.front(); prntNode->right = internalNodesQueue.front();
prntNode->right->parent = prntNode; prntNode->right->parent = prntNode;
internalNodesQueue.pop(); internalNodesQueue.pop();
} }
@ -999,7 +1002,7 @@ void CvCascadeBoostTree::read( const FileNode &node, CvBoost* _ensemble,
{ {
prntNode->left = cldNode = data->new_node( 0, 0, 0, 0 ); prntNode->left = cldNode = data->new_node( 0, 0, 0, 0 );
*leafValsuesIt >> cldNode->value; leafValsuesIt--; *leafValsuesIt >> cldNode->value; leafValsuesIt--;
cldNode->parent = prntNode; cldNode->parent = prntNode;
} }
else else
{ {
@ -1089,7 +1092,7 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
} }
} }
CV_Assert( n1 == n ); CV_Assert( n1 == n );
} }
else else
{ {
int *ldst, *rdst; int *ldst, *rdst;
@ -1116,7 +1119,7 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
} }
} }
CV_Assert( n1 == n ); CV_Assert( n1 == n );
} }
} }
// split cv_labels using newIdx relocation table // split cv_labels using newIdx relocation table
@ -1171,7 +1174,7 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
} }
} }
} }
// split sample indices // split sample indices
int *sampleIdx_src_buf = tempBuf + n; int *sampleIdx_src_buf = tempBuf + n;
const int* sampleIdx_src = data->get_sample_indices(node, sampleIdx_src_buf); const int* sampleIdx_src = data->get_sample_indices(node, sampleIdx_src_buf);
@ -1181,9 +1184,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
if (data->is_buf_16u) if (data->is_buf_16u)
{ {
unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols + unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*buf->cols +
workVarCount*scount + left->offset); workVarCount*scount + left->offset);
unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*buf->cols + unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*buf->cols +
workVarCount*scount + right->offset); workVarCount*scount + right->offset);
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
{ {
@ -1202,9 +1205,9 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
} }
else else
{ {
int* ldst = buf->data.i + left->buf_idx*buf->cols + int* ldst = buf->data.i + left->buf_idx*buf->cols +
workVarCount*scount + left->offset; workVarCount*scount + left->offset;
int* rdst = buf->data.i + right->buf_idx*buf->cols + int* rdst = buf->data.i + right->buf_idx*buf->cols +
workVarCount*scount + right->offset; workVarCount*scount + right->offset;
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
{ {
@ -1229,10 +1232,10 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
} }
// deallocate the parent node data that is not needed anymore // deallocate the parent node data that is not needed anymore
data->free_node_data(node); data->free_node_data(node);
} }
void auxMarkFeaturesInMap( const CvDTreeNode* node, Mat& featureMap) static void auxMarkFeaturesInMap( const CvDTreeNode* node, Mat& featureMap)
{ {
if ( node && node->split ) if ( node && node->split )
{ {
@ -1265,7 +1268,7 @@ bool CvCascadeBoost::train( const CvFeatureEvaluator* _featureEvaluator,
set_params( _params ); set_params( _params );
if ( (_params.boost_type == LOGIT) || (_params.boost_type == GENTLE) ) if ( (_params.boost_type == LOGIT) || (_params.boost_type == GENTLE) )
data->do_responses_copy(); data->do_responses_copy();
update_weights( 0 ); update_weights( 0 );
cout << "+----+---------+---------+" << endl; cout << "+----+---------+---------+" << endl;
@ -1316,7 +1319,7 @@ bool CvCascadeBoost::set_params( const CvBoostParams& _params )
minHitRate = ((CvCascadeBoostParams&)_params).minHitRate; minHitRate = ((CvCascadeBoostParams&)_params).minHitRate;
maxFalseAlarm = ((CvCascadeBoostParams&)_params).maxFalseAlarm; maxFalseAlarm = ((CvCascadeBoostParams&)_params).maxFalseAlarm;
return ( ( minHitRate > 0 ) && ( minHitRate < 1) && return ( ( minHitRate > 0 ) && ( minHitRate < 1) &&
( maxFalseAlarm > 0 ) && ( maxFalseAlarm < 1) && ( maxFalseAlarm > 0 ) && ( maxFalseAlarm < 1) &&
CvBoost::set_params( _params )); CvBoost::set_params( _params ));
} }
@ -1364,7 +1367,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
if (data->is_buf_16u) if (data->is_buf_16u)
{ {
unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*buf->cols + unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*buf->cols +
data->data_root->offset + (data->work_var_count-1)*data->sample_count); data->data_root->offset + (data->work_var_count-1)*data->sample_count);
for( int i = 0; i < n; i++ ) for( int i = 0; i < n; i++ )
{ {
@ -1382,7 +1385,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
} }
else else
{ {
int* labels = buf->data.i + data->data_root->buf_idx*buf->cols + int* labels = buf->data.i + data->data_root->buf_idx*buf->cols +
data->data_root->offset + (data->work_var_count-1)*data->sample_count; data->data_root->offset + (data->work_var_count-1)*data->sample_count;
for( int i = 0; i < n; i++ ) for( int i = 0; i < n; i++ )
@ -1425,7 +1428,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
{ {
// invert the subsample mask // invert the subsample mask
cvXorS( subsample_mask, cvScalar(1.), subsample_mask ); cvXorS( subsample_mask, cvScalar(1.), subsample_mask );
// run tree through all the non-processed samples // run tree through all the non-processed samples
for( int i = 0; i < n; i++ ) for( int i = 0; i < n; i++ )
if( subsample_mask->data.ptr[i] ) if( subsample_mask->data.ptr[i] )
@ -1565,7 +1568,7 @@ bool CvCascadeBoost::isErrDesired()
int sCount = data->sample_count, int sCount = data->sample_count,
numPos = 0, numNeg = 0, numFalse = 0, numPosTrue = 0; numPos = 0, numNeg = 0, numFalse = 0, numPosTrue = 0;
vector<float> eval(sCount); vector<float> eval(sCount);
for( int i = 0; i < sCount; i++ ) for( int i = 0; i < sCount; i++ )
if( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 1.0F ) if( ((CvCascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 1.0F )
eval[numPos++] = predict( i, true ); eval[numPos++] = predict( i, true );
@ -1625,7 +1628,7 @@ bool CvCascadeBoost::read( const FileNode &node,
set_params( _params ); set_params( _params );
node[CC_STAGE_THRESHOLD] >> threshold; node[CC_STAGE_THRESHOLD] >> threshold;
FileNode rnode = node[CC_WEAK_CLASSIFIERS]; FileNode rnode = node[CC_WEAK_CLASSIFIERS];
storage = cvCreateMemStorage(); storage = cvCreateMemStorage();
weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage ); weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage );

View File

@ -1,3 +1,6 @@
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "cascadeclassifier.h" #include "cascadeclassifier.h"
#include <queue> #include <queue>
@ -6,14 +9,14 @@ using namespace std;
static const char* stageTypes[] = { CC_BOOST }; static const char* stageTypes[] = { CC_BOOST };
static const char* featureTypes[] = { CC_HAAR, CC_LBP, CC_HOG }; static const char* featureTypes[] = { CC_HAAR, CC_LBP, CC_HOG };
CvCascadeParams::CvCascadeParams() : stageType( defaultStageType ), CvCascadeParams::CvCascadeParams() : stageType( defaultStageType ),
featureType( defaultFeatureType ), winSize( cvSize(24, 24) ) featureType( defaultFeatureType ), winSize( cvSize(24, 24) )
{ {
name = CC_CASCADE_PARAMS; name = CC_CASCADE_PARAMS;
} }
CvCascadeParams::CvCascadeParams( int _stageType, int _featureType ) : stageType( _stageType ), CvCascadeParams::CvCascadeParams( int _stageType, int _featureType ) : stageType( _stageType ),
featureType( _featureType ), winSize( cvSize(24, 24) ) featureType( _featureType ), winSize( cvSize(24, 24) )
{ {
name = CC_CASCADE_PARAMS; name = CC_CASCADE_PARAMS;
} }
@ -25,7 +28,7 @@ void CvCascadeParams::write( FileStorage &fs ) const
CV_Assert( !stageTypeStr.empty() ); CV_Assert( !stageTypeStr.empty() );
fs << CC_STAGE_TYPE << stageTypeStr; fs << CC_STAGE_TYPE << stageTypeStr;
String featureTypeStr = featureType == CvFeatureParams::HAAR ? CC_HAAR : String featureTypeStr = featureType == CvFeatureParams::HAAR ? CC_HAAR :
featureType == CvFeatureParams::LBP ? CC_LBP : featureType == CvFeatureParams::LBP ? CC_LBP :
featureType == CvFeatureParams::HOG ? CC_HOG : featureType == CvFeatureParams::HOG ? CC_HOG :
0; 0;
CV_Assert( !stageTypeStr.empty() ); CV_Assert( !stageTypeStr.empty() );
@ -51,7 +54,7 @@ bool CvCascadeParams::read( const FileNode &node )
return false; return false;
rnode >> featureTypeStr; rnode >> featureTypeStr;
featureType = !featureTypeStr.compare( CC_HAAR ) ? CvFeatureParams::HAAR : featureType = !featureTypeStr.compare( CC_HAAR ) ? CvFeatureParams::HAAR :
!featureTypeStr.compare( CC_LBP ) ? CvFeatureParams::LBP : !featureTypeStr.compare( CC_LBP ) ? CvFeatureParams::LBP :
!featureTypeStr.compare( CC_HOG ) ? CvFeatureParams::HOG : !featureTypeStr.compare( CC_HOG ) ? CvFeatureParams::HOG :
-1; -1;
if (featureType == -1) if (featureType == -1)
@ -125,15 +128,15 @@ bool CvCascadeParams::scanAttr( const String prmName, const String val )
bool CvCascadeClassifier::train( const String _cascadeDirName, bool CvCascadeClassifier::train( const String _cascadeDirName,
const String _posFilename, const String _posFilename,
const String _negFilename, const String _negFilename,
int _numPos, int _numNeg, int _numPos, int _numNeg,
int _precalcValBufSize, int _precalcIdxBufSize, int _precalcValBufSize, int _precalcIdxBufSize,
int _numStages, int _numStages,
const CvCascadeParams& _cascadeParams, const CvCascadeParams& _cascadeParams,
const CvFeatureParams& _featureParams, const CvFeatureParams& _featureParams,
const CvCascadeBoostParams& _stageParams, const CvCascadeBoostParams& _stageParams,
bool baseFormatSave ) bool baseFormatSave )
{ {
if( _cascadeDirName.empty() || _posFilename.empty() || _negFilename.empty() ) if( _cascadeDirName.empty() || _posFilename.empty() || _negFilename.empty() )
CV_Error( CV_StsBadArg, "_cascadeDirName or _bgfileName or _vecFileName is NULL" ); CV_Error( CV_StsBadArg, "_cascadeDirName or _bgfileName or _vecFileName is NULL" );
@ -181,17 +184,17 @@ bool CvCascadeClassifier::train( const String _cascadeDirName,
cout << endl << "Stages 0-" << startNumStages-1 << " are loaded" << endl; cout << endl << "Stages 0-" << startNumStages-1 << " are loaded" << endl;
else if ( startNumStages == 1) else if ( startNumStages == 1)
cout << endl << "Stage 0 is loaded" << endl; cout << endl << "Stage 0 is loaded" << endl;
double requiredLeafFARate = pow( (double) stageParams->maxFalseAlarm, (double) numStages ) / double requiredLeafFARate = pow( (double) stageParams->maxFalseAlarm, (double) numStages ) /
(double)stageParams->max_depth; (double)stageParams->max_depth;
double tempLeafFARate; double tempLeafFARate;
for( int i = startNumStages; i < numStages; i++ ) for( int i = startNumStages; i < numStages; i++ )
{ {
cout << endl << "===== TRAINING " << i << "-stage =====" << endl; cout << endl << "===== TRAINING " << i << "-stage =====" << endl;
cout << "<BEGIN" << endl; cout << "<BEGIN" << endl;
if ( !updateTrainingSet( tempLeafFARate ) ) if ( !updateTrainingSet( tempLeafFARate ) )
{ {
cout << "Train dataset for temp stage can not be filled. " cout << "Train dataset for temp stage can not be filled. "
"Branch training terminated." << endl; "Branch training terminated." << endl;
@ -211,10 +214,10 @@ bool CvCascadeClassifier::train( const String _cascadeDirName,
stageClassifiers.push_back( tempStage ); stageClassifiers.push_back( tempStage );
cout << "END>" << endl; cout << "END>" << endl;
// save params // save params
String filename; String filename;
if ( i == 0) if ( i == 0)
{ {
filename = dirName + CC_PARAMS_FILENAME; filename = dirName + CC_PARAMS_FILENAME;
FileStorage fs( filename, FileStorage::WRITE); FileStorage fs( filename, FileStorage::WRITE);
@ -289,7 +292,7 @@ int CvCascadeClassifier::fillPassedSamples( int first, int count, bool isPositiv
{ {
bool isGetImg = isPositive ? imgReader.getPos( img ) : bool isGetImg = isPositive ? imgReader.getPos( img ) :
imgReader.getNeg( img ); imgReader.getNeg( img );
if( !isGetImg ) if( !isGetImg )
return getcount; return getcount;
consumed++; consumed++;
@ -313,14 +316,14 @@ void CvCascadeClassifier::writeParams( FileStorage &fs ) const
void CvCascadeClassifier::writeFeatures( FileStorage &fs, const Mat& featureMap ) const void CvCascadeClassifier::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
{ {
((CvFeatureEvaluator*)((Ptr<CvFeatureEvaluator>)featureEvaluator))->writeFeatures( fs, featureMap ); ((CvFeatureEvaluator*)((Ptr<CvFeatureEvaluator>)featureEvaluator))->writeFeatures( fs, featureMap );
} }
void CvCascadeClassifier::writeStages( FileStorage &fs, const Mat& featureMap ) const void CvCascadeClassifier::writeStages( FileStorage &fs, const Mat& featureMap ) const
{ {
char cmnt[30]; char cmnt[30];
int i = 0; int i = 0;
fs << CC_STAGES << "["; fs << CC_STAGES << "[";
for( vector< Ptr<CvCascadeBoost> >::const_iterator it = stageClassifiers.begin(); for( vector< Ptr<CvCascadeBoost> >::const_iterator it = stageClassifiers.begin();
it != stageClassifiers.end(); it++, i++ ) it != stageClassifiers.end(); it++, i++ )
{ {
@ -337,17 +340,17 @@ bool CvCascadeClassifier::readParams( const FileNode &node )
{ {
if ( !node.isMap() || !cascadeParams.read( node ) ) if ( !node.isMap() || !cascadeParams.read( node ) )
return false; return false;
stageParams = new CvCascadeBoostParams; stageParams = new CvCascadeBoostParams;
FileNode rnode = node[CC_STAGE_PARAMS]; FileNode rnode = node[CC_STAGE_PARAMS];
if ( !stageParams->read( rnode ) ) if ( !stageParams->read( rnode ) )
return false; return false;
featureParams = CvFeatureParams::create(cascadeParams.featureType); featureParams = CvFeatureParams::create(cascadeParams.featureType);
rnode = node[CC_FEATURE_PARAMS]; rnode = node[CC_FEATURE_PARAMS];
if ( !featureParams->read( rnode ) ) if ( !featureParams->read( rnode ) )
return false; return false;
return true; return true;
} }
bool CvCascadeClassifier::readStages( const FileNode &node) bool CvCascadeClassifier::readStages( const FileNode &node)
@ -396,7 +399,7 @@ void CvCascadeClassifier::save( const String filename, bool baseFormat )
fs << FileStorage::getDefaultObjectName(filename) << "{"; fs << FileStorage::getDefaultObjectName(filename) << "{";
if ( !baseFormat ) if ( !baseFormat )
{ {
Mat featureMap; Mat featureMap;
getUsedFeaturesIdxMap( featureMap ); getUsedFeaturesIdxMap( featureMap );
writeParams( fs ); writeParams( fs );
fs << CC_STAGE_NUM << (int)stageClassifiers.size(); fs << CC_STAGE_NUM << (int)stageClassifiers.size();
@ -409,7 +412,7 @@ void CvCascadeClassifier::save( const String filename, bool baseFormat )
CvSeq* weak; CvSeq* weak;
if ( cascadeParams.featureType != CvFeatureParams::HAAR ) if ( cascadeParams.featureType != CvFeatureParams::HAAR )
CV_Error( CV_StsBadFunc, "old file format is used for Haar-like features only"); CV_Error( CV_StsBadFunc, "old file format is used for Haar-like features only");
fs << ICV_HAAR_SIZE_NAME << "[:" << cascadeParams.winSize.width << fs << ICV_HAAR_SIZE_NAME << "[:" << cascadeParams.winSize.width <<
cascadeParams.winSize.height << "]"; cascadeParams.winSize.height << "]";
fs << ICV_HAAR_STAGES_NAME << "["; fs << ICV_HAAR_STAGES_NAME << "[";
for( size_t si = 0; si < stageClassifiers.size(); si++ ) for( size_t si = 0; si < stageClassifiers.size(); si++ )
@ -424,16 +427,16 @@ void CvCascadeClassifier::save( const String filename, bool baseFormat )
int inner_node_idx = -1, total_inner_node_idx = -1; int inner_node_idx = -1, total_inner_node_idx = -1;
queue<const CvDTreeNode*> inner_nodes_queue; queue<const CvDTreeNode*> inner_nodes_queue;
CvCascadeBoostTree* tree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi )); CvCascadeBoostTree* tree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi ));
fs << "["; fs << "[";
/*sprintf( buf, "tree %d", wi ); /*sprintf( buf, "tree %d", wi );
CV_CALL( cvWriteComment( fs, buf, 1 ) );*/ CV_CALL( cvWriteComment( fs, buf, 1 ) );*/
const CvDTreeNode* tempNode; const CvDTreeNode* tempNode;
inner_nodes_queue.push( tree->get_root() ); inner_nodes_queue.push( tree->get_root() );
total_inner_node_idx++; total_inner_node_idx++;
while (!inner_nodes_queue.empty()) while (!inner_nodes_queue.empty())
{ {
tempNode = inner_nodes_queue.front(); tempNode = inner_nodes_queue.front();
@ -498,7 +501,7 @@ bool CvCascadeClassifier::load( const String cascadeDirName )
node = fs.getFirstTopLevelNode(); node = fs.getFirstTopLevelNode();
if ( !fs.isOpened() ) if ( !fs.isOpened() )
break; break;
CvCascadeBoost *tempStage = new CvCascadeBoost; CvCascadeBoost *tempStage = new CvCascadeBoost;
if ( !tempStage->read( node, (CvFeatureEvaluator*)featureEvaluator, *((CvCascadeBoostParams*)stageParams )) ) if ( !tempStage->read( node, (CvFeatureEvaluator*)featureEvaluator, *((CvCascadeBoostParams*)stageParams )) )
{ {
@ -516,11 +519,11 @@ void CvCascadeClassifier::getUsedFeaturesIdxMap( Mat& featureMap )
int varCount = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize(); int varCount = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize();
featureMap.create( 1, varCount, CV_32SC1 ); featureMap.create( 1, varCount, CV_32SC1 );
featureMap.setTo(Scalar(-1)); featureMap.setTo(Scalar(-1));
for( vector< Ptr<CvCascadeBoost> >::const_iterator it = stageClassifiers.begin(); for( vector< Ptr<CvCascadeBoost> >::const_iterator it = stageClassifiers.begin();
it != stageClassifiers.end(); it++ ) it != stageClassifiers.end(); it++ )
((CvCascadeBoost*)((Ptr<CvCascadeBoost>)(*it)))->markUsedFeaturesInMap( featureMap ); ((CvCascadeBoost*)((Ptr<CvCascadeBoost>)(*it)))->markUsedFeaturesInMap( featureMap );
for( int fi = 0, idx = 0; fi < varCount; fi++ ) for( int fi = 0, idx = 0; fi < varCount; fi++ )
if ( featureMap.at<int>(0, fi) >= 0 ) if ( featureMap.at<int>(0, fi) >= 0 )
featureMap.ptr<int>(0)[fi] = idx++; featureMap.ptr<int>(0)[fi] = idx++;

View File

@ -1,3 +1,6 @@
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "traincascade_features.h" #include "traincascade_features.h"
#include "cascadeclassifier.h" #include "cascadeclassifier.h"
@ -28,7 +31,7 @@ bool CvParams::scanAttr( const String prmName, const String val ) { return false
CvFeatureParams::CvFeatureParams() : maxCatCount( 0 ), featSize( 1 ) CvFeatureParams::CvFeatureParams() : maxCatCount( 0 ), featSize( 1 )
{ {
name = CC_FEATURE_PARAMS; name = CC_FEATURE_PARAMS;
} }
void CvFeatureParams::init( const CvFeatureParams& fp ) void CvFeatureParams::init( const CvFeatureParams& fp )
@ -55,7 +58,7 @@ bool CvFeatureParams::read( const FileNode &node )
Ptr<CvFeatureParams> CvFeatureParams::create( int featureType ) Ptr<CvFeatureParams> CvFeatureParams::create( int featureType )
{ {
return featureType == HAAR ? Ptr<CvFeatureParams>(new CvHaarFeatureParams) : return featureType == HAAR ? Ptr<CvFeatureParams>(new CvHaarFeatureParams) :
featureType == LBP ? Ptr<CvFeatureParams>(new CvLBPFeatureParams) : featureType == LBP ? Ptr<CvFeatureParams>(new CvLBPFeatureParams) :
featureType == HOG ? Ptr<CvFeatureParams>(new CvHOGFeatureParams) : featureType == HOG ? Ptr<CvFeatureParams>(new CvHOGFeatureParams) :
Ptr<CvFeatureParams>(); Ptr<CvFeatureParams>();
} }
@ -84,7 +87,7 @@ void CvFeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
Ptr<CvFeatureEvaluator> CvFeatureEvaluator::create(int type) Ptr<CvFeatureEvaluator> CvFeatureEvaluator::create(int type)
{ {
return type == CvFeatureParams::HAAR ? Ptr<CvFeatureEvaluator>(new CvHaarEvaluator) : return type == CvFeatureParams::HAAR ? Ptr<CvFeatureEvaluator>(new CvHaarEvaluator) :
type == CvFeatureParams::LBP ? Ptr<CvFeatureEvaluator>(new CvLBPEvaluator) : type == CvFeatureParams::LBP ? Ptr<CvFeatureEvaluator>(new CvLBPEvaluator) :
type == CvFeatureParams::HOG ? Ptr<CvFeatureEvaluator>(new CvHOGEvaluator) : type == CvFeatureParams::HOG ? Ptr<CvFeatureEvaluator>(new CvHOGEvaluator) :
Ptr<CvFeatureEvaluator>(); Ptr<CvFeatureEvaluator>();
} }

View File

@ -1,16 +1,19 @@
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "haarfeatures.h" #include "haarfeatures.h"
#include "cascadeclassifier.h" #include "cascadeclassifier.h"
using namespace std; using namespace std;
CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC) CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC)
{ {
name = HFP_NAME; name = HFP_NAME;
} }
CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode ) CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode )
{ {
name = HFP_NAME; name = HFP_NAME;
} }
void CvHaarFeatureParams::init( const CvFeatureParams& fp ) void CvHaarFeatureParams::init( const CvFeatureParams& fp )
@ -22,7 +25,7 @@ void CvHaarFeatureParams::init( const CvFeatureParams& fp )
void CvHaarFeatureParams::write( FileStorage &fs ) const void CvHaarFeatureParams::write( FileStorage &fs ) const
{ {
CvFeatureParams::write( fs ); CvFeatureParams::write( fs );
String modeStr = mode == BASIC ? CC_MODE_BASIC : String modeStr = mode == BASIC ? CC_MODE_BASIC :
mode == CORE ? CC_MODE_CORE : mode == CORE ? CC_MODE_CORE :
mode == ALL ? CC_MODE_ALL : String(); mode == ALL ? CC_MODE_ALL : String();
CV_Assert( !modeStr.empty() ); CV_Assert( !modeStr.empty() );
@ -55,7 +58,7 @@ void CvHaarFeatureParams::printDefaults() const
void CvHaarFeatureParams::printAttrs() const void CvHaarFeatureParams::printAttrs() const
{ {
CvFeatureParams::printAttrs(); CvFeatureParams::printAttrs();
String mode_str = mode == BASIC ? CC_MODE_BASIC : String mode_str = mode == BASIC ? CC_MODE_BASIC :
mode == CORE ? CC_MODE_CORE : mode == CORE ? CC_MODE_CORE :
mode == ALL ? CC_MODE_ALL : 0; mode == ALL ? CC_MODE_ALL : 0;
cout << "mode: " << mode_str << endl; cout << "mode: " << mode_str << endl;
@ -156,7 +159,7 @@ void CvHaarEvaluator::generateFeatures()
if( mode != CvHaarFeatureParams::BASIC ) if( mode != CvHaarFeatureParams::BASIC )
{ {
// haar_x4 // haar_x4
if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) ) if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )
{ {
features.push_back( Feature( offset, false, features.push_back( Feature( offset, false,
x, y, dx*4, dy, -1, x, y, dx*4, dy, -1,
@ -171,61 +174,61 @@ void CvHaarEvaluator::generateFeatures()
} }
} }
// x2_y2 // x2_y2
if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) ) if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
{ {
features.push_back( Feature( offset, false, features.push_back( Feature( offset, false,
x, y, dx*2, dy*2, -1, x, y, dx*2, dy*2, -1,
x, y, dx, dy, +2, x, y, dx, dy, +2,
x+dx, y+dy, dx, dy, +2 ) ); x+dx, y+dy, dx, dy, +2 ) );
} }
if (mode != CvHaarFeatureParams::BASIC) if (mode != CvHaarFeatureParams::BASIC)
{ {
if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) ) if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )
{ {
features.push_back( Feature( offset, false, features.push_back( Feature( offset, false,
x , y , dx*3, dy*3, -1, x , y , dx*3, dy*3, -1,
x+dx, y+dy, dx , dy , +9) ); x+dx, y+dy, dx , dy , +9) );
} }
} }
if (mode == CvHaarFeatureParams::ALL) if (mode == CvHaarFeatureParams::ALL)
{ {
// tilted haar_x2 // tilted haar_x2
if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) ) if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )
{ {
features.push_back( Feature( offset, true, features.push_back( Feature( offset, true,
x, y, dx*2, dy, -1, x, y, dx*2, dy, -1,
x, y, dx, dy, +2 ) ); x, y, dx, dy, +2 ) );
} }
// tilted haar_y2 // tilted haar_y2
if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) ) if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )
{ {
features.push_back( Feature( offset, true, features.push_back( Feature( offset, true,
x, y, dx, 2*dy, -1, x, y, dx, 2*dy, -1,
x, y, dx, dy, +2 ) ); x, y, dx, dy, +2 ) );
} }
// tilted haar_x3 // tilted haar_x3
if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) ) if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )
{ {
features.push_back( Feature( offset, true, features.push_back( Feature( offset, true,
x, y, dx*3, dy, -1, x, y, dx*3, dy, -1,
x+dx, y+dx, dx, dy, +3 ) ); x+dx, y+dx, dx, dy, +3 ) );
} }
// tilted haar_y3 // tilted haar_y3
if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) ) if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )
{ {
features.push_back( Feature( offset, true, features.push_back( Feature( offset, true,
x, y, dx, 3*dy, -1, x, y, dx, 3*dy, -1,
x-dy, y+dy, dx, dy, +3 ) ); x-dy, y+dy, dx, dy, +3 ) );
} }
// tilted haar_x4 // tilted haar_x4
if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) ) if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )
{ {
features.push_back( Feature( offset, true, features.push_back( Feature( offset, true,
x, y, dx*4, dy, -1, x, y, dx*4, dy, -1,
x+dx, y+dx, dx*2, dy, +2 ) ); x+dx, y+dx, dx*2, dy, +2 ) );
} }
// tilted haar_y4 // tilted haar_y4
if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) ) if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )
{ {
features.push_back( Feature( offset, true, features.push_back( Feature( offset, true,
x, y, dx, 4*dy, -1, x, y, dx, 4*dy, -1,
@ -296,7 +299,7 @@ void CvHaarEvaluator::Feature::write( FileStorage &fs ) const
fs << CC_RECTS << "["; fs << CC_RECTS << "[";
for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri ) for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri )
{ {
fs << "[:" << rect[ri].r.x << rect[ri].r.y << fs << "[:" << rect[ri].r.x << rect[ri].r.y <<
rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]"; rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]";
} }
fs << "]" << CC_TILTED << tilted; fs << "]" << CC_TILTED << tilted;

View File

@ -1,3 +1,6 @@
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "cv.h" #include "cv.h"
#include "imagestorage.h" #include "imagestorage.h"
#include <stdio.h> #include <stdio.h>
@ -55,7 +58,7 @@ bool CvCascadeImageReader::NegReader::nextImg()
for( size_t i = 0; i < count; i++ ) for( size_t i = 0; i < count; i++ )
{ {
src = imread( imgFilenames[last++], 0 ); src = imread( imgFilenames[last++], 0 );
if( src.empty() ) if( src.empty() )
continue; continue;
round += last / count; round += last / count;
round = round % (winSize.width * winSize.height); round = round % (winSize.width * winSize.height);
@ -63,7 +66,7 @@ bool CvCascadeImageReader::NegReader::nextImg()
_offset.x = min( (int)round % winSize.width, src.cols - winSize.width ); _offset.x = min( (int)round % winSize.width, src.cols - winSize.width );
_offset.y = min( (int)round / winSize.width, src.rows - winSize.height ); _offset.y = min( (int)round / winSize.width, src.rows - winSize.height );
if( !src.empty() && src.type() == CV_8UC1 if( !src.empty() && src.type() == CV_8UC1
&& offset.x >= 0 && offset.y >= 0 ) && offset.x >= 0 && offset.y >= 0 )
break; break;
} }
@ -73,7 +76,7 @@ bool CvCascadeImageReader::NegReader::nextImg()
point = offset = _offset; point = offset = _offset;
scale = max( ((float)winSize.width + point.x) / ((float)src.cols), scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
((float)winSize.height + point.y) / ((float)src.rows) ); ((float)winSize.height + point.y) / ((float)src.rows) );
Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) ); Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
resize( src, img, sz ); resize( src, img, sz );
return true; return true;
@ -87,7 +90,7 @@ bool CvCascadeImageReader::NegReader::get( Mat& _img )
CV_Assert( _img.rows == winSize.height ); CV_Assert( _img.rows == winSize.height );
if( img.empty() ) if( img.empty() )
if ( !nextImg() ) if ( !nextImg() )
return false; return false;
Mat mat( winSize.height, winSize.width, CV_8UC1, Mat mat( winSize.height, winSize.width, CV_8UC1,
@ -109,7 +112,7 @@ bool CvCascadeImageReader::NegReader::get( Mat& _img )
resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ) ); resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ) );
else else
{ {
if ( !nextImg() ) if ( !nextImg() )
return false; return false;
} }
} }
@ -131,7 +134,7 @@ bool CvCascadeImageReader::PosReader::create( const String _filename )
if( !file ) if( !file )
return false; return false;
short tmp = 0; short tmp = 0;
if( fread( &count, sizeof( count ), 1, file ) != 1 || if( fread( &count, sizeof( count ), 1, file ) != 1 ||
fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 || fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||
fread( &tmp, sizeof( tmp ), 1, file ) != 1 || fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||

View File

@ -1,3 +1,6 @@
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "lbpfeatures.h" #include "lbpfeatures.h"
#include "cascadeclassifier.h" #include "cascadeclassifier.h"

View File

@ -1,3 +1,6 @@
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "cv.h" #include "cv.h"
#include "cascadeclassifier.h" #include "cascadeclassifier.h"
@ -13,11 +16,11 @@ int main( int argc, char* argv[] )
int precalcValBufSize = 256, int precalcValBufSize = 256,
precalcIdxBufSize = 256; precalcIdxBufSize = 256;
bool baseFormatSave = false; bool baseFormatSave = false;
CvCascadeParams cascadeParams; CvCascadeParams cascadeParams;
CvCascadeBoostParams stageParams; CvCascadeBoostParams stageParams;
Ptr<CvFeatureParams> featureParams[] = { Ptr<CvFeatureParams>(new CvHaarFeatureParams), Ptr<CvFeatureParams> featureParams[] = { Ptr<CvFeatureParams>(new CvHaarFeatureParams),
Ptr<CvFeatureParams>(new CvLBPFeatureParams), Ptr<CvFeatureParams>(new CvLBPFeatureParams),
Ptr<CvFeatureParams>(new CvHOGFeatureParams) Ptr<CvFeatureParams>(new CvHOGFeatureParams)
}; };
int fc = sizeof(featureParams)/sizeof(featureParams[0]); int fc = sizeof(featureParams)/sizeof(featureParams[0]);
@ -85,7 +88,7 @@ int main( int argc, char* argv[] )
{ {
for( int fi = 0; fi < fc; fi++ ) for( int fi = 0; fi < fc; fi++ )
{ {
set = featureParams[fi]->scanAttr(argv[i], argv[i+1]); set = featureParams[fi]->scanAttr(argv[i], argv[i+1]);
if ( !set ) if ( !set )
{ {
i++; i++;
@ -94,11 +97,11 @@ int main( int argc, char* argv[] )
} }
} }
} }
classifier.train( cascadeDirName, classifier.train( cascadeDirName,
vecName, vecName,
bgName, bgName,
numPos, numNeg, numPos, numNeg,
precalcValBufSize, precalcIdxBufSize, precalcValBufSize, precalcIdxBufSize,
numStages, numStages,
cascadeParams, cascadeParams,

View File

@ -14,6 +14,8 @@ if(MINGW)
endif() endif()
if(MSVC) if(MSVC)
string(REGEX REPLACE "^ *| * $" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "^ *| * $" "" CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT}")
if(CMAKE_CXX_FLAGS STREQUAL CMAKE_CXX_FLAGS_INIT) if(CMAKE_CXX_FLAGS STREQUAL CMAKE_CXX_FLAGS_INIT)
# override cmake default exception handling option # override cmake default exception handling option
string(REPLACE "/EHsc" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/EHsc" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
@ -21,73 +23,112 @@ if(MSVC)
endif() endif()
endif() endif()
set(OPENCV_EXTRA_FLAGS "")
set(OPENCV_EXTRA_C_FLAGS "") set(OPENCV_EXTRA_C_FLAGS "")
set(OPENCV_EXTRA_C_FLAGS_RELEASE "") set(OPENCV_EXTRA_CXX_FLAGS "")
set(OPENCV_EXTRA_C_FLAGS_DEBUG "") set(OPENCV_EXTRA_FLAGS_RELEASE "")
set(OPENCV_EXTRA_FLAGS_DEBUG "")
set(OPENCV_EXTRA_EXE_LINKER_FLAGS "") set(OPENCV_EXTRA_EXE_LINKER_FLAGS "")
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "") set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "")
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "") set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "")
macro(add_extra_compiler_option option)
if(CMAKE_BUILD_TYPE)
set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
endif()
ocv_check_flag_support(CXX "${option}" _varname "${OPENCV_EXTRA_CXX_FLAGS} ${ARGN}")
if(${_varname})
set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} ${option}")
endif()
ocv_check_flag_support(C "${option}" _varname "${OPENCV_EXTRA_C_FLAGS} ${ARGN}")
if(${_varname})
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} ${option}")
endif()
endmacro()
if(MINGW) if(MINGW)
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40838 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40838
# here we are trying to workaround the problem # here we are trying to workaround the problem
include(CheckCXXCompilerFlag) add_extra_compiler_option(-mstackrealign)
CHECK_CXX_COMPILER_FLAG(-mstackrealign HAVE_STACKREALIGN_FLAG) if(NOT HAVE_CXX_MSTACKREALIGN)
if(HAVE_STACKREALIGN_FLAG) add_extra_compiler_option(-mpreferred-stack-boundary=2)
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() endif()
if(OPENCV_CAN_BREAK_BINARY_COMPATIBILITY)
add_definitions(-DOPENCV_CAN_BREAK_BINARY_COMPATIBILITY)
endif()
if(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_COMPILER_IS_GNUCXX)
# High level of warnings. # High level of warnings.
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -Wall") add_extra_compiler_option(-Wall)
add_extra_compiler_option(-Werror=return-type)
if(OPENCV_CAN_BREAK_BINARY_COMPATIBILITY)
add_extra_compiler_option(-Werror=non-virtual-dtor)
endif()
add_extra_compiler_option(-Werror=address)
add_extra_compiler_option(-Werror=sequence-point)
add_extra_compiler_option(-Wformat)
add_extra_compiler_option(-Werror=format-security -Wformat)
add_extra_compiler_option(-Wmissing-declarations)
add_extra_compiler_option(-Wmissing-prototypes)
add_extra_compiler_option(-Wstrict-prototypes)
add_extra_compiler_option(-Wundef)
add_extra_compiler_option(-Winit-self)
add_extra_compiler_option(-Wpointer-arith)
add_extra_compiler_option(-Wshadow)
if(ENABLE_NOISY_WARNINGS)
add_extra_compiler_option(-Wcast-align)
add_extra_compiler_option(-Wstrict-aliasing=2)
else()
add_extra_compiler_option(-Wno-narrowing)
add_extra_compiler_option(-Wno-delete-non-virtual-dtor)
add_extra_compiler_option(-Wno-unnamed-type-template-args)
endif()
# The -Wno-long-long is required in 64bit systems when including sytem headers. # The -Wno-long-long is required in 64bit systems when including sytem headers.
if(X86_64) if(X86_64)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -Wno-long-long") add_extra_compiler_option(-Wno-long-long)
endif() endif()
# We need pthread's # We need pthread's
if(UNIX AND NOT ANDROID) if(UNIX AND NOT ANDROID)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -pthread") add_extra_compiler_option(-pthread)
endif() endif()
if(OPENCV_WARNINGS_ARE_ERRORS) if(OPENCV_WARNINGS_ARE_ERRORS)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -Werror") add_extra_compiler_option(-Werror)
endif() endif()
if(X86 AND NOT MINGW64 AND NOT X86_64 AND NOT APPLE) if(X86 AND NOT MINGW64 AND NOT X86_64 AND NOT APPLE)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -march=i686") add_extra_compiler_option(-march=i686)
endif() endif()
# Other optimizations # Other optimizations
if(ENABLE_OMIT_FRAME_POINTER) if(ENABLE_OMIT_FRAME_POINTER)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -fomit-frame-pointer") add_extra_compiler_option(-fomit-frame-pointer)
else() else()
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -fno-omit-frame-pointer") add_extra_compiler_option(-fno-omit-frame-pointer)
endif() endif()
if(ENABLE_FAST_MATH) if(ENABLE_FAST_MATH)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -ffast-math") add_extra_compiler_option(-ffast-math)
endif() endif()
if(ENABLE_POWERPC) if(ENABLE_POWERPC)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mcpu=G3 -mtune=G5") add_extra_compiler_option("-mcpu=G3 -mtune=G5")
endif() endif()
if(ENABLE_SSE) if(ENABLE_SSE)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse") add_extra_compiler_option(-msse)
endif() endif()
if(ENABLE_SSE2) if(ENABLE_SSE2)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse2") add_extra_compiler_option(-msse2)
endif() endif()
# SSE3 and further should be disabled under MingW because it generates compiler errors # SSE3 and further should be disabled under MingW because it generates compiler errors
if(NOT MINGW) if(NOT MINGW)
if(ENABLE_SSE3) if(ENABLE_SSE3)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse3") add_extra_compiler_option(-msse3)
endif() endif()
if(${CMAKE_OPENCV_GCC_VERSION_NUM} GREATER 402) if(${CMAKE_OPENCV_GCC_VERSION_NUM} GREATER 402)
@ -99,14 +140,14 @@ if(CMAKE_COMPILER_IS_GNUCXX)
if(HAVE_GCC42_OR_NEWER OR APPLE) if(HAVE_GCC42_OR_NEWER OR APPLE)
if(ENABLE_SSSE3) if(ENABLE_SSSE3)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mssse3") add_extra_compiler_option(-mssse3)
endif() endif()
if(HAVE_GCC43_OR_NEWER) if(HAVE_GCC43_OR_NEWER)
if(ENABLE_SSE41) if(ENABLE_SSE41)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse4.1") add_extra_compiler_option(-msse4.1)
endif() endif()
if(ENABLE_SSE42) if(ENABLE_SSE42)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -msse4.2") add_extra_compiler_option(-msse4.2)
endif() endif()
endif() endif()
endif() endif()
@ -114,39 +155,40 @@ if(CMAKE_COMPILER_IS_GNUCXX)
if(X86 OR X86_64) if(X86 OR X86_64)
if(NOT APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 4) if(NOT APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 4)
if(ENABLE_SSE2) if(ENABLE_SSE2)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mfpmath=sse")# !! important - be on the same wave with x64 compilers add_extra_compiler_option(-mfpmath=sse)# !! important - be on the same wave with x64 compilers
else() else()
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -mfpmath=387") add_extra_compiler_option(-mfpmath=387)
endif() endif()
endif() endif()
endif() endif()
# Profiling? # Profiling?
if(ENABLE_PROFILING) if(ENABLE_PROFILING)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -pg -g") add_extra_compiler_option("-pg -g")
# turn off incompatible options # turn off incompatible options
foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS_RELEASE) foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG
OPENCV_EXTRA_FLAGS_RELEASE OPENCV_EXTRA_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS OPENCV_EXTRA_CXX_FLAGS)
string(REPLACE "-fomit-frame-pointer" "" ${flags} "${${flags}}") string(REPLACE "-fomit-frame-pointer" "" ${flags} "${${flags}}")
string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}") string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}")
endforeach() endforeach()
elseif(NOT APPLE AND NOT ANDROID) elseif(NOT APPLE AND NOT ANDROID)
# Remove unreferenced functions: function level linking # Remove unreferenced functions: function level linking
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} -ffunction-sections") add_extra_compiler_option(-ffunction-sections)
endif() endif()
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} -DNDEBUG") set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} -DNDEBUG")
set(OPENCV_EXTRA_C_FLAGS_DEBUG "${OPENCV_EXTRA_C_FLAGS_DEBUG} -O0 -DDEBUG -D_DEBUG") set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG} -O0 -DDEBUG -D_DEBUG")
if(BUILD_WITH_DEBUG_INFO) if(BUILD_WITH_DEBUG_INFO)
set(OPENCV_EXTRA_C_FLAGS_DEBUG "${OPENCV_EXTRA_C_FLAGS_DEBUG} -ggdb3") set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG} -ggdb3")
endif() endif()
endif() endif()
if(MSVC) if(MSVC)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS")
# 64-bit portability warnings, in MSVC80 # 64-bit portability warnings, in MSVC80
if(MSVC80) if(MSVC80)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /Wp64") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Wp64")
endif() endif()
if(BUILD_WITH_DEBUG_INFO) if(BUILD_WITH_DEBUG_INFO)
@ -154,38 +196,38 @@ if(MSVC)
endif() endif()
# Remove unreferenced functions: function level linking # Remove unreferenced functions: function level linking
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /Gy") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Gy")
if(NOT MSVC_VERSION LESS 1400) if(NOT MSVC_VERSION LESS 1400)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /bigobj") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /bigobj")
endif() endif()
if(BUILD_WITH_DEBUG_INFO) if(BUILD_WITH_DEBUG_INFO)
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE} /Zi") set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} /Zi")
endif() endif()
if(NOT MSVC64) if(NOT MSVC64)
# 64-bit MSVC compiler uses SSE/SSE2 by default # 64-bit MSVC compiler uses SSE/SSE2 by default
if(ENABLE_SSE) if(ENABLE_SSE)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /arch:SSE") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:SSE")
endif() endif()
if(ENABLE_SSE2) if(ENABLE_SSE2)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /arch:SSE2") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:SSE2")
endif() endif()
endif() endif()
if(ENABLE_SSE3) if(ENABLE_SSE3)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /arch:SSE3") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:SSE3")
endif() endif()
if(ENABLE_SSE4_1) if(ENABLE_SSE4_1)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /arch:SSE4.1") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /arch:SSE4.1")
endif() endif()
if(ENABLE_SSE OR ENABLE_SSE2 OR ENABLE_SSE3 OR ENABLE_SSE4_1) if(ENABLE_SSE OR ENABLE_SSE2 OR ENABLE_SSE3 OR ENABLE_SSE4_1)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /Oi") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Oi")
endif() endif()
if(X86 OR X86_64) if(X86 OR X86_64)
if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND ENABLE_SSE2) if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND ENABLE_SSE2)
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /fp:fast")# !! important - be on the same wave with x64 compilers set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /fp:fast")# !! important - be on the same wave with x64 compilers
endif() endif()
endif() endif()
endif() endif()
@ -194,25 +236,27 @@ endif()
if(NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX AND NOT ANDROID) if(NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX AND NOT ANDROID)
# Android does not need these settings because they are already set by toolchain file # Android does not need these settings because they are already set by toolchain file
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} stdc++) set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} stdc++)
set(OPENCV_EXTRA_C_FLAGS "-fPIC ${OPENCV_EXTRA_C_FLAGS}") set(OPENCV_EXTRA_FLAGS "-fPIC ${OPENCV_EXTRA_FLAGS}")
endif() endif()
# Add user supplied extra options (optimization, etc...) # Add user supplied extra options (optimization, etc...)
# ========================================================== # ==========================================================
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS}" CACHE INTERNAL "Extra compiler options") set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS}" CACHE INTERNAL "Extra compiler options")
set(OPENCV_EXTRA_C_FLAGS_RELEASE "${OPENCV_EXTRA_C_FLAGS_RELEASE}" CACHE INTERNAL "Extra compiler options for Release build") set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS}" CACHE INTERNAL "Extra compiler options for C sources")
set(OPENCV_EXTRA_C_FLAGS_DEBUG "${OPENCV_EXTRA_C_FLAGS_DEBUG}" CACHE INTERNAL "Extra compiler options for Debug build") set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS}" CACHE INTERNAL "Extra compiler options for C++ sources")
set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE}" CACHE INTERNAL "Extra compiler options for Release build")
set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG}" CACHE INTERNAL "Extra compiler options for Debug build")
set(OPENCV_EXTRA_EXE_LINKER_FLAGS "${OPENCV_EXTRA_EXE_LINKER_FLAGS}" CACHE INTERNAL "Extra linker flags") set(OPENCV_EXTRA_EXE_LINKER_FLAGS "${OPENCV_EXTRA_EXE_LINKER_FLAGS}" CACHE INTERNAL "Extra linker flags")
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE}" CACHE INTERNAL "Extra linker flags for Release build") set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE}" CACHE INTERNAL "Extra linker flags for Release build")
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "${OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Extra linker flags for Debug build") set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "${OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Extra linker flags for Debug build")
#combine all "extra" options #combine all "extra" options
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPENCV_EXTRA_C_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OPENCV_EXTRA_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OPENCV_EXTRA_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${OPENCV_EXTRA_C_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${OPENCV_EXTRA_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${OPENCV_EXTRA_C_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${OPENCV_EXTRA_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${OPENCV_EXTRA_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${OPENCV_EXTRA_FLAGS_DEBUG}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OPENCV_EXTRA_EXE_LINKER_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OPENCV_EXTRA_EXE_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE}") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG}") set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG}")
@ -225,12 +269,16 @@ if(MSVC)
string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") string(REPLACE "/W3" "/W4" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
if(NOT ENABLE_NOISY_WARNINGS AND MSVC_VERSION EQUAL 1400)
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4510 /wd4610 /wd4312 /wd4201 /wd4244 /wd4328 /wd4267)
endif()
# allow extern "C" functions throw exceptions # allow extern "C" functions throw exceptions
foreach(flags CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG) foreach(flags CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
string(REPLACE "/EHsc-" "/EHs" ${flags} "${${flags}}") string(REPLACE "/EHsc-" "/EHs" ${flags} "${${flags}}")
string(REPLACE "/EHsc" "/EHs" ${flags} "${${flags}}") string(REPLACE "/EHsc" "/EHs" ${flags} "${${flags}}")
string(REPLACE "/Zm1000" "" ${flags} "${${flags}}") string(REPLACE "/Zm1000" "" ${flags} "${${flags}}")
endforeach() endforeach()

View File

@ -44,6 +44,12 @@ if(MSVC AND CMAKE_C_COMPILER MATCHES "icc")
set(CV_ICC __INTEL_COMPILER_FOR_WINDOWS) set(CV_ICC __INTEL_COMPILER_FOR_WINDOWS)
endif() endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR (UNIX AND CV_ICC))
set(CV_COMPILER_IS_GNU TRUE)
else()
set(CV_COMPILER_IS_GNU FALSE)
endif()
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# Detect GNU version: # Detect GNU version:
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------

View File

@ -1,6 +1,6 @@
if(ANDROID) if(ANDROID)
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/tbb") add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/tbb")
ocv_include_directories(${TBB_INCLUDE_DIRS}) include_directories(SYSTEM ${TBB_INCLUDE_DIRS})
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb) set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb)
add_definitions(-DTBB_USE_GCC_BUILTINS=1 -D__TBB_GCC_BUILTIN_ATOMICS_PRESENT=1 -D__TBB_USE_GENERIC_DWORD_LOAD_STORE=1) add_definitions(-DTBB_USE_GCC_BUILTINS=1 -D__TBB_GCC_BUILTIN_ATOMICS_PRESENT=1 -D__TBB_USE_GENERIC_DWORD_LOAD_STORE=1)
set(HAVE_TBB 1) set(HAVE_TBB 1)

View File

@ -61,6 +61,16 @@ if(TIFF_BIGTIFF_VERSION AND NOT TIFF_VERSION_BIG)
set(TIFF_VERSION_BIG ${TIFF_BIGTIFF_VERSION}) set(TIFF_VERSION_BIG ${TIFF_BIGTIFF_VERSION})
endif() endif()
if(NOT TIFF_VERSION_STRING AND TIFF_INCLUDE_DIR)
list(GET TIFF_INCLUDE_DIR 0 _TIFF_INCLUDE_DIR)
if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h")
file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*")
string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}")
unset(tiff_version_str)
endif()
unset(_TIFF_INCLUDE_DIR)
endif()
# --- libjpeg (optional) --- # --- libjpeg (optional) ---
if(WITH_JPEG) if(WITH_JPEG)
if(BUILD_JPEG) if(BUILD_JPEG)

View File

@ -18,7 +18,7 @@ if(WIN32)
# Try to find the XIMEA API path in registry. # Try to find the XIMEA API path in registry.
GET_FILENAME_COMPONENT(XIMEA_PATH "[HKEY_CURRENT_USER\\Software\\XIMEA\\CamSupport\\API;Path]" ABSOLUTE) GET_FILENAME_COMPONENT(XIMEA_PATH "[HKEY_CURRENT_USER\\Software\\XIMEA\\CamSupport\\API;Path]" ABSOLUTE)
if(XIMEA_PATH) if(EXISTS XIMEA_PATH)
set(XIMEA_FOUND 1) set(XIMEA_FOUND 1)
# set LIB folders # set LIB folders

View File

@ -20,17 +20,17 @@ set(OPENCV_MOD_LIST ${OPENCV_MODULES_PUBLIC})
ocv_list_sort(OPENCV_MOD_LIST) ocv_list_sort(OPENCV_MOD_LIST)
foreach(m ${OPENCV_MOD_LIST}) foreach(m ${OPENCV_MOD_LIST})
string(TOUPPER "${m}" m) string(TOUPPER "${m}" m)
set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}#define HAVE_${m} 1\n") set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}#define HAVE_${m}\n")
endforeach() endforeach()
set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}\n") set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}\n")
set(OPENCV_MOD_LIST ${OPENCV_MODULES_DISABLED_USER} ${OPENCV_MODULES_DISABLED_AUTO}) #set(OPENCV_MOD_LIST ${OPENCV_MODULES_DISABLED_USER} ${OPENCV_MODULES_DISABLED_AUTO} ${OPENCV_MODULES_DISABLED_FORCE})
ocv_list_sort(OPENCV_MOD_LIST) #ocv_list_sort(OPENCV_MOD_LIST)
foreach(m ${OPENCV_MOD_LIST}) #foreach(m ${OPENCV_MOD_LIST})
string(TOUPPER "${m}" m) # string(TOUPPER "${m}" m)
set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}#undef HAVE_${m}\n") # set(OPENCV_MODULE_DEFINITIONS_CONFIGMAKE "${OPENCV_MODULE_DEFINITIONS_CONFIGMAKE}#undef HAVE_${m}\n")
endforeach() #endforeach()
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/opencv_modules.hpp.in" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp") configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/opencv_modules.hpp.in" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp")
install(FILES "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp" DESTINATION ${OPENCV_INCLUDE_PREFIX}/opencv2 COMPONENT main) install(FILES "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp" DESTINATION ${OPENCV_INCLUDE_PREFIX}/opencv2 COMPONENT main)

View File

@ -131,7 +131,7 @@ macro(ocv_add_module _name)
set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} "${the_module}" CACHE INTERNAL "List of OpenCV modules marked for export") set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} "${the_module}" CACHE INTERNAL "List of OpenCV modules marked for export")
endif() endif()
endif() endif()
# add self to the world dependencies # add self to the world dependencies
if(NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS" OR OPENCV_MODULE_IS_PART_OF_WORLD) if(NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS" OR OPENCV_MODULE_IS_PART_OF_WORLD)
ocv_add_dependencies(opencv_world OPTIONAL ${the_module}) ocv_add_dependencies(opencv_world OPTIONAL ${the_module})
@ -512,6 +512,8 @@ endmacro()
macro(ocv_add_precompiled_headers the_target) macro(ocv_add_precompiled_headers the_target)
if("${the_target}" MATCHES "^opencv_test_.*$") if("${the_target}" MATCHES "^opencv_test_.*$")
SET(pch_path "test/test_") SET(pch_path "test/test_")
elseif("${the_target}" MATCHES "opencv_perf_gpu_cpu")
SET(pch_path "perf_cpu/perf_cpu_")
elseif("${the_target}" MATCHES "^opencv_perf_.*$") elseif("${the_target}" MATCHES "^opencv_perf_.*$")
SET(pch_path "perf/perf_") SET(pch_path "perf/perf_")
else() else()

View File

@ -24,10 +24,12 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
ENDIF() ENDIF()
SET(_PCH_include_prefix "-I") SET(_PCH_include_prefix "-I")
SET(_PCH_isystem_prefix "-isystem")
ELSEIF(WIN32) ELSEIF(WIN32)
SET(PCHSupport_FOUND TRUE) # for experimental msvc support SET(PCHSupport_FOUND TRUE) # for experimental msvc support
SET(_PCH_include_prefix "/I") SET(_PCH_include_prefix "/I")
SET(_PCH_isystem_prefix "/I")
ELSE() ELSE()
SET(PCHSupport_FOUND FALSE) SET(PCHSupport_FOUND FALSE)
ENDIF() ENDIF()
@ -50,7 +52,11 @@ MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags)
GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES ) GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES )
FOREACH(item ${DIRINC}) FOREACH(item ${DIRINC})
LIST(APPEND ${_out_compile_flags} "${_PCH_include_prefix}\"${item}\"") if(item MATCHES "^${OpenCV_SOURCE_DIR}/modules/")
LIST(APPEND ${_out_compile_flags} "${_PCH_include_prefix}\"${item}\"")
else()
LIST(APPEND ${_out_compile_flags} "${_PCH_isystem_prefix}\"${item}\"")
endif()
ENDFOREACH(item) ENDFOREACH(item)
GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS) GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS)
@ -72,6 +78,7 @@ MACRO(_PCH_WRITE_PCHDEP_CXX _targetName _include_file _dephelp)
ADD_CUSTOM_COMMAND( ADD_CUSTOM_COMMAND(
OUTPUT "${${_dephelp}}" OUTPUT "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo "#include \\\"${_include_file}\\\"" > "${${_dephelp}}" COMMAND ${CMAKE_COMMAND} -E echo "#include \\\"${_include_file}\\\"" > "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo "int testfunction();" >> "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo "int testfunction()" >> "${${_dephelp}}" COMMAND ${CMAKE_COMMAND} -E echo "int testfunction()" >> "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo "{" >> "${${_dephelp}}" COMMAND ${CMAKE_COMMAND} -E echo "{" >> "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo " return 0;" >> "${${_dephelp}}" COMMAND ${CMAKE_COMMAND} -E echo " return 0;" >> "${${_dephelp}}"
@ -82,6 +89,7 @@ MACRO(_PCH_WRITE_PCHDEP_CXX _targetName _include_file _dephelp)
ADD_CUSTOM_COMMAND( ADD_CUSTOM_COMMAND(
OUTPUT "${${_dephelp}}" OUTPUT "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo "\\#include \\\"${_include_file}\\\"" > "${${_dephelp}}" COMMAND ${CMAKE_COMMAND} -E echo "\\#include \\\"${_include_file}\\\"" > "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo "int testfunction\\(\\)\\;" >> "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo "int testfunction\\(\\)" >> "${${_dephelp}}" COMMAND ${CMAKE_COMMAND} -E echo "int testfunction\\(\\)" >> "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo "{" >> "${${_dephelp}}" COMMAND ${CMAKE_COMMAND} -E echo "{" >> "${${_dephelp}}"
COMMAND ${CMAKE_COMMAND} -E echo " \\return 0\\;" >> "${${_dephelp}}" COMMAND ${CMAKE_COMMAND} -E echo " \\return 0\\;" >> "${${_dephelp}}"

View File

@ -19,7 +19,7 @@ function(ocv_include_directories)
if("${__abs_dir}" MATCHES "^${OpenCV_SOURCE_DIR}" OR "${__abs_dir}" MATCHES "^${OpenCV_BINARY_DIR}") if("${__abs_dir}" MATCHES "^${OpenCV_SOURCE_DIR}" OR "${__abs_dir}" MATCHES "^${OpenCV_BINARY_DIR}")
list(APPEND __add_before "${dir}") list(APPEND __add_before "${dir}")
else() else()
include_directories(AFTER "${dir}") include_directories(AFTER SYSTEM "${dir}")
endif() endif()
endforeach() endforeach()
include_directories(BEFORE ${__add_before}) include_directories(BEFORE ${__add_before})
@ -32,6 +32,125 @@ macro(ocv_clear_vars)
endforeach() endforeach()
endmacro() endmacro()
set(OCV_COMPILER_FAIL_REGEX
"command line option .* is valid for .* but not for C\\+\\+" # GNU
"unrecognized .*option" # GNU
"unknown .*option" # Clang
"ignoring unknown option" # MSVC
"warning D9002" # MSVC, any lang
"option .*not supported" # Intel
"[Uu]nknown option" # HP
"[Ww]arning: [Oo]ption" # SunPro
"command option .* is not recognized" # XL
"not supported in this configuration; ignored" # AIX
"File with unknown suffix passed to linker" # PGI
"WARNING: unknown flag:" # Open64
)
MACRO(ocv_check_compiler_flag LANG FLAG RESULT)
if(NOT DEFINED ${RESULT})
if("_${LANG}_" MATCHES "_CXX_")
set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx")
if("${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_CXX_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
FILE(WRITE "${_fname}" "int main() { return 0; }\n")
else()
FILE(WRITE "${_fname}" "#pragma\nint main() { return 0; }\n")
endif()
elseif("_${LANG}_" MATCHES "_C_")
set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c")
if("${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror " OR "${CMAKE_C_FLAGS} ${FLAG} " MATCHES "-Werror=unknown-pragmas ")
FILE(WRITE "${_fname}" "int main(void) { return 0; }\n")
else()
FILE(WRITE "${_fname}" "#pragma\nint main(void) { return 0; }\n")
endif()
else()
unset(_fname)
endif()
if(_fname)
MESSAGE(STATUS "Performing Test ${RESULT}")
TRY_COMPILE(${RESULT}
${CMAKE_BINARY_DIR}
"${_fname}"
COMPILE_DEFINITIONS "${FLAG}"
OUTPUT_VARIABLE OUTPUT)
FOREACH(_regex ${OCV_COMPILER_FAIL_REGEX})
IF("${OUTPUT}" MATCHES "${_regex}")
SET(${RESULT} 0)
break()
ENDIF()
ENDFOREACH()
IF(${RESULT})
SET(${RESULT} 1 CACHE INTERNAL "Test ${RESULT}")
MESSAGE(STATUS "Performing Test ${RESULT} - Success")
ELSE(${RESULT})
MESSAGE(STATUS "Performing Test ${RESULT} - Failed")
SET(${RESULT} "" CACHE INTERNAL "Test ${RESULT}")
ENDIF(${RESULT})
else()
SET(${RESULT} 0)
endif()
endif()
ENDMACRO()
macro(ocv_check_flag_support lang flag varname)
if("_${lang}_" MATCHES "_CXX_")
set(_lang CXX)
elseif("_${lang}_" MATCHES "_C_")
set(_lang C)
else()
set(_lang ${lang})
endif()
string(TOUPPER "${flag}" ${varname})
string(REGEX REPLACE "^(/|-)" "HAVE_${_lang}_" ${varname} "${${varname}}")
string(REGEX REPLACE " -|-|=| |\\." "_" ${varname} "${${varname}}")
ocv_check_compiler_flag("${_lang}" "${ARGN} ${flag}" ${${varname}})
endmacro()
# turns off warnings
macro(ocv_warnings_disable)
if(NOT ENABLE_NOISY_WARNINGS)
set(_flag_vars "")
set(_msvc_warnings "")
set(_gxx_warnings "")
foreach(arg ${ARGN})
if(arg MATCHES "^CMAKE_")
list(APPEND _flag_vars ${arg})
elseif(arg MATCHES "^/wd")
list(APPEND _msvc_warnings ${arg})
elseif(arg MATCHES "^-W")
list(APPEND _gxx_warnings ${arg})
endif()
endforeach()
if(MSVC AND _msvc_warnings AND _flag_vars)
foreach(var ${_flag_vars})
foreach(warning ${_msvc_warnings})
set(${var} "${${var}} ${warning}")
endforeach()
endforeach()
elseif(CV_COMPILER_IS_GNU AND _gxx_warnings AND _flag_vars)
foreach(var ${_flag_vars})
foreach(warning ${_gxx_warnings})
if(NOT warning MATCHES "^-Wno-")
string(REPLACE "${warning}" "" ${var} "${${var}}")
string(REPLACE "-W" "-Wno-" warning "${warning}")
endif()
ocv_check_flag_support(${var} "${warning}" _varname)
if(${_varname})
set(${var} "${${var}} ${warning}")
endif()
endforeach()
endforeach()
endif()
unset(_flag_vars)
unset(_msvc_warnings)
unset(_gxx_warnings)
endif(NOT ENABLE_NOISY_WARNINGS)
endmacro()
# Provides an option that the user can optionally select. # Provides an option that the user can optionally select.
# Can accept condition to control when option is available for user. # Can accept condition to control when option is available for user.
# Usage: # Usage:

View File

@ -1,3 +1,7 @@
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
#endif
#ifndef __OPENCV_PERF_PRECOMP_HPP__ #ifndef __OPENCV_PERF_PRECOMP_HPP__
#define __OPENCV_PERF_PRECOMP_HPP__ #define __OPENCV_PERF_PRECOMP_HPP__
@ -6,7 +10,7 @@
#include "opencv2/highgui/highgui.hpp" #include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/imgproc/imgproc.hpp"
#if GTEST_CREATE_SHARED_LIBRARY #ifdef GTEST_CREATE_SHARED_LIBRARY
#error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined #error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined
#endif #endif

View File

@ -230,7 +230,7 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
int found = 0; int found = 0;
CvCBQuad *quads = 0, **quad_group = 0; CvCBQuad *quads = 0, **quad_group = 0;
CvCBCorner *corners = 0, **corner_group = 0; CvCBCorner *corners = 0, **corner_group = 0;
try try
{ {
int k = 0; int k = 0;
@ -252,11 +252,11 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
if( out_corner_count ) if( out_corner_count )
*out_corner_count = 0; *out_corner_count = 0;
IplImage _img; IplImage _img;
int check_chessboard_result; int check_chessboard_result;
int quad_count = 0, group_idx = 0, i = 0, dilations = 0; int quad_count = 0, group_idx = 0, dilations = 0;
img = cvGetMat( img, &stub ); img = cvGetMat( img, &stub );
//debug_img = img; //debug_img = img;
@ -316,8 +316,8 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
for( dilations = min_dilations; dilations <= max_dilations; dilations++ ) for( dilations = min_dilations; dilations <= max_dilations; dilations++ )
{ {
if (found) if (found)
break; // already found it break; // already found it
cvFree(&quads); cvFree(&quads);
cvFree(&corners); cvFree(&corners);
@ -378,7 +378,7 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
cvCopy(dbg_img, dbg1_img); cvCopy(dbg_img, dbg1_img);
cvNamedWindow("all_quads", 1); cvNamedWindow("all_quads", 1);
// copy corners to temp array // copy corners to temp array
for( i = 0; i < quad_count; i++ ) for(int i = 0; i < quad_count; i++ )
{ {
for (int k=0; k<4; k++) for (int k=0; k<4; k++)
{ {
@ -432,7 +432,7 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
cvCopy(dbg_img,dbg2_img); cvCopy(dbg_img,dbg2_img);
cvNamedWindow("connected_group", 1); cvNamedWindow("connected_group", 1);
// copy corners to temp array // copy corners to temp array
for( i = 0; i < quad_count; i++ ) for(int i = 0; i < quad_count; i++ )
{ {
if (quads[i].group_idx == group_idx) if (quads[i].group_idx == group_idx)
for (int k=0; k<4; k++) for (int k=0; k<4; k++)
@ -455,7 +455,7 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
#endif #endif
if (count == 0) if (count == 0)
continue; // haven't found inner quads continue; // haven't found inner quads
// If count is more than it should be, this will remove those quads // If count is more than it should be, this will remove those quads
@ -472,7 +472,7 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
float sum_dist = 0; float sum_dist = 0;
int total = 0; int total = 0;
for( i = 0; i < n; i++ ) for(int i = 0; i < n; i++ )
{ {
int ni = 0; int ni = 0;
float avgi = corner_group[i]->meanDist(&ni); float avgi = corner_group[i]->meanDist(&ni);
@ -484,7 +484,7 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
if( count > 0 || (out_corner_count && -count > *out_corner_count) ) if( count > 0 || (out_corner_count && -count > *out_corner_count) )
{ {
// copy corners to output array // copy corners to output array
for( i = 0; i < n; i++ ) for(int i = 0; i < n; i++ )
out_corners[i] = corner_group[i]->pt; out_corners[i] = corner_group[i]->pt;
if( out_corner_count ) if( out_corner_count )
@ -505,19 +505,19 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
if( found ) if( found )
found = icvCheckBoardMonotony( out_corners, pattern_size ); found = icvCheckBoardMonotony( out_corners, pattern_size );
// check that none of the found corners is too close to the image boundary // check that none of the found corners is too close to the image boundary
if( found ) if( found )
{ {
const int BORDER = 8; const int BORDER = 8;
for( k = 0; k < pattern_size.width*pattern_size.height; k++ ) for( k = 0; k < pattern_size.width*pattern_size.height; k++ )
{ {
if( out_corners[k].x <= BORDER || out_corners[k].x > img->cols - BORDER || if( out_corners[k].x <= BORDER || out_corners[k].x > img->cols - BORDER ||
out_corners[k].y <= BORDER || out_corners[k].y > img->rows - BORDER ) out_corners[k].y <= BORDER || out_corners[k].y > img->rows - BORDER )
break; break;
} }
found = k == pattern_size.width*pattern_size.height; found = k == pattern_size.width*pattern_size.height;
} }
if( found && pattern_size.height % 2 == 0 && pattern_size.width % 2 == 0 ) if( found && pattern_size.height % 2 == 0 && pattern_size.width % 2 == 0 )
{ {
@ -525,8 +525,8 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
double dy0 = out_corners[last_row].y - out_corners[0].y; double dy0 = out_corners[last_row].y - out_corners[0].y;
if( dy0 < 0 ) if( dy0 < 0 )
{ {
int i, n = pattern_size.width*pattern_size.height; int n = pattern_size.width*pattern_size.height;
for( i = 0; i < n/2; i++ ) for(int i = 0; i < n/2; i++ )
{ {
CvPoint2D32f temp; CvPoint2D32f temp;
CV_SWAP(out_corners[i], out_corners[n-i-1], temp); CV_SWAP(out_corners[i], out_corners[n-i-1], temp);
@ -559,7 +559,7 @@ int cvFindChessboardCorners( const void* arr, CvSize pattern_size,
cvFree(&corner_group); cvFree(&corner_group);
throw; throw;
} }
cvFree(&quads); cvFree(&quads);
cvFree(&corners); cvFree(&corners);
cvFree(&quad_group); cvFree(&quad_group);
@ -582,7 +582,7 @@ static int
icvCheckBoardMonotony( CvPoint2D32f* corners, CvSize pattern_size ) icvCheckBoardMonotony( CvPoint2D32f* corners, CvSize pattern_size )
{ {
int i, j, k; int i, j, k;
for( k = 0; k < 2; k++ ) for( k = 0; k < 2; k++ )
{ {
for( i = 0; i < (k == 0 ? pattern_size.height : pattern_size.width); i++ ) for( i = 0; i < (k == 0 ? pattern_size.height : pattern_size.width); i++ )
@ -627,11 +627,10 @@ icvOrderFoundConnectedQuads( int quad_count, CvCBQuad **quads,
{ {
cv::Ptr<CvMemStorage> temp_storage = cvCreateChildMemStorage( storage ); cv::Ptr<CvMemStorage> temp_storage = cvCreateChildMemStorage( storage );
CvSeq* stack = cvCreateSeq( 0, sizeof(*stack), sizeof(void*), temp_storage ); CvSeq* stack = cvCreateSeq( 0, sizeof(*stack), sizeof(void*), temp_storage );
int i;
// first find an interior quad // first find an interior quad
CvCBQuad *start = NULL; CvCBQuad *start = NULL;
for (i=0; i<quad_count; i++) for (int i=0; i<quad_count; i++)
{ {
if (quads[i]->count == 4) if (quads[i]->count == 4)
{ {
@ -682,7 +681,7 @@ icvOrderFoundConnectedQuads( int quad_count, CvCBQuad **quads,
case 1: case 1:
col += 2; break; col += 2; break;
case 2: case 2:
row += 2; break; row += 2; break;
case 3: case 3:
col -= 2; break; col -= 2; break;
} }
@ -700,7 +699,7 @@ icvOrderFoundConnectedQuads( int quad_count, CvCBQuad **quads,
} }
} }
for (i=col_min; i<=col_max; i++) for (int i=col_min; i<=col_max; i++)
PRINTF("HIST[%d] = %d\n", i, col_hist[i]); PRINTF("HIST[%d] = %d\n", i, col_hist[i]);
// analyze inner quad structure // analyze inner quad structure
@ -763,7 +762,7 @@ icvOrderFoundConnectedQuads( int quad_count, CvCBQuad **quads,
// if there is an outer quad missing, fill it in // if there is an outer quad missing, fill it in
// first order all inner quads // first order all inner quads
int found = 0; int found = 0;
for (i=0; i<quad_count; i++) for (int i=0; i<quad_count; i++)
{ {
if (quads[i]->count == 4) if (quads[i]->count == 4)
{ // ok, look at neighbors { // ok, look at neighbors
@ -778,7 +777,7 @@ icvOrderFoundConnectedQuads( int quad_count, CvCBQuad **quads,
case 1: case 1:
col += 2; break; col += 2; break;
case 2: case 2:
row += 2; break; row += 2; break;
case 3: case 3:
col -= 2; break; col -= 2; break;
} }
@ -817,7 +816,7 @@ icvOrderFoundConnectedQuads( int quad_count, CvCBQuad **quads,
// final trimming of outer quads // final trimming of outer quads
if (dcol == w && drow == h) // found correct inner quads if (dcol == w && drow == h) // found correct inner quads
{ {
PRINTF("Inner bounds ok, check outer quads\n"); PRINTF("Inner bounds ok, check outer quads\n");
int rcount = quad_count; int rcount = quad_count;
@ -832,7 +831,7 @@ icvOrderFoundConnectedQuads( int quad_count, CvCBQuad **quads,
if (quads[i]->neighbors[j] && quads[i]->neighbors[j]->ordered) if (quads[i]->neighbors[j] && quads[i]->neighbors[j]->ordered)
outer = true; outer = true;
} }
if (!outer) // not an outer quad, eliminate if (!outer) // not an outer quad, eliminate
{ {
PRINTF("Removing quad %d\n", i); PRINTF("Removing quad %d\n", i);
icvRemoveQuadFromGroup(quads,rcount,quads[i]); icvRemoveQuadFromGroup(quads,rcount,quads[i]);
@ -876,7 +875,7 @@ icvAddOuterQuad( CvCBQuad *quad, CvCBQuad **quads, int quad_count,
quad->count += 1; quad->count += 1;
q->neighbors[j] = quad; q->neighbors[j] = quad;
q->group_idx = quad->group_idx; q->group_idx = quad->group_idx;
q->count = 1; // number of neighbors q->count = 1; // number of neighbors
q->ordered = false; q->ordered = false;
q->edge_len = quad->edge_len; q->edge_len = quad->edge_len;
@ -1262,7 +1261,7 @@ icvCheckQuadGroup( CvCBQuad **quad_group, int quad_count,
int width = 0, height = 0; int width = 0, height = 0;
int hist[5] = {0,0,0,0,0}; int hist[5] = {0,0,0,0,0};
CvCBCorner* first = 0, *first2 = 0, *right, *cur, *below, *c; CvCBCorner* first = 0, *first2 = 0, *right, *cur, *below, *c;
// build dual graph, which vertices are internal quad corners // build dual graph, which vertices are internal quad corners
// and two vertices are connected iff they lie on the same quad edge // and two vertices are connected iff they lie on the same quad edge
for( i = 0; i < quad_count; i++ ) for( i = 0; i < quad_count; i++ )
@ -1485,7 +1484,7 @@ icvCheckQuadGroup( CvCBQuad **quad_group, int quad_count,
result = corner_count; result = corner_count;
finalize: finalize:
if( result <= 0 ) if( result <= 0 )
{ {
corner_count = MIN( corner_count, pattern_size.width*pattern_size.height ); corner_count = MIN( corner_count, pattern_size.width*pattern_size.height );
@ -1697,7 +1696,7 @@ icvGenerateQuads( CvCBQuad **out_quads, CvCBCorner **out_corners,
CV_POLY_APPROX_DP, (float)approx_level ); CV_POLY_APPROX_DP, (float)approx_level );
if( dst_contour->total == 4 ) if( dst_contour->total == 4 )
break; break;
// we call this again on its own output, because sometimes // we call this again on its own output, because sometimes
// cvApproxPoly() does not simplify as much as it should. // cvApproxPoly() does not simplify as much as it should.
dst_contour = cvApproxPoly( dst_contour, sizeof(CvContour), temp_storage, dst_contour = cvApproxPoly( dst_contour, sizeof(CvContour), temp_storage,
@ -2006,17 +2005,17 @@ bool cv::findCirclesGrid( InputArray _image, Size patternSize,
#endif #endif
if (isFound) if (isFound)
{ {
switch(parameters.gridType) switch(parameters.gridType)
{ {
case CirclesGridFinderParameters::SYMMETRIC_GRID: case CirclesGridFinderParameters::SYMMETRIC_GRID:
boxFinder.getHoles(centers); boxFinder.getHoles(centers);
break; break;
case CirclesGridFinderParameters::ASYMMETRIC_GRID: case CirclesGridFinderParameters::ASYMMETRIC_GRID:
boxFinder.getAsymmetricHoles(centers); boxFinder.getAsymmetricHoles(centers);
break; break;
default: default:
CV_Error(CV_StsBadArg, "Unkown pattern type"); CV_Error(CV_StsBadArg, "Unkown pattern type");
} }
if (i != 0) if (i != 0)
{ {
@ -2027,7 +2026,7 @@ bool cv::findCirclesGrid( InputArray _image, Size patternSize,
Mat(centers).copyTo(_centers); Mat(centers).copyTo(_centers);
return true; return true;
} }
boxFinder.getHoles(centers); boxFinder.getHoles(centers);
if (i != attempts - 1) if (i != attempts - 1)
{ {

View File

@ -1153,7 +1153,7 @@ CV_IMPL void cvFindExtrinsicCameraParams2( const CvMat* objectPoints,
int useExtrinsicGuess ) int useExtrinsicGuess )
{ {
const int max_iter = 20; const int max_iter = 20;
Ptr<CvMat> matM, _Mxy, _m, _mn, matL, matJ; Ptr<CvMat> matM, _Mxy, _m, _mn, matL;
int i, count; int i, count;
double a[9], ar[9]={1,0,0,0,1,0,0,0,1}, R[9]; double a[9], ar[9]={1,0,0,0,1,0,0,0,1}, R[9];

View File

@ -55,12 +55,12 @@
# endif # endif
#endif #endif
void icvGetQuadrangleHypotheses(CvSeq* contours, std::vector<std::pair<float, int> >& quads, int class_id) static void icvGetQuadrangleHypotheses(CvSeq* contours, std::vector<std::pair<float, int> >& quads, int class_id)
{ {
const float min_aspect_ratio = 0.3f; const float min_aspect_ratio = 0.3f;
const float max_aspect_ratio = 3.0f; const float max_aspect_ratio = 3.0f;
const float min_box_size = 10.0f; const float min_box_size = 10.0f;
for(CvSeq* seq = contours; seq != NULL; seq = seq->h_next) for(CvSeq* seq = contours; seq != NULL; seq = seq->h_next)
{ {
CvBox2D box = cvMinAreaRect2(seq); CvBox2D box = cvMinAreaRect2(seq);
@ -75,12 +75,12 @@ void icvGetQuadrangleHypotheses(CvSeq* contours, std::vector<std::pair<float, in
{ {
continue; continue;
} }
quads.push_back(std::pair<float, int>(box_size, class_id)); quads.push_back(std::pair<float, int>(box_size, class_id));
} }
} }
void countClasses(const std::vector<std::pair<float, int> >& pairs, size_t idx1, size_t idx2, std::vector<int>& counts) static void countClasses(const std::vector<std::pair<float, int> >& pairs, size_t idx1, size_t idx2, std::vector<int>& counts)
{ {
counts.assign(2, 0); counts.assign(2, 0);
for(size_t i = idx1; i != idx2; i++) for(size_t i = idx1; i != idx2; i++)
@ -89,36 +89,36 @@ void countClasses(const std::vector<std::pair<float, int> >& pairs, size_t idx1,
} }
} }
bool less_pred(const std::pair<float, int>& p1, const std::pair<float, int>& p2) inline bool less_pred(const std::pair<float, int>& p1, const std::pair<float, int>& p2)
{ {
return p1.first < p2.first; return p1.first < p2.first;
} }
// does a fast check if a chessboard is in the input image. This is a workaround to // does a fast check if a chessboard is in the input image. This is a workaround to
// a problem of cvFindChessboardCorners being slow on images with no chessboard // a problem of cvFindChessboardCorners being slow on images with no chessboard
// - src: input image // - src: input image
// - size: chessboard size // - size: chessboard size
// Returns 1 if a chessboard can be in this image and findChessboardCorners should be called, // Returns 1 if a chessboard can be in this image and findChessboardCorners should be called,
// 0 if there is no chessboard, -1 in case of error // 0 if there is no chessboard, -1 in case of error
int cvCheckChessboard(IplImage* src, CvSize size) int cvCheckChessboard(IplImage* src, CvSize size)
{ {
if(src->nChannels > 1) if(src->nChannels > 1)
{ {
cvError(CV_BadNumChannels, "cvCheckChessboard", "supports single-channel images only", cvError(CV_BadNumChannels, "cvCheckChessboard", "supports single-channel images only",
__FILE__, __LINE__); __FILE__, __LINE__);
} }
if(src->depth != 8) if(src->depth != 8)
{ {
cvError(CV_BadDepth, "cvCheckChessboard", "supports depth=8 images only", cvError(CV_BadDepth, "cvCheckChessboard", "supports depth=8 images only",
__FILE__, __LINE__); __FILE__, __LINE__);
} }
const int erosion_count = 1; const int erosion_count = 1;
const float black_level = 20.f; const float black_level = 20.f;
const float white_level = 130.f; const float white_level = 130.f;
const float black_white_gap = 70.f; const float black_white_gap = 70.f;
#if defined(DEBUG_WINDOWS) #if defined(DEBUG_WINDOWS)
cvNamedWindow("1", 1); cvNamedWindow("1", 1);
cvShowImage("1", src); cvShowImage("1", src);
@ -126,46 +126,46 @@ int cvCheckChessboard(IplImage* src, CvSize size)
#endif //DEBUG_WINDOWS #endif //DEBUG_WINDOWS
CvMemStorage* storage = cvCreateMemStorage(); CvMemStorage* storage = cvCreateMemStorage();
IplImage* white = cvCloneImage(src); IplImage* white = cvCloneImage(src);
IplImage* black = cvCloneImage(src); IplImage* black = cvCloneImage(src);
cvErode(white, white, NULL, erosion_count); cvErode(white, white, NULL, erosion_count);
cvDilate(black, black, NULL, erosion_count); cvDilate(black, black, NULL, erosion_count);
IplImage* thresh = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); IplImage* thresh = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
int result = 0; int result = 0;
for(float thresh_level = black_level; thresh_level < white_level && !result; thresh_level += 20.0f) for(float thresh_level = black_level; thresh_level < white_level && !result; thresh_level += 20.0f)
{ {
cvThreshold(white, thresh, thresh_level + black_white_gap, 255, CV_THRESH_BINARY); cvThreshold(white, thresh, thresh_level + black_white_gap, 255, CV_THRESH_BINARY);
#if defined(DEBUG_WINDOWS) #if defined(DEBUG_WINDOWS)
cvShowImage("1", thresh); cvShowImage("1", thresh);
cvWaitKey(0); cvWaitKey(0);
#endif //DEBUG_WINDOWS #endif //DEBUG_WINDOWS
CvSeq* first = 0; CvSeq* first = 0;
std::vector<std::pair<float, int> > quads; std::vector<std::pair<float, int> > quads;
cvFindContours(thresh, storage, &first, sizeof(CvContour), CV_RETR_CCOMP); cvFindContours(thresh, storage, &first, sizeof(CvContour), CV_RETR_CCOMP);
icvGetQuadrangleHypotheses(first, quads, 1); icvGetQuadrangleHypotheses(first, quads, 1);
cvThreshold(black, thresh, thresh_level, 255, CV_THRESH_BINARY_INV); cvThreshold(black, thresh, thresh_level, 255, CV_THRESH_BINARY_INV);
#if defined(DEBUG_WINDOWS) #if defined(DEBUG_WINDOWS)
cvShowImage("1", thresh); cvShowImage("1", thresh);
cvWaitKey(0); cvWaitKey(0);
#endif //DEBUG_WINDOWS #endif //DEBUG_WINDOWS
cvFindContours(thresh, storage, &first, sizeof(CvContour), CV_RETR_CCOMP); cvFindContours(thresh, storage, &first, sizeof(CvContour), CV_RETR_CCOMP);
icvGetQuadrangleHypotheses(first, quads, 0); icvGetQuadrangleHypotheses(first, quads, 0);
const size_t min_quads_count = size.width*size.height/2; const size_t min_quads_count = size.width*size.height/2;
std::sort(quads.begin(), quads.end(), less_pred); std::sort(quads.begin(), quads.end(), less_pred);
// now check if there are many hypotheses with similar sizes // now check if there are many hypotheses with similar sizes
// do this by floodfill-style algorithm // do this by floodfill-style algorithm
const float size_rel_dev = 0.4f; const float size_rel_dev = 0.4f;
for(size_t i = 0; i < quads.size(); i++) for(size_t i = 0; i < quads.size(); i++)
{ {
size_t j = i + 1; size_t j = i + 1;
@ -176,7 +176,7 @@ int cvCheckChessboard(IplImage* src, CvSize size)
break; break;
} }
} }
if(j + 1 > min_quads_count + i) if(j + 1 > min_quads_count + i)
{ {
// check the number of black and white squares // check the number of black and white squares
@ -194,12 +194,12 @@ int cvCheckChessboard(IplImage* src, CvSize size)
} }
} }
} }
cvReleaseImage(&thresh); cvReleaseImage(&thresh);
cvReleaseImage(&white); cvReleaseImage(&white);
cvReleaseImage(&black); cvReleaseImage(&black);
cvReleaseMemStorage(&storage); cvReleaseMemStorage(&storage);
return result; return result;
} }

View File

@ -65,14 +65,14 @@ void drawPoints(const vector<Point2f> &points, Mat &outImage, int radius = 2, S
} }
#endif #endif
void CirclesGridClusterFinder::hierarchicalClustering(const vector<Point2f> points, const Size &patternSize, vector<Point2f> &patternPoints) void CirclesGridClusterFinder::hierarchicalClustering(const vector<Point2f> points, const Size &patternSz, vector<Point2f> &patternPoints)
{ {
#ifdef HAVE_TEGRA_OPTIMIZATION #ifdef HAVE_TEGRA_OPTIMIZATION
if(tegra::hierarchicalClustering(points, patternSize, patternPoints)) if(tegra::hierarchicalClustering(points, patternSz, patternPoints))
return; return;
#endif #endif
int i, j, n = (int)points.size(); int j, n = (int)points.size();
size_t pn = static_cast<size_t>(patternSize.area()); size_t pn = static_cast<size_t>(patternSz.area());
patternPoints.clear(); patternPoints.clear();
if (pn >= points.size()) if (pn >= points.size())
@ -84,7 +84,7 @@ void CirclesGridClusterFinder::hierarchicalClustering(const vector<Point2f> poin
Mat dists(n, n, CV_32FC1, Scalar(0)); Mat dists(n, n, CV_32FC1, Scalar(0));
Mat distsMask(dists.size(), CV_8UC1, Scalar(0)); Mat distsMask(dists.size(), CV_8UC1, Scalar(0));
for(i = 0; i < n; i++) for(int i = 0; i < n; i++)
{ {
for(j = i+1; j < n; j++) for(j = i+1; j < n; j++)
{ {
@ -122,7 +122,7 @@ void CirclesGridClusterFinder::hierarchicalClustering(const vector<Point2f> poin
} }
//the largest cluster can have more than pn points -- we need to filter out such situations //the largest cluster can have more than pn points -- we need to filter out such situations
if(clusters[patternClusterIdx].size() != static_cast<size_t>(patternSize.area())) if(clusters[patternClusterIdx].size() != static_cast<size_t>(patternSz.area()))
{ {
return; return;
} }
@ -505,11 +505,11 @@ void Graph::floydWarshall(cv::Mat &distanceMatrix, int infinity) const
{ {
for (Vertices::const_iterator it3 = vertices.begin(); it3 != vertices.end(); it3++) for (Vertices::const_iterator it3 = vertices.begin(); it3 != vertices.end(); it3++)
{ {
int i1 = (int)it1->first, i2 = (int)it2->first, i3 = (int)it3->first; int i1 = (int)it1->first, i2 = (int)it2->first, i3 = (int)it3->first;
int val1 = distanceMatrix.at<int> (i2, i3); int val1 = distanceMatrix.at<int> (i2, i3);
int val2; int val2;
if (distanceMatrix.at<int> (i2, i1) == infinity || if (distanceMatrix.at<int> (i2, i1) == infinity ||
distanceMatrix.at<int> (i1, i3) == infinity) distanceMatrix.at<int> (i1, i3) == infinity)
val2 = val1; val2 = val1;
else else
{ {
@ -1223,7 +1223,7 @@ void computePredecessorMatrix(const Mat &dm, int verticesCount, Mat &predecessor
} }
} }
void computeShortestPath(Mat &predecessorMatrix, size_t v1, size_t v2, vector<size_t> &path) static void computeShortestPath(Mat &predecessorMatrix, size_t v1, size_t v2, vector<size_t> &path)
{ {
if (predecessorMatrix.at<int> ((int)v1, (int)v2) < 0) if (predecessorMatrix.at<int> ((int)v1, (int)v2) < 0)
{ {
@ -1403,7 +1403,7 @@ void CirclesGridFinder::getHoles(vector<Point2f> &outHoles) const
} }
} }
bool areIndicesCorrect(Point pos, vector<vector<size_t> > *points) static bool areIndicesCorrect(Point pos, vector<vector<size_t> > *points)
{ {
if (pos.y < 0 || pos.x < 0) if (pos.y < 0 || pos.x < 0)
return false; return false;

View File

@ -8,26 +8,26 @@ epnp::epnp(const cv::Mat& cameraMatrix, const cv::Mat& opoints, const cv::Mat& i
if (cameraMatrix.depth() == CV_32F) if (cameraMatrix.depth() == CV_32F)
init_camera_parameters<float>(cameraMatrix); init_camera_parameters<float>(cameraMatrix);
else else
init_camera_parameters<double>(cameraMatrix); init_camera_parameters<double>(cameraMatrix);
number_of_correspondences = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F)); number_of_correspondences = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
pws.resize(3 * number_of_correspondences); pws.resize(3 * number_of_correspondences);
us.resize(2 * number_of_correspondences); us.resize(2 * number_of_correspondences);
if (opoints.depth() == ipoints.depth()) if (opoints.depth() == ipoints.depth())
{ {
if (opoints.depth() == CV_32F) if (opoints.depth() == CV_32F)
init_points<cv::Point3f,cv::Point2f>(opoints, ipoints); init_points<cv::Point3f,cv::Point2f>(opoints, ipoints);
else else
init_points<cv::Point3d,cv::Point2d>(opoints, ipoints); init_points<cv::Point3d,cv::Point2d>(opoints, ipoints);
} }
else if (opoints.depth() == CV_32F) else if (opoints.depth() == CV_32F)
init_points<cv::Point3f,cv::Point2d>(opoints, ipoints); init_points<cv::Point3f,cv::Point2d>(opoints, ipoints);
else else
init_points<cv::Point3d,cv::Point2f>(opoints, ipoints); init_points<cv::Point3d,cv::Point2f>(opoints, ipoints);
alphas.resize(4 * number_of_correspondences); alphas.resize(4 * number_of_correspondences);
pcs.resize(3 * number_of_correspondences); pcs.resize(3 * number_of_correspondences);
max_nr = 0; max_nr = 0;
@ -97,15 +97,15 @@ void epnp::compute_barycentric_coordinates(void)
for(int j = 0; j < 3; j++) for(int j = 0; j < 3; j++)
a[1 + j] = a[1 + j] =
ci[3 * j ] * (pi[0] - cws[0][0]) + ci[3 * j ] * (pi[0] - cws[0][0]) +
ci[3 * j + 1] * (pi[1] - cws[0][1]) + ci[3 * j + 1] * (pi[1] - cws[0][1]) +
ci[3 * j + 2] * (pi[2] - cws[0][2]); ci[3 * j + 2] * (pi[2] - cws[0][2]);
a[0] = 1.0f - a[1] - a[2] - a[3]; a[0] = 1.0f - a[1] - a[2] - a[3];
} }
} }
void epnp::fill_M(CvMat * M, void epnp::fill_M(CvMat * M,
const int row, const double * as, const double u, const double v) const int row, const double * as, const double u, const double v)
{ {
double * M1 = M->data.db + row * 12; double * M1 = M->data.db + row * 12;
double * M2 = M1 + 12; double * M2 = M1 + 12;
@ -130,7 +130,7 @@ void epnp::compute_ccs(const double * betas, const double * ut)
const double * v = ut + 12 * (11 - i); const double * v = ut + 12 * (11 - i);
for(int j = 0; j < 4; j++) for(int j = 0; j < 4; j++)
for(int k = 0; k < 3; k++) for(int k = 0; k < 3; k++)
ccs[j][k] += betas[i] * v[3 * j + k]; ccs[j][k] += betas[i] * v[3 * j + k];
} }
} }
@ -195,7 +195,7 @@ void epnp::compute_pose(cv::Mat& R, cv::Mat& t)
} }
void epnp::copy_R_and_t(const double R_src[3][3], const double t_src[3], void epnp::copy_R_and_t(const double R_src[3][3], const double t_src[3],
double R_dst[3][3], double t_dst[3]) double R_dst[3][3], double t_dst[3])
{ {
for(int i = 0; i < 3; i++) { for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) for(int j = 0; j < 3; j++)
@ -282,7 +282,7 @@ void epnp::solve_for_sign(void)
if (pcs[2] < 0.0) { if (pcs[2] < 0.0) {
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
for(int j = 0; j < 3; j++) for(int j = 0; j < 3; j++)
ccs[i][j] = -ccs[i][j]; ccs[i][j] = -ccs[i][j];
for(int i = 0; i < number_of_correspondences; i++) { for(int i = 0; i < number_of_correspondences; i++) {
pcs[3 * i ] = -pcs[3 * i]; pcs[3 * i ] = -pcs[3 * i];
@ -293,7 +293,7 @@ void epnp::solve_for_sign(void)
} }
double epnp::compute_R_and_t(const double * ut, const double * betas, double epnp::compute_R_and_t(const double * ut, const double * betas,
double R[3][3], double t[3]) double R[3][3], double t[3])
{ {
compute_ccs(betas, ut); compute_ccs(betas, ut);
compute_pcs(); compute_pcs();
@ -322,13 +322,13 @@ double epnp::reprojection_error(const double R[3][3], const double t[3])
} }
return sum2 / number_of_correspondences; return sum2 / number_of_correspondences;
} }
// betas10 = [B11 B12 B22 B13 B23 B33 B14 B24 B34 B44] // betas10 = [B11 B12 B22 B13 B23 B33 B14 B24 B34 B44]
// betas_approx_1 = [B11 B12 B13 B14] // betas_approx_1 = [B11 B12 B13 B14]
void epnp::find_betas_approx_1(const CvMat * L_6x10, const CvMat * Rho, void epnp::find_betas_approx_1(const CvMat * L_6x10, const CvMat * Rho,
double * betas) double * betas)
{ {
double l_6x4[6 * 4], b4[4]; double l_6x4[6 * 4], b4[4];
CvMat L_6x4 = cvMat(6, 4, CV_64F, l_6x4); CvMat L_6x4 = cvMat(6, 4, CV_64F, l_6x4);
@ -360,7 +360,7 @@ void epnp::find_betas_approx_1(const CvMat * L_6x10, const CvMat * Rho,
// betas_approx_2 = [B11 B12 B22 ] // betas_approx_2 = [B11 B12 B22 ]
void epnp::find_betas_approx_2(const CvMat * L_6x10, const CvMat * Rho, void epnp::find_betas_approx_2(const CvMat * L_6x10, const CvMat * Rho,
double * betas) double * betas)
{ {
double l_6x3[6 * 3], b3[3]; double l_6x3[6 * 3], b3[3];
CvMat L_6x3 = cvMat(6, 3, CV_64F, l_6x3); CvMat L_6x3 = cvMat(6, 3, CV_64F, l_6x3);
@ -392,7 +392,7 @@ void epnp::find_betas_approx_2(const CvMat * L_6x10, const CvMat * Rho,
// betas_approx_3 = [B11 B12 B22 B13 B23 ] // betas_approx_3 = [B11 B12 B22 B13 B23 ]
void epnp::find_betas_approx_3(const CvMat * L_6x10, const CvMat * Rho, void epnp::find_betas_approx_3(const CvMat * L_6x10, const CvMat * Rho,
double * betas) double * betas)
{ {
double l_6x5[6 * 5], b5[5]; double l_6x5[6 * 5], b5[5];
CvMat L_6x5 = cvMat(6, 5, CV_64F, l_6x5); CvMat L_6x5 = cvMat(6, 5, CV_64F, l_6x5);
@ -440,8 +440,8 @@ void epnp::compute_L_6x10(const double * ut, double * l_6x10)
b++; b++;
if (b > 3) { if (b > 3) {
a++; a++;
b = a + 1; b = a + 1;
} }
} }
} }
@ -473,7 +473,7 @@ void epnp::compute_rho(double * rho)
} }
void epnp::compute_A_and_b_gauss_newton(const double * l_6x10, const double * rho, void epnp::compute_A_and_b_gauss_newton(const double * l_6x10, const double * rho,
const double betas[4], CvMat * A, CvMat * b) const double betas[4], CvMat * A, CvMat * b)
{ {
for(int i = 0; i < 6; i++) { for(int i = 0; i < 6; i++) {
const double * rowL = l_6x10 + i * 10; const double * rowL = l_6x10 + i * 10;
@ -485,23 +485,22 @@ void epnp::compute_A_and_b_gauss_newton(const double * l_6x10, const double * rh
rowA[3] = rowL[6] * betas[0] + rowL[7] * betas[1] + rowL[8] * betas[2] + 2 * rowL[9] * betas[3]; rowA[3] = rowL[6] * betas[0] + rowL[7] * betas[1] + rowL[8] * betas[2] + 2 * rowL[9] * betas[3];
cvmSet(b, i, 0, rho[i] - cvmSet(b, i, 0, rho[i] -
( (
rowL[0] * betas[0] * betas[0] + rowL[0] * betas[0] * betas[0] +
rowL[1] * betas[0] * betas[1] + rowL[1] * betas[0] * betas[1] +
rowL[2] * betas[1] * betas[1] + rowL[2] * betas[1] * betas[1] +
rowL[3] * betas[0] * betas[2] + rowL[3] * betas[0] * betas[2] +
rowL[4] * betas[1] * betas[2] + rowL[4] * betas[1] * betas[2] +
rowL[5] * betas[2] * betas[2] + rowL[5] * betas[2] * betas[2] +
rowL[6] * betas[0] * betas[3] + rowL[6] * betas[0] * betas[3] +
rowL[7] * betas[1] * betas[3] + rowL[7] * betas[1] * betas[3] +
rowL[8] * betas[2] * betas[3] + rowL[8] * betas[2] * betas[3] +
rowL[9] * betas[3] * betas[3] rowL[9] * betas[3] * betas[3]
)); ));
} }
} }
void epnp::gauss_newton(const CvMat * L_6x10, const CvMat * Rho, void epnp::gauss_newton(const CvMat * L_6x10, const CvMat * Rho, double betas[4])
double betas[4])
{ {
const int iterations_number = 5; const int iterations_number = 5;
@ -510,12 +509,13 @@ void epnp::gauss_newton(const CvMat * L_6x10, const CvMat * Rho,
CvMat B = cvMat(6, 1, CV_64F, b); CvMat B = cvMat(6, 1, CV_64F, b);
CvMat X = cvMat(4, 1, CV_64F, x); CvMat X = cvMat(4, 1, CV_64F, x);
for(int k = 0; k < iterations_number; k++) { for(int k = 0; k < iterations_number; k++)
{
compute_A_and_b_gauss_newton(L_6x10->data.db, Rho->data.db, compute_A_and_b_gauss_newton(L_6x10->data.db, Rho->data.db,
betas, &A, &B); betas, &A, &B);
qr_solve(&A, &B, &X); qr_solve(&A, &B, &X);
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
betas[i] += x[i]; betas[i] += x[i];
} }
} }
@ -524,53 +524,64 @@ void epnp::qr_solve(CvMat * A, CvMat * b, CvMat * X)
const int nr = A->rows; const int nr = A->rows;
const int nc = A->cols; const int nc = A->cols;
if (max_nr != 0 && max_nr < nr) { if (max_nr != 0 && max_nr < nr)
{
delete [] A1; delete [] A1;
delete [] A2; delete [] A2;
} }
if (max_nr < nr) { if (max_nr < nr)
{
max_nr = nr; max_nr = nr;
A1 = new double[nr]; A1 = new double[nr];
A2 = new double[nr]; A2 = new double[nr];
} }
double * pA = A->data.db, * ppAkk = pA; double * pA = A->data.db, * ppAkk = pA;
for(int k = 0; k < nc; k++) { for(int k = 0; k < nc; k++)
double * ppAik = ppAkk, eta = fabs(*ppAik); {
for(int i = k + 1; i < nr; i++) { double * ppAik1 = ppAkk, eta = fabs(*ppAik1);
double elt = fabs(*ppAik); for(int i = k + 1; i < nr; i++)
{
double elt = fabs(*ppAik1);
if (eta < elt) eta = elt; if (eta < elt) eta = elt;
ppAik += nc; ppAik1 += nc;
} }
if (eta == 0) { if (eta == 0)
{
A1[k] = A2[k] = 0.0; A1[k] = A2[k] = 0.0;
//cerr << "God damnit, A is singular, this shouldn't happen." << endl; //cerr << "God damnit, A is singular, this shouldn't happen." << endl;
return; return;
} else { }
double * ppAik = ppAkk, sum = 0.0, inv_eta = 1. / eta; else
for(int i = k; i < nr; i++) { {
*ppAik *= inv_eta; double * ppAik2 = ppAkk, sum2 = 0.0, inv_eta = 1. / eta;
sum += *ppAik * *ppAik; for(int i = k; i < nr; i++)
ppAik += nc; {
*ppAik2 *= inv_eta;
sum2 += *ppAik2 * *ppAik2;
ppAik2 += nc;
} }
double sigma = sqrt(sum); double sigma = sqrt(sum2);
if (*ppAkk < 0) if (*ppAkk < 0)
sigma = -sigma; sigma = -sigma;
*ppAkk += sigma; *ppAkk += sigma;
A1[k] = sigma * *ppAkk; A1[k] = sigma * *ppAkk;
A2[k] = -eta * sigma; A2[k] = -eta * sigma;
for(int j = k + 1; j < nc; j++) { for(int j = k + 1; j < nc; j++)
double * ppAik = ppAkk, sum = 0; {
for(int i = k; i < nr; i++) { double * ppAik = ppAkk, sum = 0;
sum += *ppAik * ppAik[j - k]; for(int i = k; i < nr; i++)
ppAik += nc; {
} sum += *ppAik * ppAik[j - k];
double tau = sum / A1[k]; ppAik += nc;
ppAik = ppAkk; }
for(int i = k; i < nr; i++) { double tau = sum / A1[k];
ppAik[j - k] -= tau * *ppAik; ppAik = ppAkk;
ppAik += nc; for(int i = k; i < nr; i++)
} {
ppAik[j - k] -= tau * *ppAik;
ppAik += nc;
}
} }
} }
ppAkk += nc + 1; ppAkk += nc + 1;
@ -578,15 +589,18 @@ void epnp::qr_solve(CvMat * A, CvMat * b, CvMat * X)
// b <- Qt b // b <- Qt b
double * ppAjj = pA, * pb = b->data.db; double * ppAjj = pA, * pb = b->data.db;
for(int j = 0; j < nc; j++) { for(int j = 0; j < nc; j++)
{
double * ppAij = ppAjj, tau = 0; double * ppAij = ppAjj, tau = 0;
for(int i = j; i < nr; i++) { for(int i = j; i < nr; i++)
{
tau += *ppAij * pb[i]; tau += *ppAij * pb[i];
ppAij += nc; ppAij += nc;
} }
tau /= A1[j]; tau /= A1[j];
ppAij = ppAjj; ppAij = ppAjj;
for(int i = j; i < nr; i++) { for(int i = j; i < nr; i++)
{
pb[i] -= tau * *ppAij; pb[i] -= tau * *ppAij;
ppAij += nc; ppAij += nc;
} }
@ -596,10 +610,12 @@ void epnp::qr_solve(CvMat * A, CvMat * b, CvMat * X)
// X = R-1 b // X = R-1 b
double * pX = X->data.db; double * pX = X->data.db;
pX[nc - 1] = pb[nc - 1] / A2[nc - 1]; pX[nc - 1] = pb[nc - 1] / A2[nc - 1];
for(int i = nc - 2; i >= 0; i--) { for(int i = nc - 2; i >= 0; i--)
{
double * ppAij = pA + i * nc + (i + 1), sum = 0; double * ppAij = pA + i * nc + (i + 1), sum = 0;
for(int j = i + 1; j < nc; j++) { for(int j = i + 1; j < nc; j++)
{
sum += *ppAij * pX[j]; sum += *ppAij * pX[j];
ppAij++; ppAij++;
} }

View File

@ -9,151 +9,151 @@ using namespace std;
void p3p::init_inverse_parameters() void p3p::init_inverse_parameters()
{ {
inv_fx = 1. / fx; inv_fx = 1. / fx;
inv_fy = 1. / fy; inv_fy = 1. / fy;
cx_fx = cx / fx; cx_fx = cx / fx;
cy_fy = cy / fy; cy_fy = cy / fy;
} }
p3p::p3p(cv::Mat cameraMatrix) p3p::p3p(cv::Mat cameraMatrix)
{ {
if (cameraMatrix.depth() == CV_32F) if (cameraMatrix.depth() == CV_32F)
init_camera_parameters<float>(cameraMatrix); init_camera_parameters<float>(cameraMatrix);
else else
init_camera_parameters<double>(cameraMatrix); init_camera_parameters<double>(cameraMatrix);
init_inverse_parameters(); init_inverse_parameters();
} }
p3p::p3p(double _fx, double _fy, double _cx, double _cy) p3p::p3p(double _fx, double _fy, double _cx, double _cy)
{ {
fx = _fx; fx = _fx;
fy = _fy; fy = _fy;
cx = _cx; cx = _cx;
cy = _cy; cy = _cy;
init_inverse_parameters(); init_inverse_parameters();
} }
bool p3p::solve(cv::Mat& R, cv::Mat& tvec, const cv::Mat& opoints, const cv::Mat& ipoints) bool p3p::solve(cv::Mat& R, cv::Mat& tvec, const cv::Mat& opoints, const cv::Mat& ipoints)
{ {
double rotation_matrix[3][3], translation[3]; double rotation_matrix[3][3], translation[3];
std::vector<double> points; std::vector<double> points;
if (opoints.depth() == ipoints.depth()) if (opoints.depth() == ipoints.depth())
{ {
if (opoints.depth() == CV_32F) if (opoints.depth() == CV_32F)
extract_points<cv::Point3f,cv::Point2f>(opoints, ipoints, points); extract_points<cv::Point3f,cv::Point2f>(opoints, ipoints, points);
else else
extract_points<cv::Point3d,cv::Point2d>(opoints, ipoints, points); extract_points<cv::Point3d,cv::Point2d>(opoints, ipoints, points);
} }
else if (opoints.depth() == CV_32F) else if (opoints.depth() == CV_32F)
extract_points<cv::Point3f,cv::Point2d>(opoints, ipoints, points); extract_points<cv::Point3f,cv::Point2d>(opoints, ipoints, points);
else else
extract_points<cv::Point3d,cv::Point2f>(opoints, ipoints, points); extract_points<cv::Point3d,cv::Point2f>(opoints, ipoints, points);
bool result = solve(rotation_matrix, translation, points[0], points[1], points[2], points[3], points[4], points[5], bool result = solve(rotation_matrix, translation, points[0], points[1], points[2], points[3], points[4], points[5],
points[6], points[7], points[8], points[9], points[10], points[11], points[12], points[13], points[14], points[6], points[7], points[8], points[9], points[10], points[11], points[12], points[13], points[14],
points[15], points[16], points[17], points[18], points[19]); points[15], points[16], points[17], points[18], points[19]);
cv::Mat(3, 1, CV_64F, translation).copyTo(tvec); cv::Mat(3, 1, CV_64F, translation).copyTo(tvec);
cv::Mat(3, 3, CV_64F, rotation_matrix).copyTo(R); cv::Mat(3, 3, CV_64F, rotation_matrix).copyTo(R);
return result; return result;
} }
bool p3p::solve(double R[3][3], double t[3], bool p3p::solve(double R[3][3], double t[3],
double mu0, double mv0, double X0, double Y0, double Z0, double mu0, double mv0, double X0, double Y0, double Z0,
double mu1, double mv1, double X1, double Y1, double Z1, double mu1, double mv1, double X1, double Y1, double Z1,
double mu2, double mv2, double X2, double Y2, double Z2, double mu2, double mv2, double X2, double Y2, double Z2,
double mu3, double mv3, double X3, double Y3, double Z3) double mu3, double mv3, double X3, double Y3, double Z3)
{ {
double Rs[4][3][3], ts[4][3]; double Rs[4][3][3], ts[4][3];
int n = solve(Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2, Z2); int n = solve(Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2, Z2);
if (n == 0) if (n == 0)
return false; return false;
int ns = 0; int ns = 0;
double min_reproj = 0; double min_reproj = 0;
for(int i = 0; i < n; i++) { for(int i = 0; i < n; i++) {
double X3p = Rs[i][0][0] * X3 + Rs[i][0][1] * Y3 + Rs[i][0][2] * Z3 + ts[i][0]; double X3p = Rs[i][0][0] * X3 + Rs[i][0][1] * Y3 + Rs[i][0][2] * Z3 + ts[i][0];
double Y3p = Rs[i][1][0] * X3 + Rs[i][1][1] * Y3 + Rs[i][1][2] * Z3 + ts[i][1]; double Y3p = Rs[i][1][0] * X3 + Rs[i][1][1] * Y3 + Rs[i][1][2] * Z3 + ts[i][1];
double Z3p = Rs[i][2][0] * X3 + Rs[i][2][1] * Y3 + Rs[i][2][2] * Z3 + ts[i][2]; double Z3p = Rs[i][2][0] * X3 + Rs[i][2][1] * Y3 + Rs[i][2][2] * Z3 + ts[i][2];
double mu3p = cx + fx * X3p / Z3p; double mu3p = cx + fx * X3p / Z3p;
double mv3p = cy + fy * Y3p / Z3p; double mv3p = cy + fy * Y3p / Z3p;
double reproj = (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3); double reproj = (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3);
if (i == 0 || min_reproj > reproj) { if (i == 0 || min_reproj > reproj) {
ns = i; ns = i;
min_reproj = reproj; min_reproj = reproj;
} }
} }
for(int i = 0; i < 3; i++) { for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) for(int j = 0; j < 3; j++)
R[i][j] = Rs[ns][i][j]; R[i][j] = Rs[ns][i][j];
t[i] = ts[ns][i]; t[i] = ts[ns][i];
} }
return true; return true;
} }
int p3p::solve(double R[4][3][3], double t[4][3], int p3p::solve(double R[4][3][3], double t[4][3],
double mu0, double mv0, double X0, double Y0, double Z0, double mu0, double mv0, double X0, double Y0, double Z0,
double mu1, double mv1, double X1, double Y1, double Z1, double mu1, double mv1, double X1, double Y1, double Z1,
double mu2, double mv2, double X2, double Y2, double Z2) double mu2, double mv2, double X2, double Y2, double Z2)
{ {
double mk0, mk1, mk2; double mk0, mk1, mk2;
double norm; double norm;
mu0 = inv_fx * mu0 - cx_fx; mu0 = inv_fx * mu0 - cx_fx;
mv0 = inv_fy * mv0 - cy_fy; mv0 = inv_fy * mv0 - cy_fy;
norm = sqrt(mu0 * mu0 + mv0 * mv0 + 1); norm = sqrt(mu0 * mu0 + mv0 * mv0 + 1);
mk0 = 1. / norm; mu0 *= mk0; mv0 *= mk0; mk0 = 1. / norm; mu0 *= mk0; mv0 *= mk0;
mu1 = inv_fx * mu1 - cx_fx; mu1 = inv_fx * mu1 - cx_fx;
mv1 = inv_fy * mv1 - cy_fy; mv1 = inv_fy * mv1 - cy_fy;
norm = sqrt(mu1 * mu1 + mv1 * mv1 + 1); norm = sqrt(mu1 * mu1 + mv1 * mv1 + 1);
mk1 = 1. / norm; mu1 *= mk1; mv1 *= mk1; mk1 = 1. / norm; mu1 *= mk1; mv1 *= mk1;
mu2 = inv_fx * mu2 - cx_fx; mu2 = inv_fx * mu2 - cx_fx;
mv2 = inv_fy * mv2 - cy_fy; mv2 = inv_fy * mv2 - cy_fy;
norm = sqrt(mu2 * mu2 + mv2 * mv2 + 1); norm = sqrt(mu2 * mu2 + mv2 * mv2 + 1);
mk2 = 1. / norm; mu2 *= mk2; mv2 *= mk2; mk2 = 1. / norm; mu2 *= mk2; mv2 *= mk2;
double distances[3]; double distances[3];
distances[0] = sqrt( (X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) + (Z1 - Z2) * (Z1 - Z2) ); distances[0] = sqrt( (X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) + (Z1 - Z2) * (Z1 - Z2) );
distances[1] = sqrt( (X0 - X2) * (X0 - X2) + (Y0 - Y2) * (Y0 - Y2) + (Z0 - Z2) * (Z0 - Z2) ); distances[1] = sqrt( (X0 - X2) * (X0 - X2) + (Y0 - Y2) * (Y0 - Y2) + (Z0 - Z2) * (Z0 - Z2) );
distances[2] = sqrt( (X0 - X1) * (X0 - X1) + (Y0 - Y1) * (Y0 - Y1) + (Z0 - Z1) * (Z0 - Z1) ); distances[2] = sqrt( (X0 - X1) * (X0 - X1) + (Y0 - Y1) * (Y0 - Y1) + (Z0 - Z1) * (Z0 - Z1) );
// Calculate angles // Calculate angles
double cosines[3]; double cosines[3];
cosines[0] = mu1 * mu2 + mv1 * mv2 + mk1 * mk2; cosines[0] = mu1 * mu2 + mv1 * mv2 + mk1 * mk2;
cosines[1] = mu0 * mu2 + mv0 * mv2 + mk0 * mk2; cosines[1] = mu0 * mu2 + mv0 * mv2 + mk0 * mk2;
cosines[2] = mu0 * mu1 + mv0 * mv1 + mk0 * mk1; cosines[2] = mu0 * mu1 + mv0 * mv1 + mk0 * mk1;
double lengths[4][3]; double lengths[4][3];
int n = solve_for_lengths(lengths, distances, cosines); int n = solve_for_lengths(lengths, distances, cosines);
int nb_solutions = 0; int nb_solutions = 0;
for(int i = 0; i < n; i++) { for(int i = 0; i < n; i++) {
double M_orig[3][3]; double M_orig[3][3];
M_orig[0][0] = lengths[i][0] * mu0; M_orig[0][0] = lengths[i][0] * mu0;
M_orig[0][1] = lengths[i][0] * mv0; M_orig[0][1] = lengths[i][0] * mv0;
M_orig[0][2] = lengths[i][0] * mk0; M_orig[0][2] = lengths[i][0] * mk0;
M_orig[1][0] = lengths[i][1] * mu1; M_orig[1][0] = lengths[i][1] * mu1;
M_orig[1][1] = lengths[i][1] * mv1; M_orig[1][1] = lengths[i][1] * mv1;
M_orig[1][2] = lengths[i][1] * mk1; M_orig[1][2] = lengths[i][1] * mk1;
M_orig[2][0] = lengths[i][2] * mu2; M_orig[2][0] = lengths[i][2] * mu2;
M_orig[2][1] = lengths[i][2] * mv2; M_orig[2][1] = lengths[i][2] * mv2;
M_orig[2][2] = lengths[i][2] * mk2; M_orig[2][2] = lengths[i][2] * mk2;
if (!align(M_orig, X0, Y0, Z0, X1, Y1, Z1, X2, Y2, Z2, R[nb_solutions], t[nb_solutions])) if (!align(M_orig, X0, Y0, Z0, X1, Y1, Z1, X2, Y2, Z2, R[nb_solutions], t[nb_solutions]))
continue; continue;
nb_solutions++; nb_solutions++;
} }
return nb_solutions; return nb_solutions;
} }
/// Given 3D distances between three points and cosines of 3 angles at the apex, calculates /// Given 3D distances between three points and cosines of 3 angles at the apex, calculates
@ -170,247 +170,247 @@ int p3p::solve(double R[4][3][3], double t[4][3],
int p3p::solve_for_lengths(double lengths[4][3], double distances[3], double cosines[3]) int p3p::solve_for_lengths(double lengths[4][3], double distances[3], double cosines[3])
{ {
double p = cosines[0] * 2; double p = cosines[0] * 2;
double q = cosines[1] * 2; double q = cosines[1] * 2;
double r = cosines[2] * 2; double r = cosines[2] * 2;
double inv_d22 = 1. / (distances[2] * distances[2]); double inv_d22 = 1. / (distances[2] * distances[2]);
double a = inv_d22 * (distances[0] * distances[0]); double a = inv_d22 * (distances[0] * distances[0]);
double b = inv_d22 * (distances[1] * distances[1]); double b = inv_d22 * (distances[1] * distances[1]);
double a2 = a * a, b2 = b * b, p2 = p * p, q2 = q * q, r2 = r * r; double a2 = a * a, b2 = b * b, p2 = p * p, q2 = q * q, r2 = r * r;
double pr = p * r, pqr = q * pr; double pr = p * r, pqr = q * pr;
// Check reality condition (the four points should not be coplanar) // Check reality condition (the four points should not be coplanar)
if (p2 + q2 + r2 - pqr - 1 == 0) if (p2 + q2 + r2 - pqr - 1 == 0)
return 0; return 0;
double ab = a * b, a_2 = 2*a; double ab = a * b, a_2 = 2*a;
double A = -2 * b + b2 + a2 + 1 + ab*(2 - r2) - a_2; double A = -2 * b + b2 + a2 + 1 + ab*(2 - r2) - a_2;
// Check reality condition // Check reality condition
if (A == 0) return 0; if (A == 0) return 0;
double a_4 = 4*a; double a_4 = 4*a;
double B = q*(-2*(ab + a2 + 1 - b) + r2*ab + a_4) + pr*(b - b2 + ab); double B = q*(-2*(ab + a2 + 1 - b) + r2*ab + a_4) + pr*(b - b2 + ab);
double C = q2 + b2*(r2 + p2 - 2) - b*(p2 + pqr) - ab*(r2 + pqr) + (a2 - a_2)*(2 + q2) + 2; double C = q2 + b2*(r2 + p2 - 2) - b*(p2 + pqr) - ab*(r2 + pqr) + (a2 - a_2)*(2 + q2) + 2;
double D = pr*(ab-b2+b) + q*((p2-2)*b + 2 * (ab - a2) + a_4 - 2); double D = pr*(ab-b2+b) + q*((p2-2)*b + 2 * (ab - a2) + a_4 - 2);
double E = 1 + 2*(b - a - ab) + b2 - b*p2 + a2; double E = 1 + 2*(b - a - ab) + b2 - b*p2 + a2;
double temp = (p2*(a-1+b) + r2*(a-1-b) + pqr - a*pqr); double temp = (p2*(a-1+b) + r2*(a-1-b) + pqr - a*pqr);
double b0 = b * temp * temp; double b0 = b * temp * temp;
// Check reality condition // Check reality condition
if (b0 == 0) if (b0 == 0)
return 0; return 0;
double real_roots[4]; double real_roots[4];
int n = solve_deg4(A, B, C, D, E, real_roots[0], real_roots[1], real_roots[2], real_roots[3]); int n = solve_deg4(A, B, C, D, E, real_roots[0], real_roots[1], real_roots[2], real_roots[3]);
if (n == 0) if (n == 0)
return 0; return 0;
int nb_solutions = 0; int nb_solutions = 0;
double r3 = r2*r, pr2 = p*r2, r3q = r3 * q; double r3 = r2*r, pr2 = p*r2, r3q = r3 * q;
double inv_b0 = 1. / b0; double inv_b0 = 1. / b0;
// For each solution of x // For each solution of x
for(int i = 0; i < n; i++) { for(int i = 0; i < n; i++) {
double x = real_roots[i]; double x = real_roots[i];
// Check reality condition // Check reality condition
if (x <= 0) if (x <= 0)
continue; continue;
double x2 = x*x; double x2 = x*x;
double b1 = double b1 =
((1-a-b)*x2 + (q*a-q)*x + 1 - a + b) * ((1-a-b)*x2 + (q*a-q)*x + 1 - a + b) *
(((r3*(a2 + ab*(2 - r2) - a_2 + b2 - 2*b + 1)) * x + (((r3*(a2 + ab*(2 - r2) - a_2 + b2 - 2*b + 1)) * x +
(r3q*(2*(b-a2) + a_4 + ab*(r2 - 2) - 2) + pr2*(1 + a2 + 2*(ab-a-b) + r2*(b - b2) + b2))) * x2 + (r3q*(2*(b-a2) + a_4 + ab*(r2 - 2) - 2) + pr2*(1 + a2 + 2*(ab-a-b) + r2*(b - b2) + b2))) * x2 +
(r3*(q2*(1-2*a+a2) + r2*(b2-ab) - a_4 + 2*(a2 - b2) + 2) + r*p2*(b2 + 2*(ab - b - a) + 1 + a2) + pr2*q*(a_4 + 2*(b - ab - a2) - 2 - r2*b)) * x + (r3*(q2*(1-2*a+a2) + r2*(b2-ab) - a_4 + 2*(a2 - b2) + 2) + r*p2*(b2 + 2*(ab - b - a) + 1 + a2) + pr2*q*(a_4 + 2*(b - ab - a2) - 2 - r2*b)) * x +
2*r3q*(a_2 - b - a2 + ab - 1) + pr2*(q2 - a_4 + 2*(a2 - b2) + r2*b + q2*(a2 - a_2) + 2) + 2*r3q*(a_2 - b - a2 + ab - 1) + pr2*(q2 - a_4 + 2*(a2 - b2) + r2*b + q2*(a2 - a_2) + 2) +
p2*(p*(2*(ab - a - b) + a2 + b2 + 1) + 2*q*r*(b + a_2 - a2 - ab - 1))); p2*(p*(2*(ab - a - b) + a2 + b2 + 1) + 2*q*r*(b + a_2 - a2 - ab - 1)));
// Check reality condition // Check reality condition
if (b1 <= 0) if (b1 <= 0)
continue; continue;
double y = inv_b0 * b1; double y = inv_b0 * b1;
double v = x2 + y*y - x*y*r; double v = x2 + y*y - x*y*r;
if (v <= 0) if (v <= 0)
continue; continue;
double Z = distances[2] / sqrt(v); double Z = distances[2] / sqrt(v);
double X = x * Z; double X = x * Z;
double Y = y * Z; double Y = y * Z;
lengths[nb_solutions][0] = X; lengths[nb_solutions][0] = X;
lengths[nb_solutions][1] = Y; lengths[nb_solutions][1] = Y;
lengths[nb_solutions][2] = Z; lengths[nb_solutions][2] = Z;
nb_solutions++; nb_solutions++;
} }
return nb_solutions; return nb_solutions;
} }
bool p3p::align(double M_end[3][3], bool p3p::align(double M_end[3][3],
double X0, double Y0, double Z0, double X0, double Y0, double Z0,
double X1, double Y1, double Z1, double X1, double Y1, double Z1,
double X2, double Y2, double Z2, double X2, double Y2, double Z2,
double R[3][3], double T[3]) double R[3][3], double T[3])
{ {
// Centroids: // Centroids:
double C_start[3], C_end[3]; double C_start[3], C_end[3];
for(int i = 0; i < 3; i++) C_end[i] = (M_end[0][i] + M_end[1][i] + M_end[2][i]) / 3; for(int i = 0; i < 3; i++) C_end[i] = (M_end[0][i] + M_end[1][i] + M_end[2][i]) / 3;
C_start[0] = (X0 + X1 + X2) / 3; C_start[0] = (X0 + X1 + X2) / 3;
C_start[1] = (Y0 + Y1 + Y2) / 3; C_start[1] = (Y0 + Y1 + Y2) / 3;
C_start[2] = (Z0 + Z1 + Z2) / 3; C_start[2] = (Z0 + Z1 + Z2) / 3;
// Covariance matrix s: // Covariance matrix s:
double s[3 * 3]; double s[3 * 3];
for(int j = 0; j < 3; j++) { for(int j = 0; j < 3; j++) {
s[0 * 3 + j] = (X0 * M_end[0][j] + X1 * M_end[1][j] + X2 * M_end[2][j]) / 3 - C_end[j] * C_start[0]; s[0 * 3 + j] = (X0 * M_end[0][j] + X1 * M_end[1][j] + X2 * M_end[2][j]) / 3 - C_end[j] * C_start[0];
s[1 * 3 + j] = (Y0 * M_end[0][j] + Y1 * M_end[1][j] + Y2 * M_end[2][j]) / 3 - C_end[j] * C_start[1]; s[1 * 3 + j] = (Y0 * M_end[0][j] + Y1 * M_end[1][j] + Y2 * M_end[2][j]) / 3 - C_end[j] * C_start[1];
s[2 * 3 + j] = (Z0 * M_end[0][j] + Z1 * M_end[1][j] + Z2 * M_end[2][j]) / 3 - C_end[j] * C_start[2]; s[2 * 3 + j] = (Z0 * M_end[0][j] + Z1 * M_end[1][j] + Z2 * M_end[2][j]) / 3 - C_end[j] * C_start[2];
} }
double Qs[16], evs[4], U[16]; double Qs[16], evs[4], U[16];
Qs[0 * 4 + 0] = s[0 * 3 + 0] + s[1 * 3 + 1] + s[2 * 3 + 2]; Qs[0 * 4 + 0] = s[0 * 3 + 0] + s[1 * 3 + 1] + s[2 * 3 + 2];
Qs[1 * 4 + 1] = s[0 * 3 + 0] - s[1 * 3 + 1] - s[2 * 3 + 2]; Qs[1 * 4 + 1] = s[0 * 3 + 0] - s[1 * 3 + 1] - s[2 * 3 + 2];
Qs[2 * 4 + 2] = s[1 * 3 + 1] - s[2 * 3 + 2] - s[0 * 3 + 0]; Qs[2 * 4 + 2] = s[1 * 3 + 1] - s[2 * 3 + 2] - s[0 * 3 + 0];
Qs[3 * 4 + 3] = s[2 * 3 + 2] - s[0 * 3 + 0] - s[1 * 3 + 1]; Qs[3 * 4 + 3] = s[2 * 3 + 2] - s[0 * 3 + 0] - s[1 * 3 + 1];
Qs[1 * 4 + 0] = Qs[0 * 4 + 1] = s[1 * 3 + 2] - s[2 * 3 + 1]; Qs[1 * 4 + 0] = Qs[0 * 4 + 1] = s[1 * 3 + 2] - s[2 * 3 + 1];
Qs[2 * 4 + 0] = Qs[0 * 4 + 2] = s[2 * 3 + 0] - s[0 * 3 + 2]; Qs[2 * 4 + 0] = Qs[0 * 4 + 2] = s[2 * 3 + 0] - s[0 * 3 + 2];
Qs[3 * 4 + 0] = Qs[0 * 4 + 3] = s[0 * 3 + 1] - s[1 * 3 + 0]; Qs[3 * 4 + 0] = Qs[0 * 4 + 3] = s[0 * 3 + 1] - s[1 * 3 + 0];
Qs[2 * 4 + 1] = Qs[1 * 4 + 2] = s[1 * 3 + 0] + s[0 * 3 + 1]; Qs[2 * 4 + 1] = Qs[1 * 4 + 2] = s[1 * 3 + 0] + s[0 * 3 + 1];
Qs[3 * 4 + 1] = Qs[1 * 4 + 3] = s[2 * 3 + 0] + s[0 * 3 + 2]; Qs[3 * 4 + 1] = Qs[1 * 4 + 3] = s[2 * 3 + 0] + s[0 * 3 + 2];
Qs[3 * 4 + 2] = Qs[2 * 4 + 3] = s[2 * 3 + 1] + s[1 * 3 + 2]; Qs[3 * 4 + 2] = Qs[2 * 4 + 3] = s[2 * 3 + 1] + s[1 * 3 + 2];
jacobi_4x4(Qs, evs, U); jacobi_4x4(Qs, evs, U);
// Looking for the largest eigen value: // Looking for the largest eigen value:
int i_ev = 0; int i_ev = 0;
double ev_max = evs[i_ev]; double ev_max = evs[i_ev];
for(int i = 1; i < 4; i++) for(int i = 1; i < 4; i++)
if (evs[i] > ev_max) if (evs[i] > ev_max)
ev_max = evs[i_ev = i]; ev_max = evs[i_ev = i];
// Quaternion: // Quaternion:
double q[4]; double q[4];
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
q[i] = U[i * 4 + i_ev]; q[i] = U[i * 4 + i_ev];
double q02 = q[0] * q[0], q12 = q[1] * q[1], q22 = q[2] * q[2], q32 = q[3] * q[3]; double q02 = q[0] * q[0], q12 = q[1] * q[1], q22 = q[2] * q[2], q32 = q[3] * q[3];
double q0_1 = q[0] * q[1], q0_2 = q[0] * q[2], q0_3 = q[0] * q[3]; double q0_1 = q[0] * q[1], q0_2 = q[0] * q[2], q0_3 = q[0] * q[3];
double q1_2 = q[1] * q[2], q1_3 = q[1] * q[3]; double q1_2 = q[1] * q[2], q1_3 = q[1] * q[3];
double q2_3 = q[2] * q[3]; double q2_3 = q[2] * q[3];
R[0][0] = q02 + q12 - q22 - q32; R[0][0] = q02 + q12 - q22 - q32;
R[0][1] = 2. * (q1_2 - q0_3); R[0][1] = 2. * (q1_2 - q0_3);
R[0][2] = 2. * (q1_3 + q0_2); R[0][2] = 2. * (q1_3 + q0_2);
R[1][0] = 2. * (q1_2 + q0_3); R[1][0] = 2. * (q1_2 + q0_3);
R[1][1] = q02 + q22 - q12 - q32; R[1][1] = q02 + q22 - q12 - q32;
R[1][2] = 2. * (q2_3 - q0_1); R[1][2] = 2. * (q2_3 - q0_1);
R[2][0] = 2. * (q1_3 - q0_2); R[2][0] = 2. * (q1_3 - q0_2);
R[2][1] = 2. * (q2_3 + q0_1); R[2][1] = 2. * (q2_3 + q0_1);
R[2][2] = q02 + q32 - q12 - q22; R[2][2] = q02 + q32 - q12 - q22;
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
T[i] = C_end[i] - (R[i][0] * C_start[0] + R[i][1] * C_start[1] + R[i][2] * C_start[2]); T[i] = C_end[i] - (R[i][0] * C_start[0] + R[i][1] * C_start[1] + R[i][2] * C_start[2]);
return true; return true;
} }
bool p3p::jacobi_4x4(double * A, double * D, double * U) bool p3p::jacobi_4x4(double * A, double * D, double * U)
{ {
double B[4], Z[4]; double B[4], Z[4];
double Id[16] = {1., 0., 0., 0., double Id[16] = {1., 0., 0., 0.,
0., 1., 0., 0., 0., 1., 0., 0.,
0., 0., 1., 0., 0., 0., 1., 0.,
0., 0., 0., 1.}; 0., 0., 0., 1.};
memcpy(U, Id, 16 * sizeof(double)); memcpy(U, Id, 16 * sizeof(double));
B[0] = A[0]; B[1] = A[5]; B[2] = A[10]; B[3] = A[15]; B[0] = A[0]; B[1] = A[5]; B[2] = A[10]; B[3] = A[15];
memcpy(D, B, 4 * sizeof(double)); memcpy(D, B, 4 * sizeof(double));
memset(Z, 0, 4 * sizeof(double)); memset(Z, 0, 4 * sizeof(double));
for(int iter = 0; iter < 50; iter++) { for(int iter = 0; iter < 50; iter++) {
double sum = fabs(A[1]) + fabs(A[2]) + fabs(A[3]) + fabs(A[6]) + fabs(A[7]) + fabs(A[11]); double sum = fabs(A[1]) + fabs(A[2]) + fabs(A[3]) + fabs(A[6]) + fabs(A[7]) + fabs(A[11]);
if (sum == 0.0) if (sum == 0.0)
return true; return true;
double tresh = (iter < 3) ? 0.2 * sum / 16. : 0.0; double tresh = (iter < 3) ? 0.2 * sum / 16. : 0.0;
for(int i = 0; i < 3; i++) { for(int i = 0; i < 3; i++) {
double * pAij = A + 5 * i + 1; double * pAij = A + 5 * i + 1;
for(int j = i + 1 ; j < 4; j++) { for(int j = i + 1 ; j < 4; j++) {
double Aij = *pAij; double Aij = *pAij;
double eps_machine = 100.0 * fabs(Aij); double eps_machine = 100.0 * fabs(Aij);
if ( iter > 3 && fabs(D[i]) + eps_machine == fabs(D[i]) && fabs(D[j]) + eps_machine == fabs(D[j]) ) if ( iter > 3 && fabs(D[i]) + eps_machine == fabs(D[i]) && fabs(D[j]) + eps_machine == fabs(D[j]) )
*pAij = 0.0; *pAij = 0.0;
else if (fabs(Aij) > tresh) { else if (fabs(Aij) > tresh) {
double h = D[j] - D[i], t; double hh = D[j] - D[i], t;
if (fabs(h) + eps_machine == fabs(h)) if (fabs(hh) + eps_machine == fabs(hh))
t = Aij / h; t = Aij / hh;
else { else {
double theta = 0.5 * h / Aij; double theta = 0.5 * hh / Aij;
t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta)); t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
if (theta < 0.0) t = -t; if (theta < 0.0) t = -t;
} }
h = t * Aij; hh = t * Aij;
Z[i] -= h; Z[i] -= hh;
Z[j] += h; Z[j] += hh;
D[i] -= h; D[i] -= hh;
D[j] += h; D[j] += hh;
*pAij = 0.0; *pAij = 0.0;
double c = 1.0 / sqrt(1 + t * t); double c = 1.0 / sqrt(1 + t * t);
double s = t * c; double s = t * c;
double tau = s / (1.0 + c); double tau = s / (1.0 + c);
for(int k = 0; k <= i - 1; k++) { for(int k = 0; k <= i - 1; k++) {
double g = A[k * 4 + i], h = A[k * 4 + j]; double g = A[k * 4 + i], h = A[k * 4 + j];
A[k * 4 + i] = g - s * (h + g * tau); A[k * 4 + i] = g - s * (h + g * tau);
A[k * 4 + j] = h + s * (g - h * tau); A[k * 4 + j] = h + s * (g - h * tau);
} }
for(int k = i + 1; k <= j - 1; k++) { for(int k = i + 1; k <= j - 1; k++) {
double g = A[i * 4 + k], h = A[k * 4 + j]; double g = A[i * 4 + k], h = A[k * 4 + j];
A[i * 4 + k] = g - s * (h + g * tau); A[i * 4 + k] = g - s * (h + g * tau);
A[k * 4 + j] = h + s * (g - h * tau); A[k * 4 + j] = h + s * (g - h * tau);
} }
for(int k = j + 1; k < 4; k++) { for(int k = j + 1; k < 4; k++) {
double g = A[i * 4 + k], h = A[j * 4 + k]; double g = A[i * 4 + k], h = A[j * 4 + k];
A[i * 4 + k] = g - s * (h + g * tau); A[i * 4 + k] = g - s * (h + g * tau);
A[j * 4 + k] = h + s * (g - h * tau); A[j * 4 + k] = h + s * (g - h * tau);
} }
for(int k = 0; k < 4; k++) { for(int k = 0; k < 4; k++) {
double g = U[k * 4 + i], h = U[k * 4 + j]; double g = U[k * 4 + i], h = U[k * 4 + j];
U[k * 4 + i] = g - s * (h + g * tau); U[k * 4 + i] = g - s * (h + g * tau);
U[k * 4 + j] = h + s * (g - h * tau); U[k * 4 + j] = h + s * (g - h * tau);
} }
} }
pAij++; pAij++;
} }
} }
for(int i = 0; i < 4; i++) B[i] += Z[i]; for(int i = 0; i < 4; i++) B[i] += Z[i];
memcpy(D, B, 4 * sizeof(double)); memcpy(D, B, 4 * sizeof(double));
memset(Z, 0, 4 * sizeof(double)); memset(Z, 0, 4 * sizeof(double));
} }
return false; return false;
} }

View File

@ -42,11 +42,7 @@
#ifndef __OPENCV_PRECOMP_H__ #ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__ #define __OPENCV_PRECOMP_H__
#if _MSC_VER >= 1200 #ifdef HAVE_CVCONFIG_H
#pragma warning( disable: 4251 4710 4711 4514 4996 )
#endif
#ifdef HAVE_CVCONFIG_H
#include "cvconfig.h" #include "cvconfig.h"
#endif #endif

View File

@ -52,41 +52,41 @@
#undef max #undef max
namespace cv { namespace cv {
void drawCircles(Mat& img, const vector<Point2f>& corners, const vector<float>& radius) // static void drawCircles(Mat& img, const vector<Point2f>& corners, const vector<float>& radius)
{ // {
for(size_t i = 0; i < corners.size(); i++) // for(size_t i = 0; i < corners.size(); i++)
{ // {
circle(img, corners[i], cvRound(radius[i]), CV_RGB(255, 0, 0)); // circle(img, corners[i], cvRound(radius[i]), CV_RGB(255, 0, 0));
} // }
} // }
int histQuantile(const Mat& hist, float quantile) // static int histQuantile(const Mat& hist, float quantile)
{ // {
if(hist.dims > 1) return -1; // works for 1D histograms only // if(hist.dims > 1) return -1; // works for 1D histograms only
float cur_sum = 0; // float cur_sum = 0;
float total_sum = (float)sum(hist).val[0]; // float total_sum = (float)sum(hist).val[0];
float quantile_sum = total_sum*quantile; // float quantile_sum = total_sum*quantile;
for(int j = 0; j < hist.size[0]; j++) // for(int j = 0; j < hist.size[0]; j++)
{ // {
cur_sum += (float)hist.at<float>(j); // cur_sum += (float)hist.at<float>(j);
if(cur_sum > quantile_sum) // if(cur_sum > quantile_sum)
{ // {
return j; // return j;
} // }
} // }
return hist.size[0] - 1; // return hist.size[0] - 1;
} // }
bool is_smaller(const std::pair<int, float>& p1, const std::pair<int, float>& p2) inline bool is_smaller(const std::pair<int, float>& p1, const std::pair<int, float>& p2)
{ {
return p1.second < p2.second; return p1.second < p2.second;
} }
void orderContours(const vector<vector<Point> >& contours, Point2f point, vector<std::pair<int, float> >& order) static void orderContours(const vector<vector<Point> >& contours, Point2f point, vector<std::pair<int, float> >& order)
{ {
order.clear(); order.clear();
size_t i, j, n = contours.size(); size_t i, j, n = contours.size();
@ -101,58 +101,58 @@ void orderContours(const vector<vector<Point> >& contours, Point2f point, vector
} }
order.push_back(std::pair<int, float>((int)i, (float)min_dist)); order.push_back(std::pair<int, float>((int)i, (float)min_dist));
} }
std::sort(order.begin(), order.end(), is_smaller); std::sort(order.begin(), order.end(), is_smaller);
} }
// fit second order curve to a set of 2D points // fit second order curve to a set of 2D points
void fitCurve2Order(const vector<Point2f>& /*points*/, vector<float>& /*curve*/) inline void fitCurve2Order(const vector<Point2f>& /*points*/, vector<float>& /*curve*/)
{ {
// TBD // TBD
} }
void findCurvesCross(const vector<float>& /*curve1*/, const vector<float>& /*curve2*/, Point2f& /*cross_point*/) inline void findCurvesCross(const vector<float>& /*curve1*/, const vector<float>& /*curve2*/, Point2f& /*cross_point*/)
{ {
} }
void findLinesCrossPoint(Point2f origin1, Point2f dir1, Point2f origin2, Point2f dir2, Point2f& cross_point) static void findLinesCrossPoint(Point2f origin1, Point2f dir1, Point2f origin2, Point2f dir2, Point2f& cross_point)
{ {
float det = dir2.x*dir1.y - dir2.y*dir1.x; float det = dir2.x*dir1.y - dir2.y*dir1.x;
Point2f offset = origin2 - origin1; Point2f offset = origin2 - origin1;
float alpha = (dir2.x*offset.y - dir2.y*offset.x)/det; float alpha = (dir2.x*offset.y - dir2.y*offset.x)/det;
cross_point = origin1 + dir1*alpha; cross_point = origin1 + dir1*alpha;
} }
void findCorner(const vector<Point>& contour, Point2f point, Point2f& corner)
{
// find the nearest point
double min_dist = std::numeric_limits<double>::max();
int min_idx = -1;
// find corner idx
for(size_t i = 0; i < contour.size(); i++)
{
double dist = norm(Point2f((float)contour[i].x, (float)contour[i].y) - point);
if(dist < min_dist)
{
min_dist = dist;
min_idx = (int)i;
}
}
assert(min_idx >= 0);
// temporary solution, have to make something more precise
corner = contour[min_idx];
return;
}
void findCorner(const vector<Point2f>& contour, Point2f point, Point2f& corner) // static void findCorner(const vector<Point>& contour, Point2f point, Point2f& corner)
// {
// // find the nearest point
// double min_dist = std::numeric_limits<double>::max();
// int min_idx = -1;
// // find corner idx
// for(size_t i = 0; i < contour.size(); i++)
// {
// double dist = norm(Point2f((float)contour[i].x, (float)contour[i].y) - point);
// if(dist < min_dist)
// {
// min_dist = dist;
// min_idx = (int)i;
// }
// }
// assert(min_idx >= 0);
// // temporary solution, have to make something more precise
// corner = contour[min_idx];
// return;
// }
static void findCorner(const vector<Point2f>& contour, Point2f point, Point2f& corner)
{ {
// find the nearest point // find the nearest point
double min_dist = std::numeric_limits<double>::max(); double min_dist = std::numeric_limits<double>::max();
int min_idx = -1; int min_idx = -1;
// find corner idx // find corner idx
for(size_t i = 0; i < contour.size(); i++) for(size_t i = 0; i < contour.size(); i++)
{ {
@ -164,23 +164,23 @@ void findCorner(const vector<Point2f>& contour, Point2f point, Point2f& corner)
} }
} }
assert(min_idx >= 0); assert(min_idx >= 0);
// temporary solution, have to make something more precise // temporary solution, have to make something more precise
corner = contour[min_idx]; corner = contour[min_idx];
return; return;
} }
int segment_hist_max(const Mat& hist, int& low_thresh, int& high_thresh) static int segment_hist_max(const Mat& hist, int& low_thresh, int& high_thresh)
{ {
Mat bw; Mat bw;
//const double max_bell_width = 20; // we expect two bells with width bounded above //const double max_bell_width = 20; // we expect two bells with width bounded above
//const double min_bell_width = 5; // and below //const double min_bell_width = 5; // and below
double total_sum = sum(hist).val[0]; double total_sum = sum(hist).val[0];
//double thresh = total_sum/(2*max_bell_width)*0.25f; // quarter of a bar inside a bell //double thresh = total_sum/(2*max_bell_width)*0.25f; // quarter of a bar inside a bell
// threshold(hist, bw, thresh, 255.0, CV_THRESH_BINARY); // threshold(hist, bw, thresh, 255.0, CV_THRESH_BINARY);
double quantile_sum = 0.0; double quantile_sum = 0.0;
//double min_quantile = 0.2; //double min_quantile = 0.2;
double low_sum = 0; double low_sum = 0;
@ -193,7 +193,7 @@ int segment_hist_max(const Mat& hist, int& low_thresh, int& high_thresh)
{ {
quantile_sum += hist.at<float>(x); quantile_sum += hist.at<float>(x);
if(quantile_sum < 0.2*total_sum) continue; if(quantile_sum < 0.2*total_sum) continue;
if(quantile_sum - low_sum > out_of_bells_fraction*total_sum) if(quantile_sum - low_sum > out_of_bells_fraction*total_sum)
{ {
if(max_segment_length < x - start_x) if(max_segment_length < x - start_x)
@ -207,7 +207,7 @@ int segment_hist_max(const Mat& hist, int& low_thresh, int& high_thresh)
start_x = x; start_x = x;
} }
} }
if(start_x == -1) if(start_x == -1)
{ {
return 0; return 0;
@ -219,9 +219,9 @@ int segment_hist_max(const Mat& hist, int& low_thresh, int& high_thresh)
return 1; return 1;
} }
} }
} }
bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size region_size) bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size region_size)
{ {
Mat img = _img.getMat(), cornersM = _corners.getMat(); Mat img = _img.getMat(), cornersM = _corners.getMat();
@ -232,33 +232,33 @@ bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size
float ranges[] = {0, 256}; float ranges[] = {0, 256};
const float* _ranges = ranges; const float* _ranges = ranges;
Mat hist; Mat hist;
#if defined(_SUBPIX_VERBOSE) #if defined(_SUBPIX_VERBOSE)
vector<float> radius; vector<float> radius;
radius.assign(corners.size(), 0.0f); radius.assign(corners.size(), 0.0f);
#endif //_SUBPIX_VERBOSE #endif //_SUBPIX_VERBOSE
Mat black_comp, white_comp; Mat black_comp, white_comp;
for(int i = 0; i < ncorners; i++) for(int i = 0; i < ncorners; i++)
{ {
int channels = 0; int channels = 0;
Rect roi(cvRound(corners[i].x - region_size.width), cvRound(corners[i].y - region_size.height), Rect roi(cvRound(corners[i].x - region_size.width), cvRound(corners[i].y - region_size.height),
region_size.width*2 + 1, region_size.height*2 + 1); region_size.width*2 + 1, region_size.height*2 + 1);
Mat img_roi = img(roi); Mat img_roi = img(roi);
calcHist(&img_roi, 1, &channels, Mat(), hist, 1, &nbins, &_ranges); calcHist(&img_roi, 1, &channels, Mat(), hist, 1, &nbins, &_ranges);
#if 0 #if 0
int black_thresh = histQuantile(hist, 0.45f); int black_thresh = histQuantile(hist, 0.45f);
int white_thresh = histQuantile(hist, 0.55f); int white_thresh = histQuantile(hist, 0.55f);
#else #else
int black_thresh, white_thresh; int black_thresh = 0, white_thresh = 0;
segment_hist_max(hist, black_thresh, white_thresh); segment_hist_max(hist, black_thresh, white_thresh);
#endif #endif
threshold(img, black_comp, black_thresh, 255.0, CV_THRESH_BINARY_INV); threshold(img, black_comp, black_thresh, 255.0, CV_THRESH_BINARY_INV);
threshold(img, white_comp, white_thresh, 255.0, CV_THRESH_BINARY); threshold(img, white_comp, white_thresh, 255.0, CV_THRESH_BINARY);
const int erode_count = 1; const int erode_count = 1;
erode(black_comp, black_comp, Mat(), Point(-1, -1), erode_count); erode(black_comp, black_comp, Mat(), Point(-1, -1), erode_count);
erode(white_comp, white_comp, Mat(), Point(-1, -1), erode_count); erode(white_comp, white_comp, Mat(), Point(-1, -1), erode_count);
@ -275,28 +275,28 @@ bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size
imwrite("black.jpg", black_comp); imwrite("black.jpg", black_comp);
imwrite("white.jpg", white_comp); imwrite("white.jpg", white_comp);
#endif #endif
vector<vector<Point> > white_contours, black_contours; vector<vector<Point> > white_contours, black_contours;
vector<Vec4i> white_hierarchy, black_hierarchy; vector<Vec4i> white_hierarchy, black_hierarchy;
findContours(black_comp, black_contours, black_hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); findContours(black_comp, black_contours, black_hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
findContours(white_comp, white_contours, white_hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); findContours(white_comp, white_contours, white_hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
if(black_contours.size() < 5 || white_contours.size() < 5) continue; if(black_contours.size() < 5 || white_contours.size() < 5) continue;
// find two white and black blobs that are close to the input point // find two white and black blobs that are close to the input point
vector<std::pair<int, float> > white_order, black_order; vector<std::pair<int, float> > white_order, black_order;
orderContours(black_contours, corners[i], black_order); orderContours(black_contours, corners[i], black_order);
orderContours(white_contours, corners[i], white_order); orderContours(white_contours, corners[i], white_order);
const float max_dist = 10.0f; const float max_dist = 10.0f;
if(black_order[0].second > max_dist || black_order[1].second > max_dist || if(black_order[0].second > max_dist || black_order[1].second > max_dist ||
white_order[0].second > max_dist || white_order[1].second > max_dist) white_order[0].second > max_dist || white_order[1].second > max_dist)
{ {
continue; // there will be no improvement in this corner position continue; // there will be no improvement in this corner position
} }
const vector<Point>* quads[4] = {&black_contours[black_order[0].first], &black_contours[black_order[1].first], const vector<Point>* quads[4] = {&black_contours[black_order[0].first], &black_contours[black_order[1].first],
&white_contours[white_order[0].first], &white_contours[white_order[1].first]}; &white_contours[white_order[0].first], &white_contours[white_order[1].first]};
vector<Point2f> quads_approx[4]; vector<Point2f> quads_approx[4];
Point2f quad_corners[4]; Point2f quad_corners[4];
@ -306,14 +306,14 @@ bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size
vector<Point2f> temp; vector<Point2f> temp;
for(size_t j = 0; j < quads[k]->size(); j++) temp.push_back((*quads[k])[j]); for(size_t j = 0; j < quads[k]->size(); j++) temp.push_back((*quads[k])[j]);
approxPolyDP(Mat(temp), quads_approx[k], 0.5, true); approxPolyDP(Mat(temp), quads_approx[k], 0.5, true);
findCorner(quads_approx[k], corners[i], quad_corners[k]); findCorner(quads_approx[k], corners[i], quad_corners[k]);
#else #else
findCorner(*quads[k], corners[i], quad_corners[k]); findCorner(*quads[k], corners[i], quad_corners[k]);
#endif #endif
quad_corners[k] += Point2f(0.5f, 0.5f); quad_corners[k] += Point2f(0.5f, 0.5f);
} }
// cross two lines // cross two lines
Point2f origin1 = quad_corners[0]; Point2f origin1 = quad_corners[0];
Point2f dir1 = quad_corners[1] - quad_corners[0]; Point2f dir1 = quad_corners[1] - quad_corners[0];
@ -321,12 +321,12 @@ bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size
Point2f dir2 = quad_corners[3] - quad_corners[2]; Point2f dir2 = quad_corners[3] - quad_corners[2];
double angle = acos(dir1.dot(dir2)/(norm(dir1)*norm(dir2))); double angle = acos(dir1.dot(dir2)/(norm(dir1)*norm(dir2)));
if(cvIsNaN(angle) || cvIsInf(angle) || angle < 0.5 || angle > CV_PI - 0.5) continue; if(cvIsNaN(angle) || cvIsInf(angle) || angle < 0.5 || angle > CV_PI - 0.5) continue;
findLinesCrossPoint(origin1, dir1, origin2, dir2, corners[i]); findLinesCrossPoint(origin1, dir1, origin2, dir2, corners[i]);
#if defined(_SUBPIX_VERBOSE) #if defined(_SUBPIX_VERBOSE)
radius[i] = norm(corners[i] - ground_truth_corners[ground_truth_idx])*6; radius[i] = norm(corners[i] - ground_truth_corners[ground_truth_idx])*6;
#if 1 #if 1
Mat test(img.size(), CV_32FC3); Mat test(img.size(), CV_32FC3);
cvtColor(img, test, CV_GRAY2RGB); cvtColor(img, test, CV_GRAY2RGB);
@ -349,9 +349,9 @@ bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size
waitKey(0); waitKey(0);
#endif #endif
#endif //_SUBPIX_VERBOSE #endif //_SUBPIX_VERBOSE
} }
#if defined(_SUBPIX_VERBOSE) #if defined(_SUBPIX_VERBOSE)
Mat test(img.size(), CV_32FC3); Mat test(img.size(), CV_32FC3);
cvtColor(img, test, CV_GRAY2RGB); cvtColor(img, test, CV_GRAY2RGB);
@ -361,6 +361,6 @@ bool cv::find4QuadCornerSubpix(InputArray _img, InputOutputArray _corners, Size
imshow("corners", test); imshow("corners", test);
waitKey(); waitKey();
#endif //_SUBPIX_VERBOSE #endif //_SUBPIX_VERBOSE
return true; return true;
} }

View File

@ -52,48 +52,48 @@ bool cv::solvePnP( InputArray _opoints, InputArray _ipoints,
{ {
Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat(); Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F)); int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
CV_Assert( npoints >= 0 && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) ); CV_Assert( npoints >= 0 && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) );
_rvec.create(3, 1, CV_64F); _rvec.create(3, 1, CV_64F);
_tvec.create(3, 1, CV_64F); _tvec.create(3, 1, CV_64F);
Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
if (flags == CV_EPNP) if (flags == CV_EPNP)
{ {
cv::Mat undistortedPoints; cv::Mat undistortedPoints;
cv::undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs); cv::undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs);
epnp PnP(cameraMatrix, opoints, undistortedPoints); epnp PnP(cameraMatrix, opoints, undistortedPoints);
cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat(); cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat();
PnP.compute_pose(R, tvec); PnP.compute_pose(R, tvec);
cv::Rodrigues(R, rvec); cv::Rodrigues(R, rvec);
return true; return true;
} }
else if (flags == CV_P3P) else if (flags == CV_P3P)
{ {
CV_Assert( npoints == 4); CV_Assert( npoints == 4);
cv::Mat undistortedPoints; cv::Mat undistortedPoints;
cv::undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs); cv::undistortPoints(ipoints, undistortedPoints, cameraMatrix, distCoeffs);
p3p P3Psolver(cameraMatrix); p3p P3Psolver(cameraMatrix);
cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat(); cv::Mat R, rvec = _rvec.getMat(), tvec = _tvec.getMat();
bool result = P3Psolver.solve(R, tvec, opoints, undistortedPoints); bool result = P3Psolver.solve(R, tvec, opoints, undistortedPoints);
if (result) if (result)
cv::Rodrigues(R, rvec); cv::Rodrigues(R, rvec);
return result; return result;
} }
else if (flags == CV_ITERATIVE) else if (flags == CV_ITERATIVE)
{ {
CvMat c_objectPoints = opoints, c_imagePoints = ipoints; CvMat c_objectPoints = opoints, c_imagePoints = ipoints;
CvMat c_cameraMatrix = cameraMatrix, c_distCoeffs = distCoeffs; CvMat c_cameraMatrix = cameraMatrix, c_distCoeffs = distCoeffs;
CvMat c_rvec = _rvec.getMat(), c_tvec = _tvec.getMat(); CvMat c_rvec = _rvec.getMat(), c_tvec = _tvec.getMat();
cvFindExtrinsicCameraParams2(&c_objectPoints, &c_imagePoints, &c_cameraMatrix, cvFindExtrinsicCameraParams2(&c_objectPoints, &c_imagePoints, &c_cameraMatrix,
c_distCoeffs.rows*c_distCoeffs.cols ? &c_distCoeffs : 0, c_distCoeffs.rows*c_distCoeffs.cols ? &c_distCoeffs : 0,
&c_rvec, &c_tvec, useExtrinsicGuess ); &c_rvec, &c_tvec, useExtrinsicGuess );
return true; return true;
} }
else else
CV_Error(CV_StsBadArg, "The flags argument must be one of CV_ITERATIVE or CV_EPNP"); CV_Error(CV_StsBadArg, "The flags argument must be one of CV_ITERATIVE or CV_EPNP");
return false; return false;
} }
namespace cv namespace cv
@ -101,8 +101,8 @@ namespace cv
namespace pnpransac namespace pnpransac
{ {
const int MIN_POINTS_COUNT = 4; const int MIN_POINTS_COUNT = 4;
void project3dPoints(const Mat& points, const Mat& rvec, const Mat& tvec, Mat& modif_points) static void project3dPoints(const Mat& points, const Mat& rvec, const Mat& tvec, Mat& modif_points)
{ {
modif_points.create(1, points.cols, CV_32FC3); modif_points.create(1, points.cols, CV_32FC3);
Mat R(3, 3, CV_64FC1); Mat R(3, 3, CV_64FC1);
@ -114,32 +114,32 @@ namespace cv
tvec.copyTo(t); tvec.copyTo(t);
transform(points, modif_points, transformation); transform(points, modif_points, transformation);
} }
class Mutex class Mutex
{ {
public: public:
Mutex() { Mutex() {
} }
void lock() void lock()
{ {
#ifdef HAVE_TBB #ifdef HAVE_TBB
resultsMutex.lock(); resultsMutex.lock();
#endif #endif
} }
void unlock() void unlock()
{ {
#ifdef HAVE_TBB #ifdef HAVE_TBB
resultsMutex.unlock(); resultsMutex.unlock();
#endif #endif
} }
private: private:
#ifdef HAVE_TBB #ifdef HAVE_TBB
tbb::mutex resultsMutex; tbb::mutex resultsMutex;
#endif #endif
}; };
struct CameraParameters struct CameraParameters
{ {
void init(Mat _intrinsics, Mat _distCoeffs) void init(Mat _intrinsics, Mat _distCoeffs)
@ -147,22 +147,22 @@ namespace cv
_intrinsics.copyTo(intrinsics); _intrinsics.copyTo(intrinsics);
_distCoeffs.copyTo(distortion); _distCoeffs.copyTo(distortion);
} }
Mat intrinsics; Mat intrinsics;
Mat distortion; Mat distortion;
}; };
struct Parameters struct Parameters
{ {
int iterationsCount; int iterationsCount;
float reprojectionError; float reprojectionError;
int minInliersCount; int minInliersCount;
bool useExtrinsicGuess; bool useExtrinsicGuess;
int flags; int flags;
CameraParameters camera; CameraParameters camera;
}; };
void pnpTask(const vector<char>& pointsMask, const Mat& objectPoints, const Mat& imagePoints, static void pnpTask(const vector<char>& pointsMask, const Mat& objectPoints, const Mat& imagePoints,
const Parameters& params, vector<int>& inliers, Mat& rvec, Mat& tvec, const Parameters& params, vector<int>& inliers, Mat& rvec, Mat& tvec,
const Mat& rvecInit, const Mat& tvecInit, Mutex& resultsMutex) const Mat& rvecInit, const Mat& tvecInit, Mutex& resultsMutex)
{ {
@ -178,7 +178,7 @@ namespace cv
colIndex = colIndex+1; colIndex = colIndex+1;
} }
} }
//filter same 3d points, hang in solvePnP //filter same 3d points, hang in solvePnP
double eps = 1e-10; double eps = 1e-10;
int num_same_points = 0; int num_same_points = 0;
@ -190,22 +190,22 @@ namespace cv
} }
if (num_same_points > 0) if (num_same_points > 0)
return; return;
Mat localRvec, localTvec; Mat localRvec, localTvec;
rvecInit.copyTo(localRvec); rvecInit.copyTo(localRvec);
tvecInit.copyTo(localTvec); tvecInit.copyTo(localTvec);
solvePnP(modelObjectPoints, modelImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec, solvePnP(modelObjectPoints, modelImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec,
params.useExtrinsicGuess, params.flags); params.useExtrinsicGuess, params.flags);
vector<Point2f> projected_points; vector<Point2f> projected_points;
projected_points.resize(objectPoints.cols); projected_points.resize(objectPoints.cols);
projectPoints(objectPoints, localRvec, localTvec, params.camera.intrinsics, params.camera.distortion, projected_points); projectPoints(objectPoints, localRvec, localTvec, params.camera.intrinsics, params.camera.distortion, projected_points);
Mat rotatedPoints; Mat rotatedPoints;
project3dPoints(objectPoints, localRvec, localTvec, rotatedPoints); project3dPoints(objectPoints, localRvec, localTvec, rotatedPoints);
vector<int> localInliers; vector<int> localInliers;
for (int i = 0; i < objectPoints.cols; i++) for (int i = 0; i < objectPoints.cols; i++)
{ {
@ -216,21 +216,21 @@ namespace cv
localInliers.push_back(i); localInliers.push_back(i);
} }
} }
if (localInliers.size() > inliers.size()) if (localInliers.size() > inliers.size())
{ {
resultsMutex.lock(); resultsMutex.lock();
inliers.clear(); inliers.clear();
inliers.resize(localInliers.size()); inliers.resize(localInliers.size());
memcpy(&inliers[0], &localInliers[0], sizeof(int) * localInliers.size()); memcpy(&inliers[0], &localInliers[0], sizeof(int) * localInliers.size());
localRvec.copyTo(rvec); localRvec.copyTo(rvec);
localTvec.copyTo(tvec); localTvec.copyTo(tvec);
resultsMutex.unlock(); resultsMutex.unlock();
} }
} }
class PnPSolver class PnPSolver
{ {
public: public:
@ -253,27 +253,27 @@ namespace cv
} }
} }
} }
PnPSolver(const Mat& objectPoints, const Mat& imagePoints, const Parameters& parameters, PnPSolver(const Mat& _objectPoints, const Mat& _imagePoints, const Parameters& _parameters,
Mat& rvec, Mat& tvec, vector<int>& inliers): Mat& _rvec, Mat& _tvec, vector<int>& _inliers):
objectPoints(objectPoints), imagePoints(imagePoints), parameters(parameters), objectPoints(_objectPoints), imagePoints(_imagePoints), parameters(_parameters),
rvec(rvec), tvec(tvec), inliers(inliers) rvec(_rvec), tvec(_tvec), inliers(_inliers)
{ {
rvec.copyTo(initRvec); rvec.copyTo(initRvec);
tvec.copyTo(initTvec); tvec.copyTo(initTvec);
} }
private: private:
PnPSolver& operator=(const PnPSolver&); PnPSolver& operator=(const PnPSolver&);
const Mat& objectPoints; const Mat& objectPoints;
const Mat& imagePoints; const Mat& imagePoints;
const Parameters& parameters; const Parameters& parameters;
Mat &rvec, &tvec; Mat &rvec, &tvec;
vector<int>& inliers; vector<int>& inliers;
Mat initRvec, initTvec; Mat initRvec, initTvec;
static RNG generator; static RNG generator;
static Mutex syncMutex; static Mutex syncMutex;
void generateVar(vector<char>& mask) const void generateVar(vector<char>& mask) const
{ {
int size = (int)mask.size(); int size = (int)mask.size();
@ -287,10 +287,10 @@ namespace cv
} }
} }
}; };
Mutex PnPSolver::syncMutex; Mutex PnPSolver::syncMutex;
RNG PnPSolver::generator; RNG PnPSolver::generator;
} }
} }
@ -302,21 +302,21 @@ void cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
{ {
Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat(); Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat(); Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
CV_Assert(opoints.isContinuous()); CV_Assert(opoints.isContinuous());
CV_Assert(opoints.depth() == CV_32F); CV_Assert(opoints.depth() == CV_32F);
CV_Assert((opoints.rows == 1 && opoints.channels() == 3) || opoints.cols*opoints.channels() == 3); CV_Assert((opoints.rows == 1 && opoints.channels() == 3) || opoints.cols*opoints.channels() == 3);
CV_Assert(ipoints.isContinuous()); CV_Assert(ipoints.isContinuous());
CV_Assert(ipoints.depth() == CV_32F); CV_Assert(ipoints.depth() == CV_32F);
CV_Assert((ipoints.rows == 1 && ipoints.channels() == 2) || ipoints.cols*ipoints.channels() == 2); CV_Assert((ipoints.rows == 1 && ipoints.channels() == 2) || ipoints.cols*ipoints.channels() == 2);
_rvec.create(3, 1, CV_64FC1); _rvec.create(3, 1, CV_64FC1);
_tvec.create(3, 1, CV_64FC1); _tvec.create(3, 1, CV_64FC1);
Mat rvec = _rvec.getMat(); Mat rvec = _rvec.getMat();
Mat tvec = _tvec.getMat(); Mat tvec = _tvec.getMat();
Mat objectPoints = opoints.reshape(3, 1), imagePoints = ipoints.reshape(2, 1); Mat objectPoints = opoints.reshape(3, 1), imagePoints = ipoints.reshape(2, 1);
if (minInliersCount <= 0) if (minInliersCount <= 0)
minInliersCount = objectPoints.cols; minInliersCount = objectPoints.cols;
cv::pnpransac::Parameters params; cv::pnpransac::Parameters params;
@ -325,36 +325,36 @@ void cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
params.reprojectionError = reprojectionError; params.reprojectionError = reprojectionError;
params.useExtrinsicGuess = useExtrinsicGuess; params.useExtrinsicGuess = useExtrinsicGuess;
params.camera.init(cameraMatrix, distCoeffs); params.camera.init(cameraMatrix, distCoeffs);
params.flags = flags; params.flags = flags;
vector<int> localInliers; vector<int> localInliers;
Mat localRvec, localTvec; Mat localRvec, localTvec;
rvec.copyTo(localRvec); rvec.copyTo(localRvec);
tvec.copyTo(localTvec); tvec.copyTo(localTvec);
if (objectPoints.cols >= pnpransac::MIN_POINTS_COUNT) if (objectPoints.cols >= pnpransac::MIN_POINTS_COUNT)
{ {
parallel_for(BlockedRange(0,iterationsCount), cv::pnpransac::PnPSolver(objectPoints, imagePoints, params, parallel_for(BlockedRange(0,iterationsCount), cv::pnpransac::PnPSolver(objectPoints, imagePoints, params,
localRvec, localTvec, localInliers)); localRvec, localTvec, localInliers));
} }
if (localInliers.size() >= (size_t)pnpransac::MIN_POINTS_COUNT) if (localInliers.size() >= (size_t)pnpransac::MIN_POINTS_COUNT)
{ {
if (flags != CV_P3P) if (flags != CV_P3P)
{ {
int i, pointsCount = (int)localInliers.size(); int i, pointsCount = (int)localInliers.size();
Mat inlierObjectPoints(1, pointsCount, CV_32FC3), inlierImagePoints(1, pointsCount, CV_32FC2); Mat inlierObjectPoints(1, pointsCount, CV_32FC3), inlierImagePoints(1, pointsCount, CV_32FC2);
for (i = 0; i < pointsCount; i++) for (i = 0; i < pointsCount; i++)
{ {
int index = localInliers[i]; int index = localInliers[i];
Mat colInlierImagePoints = inlierImagePoints(Rect(i, 0, 1, 1)); Mat colInlierImagePoints = inlierImagePoints(Rect(i, 0, 1, 1));
imagePoints.col(index).copyTo(colInlierImagePoints); imagePoints.col(index).copyTo(colInlierImagePoints);
Mat colInlierObjectPoints = inlierObjectPoints(Rect(i, 0, 1, 1)); Mat colInlierObjectPoints = inlierObjectPoints(Rect(i, 0, 1, 1));
objectPoints.col(index).copyTo(colInlierObjectPoints); objectPoints.col(index).copyTo(colInlierObjectPoints);
} }
solvePnP(inlierObjectPoints, inlierImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec, true, flags); solvePnP(inlierObjectPoints, inlierImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec, true, flags);
} }
localRvec.copyTo(rvec); localRvec.copyTo(rvec);
localTvec.copyTo(tvec); localTvec.copyTo(tvec);
if (_inliers.needed()) if (_inliers.needed())
Mat(localInliers).copyTo(_inliers); Mat(localInliers).copyTo(_inliers);

View File

@ -155,7 +155,7 @@ static void prefilterNorm( const Mat& src, Mat& dst, int winsize, int ftzero, uc
val = ((curr[x]*4 + curr[x-1] + curr[x+1] + prev[x] + next[x])*scale_g - sum*scale_s) >> 10; val = ((curr[x]*4 + curr[x-1] + curr[x+1] + prev[x] + next[x])*scale_g - sum*scale_s) >> 10;
dptr[x] = tab[val + OFS]; dptr[x] = tab[val + OFS];
} }
sum += vsum[x+wsz2] - vsum[x-wsz2-1]; sum += vsum[x+wsz2] - vsum[x-wsz2-1];
val = ((curr[x]*5 + curr[x-1] + prev[x] + next[x])*scale_g - sum*scale_s) >> 10; val = ((curr[x]*5 + curr[x-1] + prev[x] + next[x])*scale_g - sum*scale_s) >> 10;
dptr[x] = tab[val + OFS]; dptr[x] = tab[val + OFS];
@ -170,15 +170,15 @@ prefilterXSobel( const Mat& src, Mat& dst, int ftzero )
const int OFS = 256*4, TABSZ = OFS*2 + 256; const int OFS = 256*4, TABSZ = OFS*2 + 256;
uchar tab[TABSZ]; uchar tab[TABSZ];
Size size = src.size(); Size size = src.size();
for( x = 0; x < TABSZ; x++ ) for( x = 0; x < TABSZ; x++ )
tab[x] = (uchar)(x - OFS < -ftzero ? 0 : x - OFS > ftzero ? ftzero*2 : x - OFS + ftzero); tab[x] = (uchar)(x - OFS < -ftzero ? 0 : x - OFS > ftzero ? ftzero*2 : x - OFS + ftzero);
uchar val0 = tab[0 + OFS]; uchar val0 = tab[0 + OFS];
#if CV_SSE2 #if CV_SSE2
volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2); volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
#endif #endif
for( y = 0; y < size.height-1; y += 2 ) for( y = 0; y < size.height-1; y += 2 )
{ {
const uchar* srow1 = src.ptr<uchar>(y); const uchar* srow1 = src.ptr<uchar>(y);
@ -187,10 +187,10 @@ prefilterXSobel( const Mat& src, Mat& dst, int ftzero )
const uchar* srow3 = y < size.height-2 ? srow1 + src.step*2 : srow1; const uchar* srow3 = y < size.height-2 ? srow1 + src.step*2 : srow1;
uchar* dptr0 = dst.ptr<uchar>(y); uchar* dptr0 = dst.ptr<uchar>(y);
uchar* dptr1 = dptr0 + dst.step; uchar* dptr1 = dptr0 + dst.step;
dptr0[0] = dptr0[size.width-1] = dptr1[0] = dptr1[size.width-1] = val0; dptr0[0] = dptr0[size.width-1] = dptr1[0] = dptr1[size.width-1] = val0;
x = 1; x = 1;
#if CV_SSE2 #if CV_SSE2
if( useSIMD ) if( useSIMD )
{ {
@ -205,26 +205,26 @@ prefilterXSobel( const Mat& src, Mat& dst, int ftzero )
d0 = _mm_sub_epi16(d0, c0); d0 = _mm_sub_epi16(d0, c0);
d1 = _mm_sub_epi16(d1, c1); d1 = _mm_sub_epi16(d1, c1);
__m128i c2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x - 1)), z); __m128i c2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x - 1)), z);
__m128i c3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x - 1)), z); __m128i c3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x - 1)), z);
__m128i d2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x + 1)), z); __m128i d2 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x + 1)), z);
__m128i d3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x + 1)), z); __m128i d3 = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)(srow2 + x + 1)), z);
d2 = _mm_sub_epi16(d2, c2); d2 = _mm_sub_epi16(d2, c2);
d3 = _mm_sub_epi16(d3, c3); d3 = _mm_sub_epi16(d3, c3);
__m128i v0 = _mm_add_epi16(d0, _mm_add_epi16(d2, _mm_add_epi16(d1, d1))); __m128i v0 = _mm_add_epi16(d0, _mm_add_epi16(d2, _mm_add_epi16(d1, d1)));
__m128i v1 = _mm_add_epi16(d1, _mm_add_epi16(d3, _mm_add_epi16(d2, d2))); __m128i v1 = _mm_add_epi16(d1, _mm_add_epi16(d3, _mm_add_epi16(d2, d2)));
v0 = _mm_packus_epi16(_mm_add_epi16(v0, ftz), _mm_add_epi16(v1, ftz)); v0 = _mm_packus_epi16(_mm_add_epi16(v0, ftz), _mm_add_epi16(v1, ftz));
v0 = _mm_min_epu8(v0, ftz2); v0 = _mm_min_epu8(v0, ftz2);
_mm_storel_epi64((__m128i*)(dptr0 + x), v0); _mm_storel_epi64((__m128i*)(dptr0 + x), v0);
_mm_storel_epi64((__m128i*)(dptr1 + x), _mm_unpackhi_epi64(v0, v0)); _mm_storel_epi64((__m128i*)(dptr1 + x), _mm_unpackhi_epi64(v0, v0));
} }
} }
#endif #endif
for( ; x < size.width-1; x++ ) for( ; x < size.width-1; x++ )
{ {
int d0 = srow0[x+1] - srow0[x-1], d1 = srow1[x+1] - srow1[x-1], int d0 = srow0[x+1] - srow0[x-1], d1 = srow1[x+1] - srow1[x-1],
@ -235,7 +235,7 @@ prefilterXSobel( const Mat& src, Mat& dst, int ftzero )
dptr1[x] = (uchar)v1; dptr1[x] = (uchar)v1;
} }
} }
for( ; y < size.height; y++ ) for( ; y < size.height; y++ )
{ {
uchar* dptr = dst.ptr<uchar>(y); uchar* dptr = dst.ptr<uchar>(y);
@ -336,7 +336,7 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right,
short* costptr = cost.data ? (short*)cost.data + lofs + x : &costbuf; short* costptr = cost.data ? (short*)cost.data + lofs + x : &costbuf;
int x0 = x - wsz2 - 1, x1 = x + wsz2; int x0 = x - wsz2 - 1, x1 = x + wsz2;
const uchar* cbuf_sub = cbuf0 + ((x0 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp; const uchar* cbuf_sub = cbuf0 + ((x0 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
uchar* cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp; cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
hsad = hsad0 - dy0*ndisp; hsad = hsad0 - dy0*ndisp;
lptr_sub = lptr0 + MIN(MAX(x0, -lofs), width-1-lofs) - dy0*sstep; lptr_sub = lptr0 + MIN(MAX(x0, -lofs), width-1-lofs) - dy0*sstep;
lptr = lptr0 + MIN(MAX(x1, -lofs), width-1-lofs) - dy0*sstep; lptr = lptr0 + MIN(MAX(x1, -lofs), width-1-lofs) - dy0*sstep;
@ -374,7 +374,7 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right,
// initialize sums // initialize sums
for( d = 0; d < ndisp; d++ ) for( d = 0; d < ndisp; d++ )
sad[d] = (ushort)(hsad0[d-ndisp*dy0]*(wsz2 + 2 - dy0)); sad[d] = (ushort)(hsad0[d-ndisp*dy0]*(wsz2 + 2 - dy0));
hsad = hsad0 + (1 - dy0)*ndisp; hsad = hsad0 + (1 - dy0)*ndisp;
for( y = 1 - dy0; y < wsz2; y++, hsad += ndisp ) for( y = 1 - dy0; y < wsz2; y++, hsad += ndisp )
for( d = 0; d < ndisp; d += 16 ) for( d = 0; d < ndisp; d += 16 )
@ -405,28 +405,28 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right,
{ {
__m128i u0 = _mm_load_si128((__m128i*)(hsad_sub + d)); __m128i u0 = _mm_load_si128((__m128i*)(hsad_sub + d));
__m128i u1 = _mm_load_si128((__m128i*)(hsad + d)); __m128i u1 = _mm_load_si128((__m128i*)(hsad + d));
__m128i v0 = _mm_load_si128((__m128i*)(hsad_sub + d + 8)); __m128i v0 = _mm_load_si128((__m128i*)(hsad_sub + d + 8));
__m128i v1 = _mm_load_si128((__m128i*)(hsad + d + 8)); __m128i v1 = _mm_load_si128((__m128i*)(hsad + d + 8));
__m128i usad8 = _mm_load_si128((__m128i*)(sad + d)); __m128i usad8 = _mm_load_si128((__m128i*)(sad + d));
__m128i vsad8 = _mm_load_si128((__m128i*)(sad + d + 8)); __m128i vsad8 = _mm_load_si128((__m128i*)(sad + d + 8));
u1 = _mm_sub_epi16(u1, u0); u1 = _mm_sub_epi16(u1, u0);
v1 = _mm_sub_epi16(v1, v0); v1 = _mm_sub_epi16(v1, v0);
usad8 = _mm_add_epi16(usad8, u1); usad8 = _mm_add_epi16(usad8, u1);
vsad8 = _mm_add_epi16(vsad8, v1); vsad8 = _mm_add_epi16(vsad8, v1);
mask = _mm_cmpgt_epi16(minsad8, usad8); mask = _mm_cmpgt_epi16(minsad8, usad8);
minsad8 = _mm_min_epi16(minsad8, usad8); minsad8 = _mm_min_epi16(minsad8, usad8);
mind8 = _mm_max_epi16(mind8, _mm_and_si128(mask, d8)); mind8 = _mm_max_epi16(mind8, _mm_and_si128(mask, d8));
_mm_store_si128((__m128i*)(sad + d), usad8); _mm_store_si128((__m128i*)(sad + d), usad8);
_mm_store_si128((__m128i*)(sad + d + 8), vsad8); _mm_store_si128((__m128i*)(sad + d + 8), vsad8);
mask = _mm_cmpgt_epi16(minsad8, vsad8); mask = _mm_cmpgt_epi16(minsad8, vsad8);
minsad8 = _mm_min_epi16(minsad8, vsad8); minsad8 = _mm_min_epi16(minsad8, vsad8);
d8 = _mm_add_epi16(d8, dd_8); d8 = _mm_add_epi16(d8, dd_8);
mind8 = _mm_max_epi16(mind8, _mm_and_si128(mask, d8)); mind8 = _mm_max_epi16(mind8, _mm_and_si128(mask, d8));
d8 = _mm_add_epi16(d8, dd_8); d8 = _mm_add_epi16(d8, dd_8);
@ -438,32 +438,33 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right,
dptr[y*dstep] = FILTERED; dptr[y*dstep] = FILTERED;
continue; continue;
} }
__m128i minsad82 = _mm_unpackhi_epi64(minsad8, minsad8); __m128i minsad82 = _mm_unpackhi_epi64(minsad8, minsad8);
__m128i mind82 = _mm_unpackhi_epi64(mind8, mind8); __m128i mind82 = _mm_unpackhi_epi64(mind8, mind8);
mask = _mm_cmpgt_epi16(minsad8, minsad82); mask = _mm_cmpgt_epi16(minsad8, minsad82);
mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask)); mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask));
minsad8 = _mm_min_epi16(minsad8, minsad82); minsad8 = _mm_min_epi16(minsad8, minsad82);
minsad82 = _mm_shufflelo_epi16(minsad8, _MM_SHUFFLE(3,2,3,2)); minsad82 = _mm_shufflelo_epi16(minsad8, _MM_SHUFFLE(3,2,3,2));
mind82 = _mm_shufflelo_epi16(mind8, _MM_SHUFFLE(3,2,3,2)); mind82 = _mm_shufflelo_epi16(mind8, _MM_SHUFFLE(3,2,3,2));
mask = _mm_cmpgt_epi16(minsad8, minsad82); mask = _mm_cmpgt_epi16(minsad8, minsad82);
mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask)); mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask));
minsad8 = _mm_min_epi16(minsad8, minsad82); minsad8 = _mm_min_epi16(minsad8, minsad82);
minsad82 = _mm_shufflelo_epi16(minsad8, 1); minsad82 = _mm_shufflelo_epi16(minsad8, 1);
mind82 = _mm_shufflelo_epi16(mind8, 1); mind82 = _mm_shufflelo_epi16(mind8, 1);
mask = _mm_cmpgt_epi16(minsad8, minsad82); mask = _mm_cmpgt_epi16(minsad8, minsad82);
mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask)); mind8 = _mm_xor_si128(mind8,_mm_and_si128(_mm_xor_si128(mind82,mind8),mask));
mind = (short)_mm_cvtsi128_si32(mind8); mind = (short)_mm_cvtsi128_si32(mind8);
minsad = sad[mind]; minsad = sad[mind];
if( uniquenessRatio > 0 ) if( uniquenessRatio > 0 )
{ {
int thresh = minsad + ((minsad * uniquenessRatio) >> 8); int thresh = minsad + ((minsad * uniquenessRatio) >> 8);
__m128i thresh8 = _mm_set1_epi16((short)(thresh + 1)); __m128i thresh8 = _mm_set1_epi16((short)(thresh + 1));
__m128i d1 = _mm_set1_epi16((short)(mind-1)), d2 = _mm_set1_epi16((short)(mind+1)); __m128i d1 = _mm_set1_epi16((short)(mind-1)), d2 = _mm_set1_epi16((short)(mind+1));
__m128i dd_16 = _mm_add_epi16(dd_8, dd_8), d8 = _mm_sub_epi16(d0_8, dd_16); __m128i dd_16 = _mm_add_epi16(dd_8, dd_8);
d8 = _mm_sub_epi16(d0_8, dd_16);
for( d = 0; d < ndisp; d += 16 ) for( d = 0; d < ndisp; d += 16 )
{ {
@ -492,7 +493,8 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right,
if( 0 < mind && mind < ndisp - 1 ) if( 0 < mind && mind < ndisp - 1 )
{ {
int p = sad[mind+1], n = sad[mind-1], d = p + n - 2*sad[mind] + std::abs(p - n); int p = sad[mind+1], n = sad[mind-1];
d = p + n - 2*sad[mind] + std::abs(p - n);
dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*256/d : 0) + 15) >> 4); dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*256/d : 0) + 15) >> 4);
} }
else else
@ -567,7 +569,7 @@ findStereoCorrespondenceBM( const Mat& left, const Mat& right,
htext[y] += tab[lval]; htext[y] += tab[lval];
} }
} }
// initialize the left and right borders of the disparity map // initialize the left and right borders of the disparity map
for( y = 0; y < height; y++ ) for( y = 0; y < height; y++ )
{ {
@ -583,7 +585,7 @@ findStereoCorrespondenceBM( const Mat& left, const Mat& right,
int* costptr = cost.data ? (int*)cost.data + lofs + x : &costbuf; int* costptr = cost.data ? (int*)cost.data + lofs + x : &costbuf;
int x0 = x - wsz2 - 1, x1 = x + wsz2; int x0 = x - wsz2 - 1, x1 = x + wsz2;
const uchar* cbuf_sub = cbuf0 + ((x0 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp; const uchar* cbuf_sub = cbuf0 + ((x0 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
uchar* cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp; cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
hsad = hsad0 - dy0*ndisp; hsad = hsad0 - dy0*ndisp;
lptr_sub = lptr0 + MIN(MAX(x0, -lofs), width-1-lofs) - dy0*sstep; lptr_sub = lptr0 + MIN(MAX(x0, -lofs), width-1-lofs) - dy0*sstep;
lptr = lptr0 + MIN(MAX(x1, -lofs), width-1-lofs) - dy0*sstep; lptr = lptr0 + MIN(MAX(x1, -lofs), width-1-lofs) - dy0*sstep;
@ -611,7 +613,7 @@ findStereoCorrespondenceBM( const Mat& left, const Mat& right,
// initialize sums // initialize sums
for( d = 0; d < ndisp; d++ ) for( d = 0; d < ndisp; d++ )
sad[d] = (int)(hsad0[d-ndisp*dy0]*(wsz2 + 2 - dy0)); sad[d] = (int)(hsad0[d-ndisp*dy0]*(wsz2 + 2 - dy0));
hsad = hsad0 + (1 - dy0)*ndisp; hsad = hsad0 + (1 - dy0)*ndisp;
for( y = 1 - dy0; y < wsz2; y++, hsad += ndisp ) for( y = 1 - dy0; y < wsz2; y++, hsad += ndisp )
for( d = 0; d < ndisp; d++ ) for( d = 0; d < ndisp; d++ )
@ -662,7 +664,8 @@ findStereoCorrespondenceBM( const Mat& left, const Mat& right,
{ {
sad[-1] = sad[1]; sad[-1] = sad[1];
sad[ndisp] = sad[ndisp-2]; sad[ndisp] = sad[ndisp-2];
int p = sad[mind+1], n = sad[mind-1], d = p + n - 2*sad[mind] + std::abs(p - n); int p = sad[mind+1], n = sad[mind-1];
d = p + n - 2*sad[mind] + std::abs(p - n);
dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*256/d : 0) + 15) >> 4); dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*256/d : 0) + 15) >> 4);
costptr[y*coststep] = sad[mind]; costptr[y*coststep] = sad[mind];
} }
@ -681,16 +684,16 @@ struct PrefilterInvoker
state = _state; state = _state;
} }
void operator()( int ind ) const void operator()( int ind ) const
{ {
if( state->preFilterType == CV_STEREO_BM_NORMALIZED_RESPONSE ) if( state->preFilterType == CV_STEREO_BM_NORMALIZED_RESPONSE )
prefilterNorm( *imgs0[ind], *imgs[ind], state->preFilterSize, state->preFilterCap, buf[ind] ); prefilterNorm( *imgs0[ind], *imgs[ind], state->preFilterSize, state->preFilterCap, buf[ind] );
else else
prefilterXSobel( *imgs0[ind], *imgs[ind], state->preFilterCap ); prefilterXSobel( *imgs0[ind], *imgs[ind], state->preFilterCap );
} }
const Mat* imgs0[2]; const Mat* imgs0[2];
Mat* imgs[2]; Mat* imgs[2];
uchar* buf[2]; uchar* buf[2];
CvStereoBMState *state; CvStereoBMState *state;
}; };
@ -709,21 +712,21 @@ struct FindStereoCorrespInvoker
useShorts = _useShorts; useShorts = _useShorts;
validDisparityRect = _validDisparityRect; validDisparityRect = _validDisparityRect;
} }
void operator()( const BlockedRange& range ) const void operator()( const BlockedRange& range ) const
{ {
int cols = left->cols, rows = left->rows; int cols = left->cols, rows = left->rows;
int _row0 = min(cvRound(range.begin() * rows / nstripes), rows); int _row0 = min(cvRound(range.begin() * rows / nstripes), rows);
int _row1 = min(cvRound(range.end() * rows / nstripes), rows); int _row1 = min(cvRound(range.end() * rows / nstripes), rows);
uchar *ptr = state->slidingSumBuf->data.ptr + range.begin() * stripeBufSize; uchar *ptr = state->slidingSumBuf->data.ptr + range.begin() * stripeBufSize;
int FILTERED = (state->minDisparity - 1)*16; int FILTERED = (state->minDisparity - 1)*16;
Rect roi = validDisparityRect & Rect(0, _row0, cols, _row1 - _row0); Rect roi = validDisparityRect & Rect(0, _row0, cols, _row1 - _row0);
if( roi.height == 0 ) if( roi.height == 0 )
return; return;
int row0 = roi.y; int row0 = roi.y;
int row1 = roi.y + roi.height; int row1 = roi.y + roi.height;
Mat part; Mat part;
if( row0 > _row0 ) if( row0 > _row0 )
{ {
@ -735,22 +738,22 @@ struct FindStereoCorrespInvoker
part = disp->rowRange(row1, _row1); part = disp->rowRange(row1, _row1);
part = Scalar::all(FILTERED); part = Scalar::all(FILTERED);
} }
Mat left_i = left->rowRange(row0, row1); Mat left_i = left->rowRange(row0, row1);
Mat right_i = right->rowRange(row0, row1); Mat right_i = right->rowRange(row0, row1);
Mat disp_i = disp->rowRange(row0, row1); Mat disp_i = disp->rowRange(row0, row1);
Mat cost_i = state->disp12MaxDiff >= 0 ? Mat(state->cost).rowRange(row0, row1) : Mat(); Mat cost_i = state->disp12MaxDiff >= 0 ? Mat(state->cost).rowRange(row0, row1) : Mat();
#if CV_SSE2 #if CV_SSE2
if( useShorts ) if( useShorts )
findStereoCorrespondenceBM_SSE2( left_i, right_i, disp_i, cost_i, *state, ptr, row0, rows - row1 ); findStereoCorrespondenceBM_SSE2( left_i, right_i, disp_i, cost_i, *state, ptr, row0, rows - row1 );
else else
#endif #endif
findStereoCorrespondenceBM( left_i, right_i, disp_i, cost_i, *state, ptr, row0, rows - row1 ); findStereoCorrespondenceBM( left_i, right_i, disp_i, cost_i, *state, ptr, row0, rows - row1 );
if( state->disp12MaxDiff >= 0 ) if( state->disp12MaxDiff >= 0 )
validateDisparity( disp_i, cost_i, state->minDisparity, state->numberOfDisparities, state->disp12MaxDiff ); validateDisparity( disp_i, cost_i, state->minDisparity, state->numberOfDisparities, state->disp12MaxDiff );
if( roi.x > 0 ) if( roi.x > 0 )
{ {
part = disp_i.colRange(0, roi.x); part = disp_i.colRange(0, roi.x);
@ -767,7 +770,7 @@ protected:
const Mat *left, *right; const Mat *left, *right;
Mat* disp; Mat* disp;
CvStereoBMState *state; CvStereoBMState *state;
int nstripes; int nstripes;
int stripeBufSize; int stripeBufSize;
bool useShorts; bool useShorts;
@ -775,7 +778,7 @@ protected:
}; };
static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat& disp0, CvStereoBMState* state) static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat& disp0, CvStereoBMState* state)
{ {
if (left0.size() != right0.size() || disp0.size() != left0.size()) if (left0.size() != right0.size() || disp0.size() != left0.size())
CV_Error( CV_StsUnmatchedSizes, "All the images must have the same size" ); CV_Error( CV_StsUnmatchedSizes, "All the images must have the same size" );
@ -783,7 +786,7 @@ static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat
CV_Error( CV_StsUnsupportedFormat, "Both input images must have CV_8UC1" ); CV_Error( CV_StsUnsupportedFormat, "Both input images must have CV_8UC1" );
if (disp0.type() != CV_16SC1 && disp0.type() != CV_32FC1) if (disp0.type() != CV_16SC1 && disp0.type() != CV_32FC1)
CV_Error( CV_StsUnsupportedFormat, "Disparity image must have CV_16SC1 or CV_32FC1 format" ); CV_Error( CV_StsUnsupportedFormat, "Disparity image must have CV_16SC1 or CV_32FC1 format" );
if( !state ) if( !state )
CV_Error( CV_StsNullPtr, "Stereo BM state is NULL." ); CV_Error( CV_StsNullPtr, "Stereo BM state is NULL." );
@ -809,7 +812,7 @@ static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat
if( state->uniquenessRatio < 0 ) if( state->uniquenessRatio < 0 )
CV_Error( CV_StsOutOfRange, "uniqueness ratio must be non-negative" ); CV_Error( CV_StsOutOfRange, "uniqueness ratio must be non-negative" );
if( !state->preFilteredImg0 || state->preFilteredImg0->cols * state->preFilteredImg0->rows < left0.cols * left0.rows ) if( !state->preFilteredImg0 || state->preFilteredImg0->cols * state->preFilteredImg0->rows < left0.cols * left0.rows )
{ {
cvReleaseMat( &state->preFilteredImg0 ); cvReleaseMat( &state->preFilteredImg0 );
@ -822,7 +825,7 @@ static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat
} }
Mat left(left0.size(), CV_8U, state->preFilteredImg0->data.ptr); Mat left(left0.size(), CV_8U, state->preFilteredImg0->data.ptr);
Mat right(right0.size(), CV_8U, state->preFilteredImg1->data.ptr); Mat right(right0.size(), CV_8U, state->preFilteredImg1->data.ptr);
int mindisp = state->minDisparity; int mindisp = state->minDisparity;
int ndisp = state->numberOfDisparities; int ndisp = state->numberOfDisparities;
@ -832,15 +835,15 @@ static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat
int rofs = -min(ndisp - 1 + mindisp, 0); int rofs = -min(ndisp - 1 + mindisp, 0);
int width1 = width - rofs - ndisp + 1; int width1 = width - rofs - ndisp + 1;
int FILTERED = (state->minDisparity - 1) << DISPARITY_SHIFT; int FILTERED = (state->minDisparity - 1) << DISPARITY_SHIFT;
if( lofs >= width || rofs >= width || width1 < 1 ) if( lofs >= width || rofs >= width || width1 < 1 )
{ {
disp0 = Scalar::all( FILTERED * ( disp0.type() < CV_32F ? 1 : 1./(1 << DISPARITY_SHIFT) ) ); disp0 = Scalar::all( FILTERED * ( disp0.type() < CV_32F ? 1 : 1./(1 << DISPARITY_SHIFT) ) );
return; return;
} }
Mat disp = disp0; Mat disp = disp0;
if( disp0.type() == CV_32F) if( disp0.type() == CV_32F)
{ {
if( !state->disp || state->disp->rows != disp0.rows || state->disp->cols != disp0.cols ) if( !state->disp || state->disp->rows != disp0.rows || state->disp->cols != disp0.cols )
@ -850,8 +853,8 @@ static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat
} }
disp = cv::cvarrToMat(state->disp); disp = cv::cvarrToMat(state->disp);
} }
int wsz = state->SADWindowSize; int wsz = state->SADWindowSize;
int bufSize0 = (int)((ndisp + 2)*sizeof(int)); int bufSize0 = (int)((ndisp + 2)*sizeof(int));
bufSize0 += (int)((height+wsz+2)*ndisp*sizeof(int)); bufSize0 += (int)((height+wsz+2)*ndisp*sizeof(int));
bufSize0 += (int)((height + wsz + 2)*sizeof(int)); bufSize0 += (int)((height + wsz + 2)*sizeof(int));
@ -861,16 +864,16 @@ static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat
int bufSize2 = 0; int bufSize2 = 0;
if( state->speckleRange >= 0 && state->speckleWindowSize > 0 ) if( state->speckleRange >= 0 && state->speckleWindowSize > 0 )
bufSize2 = width*height*(sizeof(cv::Point_<short>) + sizeof(int) + sizeof(uchar)); bufSize2 = width*height*(sizeof(cv::Point_<short>) + sizeof(int) + sizeof(uchar));
#if CV_SSE2 #if CV_SSE2
bool useShorts = state->preFilterCap <= 31 && state->SADWindowSize <= 21 && checkHardwareSupport(CV_CPU_SSE2); bool useShorts = state->preFilterCap <= 31 && state->SADWindowSize <= 21 && checkHardwareSupport(CV_CPU_SSE2);
#else #else
const bool useShorts = false; const bool useShorts = false;
#endif #endif
#ifdef HAVE_TBB #ifdef HAVE_TBB
const double SAD_overhead_coeff = 10.0; const double SAD_overhead_coeff = 10.0;
double N0 = 8000000 / (useShorts ? 1 : 4); // approx tbb's min number instructions reasonable for one thread double N0 = 8000000 / (useShorts ? 1 : 4); // approx tbb's min number instructions reasonable for one thread
double maxStripeSize = min(max(N0 / (width * ndisp), (wsz-1) * SAD_overhead_coeff), (double)height); double maxStripeSize = min(max(N0 / (width * ndisp), (wsz-1) * SAD_overhead_coeff), (double)height);
int nstripes = cvCeil(height / maxStripeSize); int nstripes = cvCeil(height / maxStripeSize);
#else #else
@ -878,27 +881,27 @@ static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat
#endif #endif
int bufSize = max(bufSize0 * nstripes, max(bufSize1 * 2, bufSize2)); int bufSize = max(bufSize0 * nstripes, max(bufSize1 * 2, bufSize2));
if( !state->slidingSumBuf || state->slidingSumBuf->cols < bufSize ) if( !state->slidingSumBuf || state->slidingSumBuf->cols < bufSize )
{ {
cvReleaseMat( &state->slidingSumBuf ); cvReleaseMat( &state->slidingSumBuf );
state->slidingSumBuf = cvCreateMat( 1, bufSize, CV_8U ); state->slidingSumBuf = cvCreateMat( 1, bufSize, CV_8U );
} }
uchar *_buf = state->slidingSumBuf->data.ptr; uchar *_buf = state->slidingSumBuf->data.ptr;
int idx[] = {0,1}; int idx[] = {0,1};
parallel_do(idx, idx+2, PrefilterInvoker(left0, right0, left, right, _buf, _buf + bufSize1, state)); parallel_do(idx, idx+2, PrefilterInvoker(left0, right0, left, right, _buf, _buf + bufSize1, state));
Rect validDisparityRect(0, 0, width, height), R1 = state->roi1, R2 = state->roi2; Rect validDisparityRect(0, 0, width, height), R1 = state->roi1, R2 = state->roi2;
validDisparityRect = getValidDisparityROI(R1.area() > 0 ? Rect(0, 0, width, height) : validDisparityRect, validDisparityRect = getValidDisparityROI(R1.area() > 0 ? Rect(0, 0, width, height) : validDisparityRect,
R2.area() > 0 ? Rect(0, 0, width, height) : validDisparityRect, R2.area() > 0 ? Rect(0, 0, width, height) : validDisparityRect,
state->minDisparity, state->numberOfDisparities, state->minDisparity, state->numberOfDisparities,
state->SADWindowSize); state->SADWindowSize);
parallel_for(BlockedRange(0, nstripes), parallel_for(BlockedRange(0, nstripes),
FindStereoCorrespInvoker(left, right, disp, state, nstripes, FindStereoCorrespInvoker(left, right, disp, state, nstripes,
bufSize0, useShorts, validDisparityRect)); bufSize0, useShorts, validDisparityRect));
if( state->speckleRange >= 0 && state->speckleWindowSize > 0 ) if( state->speckleRange >= 0 && state->speckleWindowSize > 0 )
{ {
Mat buf(state->slidingSumBuf); Mat buf(state->slidingSumBuf);
@ -906,7 +909,7 @@ static void findStereoCorrespondenceBM( const Mat& left0, const Mat& right0, Mat
} }
if (disp0.data != disp.data) if (disp0.data != disp.data)
disp.convertTo(disp0, disp0.type(), 1./(1 << DISPARITY_SHIFT), 0); disp.convertTo(disp0, disp0.type(), 1./(1 << DISPARITY_SHIFT), 0);
} }
StereoBM::StereoBM() StereoBM::StereoBM()
@ -928,13 +931,13 @@ void StereoBM::operator()( InputArray _left, InputArray _right,
CV_Assert( disptype == CV_16S || disptype == CV_32F ); CV_Assert( disptype == CV_16S || disptype == CV_32F );
_disparity.create(left.size(), disptype); _disparity.create(left.size(), disptype);
Mat disparity = _disparity.getMat(); Mat disparity = _disparity.getMat();
findStereoCorrespondenceBM(left, right, disparity, state); findStereoCorrespondenceBM(left, right, disparity, state);
} }
template<> void Ptr<CvStereoBMState>::delete_obj() template<> void Ptr<CvStereoBMState>::delete_obj()
{ cvReleaseStereoBMState(&obj); } { cvReleaseStereoBMState(&obj); }
} }
CV_IMPL void cvFindStereoCorrespondenceBM( const CvArr* leftarr, const CvArr* rightarr, CV_IMPL void cvFindStereoCorrespondenceBM( const CvArr* leftarr, const CvArr* rightarr,
@ -942,7 +945,7 @@ CV_IMPL void cvFindStereoCorrespondenceBM( const CvArr* leftarr, const CvArr* ri
{ {
cv::Mat left = cv::cvarrToMat(leftarr), cv::Mat left = cv::cvarrToMat(leftarr),
right = cv::cvarrToMat(rightarr), right = cv::cvarrToMat(rightarr),
disp = cv::cvarrToMat(disparr); disp = cv::cvarrToMat(disparr);
cv::findStereoCorrespondenceBM(left, right, disp, state); cv::findStereoCorrespondenceBM(left, right, disp, state);
} }

View File

@ -44,17 +44,17 @@
This is a variation of This is a variation of
"Stereo Processing by Semiglobal Matching and Mutual Information" "Stereo Processing by Semiglobal Matching and Mutual Information"
by Heiko Hirschmuller. by Heiko Hirschmuller.
We match blocks rather than individual pixels, thus the algorithm is called We match blocks rather than individual pixels, thus the algorithm is called
SGBM (Semi-global block matching) SGBM (Semi-global block matching)
*/ */
#include "precomp.hpp" #include "precomp.hpp"
#include <limits.h> #include <limits.h>
namespace cv namespace cv
{ {
typedef uchar PixType; typedef uchar PixType;
typedef short CostType; typedef short CostType;
typedef short DispType; typedef short DispType;
@ -105,7 +105,7 @@ StereoSGBM::~StereoSGBM()
row1[x] and row2[x-d]. The subpixel algorithm from row1[x] and row2[x-d]. The subpixel algorithm from
"Depth Discontinuities by Pixel-to-Pixel Stereo" by Stan Birchfield and C. Tomasi "Depth Discontinuities by Pixel-to-Pixel Stereo" by Stan Birchfield and C. Tomasi
is used, hence the suffix BT. is used, hence the suffix BT.
the temporary buffer should contain width2*2 elements the temporary buffer should contain width2*2 elements
*/ */
static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y, static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
@ -119,25 +119,25 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
int D = maxD - minD, width1 = maxX1 - minX1, width2 = maxX2 - minX2; int D = maxD - minD, width1 = maxX1 - minX1, width2 = maxX2 - minX2;
const PixType *row1 = img1.ptr<PixType>(y), *row2 = img2.ptr<PixType>(y); const PixType *row1 = img1.ptr<PixType>(y), *row2 = img2.ptr<PixType>(y);
PixType *prow1 = buffer + width2*2, *prow2 = prow1 + width*cn*2; PixType *prow1 = buffer + width2*2, *prow2 = prow1 + width*cn*2;
tab += tabOfs; tab += tabOfs;
for( c = 0; c < cn*2; c++ ) for( c = 0; c < cn*2; c++ )
{ {
prow1[width*c] = prow1[width*c + width-1] = prow1[width*c] = prow1[width*c + width-1] =
prow2[width*c] = prow2[width*c + width-1] = tab[0]; prow2[width*c] = prow2[width*c + width-1] = tab[0];
} }
int n1 = y > 0 ? -(int)img1.step : 0, s1 = y < img1.rows-1 ? (int)img1.step : 0; int n1 = y > 0 ? -(int)img1.step : 0, s1 = y < img1.rows-1 ? (int)img1.step : 0;
int n2 = y > 0 ? -(int)img2.step : 0, s2 = y < img2.rows-1 ? (int)img2.step : 0; int n2 = y > 0 ? -(int)img2.step : 0, s2 = y < img2.rows-1 ? (int)img2.step : 0;
if( cn == 1 ) if( cn == 1 )
{ {
for( x = 1; x < width-1; x++ ) for( x = 1; x < width-1; x++ )
{ {
prow1[x] = tab[(row1[x+1] - row1[x-1])*2 + row1[x+n1+1] - row1[x+n1-1] + row1[x+s1+1] - row1[x+s1-1]]; prow1[x] = tab[(row1[x+1] - row1[x-1])*2 + row1[x+n1+1] - row1[x+n1-1] + row1[x+s1+1] - row1[x+s1-1]];
prow2[width-1-x] = tab[(row2[x+1] - row2[x-1])*2 + row2[x+n2+1] - row2[x+n2-1] + row2[x+s2+1] - row2[x+s2-1]]; prow2[width-1-x] = tab[(row2[x+1] - row2[x-1])*2 + row2[x+n2+1] - row2[x+n2-1] + row2[x+s2+1] - row2[x+s2-1]];
prow1[x+width] = row1[x]; prow1[x+width] = row1[x];
prow2[width-1-x+width] = row2[x]; prow2[width-1-x+width] = row2[x];
} }
@ -149,35 +149,35 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
prow1[x] = tab[(row1[x*3+3] - row1[x*3-3])*2 + row1[x*3+n1+3] - row1[x*3+n1-3] + row1[x*3+s1+3] - row1[x*3+s1-3]]; prow1[x] = tab[(row1[x*3+3] - row1[x*3-3])*2 + row1[x*3+n1+3] - row1[x*3+n1-3] + row1[x*3+s1+3] - row1[x*3+s1-3]];
prow1[x+width] = tab[(row1[x*3+4] - row1[x*3-2])*2 + row1[x*3+n1+4] - row1[x*3+n1-2] + row1[x*3+s1+4] - row1[x*3+s1-2]]; prow1[x+width] = tab[(row1[x*3+4] - row1[x*3-2])*2 + row1[x*3+n1+4] - row1[x*3+n1-2] + row1[x*3+s1+4] - row1[x*3+s1-2]];
prow1[x+width*2] = tab[(row1[x*3+5] - row1[x*3-1])*2 + row1[x*3+n1+5] - row1[x*3+n1-1] + row1[x*3+s1+5] - row1[x*3+s1-1]]; prow1[x+width*2] = tab[(row1[x*3+5] - row1[x*3-1])*2 + row1[x*3+n1+5] - row1[x*3+n1-1] + row1[x*3+s1+5] - row1[x*3+s1-1]];
prow2[width-1-x] = tab[(row2[x*3+3] - row2[x*3-3])*2 + row2[x*3+n2+3] - row2[x*3+n2-3] + row2[x*3+s2+3] - row2[x*3+s2-3]]; prow2[width-1-x] = tab[(row2[x*3+3] - row2[x*3-3])*2 + row2[x*3+n2+3] - row2[x*3+n2-3] + row2[x*3+s2+3] - row2[x*3+s2-3]];
prow2[width-1-x+width] = tab[(row2[x*3+4] - row2[x*3-2])*2 + row2[x*3+n2+4] - row2[x*3+n2-2] + row2[x*3+s2+4] - row2[x*3+s2-2]]; prow2[width-1-x+width] = tab[(row2[x*3+4] - row2[x*3-2])*2 + row2[x*3+n2+4] - row2[x*3+n2-2] + row2[x*3+s2+4] - row2[x*3+s2-2]];
prow2[width-1-x+width*2] = tab[(row2[x*3+5] - row2[x*3-1])*2 + row2[x*3+n2+5] - row2[x*3+n2-1] + row2[x*3+s2+5] - row2[x*3+s2-1]]; prow2[width-1-x+width*2] = tab[(row2[x*3+5] - row2[x*3-1])*2 + row2[x*3+n2+5] - row2[x*3+n2-1] + row2[x*3+s2+5] - row2[x*3+s2-1]];
prow1[x+width*3] = row1[x*3]; prow1[x+width*3] = row1[x*3];
prow1[x+width*4] = row1[x*3+1]; prow1[x+width*4] = row1[x*3+1];
prow1[x+width*5] = row1[x*3+2]; prow1[x+width*5] = row1[x*3+2];
prow2[width-1-x+width*3] = row2[x*3]; prow2[width-1-x+width*3] = row2[x*3];
prow2[width-1-x+width*4] = row2[x*3+1]; prow2[width-1-x+width*4] = row2[x*3+1];
prow2[width-1-x+width*5] = row2[x*3+2]; prow2[width-1-x+width*5] = row2[x*3+2];
} }
} }
memset( cost, 0, width1*D*sizeof(cost[0]) ); memset( cost, 0, width1*D*sizeof(cost[0]) );
buffer -= minX2; buffer -= minX2;
cost -= minX1*D + minD; // simplify the cost indices inside the loop cost -= minX1*D + minD; // simplify the cost indices inside the loop
#if CV_SSE2 #if CV_SSE2
volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2); volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
#endif #endif
#if 1 #if 1
for( c = 0; c < cn*2; c++, prow1 += width, prow2 += width ) for( c = 0; c < cn*2; c++, prow1 += width, prow2 += width )
{ {
int diff_scale = c < cn ? 0 : 2; int diff_scale = c < cn ? 0 : 2;
// precompute // precompute
// v0 = min(row2[x-1/2], row2[x], row2[x+1/2]) and // v0 = min(row2[x-1/2], row2[x], row2[x+1/2]) and
// v1 = max(row2[x-1/2], row2[x], row2[x+1/2]) and // v1 = max(row2[x-1/2], row2[x], row2[x+1/2]) and
@ -191,7 +191,7 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
buffer[x] = (PixType)v0; buffer[x] = (PixType)v0;
buffer[x + width2] = (PixType)v1; buffer[x + width2] = (PixType)v1;
} }
for( x = minX1; x < maxX1; x++ ) for( x = minX1; x < maxX1; x++ )
{ {
int u = prow1[x]; int u = prow1[x];
@ -199,14 +199,14 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
int ur = x < width-1 ? (u + prow1[x+1])/2 : u; int ur = x < width-1 ? (u + prow1[x+1])/2 : u;
int u0 = min(ul, ur); u0 = min(u0, u); int u0 = min(ul, ur); u0 = min(u0, u);
int u1 = max(ul, ur); u1 = max(u1, u); int u1 = max(ul, ur); u1 = max(u1, u);
#if CV_SSE2 #if CV_SSE2
if( useSIMD ) if( useSIMD )
{ {
__m128i _u = _mm_set1_epi8((char)u), _u0 = _mm_set1_epi8((char)u0); __m128i _u = _mm_set1_epi8((char)u), _u0 = _mm_set1_epi8((char)u0);
__m128i _u1 = _mm_set1_epi8((char)u1), z = _mm_setzero_si128(); __m128i _u1 = _mm_set1_epi8((char)u1), z = _mm_setzero_si128();
__m128i ds = _mm_cvtsi32_si128(diff_scale); __m128i ds = _mm_cvtsi32_si128(diff_scale);
for( int d = minD; d < maxD; d += 16 ) for( int d = minD; d < maxD; d += 16 )
{ {
__m128i _v = _mm_loadu_si128((const __m128i*)(prow2 + width-x-1 + d)); __m128i _v = _mm_loadu_si128((const __m128i*)(prow2 + width-x-1 + d));
@ -215,10 +215,10 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
__m128i c0 = _mm_max_epu8(_mm_subs_epu8(_u, _v1), _mm_subs_epu8(_v0, _u)); __m128i c0 = _mm_max_epu8(_mm_subs_epu8(_u, _v1), _mm_subs_epu8(_v0, _u));
__m128i c1 = _mm_max_epu8(_mm_subs_epu8(_v, _u1), _mm_subs_epu8(_u0, _v)); __m128i c1 = _mm_max_epu8(_mm_subs_epu8(_v, _u1), _mm_subs_epu8(_u0, _v));
__m128i diff = _mm_min_epu8(c0, c1); __m128i diff = _mm_min_epu8(c0, c1);
c0 = _mm_load_si128((__m128i*)(cost + x*D + d)); c0 = _mm_load_si128((__m128i*)(cost + x*D + d));
c1 = _mm_load_si128((__m128i*)(cost + x*D + d + 8)); c1 = _mm_load_si128((__m128i*)(cost + x*D + d + 8));
_mm_store_si128((__m128i*)(cost + x*D + d), _mm_adds_epi16(c0, _mm_srl_epi16(_mm_unpacklo_epi8(diff,z), ds))); _mm_store_si128((__m128i*)(cost + x*D + d), _mm_adds_epi16(c0, _mm_srl_epi16(_mm_unpacklo_epi8(diff,z), ds)));
_mm_store_si128((__m128i*)(cost + x*D + d + 8), _mm_adds_epi16(c1, _mm_srl_epi16(_mm_unpackhi_epi8(diff,z), ds))); _mm_store_si128((__m128i*)(cost + x*D + d + 8), _mm_adds_epi16(c1, _mm_srl_epi16(_mm_unpackhi_epi8(diff,z), ds)));
} }
@ -233,7 +233,7 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
int v1 = buffer[width-x-1 + d + width2]; int v1 = buffer[width-x-1 + d + width2];
int c0 = max(0, u - v1); c0 = max(c0, v0 - u); int c0 = max(0, u - v1); c0 = max(c0, v0 - u);
int c1 = max(0, v - u1); c1 = max(c1, u0 - v); int c1 = max(0, v - u1); c1 = max(c1, u0 - v);
cost[x*D + d] = (CostType)(cost[x*D+d] + (min(c0, c1) >> diff_scale)); cost[x*D + d] = (CostType)(cost[x*D+d] + (min(c0, c1) >> diff_scale));
} }
} }
@ -249,14 +249,14 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
if( useSIMD ) if( useSIMD )
{ {
__m128i _u = _mm_set1_epi8(u), z = _mm_setzero_si128(); __m128i _u = _mm_set1_epi8(u), z = _mm_setzero_si128();
for( int d = minD; d < maxD; d += 16 ) for( int d = minD; d < maxD; d += 16 )
{ {
__m128i _v = _mm_loadu_si128((const __m128i*)(prow2 + width-1-x + d)); __m128i _v = _mm_loadu_si128((const __m128i*)(prow2 + width-1-x + d));
__m128i diff = _mm_adds_epu8(_mm_subs_epu8(_u,_v), _mm_subs_epu8(_v,_u)); __m128i diff = _mm_adds_epu8(_mm_subs_epu8(_u,_v), _mm_subs_epu8(_v,_u));
__m128i c0 = _mm_load_si128((__m128i*)(cost + x*D + d)); __m128i c0 = _mm_load_si128((__m128i*)(cost + x*D + d));
__m128i c1 = _mm_load_si128((__m128i*)(cost + x*D + d + 8)); __m128i c1 = _mm_load_si128((__m128i*)(cost + x*D + d + 8));
_mm_store_si128((__m128i*)(cost + x*D + d), _mm_adds_epi16(c0, _mm_unpacklo_epi8(diff,z))); _mm_store_si128((__m128i*)(cost + x*D + d), _mm_adds_epi16(c0, _mm_unpacklo_epi8(diff,z)));
_mm_store_si128((__m128i*)(cost + x*D + d + 8), _mm_adds_epi16(c1, _mm_unpackhi_epi8(diff,z))); _mm_store_si128((__m128i*)(cost + x*D + d + 8), _mm_adds_epi16(c1, _mm_unpackhi_epi8(diff,z)));
} }
@ -282,22 +282,22 @@ static void calcPixelCostBT( const Mat& img1, const Mat& img2, int y,
minD <= d < maxD. minD <= d < maxD.
disp2full is the reverse disparity map, that is: disp2full is the reverse disparity map, that is:
disp2full(x+roi.x,y+roi.y)=d means that img2(x+roi.x, y+roi.y) ~ img1(x+roi.x+d, y+roi.y) disp2full(x+roi.x,y+roi.y)=d means that img2(x+roi.x, y+roi.y) ~ img1(x+roi.x+d, y+roi.y)
note that disp1buf will have the same size as the roi and note that disp1buf will have the same size as the roi and
disp2full will have the same size as img1 (or img2). disp2full will have the same size as img1 (or img2).
On exit disp2buf is not the final disparity, it is an intermediate result that becomes On exit disp2buf is not the final disparity, it is an intermediate result that becomes
final after all the tiles are processed. final after all the tiles are processed.
the disparity in disp1buf is written with sub-pixel accuracy the disparity in disp1buf is written with sub-pixel accuracy
(4 fractional bits, see CvStereoSGBM::DISP_SCALE), (4 fractional bits, see CvStereoSGBM::DISP_SCALE),
using quadratic interpolation, while the disparity in disp2buf using quadratic interpolation, while the disparity in disp2buf
is written as is, without interpolation. is written as is, without interpolation.
disp2cost also has the same size as img1 (or img2). disp2cost also has the same size as img1 (or img2).
It contains the minimum current cost, used to find the best disparity, corresponding to the minimal cost. It contains the minimum current cost, used to find the best disparity, corresponding to the minimal cost.
*/ */
static void computeDisparitySGBM( const Mat& img1, const Mat& img2, static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
Mat& disp1, const StereoSGBM& params, Mat& disp1, const StereoSGBM& params,
Mat& buffer ) Mat& buffer )
{ {
#if CV_SSE2 #if CV_SSE2
@ -312,15 +312,15 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
}; };
volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2); volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
#endif #endif
const int ALIGN = 16; const int ALIGN = 16;
const int DISP_SHIFT = StereoSGBM::DISP_SHIFT; const int DISP_SHIFT = StereoSGBM::DISP_SHIFT;
const int DISP_SCALE = StereoSGBM::DISP_SCALE; const int DISP_SCALE = StereoSGBM::DISP_SCALE;
const CostType MAX_COST = SHRT_MAX; const CostType MAX_COST = SHRT_MAX;
int minD = params.minDisparity, maxD = minD + params.numberOfDisparities; int minD = params.minDisparity, maxD = minD + params.numberOfDisparities;
Size SADWindowSize; Size SADWindowSize;
SADWindowSize.width = SADWindowSize.height = params.SADWindowSize > 0 ? params.SADWindowSize : 5; SADWindowSize.width = SADWindowSize.height = params.SADWindowSize > 0 ? params.SADWindowSize : 5;
@ -336,28 +336,28 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
int npasses = params.fullDP ? 2 : 1; int npasses = params.fullDP ? 2 : 1;
const int TAB_OFS = 256*4, TAB_SIZE = 256 + TAB_OFS*2; const int TAB_OFS = 256*4, TAB_SIZE = 256 + TAB_OFS*2;
PixType clipTab[TAB_SIZE]; PixType clipTab[TAB_SIZE];
for( k = 0; k < TAB_SIZE; k++ ) for( k = 0; k < TAB_SIZE; k++ )
clipTab[k] = (PixType)(min(max(k - TAB_OFS, -ftzero), ftzero) + ftzero); clipTab[k] = (PixType)(min(max(k - TAB_OFS, -ftzero), ftzero) + ftzero);
if( minX1 >= maxX1 ) if( minX1 >= maxX1 )
{ {
disp1 = Scalar::all(INVALID_DISP_SCALED); disp1 = Scalar::all(INVALID_DISP_SCALED);
return; return;
} }
CV_Assert( D % 16 == 0 ); CV_Assert( D % 16 == 0 );
// NR - the number of directions. the loop on x below that computes Lr assumes that NR == 8. // NR - the number of directions. the loop on x below that computes Lr assumes that NR == 8.
// if you change NR, please, modify the loop as well. // if you change NR, please, modify the loop as well.
int D2 = D+16, NRD2 = NR2*D2; int D2 = D+16, NRD2 = NR2*D2;
// the number of L_r(.,.) and min_k L_r(.,.) lines in the buffer: // the number of L_r(.,.) and min_k L_r(.,.) lines in the buffer:
// for 8-way dynamic programming we need the current row and // for 8-way dynamic programming we need the current row and
// the previous row, i.e. 2 rows in total // the previous row, i.e. 2 rows in total
const int NLR = 2; const int NLR = 2;
const int LrBorder = NLR - 1; const int LrBorder = NLR - 1;
// for each possible stereo match (img1(x,y) <=> img2(x-d,y)) // for each possible stereo match (img1(x,y) <=> img2(x-d,y))
// we keep pixel difference cost (C) and the summary cost over NR directions (S). // we keep pixel difference cost (C) and the summary cost over NR directions (S).
// we also keep all the partial costs for the previous line L_r(x,d) and also min_k L_r(x, k) // we also keep all the partial costs for the previous line L_r(x,d) and also min_k L_r(x, k)
@ -370,29 +370,29 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
CSBufSize*2*sizeof(CostType) + // C, S CSBufSize*2*sizeof(CostType) + // C, S
width*16*img1.channels()*sizeof(PixType) + // temp buffer for computing per-pixel cost width*16*img1.channels()*sizeof(PixType) + // temp buffer for computing per-pixel cost
width*(sizeof(CostType) + sizeof(DispType)) + 1024; // disp2cost + disp2 width*(sizeof(CostType) + sizeof(DispType)) + 1024; // disp2cost + disp2
if( !buffer.data || !buffer.isContinuous() || if( !buffer.data || !buffer.isContinuous() ||
buffer.cols*buffer.rows*buffer.elemSize() < totalBufSize ) buffer.cols*buffer.rows*buffer.elemSize() < totalBufSize )
buffer.create(1, (int)totalBufSize, CV_8U); buffer.create(1, (int)totalBufSize, CV_8U);
// summary cost over different (nDirs) directions // summary cost over different (nDirs) directions
CostType* Cbuf = (CostType*)alignPtr(buffer.data, ALIGN); CostType* Cbuf = (CostType*)alignPtr(buffer.data, ALIGN);
CostType* Sbuf = Cbuf + CSBufSize; CostType* Sbuf = Cbuf + CSBufSize;
CostType* hsumBuf = Sbuf + CSBufSize; CostType* hsumBuf = Sbuf + CSBufSize;
CostType* pixDiff = hsumBuf + costBufSize*hsumBufNRows; CostType* pixDiff = hsumBuf + costBufSize*hsumBufNRows;
CostType* disp2cost = pixDiff + costBufSize + (LrSize + minLrSize)*NLR; CostType* disp2cost = pixDiff + costBufSize + (LrSize + minLrSize)*NLR;
DispType* disp2ptr = (DispType*)(disp2cost + width); DispType* disp2ptr = (DispType*)(disp2cost + width);
PixType* tempBuf = (PixType*)(disp2ptr + width); PixType* tempBuf = (PixType*)(disp2ptr + width);
// add P2 to every C(x,y). it saves a few operations in the inner loops // add P2 to every C(x,y). it saves a few operations in the inner loops
for( k = 0; k < width1*D; k++ ) for( k = 0; k < width1*D; k++ )
Cbuf[k] = (CostType)P2; Cbuf[k] = (CostType)P2;
for( int pass = 1; pass <= npasses; pass++ ) for( int pass = 1; pass <= npasses; pass++ )
{ {
int x1, y1, x2, y2, dx, dy; int x1, y1, x2, y2, dx, dy;
if( pass == 1 ) if( pass == 1 )
{ {
y1 = 0; y2 = height; dy = 1; y1 = 0; y2 = height; dy = 1;
@ -403,9 +403,9 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
y1 = height-1; y2 = -1; dy = -1; y1 = height-1; y2 = -1; dy = -1;
x1 = width1-1; x2 = -1; dx = -1; x1 = width1-1; x2 = -1; dx = -1;
} }
CostType *Lr[NLR]={0}, *minLr[NLR]={0}; CostType *Lr[NLR]={0}, *minLr[NLR]={0};
for( k = 0; k < NLR; k++ ) for( k = 0; k < NLR; k++ )
{ {
// shift Lr[k] and minLr[k] pointers, because we allocated them with the borders, // shift Lr[k] and minLr[k] pointers, because we allocated them with the borders,
@ -418,26 +418,26 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
minLr[k] = pixDiff + costBufSize + LrSize*NLR + minLrSize*k + NR2*2; minLr[k] = pixDiff + costBufSize + LrSize*NLR + minLrSize*k + NR2*2;
memset( minLr[k] - LrBorder*NR2, 0, minLrSize*sizeof(CostType) ); memset( minLr[k] - LrBorder*NR2, 0, minLrSize*sizeof(CostType) );
} }
for( int y = y1; y != y2; y += dy ) for( int y = y1; y != y2; y += dy )
{ {
int x, d; int x, d;
DispType* disp1ptr = disp1.ptr<DispType>(y); DispType* disp1ptr = disp1.ptr<DispType>(y);
CostType* C = Cbuf + (!params.fullDP ? 0 : y*costBufSize); CostType* C = Cbuf + (!params.fullDP ? 0 : y*costBufSize);
CostType* S = Sbuf + (!params.fullDP ? 0 : y*costBufSize); CostType* S = Sbuf + (!params.fullDP ? 0 : y*costBufSize);
if( pass == 1 ) // compute C on the first pass, and reuse it on the second pass, if any. if( pass == 1 ) // compute C on the first pass, and reuse it on the second pass, if any.
{ {
int dy1 = y == 0 ? 0 : y + SH2, dy2 = y == 0 ? SH2 : dy1; int dy1 = y == 0 ? 0 : y + SH2, dy2 = y == 0 ? SH2 : dy1;
for( k = dy1; k <= dy2; k++ ) for( k = dy1; k <= dy2; k++ )
{ {
CostType* hsumAdd = hsumBuf + (min(k, height-1) % hsumBufNRows)*costBufSize; CostType* hsumAdd = hsumBuf + (min(k, height-1) % hsumBufNRows)*costBufSize;
if( k < height ) if( k < height )
{ {
calcPixelCostBT( img1, img2, k, minD, maxD, pixDiff, tempBuf, clipTab, TAB_OFS, ftzero ); calcPixelCostBT( img1, img2, k, minD, maxD, pixDiff, tempBuf, clipTab, TAB_OFS, ftzero );
memset(hsumAdd, 0, D*sizeof(CostType)); memset(hsumAdd, 0, D*sizeof(CostType));
for( x = 0; x <= SW2*D; x += D ) for( x = 0; x <= SW2*D; x += D )
{ {
@ -445,17 +445,17 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
for( d = 0; d < D; d++ ) for( d = 0; d < D; d++ )
hsumAdd[d] = (CostType)(hsumAdd[d] + pixDiff[x + d]*scale); hsumAdd[d] = (CostType)(hsumAdd[d] + pixDiff[x + d]*scale);
} }
if( y > 0 ) if( y > 0 )
{ {
const CostType* hsumSub = hsumBuf + (max(y - SH2 - 1, 0) % hsumBufNRows)*costBufSize; const CostType* hsumSub = hsumBuf + (max(y - SH2 - 1, 0) % hsumBufNRows)*costBufSize;
const CostType* Cprev = !params.fullDP || y == 0 ? C : C - costBufSize; const CostType* Cprev = !params.fullDP || y == 0 ? C : C - costBufSize;
for( x = D; x < width1*D; x += D ) for( x = D; x < width1*D; x += D )
{ {
const CostType* pixAdd = pixDiff + min(x + SW2*D, (width1-1)*D); const CostType* pixAdd = pixDiff + min(x + SW2*D, (width1-1)*D);
const CostType* pixSub = pixDiff + max(x - (SW2+1)*D, 0); const CostType* pixSub = pixDiff + max(x - (SW2+1)*D, 0);
#if CV_SSE2 #if CV_SSE2
if( useSIMD ) if( useSIMD )
{ {
@ -490,13 +490,13 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
{ {
const CostType* pixAdd = pixDiff + min(x + SW2*D, (width1-1)*D); const CostType* pixAdd = pixDiff + min(x + SW2*D, (width1-1)*D);
const CostType* pixSub = pixDiff + max(x - (SW2+1)*D, 0); const CostType* pixSub = pixDiff + max(x - (SW2+1)*D, 0);
for( d = 0; d < D; d++ ) for( d = 0; d < D; d++ )
hsumAdd[x + d] = (CostType)(hsumAdd[x - D + d] + pixAdd[d] - pixSub[d]); hsumAdd[x + d] = (CostType)(hsumAdd[x - D + d] + pixAdd[d] - pixSub[d]);
} }
} }
} }
if( y == 0 ) if( y == 0 )
{ {
int scale = k == 0 ? SH2 + 1 : 1; int scale = k == 0 ? SH2 + 1 : 1;
@ -504,18 +504,18 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
C[x] = (CostType)(C[x] + hsumAdd[x]*scale); C[x] = (CostType)(C[x] + hsumAdd[x]*scale);
} }
} }
// also, clear the S buffer // also, clear the S buffer
for( k = 0; k < width1*D; k++ ) for( k = 0; k < width1*D; k++ )
S[k] = 0; S[k] = 0;
} }
// clear the left and the right borders // clear the left and the right borders
memset( Lr[0] - NRD2*LrBorder - 8, 0, NRD2*LrBorder*sizeof(CostType) ); memset( Lr[0] - NRD2*LrBorder - 8, 0, NRD2*LrBorder*sizeof(CostType) );
memset( Lr[0] + width1*NRD2 - 8, 0, NRD2*LrBorder*sizeof(CostType) ); memset( Lr[0] + width1*NRD2 - 8, 0, NRD2*LrBorder*sizeof(CostType) );
memset( minLr[0] - NR2*LrBorder, 0, NR2*LrBorder*sizeof(CostType) ); memset( minLr[0] - NR2*LrBorder, 0, NR2*LrBorder*sizeof(CostType) );
memset( minLr[0] + width1*NR2, 0, NR2*LrBorder*sizeof(CostType) ); memset( minLr[0] + width1*NR2, 0, NR2*LrBorder*sizeof(CostType) );
/* /*
[formula 13 in the paper] [formula 13 in the paper]
compute L_r(p, d) = C(p, d) + compute L_r(p, d) = C(p, d) +
@ -537,87 +537,87 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
for( x = x1; x != x2; x += dx ) for( x = x1; x != x2; x += dx )
{ {
int xm = x*NR2, xd = xm*D2; int xm = x*NR2, xd = xm*D2;
int delta0 = minLr[0][xm - dx*NR2] + P2, delta1 = minLr[1][xm - NR2 + 1] + P2; int delta0 = minLr[0][xm - dx*NR2] + P2, delta1 = minLr[1][xm - NR2 + 1] + P2;
int delta2 = minLr[1][xm + 2] + P2, delta3 = minLr[1][xm + NR2 + 3] + P2; int delta2 = minLr[1][xm + 2] + P2, delta3 = minLr[1][xm + NR2 + 3] + P2;
CostType* Lr_p0 = Lr[0] + xd - dx*NRD2; CostType* Lr_p0 = Lr[0] + xd - dx*NRD2;
CostType* Lr_p1 = Lr[1] + xd - NRD2 + D2; CostType* Lr_p1 = Lr[1] + xd - NRD2 + D2;
CostType* Lr_p2 = Lr[1] + xd + D2*2; CostType* Lr_p2 = Lr[1] + xd + D2*2;
CostType* Lr_p3 = Lr[1] + xd + NRD2 + D2*3; CostType* Lr_p3 = Lr[1] + xd + NRD2 + D2*3;
Lr_p0[-1] = Lr_p0[D] = Lr_p1[-1] = Lr_p1[D] = Lr_p0[-1] = Lr_p0[D] = Lr_p1[-1] = Lr_p1[D] =
Lr_p2[-1] = Lr_p2[D] = Lr_p3[-1] = Lr_p3[D] = MAX_COST; Lr_p2[-1] = Lr_p2[D] = Lr_p3[-1] = Lr_p3[D] = MAX_COST;
CostType* Lr_p = Lr[0] + xd; CostType* Lr_p = Lr[0] + xd;
const CostType* Cp = C + x*D; const CostType* Cp = C + x*D;
CostType* Sp = S + x*D; CostType* Sp = S + x*D;
#if CV_SSE2 #if CV_SSE2
if( useSIMD ) if( useSIMD )
{ {
__m128i _P1 = _mm_set1_epi16((short)P1); __m128i _P1 = _mm_set1_epi16((short)P1);
__m128i _delta0 = _mm_set1_epi16((short)delta0); __m128i _delta0 = _mm_set1_epi16((short)delta0);
__m128i _delta1 = _mm_set1_epi16((short)delta1); __m128i _delta1 = _mm_set1_epi16((short)delta1);
__m128i _delta2 = _mm_set1_epi16((short)delta2); __m128i _delta2 = _mm_set1_epi16((short)delta2);
__m128i _delta3 = _mm_set1_epi16((short)delta3); __m128i _delta3 = _mm_set1_epi16((short)delta3);
__m128i _minL0 = _mm_set1_epi16((short)MAX_COST); __m128i _minL0 = _mm_set1_epi16((short)MAX_COST);
for( d = 0; d < D; d += 8 ) for( d = 0; d < D; d += 8 )
{ {
__m128i Cpd = _mm_load_si128((const __m128i*)(Cp + d)); __m128i Cpd = _mm_load_si128((const __m128i*)(Cp + d));
__m128i L0, L1, L2, L3; __m128i L0, L1, L2, L3;
L0 = _mm_load_si128((const __m128i*)(Lr_p0 + d)); L0 = _mm_load_si128((const __m128i*)(Lr_p0 + d));
L1 = _mm_load_si128((const __m128i*)(Lr_p1 + d)); L1 = _mm_load_si128((const __m128i*)(Lr_p1 + d));
L2 = _mm_load_si128((const __m128i*)(Lr_p2 + d)); L2 = _mm_load_si128((const __m128i*)(Lr_p2 + d));
L3 = _mm_load_si128((const __m128i*)(Lr_p3 + d)); L3 = _mm_load_si128((const __m128i*)(Lr_p3 + d));
L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d - 1)), _P1)); L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d - 1)), _P1));
L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d + 1)), _P1)); L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d + 1)), _P1));
L1 = _mm_min_epi16(L1, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p1 + d - 1)), _P1)); L1 = _mm_min_epi16(L1, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p1 + d - 1)), _P1));
L1 = _mm_min_epi16(L1, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p1 + d + 1)), _P1)); L1 = _mm_min_epi16(L1, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p1 + d + 1)), _P1));
L2 = _mm_min_epi16(L2, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p2 + d - 1)), _P1)); L2 = _mm_min_epi16(L2, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p2 + d - 1)), _P1));
L2 = _mm_min_epi16(L2, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p2 + d + 1)), _P1)); L2 = _mm_min_epi16(L2, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p2 + d + 1)), _P1));
L3 = _mm_min_epi16(L3, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p3 + d - 1)), _P1)); L3 = _mm_min_epi16(L3, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p3 + d - 1)), _P1));
L3 = _mm_min_epi16(L3, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p3 + d + 1)), _P1)); L3 = _mm_min_epi16(L3, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p3 + d + 1)), _P1));
L0 = _mm_min_epi16(L0, _delta0); L0 = _mm_min_epi16(L0, _delta0);
L0 = _mm_adds_epi16(_mm_subs_epi16(L0, _delta0), Cpd); L0 = _mm_adds_epi16(_mm_subs_epi16(L0, _delta0), Cpd);
L1 = _mm_min_epi16(L1, _delta1); L1 = _mm_min_epi16(L1, _delta1);
L1 = _mm_adds_epi16(_mm_subs_epi16(L1, _delta1), Cpd); L1 = _mm_adds_epi16(_mm_subs_epi16(L1, _delta1), Cpd);
L2 = _mm_min_epi16(L2, _delta2); L2 = _mm_min_epi16(L2, _delta2);
L2 = _mm_adds_epi16(_mm_subs_epi16(L2, _delta2), Cpd); L2 = _mm_adds_epi16(_mm_subs_epi16(L2, _delta2), Cpd);
L3 = _mm_min_epi16(L3, _delta3); L3 = _mm_min_epi16(L3, _delta3);
L3 = _mm_adds_epi16(_mm_subs_epi16(L3, _delta3), Cpd); L3 = _mm_adds_epi16(_mm_subs_epi16(L3, _delta3), Cpd);
_mm_store_si128( (__m128i*)(Lr_p + d), L0); _mm_store_si128( (__m128i*)(Lr_p + d), L0);
_mm_store_si128( (__m128i*)(Lr_p + d + D2), L1); _mm_store_si128( (__m128i*)(Lr_p + d + D2), L1);
_mm_store_si128( (__m128i*)(Lr_p + d + D2*2), L2); _mm_store_si128( (__m128i*)(Lr_p + d + D2*2), L2);
_mm_store_si128( (__m128i*)(Lr_p + d + D2*3), L3); _mm_store_si128( (__m128i*)(Lr_p + d + D2*3), L3);
__m128i t0 = _mm_min_epi16(_mm_unpacklo_epi16(L0, L2), _mm_unpackhi_epi16(L0, L2)); __m128i t0 = _mm_min_epi16(_mm_unpacklo_epi16(L0, L2), _mm_unpackhi_epi16(L0, L2));
__m128i t1 = _mm_min_epi16(_mm_unpacklo_epi16(L1, L3), _mm_unpackhi_epi16(L1, L3)); __m128i t1 = _mm_min_epi16(_mm_unpacklo_epi16(L1, L3), _mm_unpackhi_epi16(L1, L3));
t0 = _mm_min_epi16(_mm_unpacklo_epi16(t0, t1), _mm_unpackhi_epi16(t0, t1)); t0 = _mm_min_epi16(_mm_unpacklo_epi16(t0, t1), _mm_unpackhi_epi16(t0, t1));
_minL0 = _mm_min_epi16(_minL0, t0); _minL0 = _mm_min_epi16(_minL0, t0);
__m128i Sval = _mm_load_si128((const __m128i*)(Sp + d)); __m128i Sval = _mm_load_si128((const __m128i*)(Sp + d));
L0 = _mm_adds_epi16(L0, L1); L0 = _mm_adds_epi16(L0, L1);
L2 = _mm_adds_epi16(L2, L3); L2 = _mm_adds_epi16(L2, L3);
Sval = _mm_adds_epi16(Sval, L0); Sval = _mm_adds_epi16(Sval, L0);
Sval = _mm_adds_epi16(Sval, L2); Sval = _mm_adds_epi16(Sval, L2);
_mm_store_si128((__m128i*)(Sp + d), Sval); _mm_store_si128((__m128i*)(Sp + d), Sval);
} }
_minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 8)); _minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 8));
_mm_storel_epi64((__m128i*)&minLr[0][xm], _minL0); _mm_storel_epi64((__m128i*)&minLr[0][xm], _minL0);
} }
@ -625,28 +625,28 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
#endif #endif
{ {
int minL0 = MAX_COST, minL1 = MAX_COST, minL2 = MAX_COST, minL3 = MAX_COST; int minL0 = MAX_COST, minL1 = MAX_COST, minL2 = MAX_COST, minL3 = MAX_COST;
for( d = 0; d < D; d++ ) for( d = 0; d < D; d++ )
{ {
int Cpd = Cp[d], L0, L1, L2, L3; int Cpd = Cp[d], L0, L1, L2, L3;
L0 = Cpd + min((int)Lr_p0[d], min(Lr_p0[d-1] + P1, min(Lr_p0[d+1] + P1, delta0))) - delta0; L0 = Cpd + min((int)Lr_p0[d], min(Lr_p0[d-1] + P1, min(Lr_p0[d+1] + P1, delta0))) - delta0;
L1 = Cpd + min((int)Lr_p1[d], min(Lr_p1[d-1] + P1, min(Lr_p1[d+1] + P1, delta1))) - delta1; L1 = Cpd + min((int)Lr_p1[d], min(Lr_p1[d-1] + P1, min(Lr_p1[d+1] + P1, delta1))) - delta1;
L2 = Cpd + min((int)Lr_p2[d], min(Lr_p2[d-1] + P1, min(Lr_p2[d+1] + P1, delta2))) - delta2; L2 = Cpd + min((int)Lr_p2[d], min(Lr_p2[d-1] + P1, min(Lr_p2[d+1] + P1, delta2))) - delta2;
L3 = Cpd + min((int)Lr_p3[d], min(Lr_p3[d-1] + P1, min(Lr_p3[d+1] + P1, delta3))) - delta3; L3 = Cpd + min((int)Lr_p3[d], min(Lr_p3[d-1] + P1, min(Lr_p3[d+1] + P1, delta3))) - delta3;
Lr_p[d] = (CostType)L0; Lr_p[d] = (CostType)L0;
minL0 = min(minL0, L0); minL0 = min(minL0, L0);
Lr_p[d + D2] = (CostType)L1; Lr_p[d + D2] = (CostType)L1;
minL1 = min(minL1, L1); minL1 = min(minL1, L1);
Lr_p[d + D2*2] = (CostType)L2; Lr_p[d + D2*2] = (CostType)L2;
minL2 = min(minL2, L2); minL2 = min(minL2, L2);
Lr_p[d + D2*3] = (CostType)L3; Lr_p[d + D2*3] = (CostType)L3;
minL3 = min(minL3, L3); minL3 = min(minL3, L3);
Sp[d] = saturate_cast<CostType>(Sp[d] + L0 + L1 + L2 + L3); Sp[d] = saturate_cast<CostType>(Sp[d] + L0 + L1 + L2 + L3);
} }
minLr[0][xm] = (CostType)minL0; minLr[0][xm] = (CostType)minL0;
@ -655,7 +655,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
minLr[0][xm+3] = (CostType)minL3; minLr[0][xm+3] = (CostType)minL3;
} }
} }
if( pass == npasses ) if( pass == npasses )
{ {
for( x = 0; x < width; x++ ) for( x = 0; x < width; x++ )
@ -663,73 +663,73 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
disp1ptr[x] = disp2ptr[x] = (DispType)INVALID_DISP_SCALED; disp1ptr[x] = disp2ptr[x] = (DispType)INVALID_DISP_SCALED;
disp2cost[x] = MAX_COST; disp2cost[x] = MAX_COST;
} }
for( x = width1 - 1; x >= 0; x-- ) for( x = width1 - 1; x >= 0; x-- )
{ {
CostType* Sp = S + x*D; CostType* Sp = S + x*D;
int minS = MAX_COST, bestDisp = -1; int minS = MAX_COST, bestDisp = -1;
if( npasses == 1 ) if( npasses == 1 )
{ {
int xm = x*NR2, xd = xm*D2; int xm = x*NR2, xd = xm*D2;
int minL0 = MAX_COST; int minL0 = MAX_COST;
int delta0 = minLr[0][xm + NR2] + P2; int delta0 = minLr[0][xm + NR2] + P2;
CostType* Lr_p0 = Lr[0] + xd + NRD2; CostType* Lr_p0 = Lr[0] + xd + NRD2;
Lr_p0[-1] = Lr_p0[D] = MAX_COST; Lr_p0[-1] = Lr_p0[D] = MAX_COST;
CostType* Lr_p = Lr[0] + xd; CostType* Lr_p = Lr[0] + xd;
const CostType* Cp = C + x*D; const CostType* Cp = C + x*D;
#if CV_SSE2 #if CV_SSE2
if( useSIMD ) if( useSIMD )
{ {
__m128i _P1 = _mm_set1_epi16((short)P1); __m128i _P1 = _mm_set1_epi16((short)P1);
__m128i _delta0 = _mm_set1_epi16((short)delta0); __m128i _delta0 = _mm_set1_epi16((short)delta0);
__m128i _minL0 = _mm_set1_epi16((short)minL0); __m128i _minL0 = _mm_set1_epi16((short)minL0);
__m128i _minS = _mm_set1_epi16(MAX_COST), _bestDisp = _mm_set1_epi16(-1); __m128i _minS = _mm_set1_epi16(MAX_COST), _bestDisp = _mm_set1_epi16(-1);
__m128i _d8 = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7), _8 = _mm_set1_epi16(8); __m128i _d8 = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7), _8 = _mm_set1_epi16(8);
for( d = 0; d < D; d += 8 ) for( d = 0; d < D; d += 8 )
{ {
__m128i Cpd = _mm_load_si128((const __m128i*)(Cp + d)), L0; __m128i Cpd = _mm_load_si128((const __m128i*)(Cp + d)), L0;
L0 = _mm_load_si128((const __m128i*)(Lr_p0 + d)); L0 = _mm_load_si128((const __m128i*)(Lr_p0 + d));
L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d - 1)), _P1)); L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d - 1)), _P1));
L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d + 1)), _P1)); L0 = _mm_min_epi16(L0, _mm_adds_epi16(_mm_loadu_si128((const __m128i*)(Lr_p0 + d + 1)), _P1));
L0 = _mm_min_epi16(L0, _delta0); L0 = _mm_min_epi16(L0, _delta0);
L0 = _mm_adds_epi16(_mm_subs_epi16(L0, _delta0), Cpd); L0 = _mm_adds_epi16(_mm_subs_epi16(L0, _delta0), Cpd);
_mm_store_si128((__m128i*)(Lr_p + d), L0); _mm_store_si128((__m128i*)(Lr_p + d), L0);
_minL0 = _mm_min_epi16(_minL0, L0); _minL0 = _mm_min_epi16(_minL0, L0);
L0 = _mm_adds_epi16(L0, *(__m128i*)(Sp + d)); L0 = _mm_adds_epi16(L0, *(__m128i*)(Sp + d));
_mm_store_si128((__m128i*)(Sp + d), L0); _mm_store_si128((__m128i*)(Sp + d), L0);
__m128i mask = _mm_cmpgt_epi16(_minS, L0); __m128i mask = _mm_cmpgt_epi16(_minS, L0);
_minS = _mm_min_epi16(_minS, L0); _minS = _mm_min_epi16(_minS, L0);
_bestDisp = _mm_xor_si128(_bestDisp, _mm_and_si128(_mm_xor_si128(_bestDisp,_d8), mask)); _bestDisp = _mm_xor_si128(_bestDisp, _mm_and_si128(_mm_xor_si128(_bestDisp,_d8), mask));
_d8 = _mm_adds_epi16(_d8, _8); _d8 = _mm_adds_epi16(_d8, _8);
} }
short CV_DECL_ALIGNED(16) bestDispBuf[8]; short CV_DECL_ALIGNED(16) bestDispBuf[8];
_mm_store_si128((__m128i*)bestDispBuf, _bestDisp); _mm_store_si128((__m128i*)bestDispBuf, _bestDisp);
_minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 8)); _minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 8));
_minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 4)); _minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 4));
_minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 2)); _minL0 = _mm_min_epi16(_minL0, _mm_srli_si128(_minL0, 2));
__m128i qS = _mm_min_epi16(_minS, _mm_srli_si128(_minS, 8)); __m128i qS = _mm_min_epi16(_minS, _mm_srli_si128(_minS, 8));
qS = _mm_min_epi16(qS, _mm_srli_si128(qS, 4)); qS = _mm_min_epi16(qS, _mm_srli_si128(qS, 4));
qS = _mm_min_epi16(qS, _mm_srli_si128(qS, 2)); qS = _mm_min_epi16(qS, _mm_srli_si128(qS, 2));
minLr[0][xm] = (CostType)_mm_cvtsi128_si32(_minL0); minLr[0][xm] = (CostType)_mm_cvtsi128_si32(_minL0);
minS = (CostType)_mm_cvtsi128_si32(qS); minS = (CostType)_mm_cvtsi128_si32(qS);
qS = _mm_shuffle_epi32(_mm_unpacklo_epi16(qS, qS), 0); qS = _mm_shuffle_epi32(_mm_unpacklo_epi16(qS, qS), 0);
qS = _mm_cmpeq_epi16(_minS, qS); qS = _mm_cmpeq_epi16(_minS, qS);
int idx = _mm_movemask_epi8(_mm_packs_epi16(qS, qS)) & 255; int idx = _mm_movemask_epi8(_mm_packs_epi16(qS, qS)) & 255;
bestDisp = bestDispBuf[LSBTab[idx]]; bestDisp = bestDispBuf[LSBTab[idx]];
} }
else else
@ -738,10 +738,10 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
for( d = 0; d < D; d++ ) for( d = 0; d < D; d++ )
{ {
int L0 = Cp[d] + min((int)Lr_p0[d], min(Lr_p0[d-1] + P1, min(Lr_p0[d+1] + P1, delta0))) - delta0; int L0 = Cp[d] + min((int)Lr_p0[d], min(Lr_p0[d-1] + P1, min(Lr_p0[d+1] + P1, delta0))) - delta0;
Lr_p[d] = (CostType)L0; Lr_p[d] = (CostType)L0;
minL0 = min(minL0, L0); minL0 = min(minL0, L0);
int Sval = Sp[d] = saturate_cast<CostType>(Sp[d] + L0); int Sval = Sp[d] = saturate_cast<CostType>(Sp[d] + L0);
if( Sval < minS ) if( Sval < minS )
{ {
@ -764,7 +764,7 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
} }
} }
} }
for( d = 0; d < D; d++ ) for( d = 0; d < D; d++ )
{ {
if( Sp[d]*(100 - uniquenessRatio) < minS*100 && std::abs(bestDisp - d) > 1 ) if( Sp[d]*(100 - uniquenessRatio) < minS*100 && std::abs(bestDisp - d) > 1 )
@ -773,13 +773,13 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
if( d < D ) if( d < D )
continue; continue;
d = bestDisp; d = bestDisp;
int x2 = x + minX1 - d - minD; int _x2 = x + minX1 - d - minD;
if( disp2cost[x2] > minS ) if( disp2cost[_x2] > minS )
{ {
disp2cost[x2] = (CostType)minS; disp2cost[_x2] = (CostType)minS;
disp2ptr[x2] = (DispType)(d + minD); disp2ptr[_x2] = (DispType)(d + minD);
} }
if( 0 < d && d < D-1 ) if( 0 < d && d < D-1 )
{ {
// do subpixel quadratic interpolation: // do subpixel quadratic interpolation:
@ -792,24 +792,24 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
d *= DISP_SCALE; d *= DISP_SCALE;
disp1ptr[x + minX1] = (DispType)(d + minD*DISP_SCALE); disp1ptr[x + minX1] = (DispType)(d + minD*DISP_SCALE);
} }
for( x = minX1; x < maxX1; x++ ) for( x = minX1; x < maxX1; x++ )
{ {
// we round the computed disparity both towards -inf and +inf and check // we round the computed disparity both towards -inf and +inf and check
// if either of the corresponding disparities in disp2 is consistent. // if either of the corresponding disparities in disp2 is consistent.
// This is to give the computed disparity a chance to look valid if it is. // This is to give the computed disparity a chance to look valid if it is.
int d = disp1ptr[x]; int d1 = disp1ptr[x];
if( d == INVALID_DISP_SCALED ) if( d1 == INVALID_DISP_SCALED )
continue; continue;
int _d = d >> DISP_SHIFT; int _d = d1 >> DISP_SHIFT;
int d_ = (d + DISP_SCALE-1) >> DISP_SHIFT; int d_ = (d1 + DISP_SCALE-1) >> DISP_SHIFT;
int _x = x - _d, x_ = x - d_; int _x = x - _d, x_ = x - d_;
if( 0 <= _x && _x < width && disp2ptr[_x] >= minD && std::abs(disp2ptr[_x] - _d) > disp12MaxDiff && if( 0 <= _x && _x < width && disp2ptr[_x] >= minD && std::abs(disp2ptr[_x] - _d) > disp12MaxDiff &&
0 <= x_ && x_ < width && disp2ptr[x_] >= minD && std::abs(disp2ptr[x_] - d_) > disp12MaxDiff ) 0 <= x_ && x_ < width && disp2ptr[x_] >= minD && std::abs(disp2ptr[x_] - d_) > disp12MaxDiff )
disp1ptr[x] = (DispType)INVALID_DISP_SCALED; disp1ptr[x] = (DispType)INVALID_DISP_SCALED;
} }
} }
// now shift the cyclic buffers // now shift the cyclic buffers
std::swap( Lr[0], Lr[1] ); std::swap( Lr[0], Lr[1] );
std::swap( minLr[0], minLr[1] ); std::swap( minLr[0], minLr[1] );
@ -825,13 +825,13 @@ void StereoSGBM::operator ()( InputArray _left, InputArray _right,
Mat left = _left.getMat(), right = _right.getMat(); Mat left = _left.getMat(), right = _right.getMat();
CV_Assert( left.size() == right.size() && left.type() == right.type() && CV_Assert( left.size() == right.size() && left.type() == right.type() &&
left.depth() == DataType<PixType>::depth ); left.depth() == DataType<PixType>::depth );
_disp.create( left.size(), CV_16S ); _disp.create( left.size(), CV_16S );
Mat disp = _disp.getMat(); Mat disp = _disp.getMat();
computeDisparitySGBM( left, right, disp, *this, buffer ); computeDisparitySGBM( left, right, disp, *this, buffer );
medianBlur(disp, disp, 3); medianBlur(disp, disp, 3);
if( speckleWindowSize > 0 ) if( speckleWindowSize > 0 )
filterSpeckles(disp, (minDisparity - 1)*DISP_SCALE, speckleWindowSize, DISP_SCALE*speckleRange, buffer); filterSpeckles(disp, (minDisparity - 1)*DISP_SCALE, speckleWindowSize, DISP_SCALE*speckleRange, buffer);
} }
@ -844,33 +844,33 @@ Rect getValidDisparityROI( Rect roi1, Rect roi2,
{ {
int SW2 = SADWindowSize/2; int SW2 = SADWindowSize/2;
int minD = minDisparity, maxD = minDisparity + numberOfDisparities - 1; int minD = minDisparity, maxD = minDisparity + numberOfDisparities - 1;
int xmin = max(roi1.x, roi2.x + maxD) + SW2; int xmin = max(roi1.x, roi2.x + maxD) + SW2;
int xmax = min(roi1.x + roi1.width, roi2.x + roi2.width - minD) - SW2; int xmax = min(roi1.x + roi1.width, roi2.x + roi2.width - minD) - SW2;
int ymin = max(roi1.y, roi2.y) + SW2; int ymin = max(roi1.y, roi2.y) + SW2;
int ymax = min(roi1.y + roi1.height, roi2.y + roi2.height) - SW2; int ymax = min(roi1.y + roi1.height, roi2.y + roi2.height) - SW2;
Rect r(xmin, ymin, xmax - xmin, ymax - ymin); Rect r(xmin, ymin, xmax - xmin, ymax - ymin);
return r.width > 0 && r.height > 0 ? r : Rect(); return r.width > 0 && r.height > 0 ? r : Rect();
}
} }
}
void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSize, void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSize,
double _maxDiff, InputOutputArray __buf ) double _maxDiff, InputOutputArray __buf )
{ {
Mat img = _img.getMat(); Mat img = _img.getMat();
Mat temp, &_buf = __buf.needed() ? __buf.getMatRef() : temp; Mat temp, &_buf = __buf.needed() ? __buf.getMatRef() : temp;
CV_Assert( img.type() == CV_16SC1 ); CV_Assert( img.type() == CV_16SC1 );
int newVal = cvRound(_newval); int newVal = cvRound(_newval);
int maxDiff = cvRound(_maxDiff); int maxDiff = cvRound(_maxDiff);
int width = img.cols, height = img.rows, npixels = width*height; int width = img.cols, height = img.rows, npixels = width*height;
size_t bufSize = npixels*(int)(sizeof(Point2s) + sizeof(int) + sizeof(uchar)); size_t bufSize = npixels*(int)(sizeof(Point2s) + sizeof(int) + sizeof(uchar));
if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize ) if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize )
_buf.create(1, (int)bufSize, CV_8U); _buf.create(1, (int)bufSize, CV_8U);
uchar* buf = _buf.data; uchar* buf = _buf.data;
int i, j, dstep = (int)(img.step/sizeof(short)); int i, j, dstep = (int)(img.step/sizeof(short));
int* labels = (int*)buf; int* labels = (int*)buf;
@ -879,33 +879,33 @@ void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSi
buf += npixels*sizeof(wbuf[0]); buf += npixels*sizeof(wbuf[0]);
uchar* rtype = (uchar*)buf; uchar* rtype = (uchar*)buf;
int curlabel = 0; int curlabel = 0;
// clear out label assignments // clear out label assignments
memset(labels, 0, npixels*sizeof(labels[0])); memset(labels, 0, npixels*sizeof(labels[0]));
for( i = 0; i < height; i++ ) for( i = 0; i < height; i++ )
{ {
short* ds = img.ptr<short>(i); short* ds = img.ptr<short>(i);
int* ls = labels + width*i; int* ls = labels + width*i;
for( j = 0; j < width; j++ ) for( j = 0; j < width; j++ )
{ {
if( ds[j] != newVal ) // not a bad disparity if( ds[j] != newVal ) // not a bad disparity
{ {
if( ls[j] ) // has a label, check for bad label if( ls[j] ) // has a label, check for bad label
{ {
if( rtype[ls[j]] ) // small region, zero out disparity if( rtype[ls[j]] ) // small region, zero out disparity
ds[j] = (short)newVal; ds[j] = (short)newVal;
} }
// no label, assign and propagate // no label, assign and propagate
else else
{ {
Point2s* ws = wbuf; // initialize wavefront Point2s* ws = wbuf; // initialize wavefront
Point2s p((short)j, (short)i); // current pixel Point2s p((short)j, (short)i); // current pixel
curlabel++; // next label curlabel++; // next label
int count = 0; // current region size int count = 0; // current region size
ls[j] = curlabel; ls[j] = curlabel;
// wavefront propagation // wavefront propagation
while( ws >= wbuf ) // wavefront not empty while( ws >= wbuf ) // wavefront not empty
{ {
@ -914,50 +914,50 @@ void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSi
short* dpp = &img.at<short>(p.y, p.x); short* dpp = &img.at<short>(p.y, p.x);
short dp = *dpp; short dp = *dpp;
int* lpp = labels + width*p.y + p.x; int* lpp = labels + width*p.y + p.x;
if( p.x < width-1 && !lpp[+1] && dpp[+1] != newVal && std::abs(dp - dpp[+1]) <= maxDiff ) if( p.x < width-1 && !lpp[+1] && dpp[+1] != newVal && std::abs(dp - dpp[+1]) <= maxDiff )
{ {
lpp[+1] = curlabel; lpp[+1] = curlabel;
*ws++ = Point2s(p.x+1, p.y); *ws++ = Point2s(p.x+1, p.y);
} }
if( p.x > 0 && !lpp[-1] && dpp[-1] != newVal && std::abs(dp - dpp[-1]) <= maxDiff ) if( p.x > 0 && !lpp[-1] && dpp[-1] != newVal && std::abs(dp - dpp[-1]) <= maxDiff )
{ {
lpp[-1] = curlabel; lpp[-1] = curlabel;
*ws++ = Point2s(p.x-1, p.y); *ws++ = Point2s(p.x-1, p.y);
} }
if( p.y < height-1 && !lpp[+width] && dpp[+dstep] != newVal && std::abs(dp - dpp[+dstep]) <= maxDiff ) if( p.y < height-1 && !lpp[+width] && dpp[+dstep] != newVal && std::abs(dp - dpp[+dstep]) <= maxDiff )
{ {
lpp[+width] = curlabel; lpp[+width] = curlabel;
*ws++ = Point2s(p.x, p.y+1); *ws++ = Point2s(p.x, p.y+1);
} }
if( p.y > 0 && !lpp[-width] && dpp[-dstep] != newVal && std::abs(dp - dpp[-dstep]) <= maxDiff ) if( p.y > 0 && !lpp[-width] && dpp[-dstep] != newVal && std::abs(dp - dpp[-dstep]) <= maxDiff )
{ {
lpp[-width] = curlabel; lpp[-width] = curlabel;
*ws++ = Point2s(p.x, p.y-1); *ws++ = Point2s(p.x, p.y-1);
} }
// pop most recent and propagate // pop most recent and propagate
// NB: could try least recent, maybe better convergence // NB: could try least recent, maybe better convergence
p = *--ws; p = *--ws;
} }
// assign label type // assign label type
if( count <= maxSpeckleSize ) // speckle region if( count <= maxSpeckleSize ) // speckle region
{ {
rtype[ls[j]] = 1; // small region label rtype[ls[j]] = 1; // small region label
ds[j] = (short)newVal; ds[j] = (short)newVal;
} }
else else
rtype[ls[j]] = 0; // large region label rtype[ls[j]] = 0; // large region label
} }
} }
} }
} }
} }
void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDisparity, void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDisparity,
int numberOfDisparities, int disp12MaxDiff ) int numberOfDisparities, int disp12MaxDiff )
{ {
@ -971,32 +971,32 @@ void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDis
const int DISP_SHIFT = 4, DISP_SCALE = 1 << DISP_SHIFT; const int DISP_SHIFT = 4, DISP_SCALE = 1 << DISP_SHIFT;
int INVALID_DISP = minD - 1, INVALID_DISP_SCALED = INVALID_DISP*DISP_SCALE; int INVALID_DISP = minD - 1, INVALID_DISP_SCALED = INVALID_DISP*DISP_SCALE;
int costType = cost.type(); int costType = cost.type();
disp12MaxDiff *= DISP_SCALE; disp12MaxDiff *= DISP_SCALE;
CV_Assert( numberOfDisparities > 0 && disp.type() == CV_16S && CV_Assert( numberOfDisparities > 0 && disp.type() == CV_16S &&
(costType == CV_16S || costType == CV_32S) && (costType == CV_16S || costType == CV_32S) &&
disp.size() == cost.size() ); disp.size() == cost.size() );
for( int y = 0; y < rows; y++ ) for( int y = 0; y < rows; y++ )
{ {
short* dptr = disp.ptr<short>(y); short* dptr = disp.ptr<short>(y);
for( x = 0; x < cols; x++ ) for( x = 0; x < cols; x++ )
{ {
disp2buf[x] = INVALID_DISP_SCALED; disp2buf[x] = INVALID_DISP_SCALED;
disp2cost[x] = INT_MAX; disp2cost[x] = INT_MAX;
} }
if( costType == CV_16S ) if( costType == CV_16S )
{ {
const short* cptr = cost.ptr<short>(y); const short* cptr = cost.ptr<short>(y);
for( x = minX1; x < maxX1; x++ ) for( x = minX1; x < maxX1; x++ )
{ {
int d = dptr[x], c = cptr[x]; int d = dptr[x], c = cptr[x];
int x2 = x - ((d + DISP_SCALE/2) >> DISP_SHIFT); int x2 = x - ((d + DISP_SCALE/2) >> DISP_SHIFT);
if( disp2cost[x2] > c ) if( disp2cost[x2] > c )
{ {
disp2cost[x2] = c; disp2cost[x2] = c;
@ -1007,12 +1007,12 @@ void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDis
else else
{ {
const int* cptr = cost.ptr<int>(y); const int* cptr = cost.ptr<int>(y);
for( x = minX1; x < maxX1; x++ ) for( x = minX1; x < maxX1; x++ )
{ {
int d = dptr[x], c = cptr[x]; int d = dptr[x], c = cptr[x];
int x2 = x - ((d + DISP_SCALE/2) >> DISP_SHIFT); int x2 = x - ((d + DISP_SCALE/2) >> DISP_SHIFT);
if( disp2cost[x2] < c ) if( disp2cost[x2] < c )
{ {
disp2cost[x2] = c; disp2cost[x2] = c;
@ -1020,7 +1020,7 @@ void cv::validateDisparity( InputOutputArray _disp, InputArray _cost, int minDis
} }
} }
} }
for( x = minX1; x < maxX1; x++ ) for( x = minX1; x < maxX1; x++ )
{ {
// we round the computed disparity both towards -inf and +inf and check // we round the computed disparity both towards -inf and +inf and check

File diff suppressed because it is too large Load Diff

View File

@ -55,22 +55,22 @@ using namespace cv;
using namespace std; using namespace std;
//template<class T> ostream& operator<<(ostream& out, const Mat_<T>& mat) //template<class T> ostream& operator<<(ostream& out, const Mat_<T>& mat)
//{ //{
// for(Mat_<T>::const_iterator pos = mat.begin(), end = mat.end(); pos != end; ++pos) // for(Mat_<T>::const_iterator pos = mat.begin(), end = mat.end(); pos != end; ++pos)
// out << *pos << " "; // out << *pos << " ";
// return out; // return out;
//} //}
//ostream& operator<<(ostream& out, const Mat& mat) { return out << Mat_<double>(mat); } //ostream& operator<<(ostream& out, const Mat& mat) { return out << Mat_<double>(mat); }
Mat calcRvec(const vector<Point3f>& points, const Size& cornerSize) Mat calcRvec(const vector<Point3f>& points, const Size& cornerSize)
{ {
Point3f p00 = points[0]; Point3f p00 = points[0];
Point3f p10 = points[1]; Point3f p10 = points[1];
Point3f p01 = points[cornerSize.width]; Point3f p01 = points[cornerSize.width];
Vec3d ex(p10.x - p00.x, p10.y - p00.y, p10.z - p00.z); Vec3d ex(p10.x - p00.x, p10.y - p00.y, p10.z - p00.z);
Vec3d ey(p01.x - p00.x, p01.y - p00.y, p01.z - p00.z); Vec3d ey(p01.x - p00.x, p01.y - p00.y, p01.z - p00.z);
Vec3d ez = ex.cross(ey); Vec3d ez = ex.cross(ey);
Mat rot(3, 3, CV_64F); Mat rot(3, 3, CV_64F);
*rot.ptr<Vec3d>(0) = ex; *rot.ptr<Vec3d>(0) = ex;
@ -89,7 +89,7 @@ public:
{ {
} }
~CV_CalibrateCameraArtificialTest() {} ~CV_CalibrateCameraArtificialTest() {}
protected: protected:
int r; int r;
const static int JUST_FIND_CORNERS = 0; const static int JUST_FIND_CORNERS = 0;
@ -111,7 +111,7 @@ protected:
{ {
ts->printf( cvtest::TS::LOG, "Bad shape of camera matrix returned \n"); ts->printf( cvtest::TS::LOG, "Bad shape of camera matrix returned \n");
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
} }
double fx_e = camMat_est.at<double>(0, 0), fy_e = camMat_est.at<double>(1, 1); double fx_e = camMat_est.at<double>(0, 0), fy_e = camMat_est.at<double>(1, 1);
double cx_e = camMat_est.at<double>(0, 2), cy_e = camMat_est.at<double>(1, 2); double cx_e = camMat_est.at<double>(0, 2), cy_e = camMat_est.at<double>(1, 2);
@ -121,19 +121,19 @@ protected:
const double eps = 1e-2; const double eps = 1e-2;
const double dlt = 1e-5; const double dlt = 1e-5;
bool fail = checkErr(fx_e, fx, eps, dlt) || checkErr(fy_e, fy, eps, dlt) || bool fail = checkErr(fx_e, fx, eps, dlt) || checkErr(fy_e, fy, eps, dlt) ||
checkErr(cx_e, cx, eps, dlt) || checkErr(cy_e, cy, eps, dlt); checkErr(cx_e, cx, eps, dlt) || checkErr(cy_e, cy, eps, dlt);
if (fail) if (fail)
{ {
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
} }
ts->printf( cvtest::TS::LOG, "%d) Expected [Fx Fy Cx Cy] = [%.3f %.3f %.3f %.3f]\n", r, fx, fy, cx, cy); ts->printf( cvtest::TS::LOG, "%d) Expected [Fx Fy Cx Cy] = [%.3f %.3f %.3f %.3f]\n", r, fx, fy, cx, cy);
ts->printf( cvtest::TS::LOG, "%d) Estimated [Fx Fy Cx Cy] = [%.3f %.3f %.3f %.3f]\n", r, fx_e, fy_e, cx_e, cy_e); ts->printf( cvtest::TS::LOG, "%d) Estimated [Fx Fy Cx Cy] = [%.3f %.3f %.3f %.3f]\n", r, fx_e, fy_e, cx_e, cy_e);
} }
void compareDistCoeffs(const Mat_<double>& distCoeffs, const Mat& distCoeffs_est) void compareDistCoeffs(const Mat_<double>& distCoeffs, const Mat& distCoeffs_est)
{ {
const double *dt_e = distCoeffs_est.ptr<double>(); const double *dt_e = distCoeffs_est.ptr<double>();
double k1_e = dt_e[0], k2_e = dt_e[1], k3_e = dt_e[4]; double k1_e = dt_e[0], k2_e = dt_e[1], k3_e = dt_e[4];
@ -143,21 +143,21 @@ protected:
double p1 = distCoeffs(0, 2), p2 = distCoeffs(0, 3); double p1 = distCoeffs(0, 2), p2 = distCoeffs(0, 3);
const double eps = 5e-2; const double eps = 5e-2;
const double dlt = 1e-3; const double dlt = 1e-3;
const double eps_k3 = 5; const double eps_k3 = 5;
const double dlt_k3 = 1e-3; const double dlt_k3 = 1e-3;
bool fail = checkErr(k1_e, k1, eps, dlt) || checkErr(k2_e, k2, eps, dlt) || checkErr(k3_e, k3, eps_k3, dlt_k3) || bool fail = checkErr(k1_e, k1, eps, dlt) || checkErr(k2_e, k2, eps, dlt) || checkErr(k3_e, k3, eps_k3, dlt_k3) ||
checkErr(p1_e, p1, eps, dlt) || checkErr(p2_e, p2, eps, dlt); checkErr(p1_e, p1, eps, dlt) || checkErr(p2_e, p2, eps, dlt);
if (fail) if (fail)
{ {
// commented according to vp123's recomendation. TODO - improve accuaracy // commented according to vp123's recomendation. TODO - improve accuaracy
//ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ss //ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ss
} }
ts->printf( cvtest::TS::LOG, "%d) DistCoeff exp=(%.2f, %.2f, %.4f, %.4f %.2f)\n", r, k1, k2, p1, p2, k3); ts->printf( cvtest::TS::LOG, "%d) DistCoeff exp=(%.2f, %.2f, %.4f, %.4f %.2f)\n", r, k1, k2, p1, p2, k3);
ts->printf( cvtest::TS::LOG, "%d) DistCoeff est=(%.2f, %.2f, %.4f, %.4f %.2f)\n", r, k1_e, k2_e, p1_e, p2_e, k3_e); ts->printf( cvtest::TS::LOG, "%d) DistCoeff est=(%.2f, %.2f, %.4f, %.4f %.2f)\n", r, k1_e, k2_e, p1_e, p2_e, k3_e);
ts->printf( cvtest::TS::LOG, "%d) AbsError = [%.5f %.5f %.5f %.5f %.5f]\n", r, fabs(k1-k1_e), fabs(k2-k2_e), fabs(p1-p1_e), fabs(p2-p2_e), fabs(k3-k3_e)); ts->printf( cvtest::TS::LOG, "%d) AbsError = [%.5f %.5f %.5f %.5f %.5f]\n", r, fabs(k1-k1_e), fabs(k2-k2_e), fabs(p1-p1_e), fabs(p2-p2_e), fabs(k3-k3_e));
} }
@ -173,20 +173,20 @@ protected:
const Point3d& tvec = *tvecs[i].ptr<Point3d>(); const Point3d& tvec = *tvecs[i].ptr<Point3d>();
const Point3d& tvec_est = *tvecs_est[i].ptr<Point3d>(); const Point3d& tvec_est = *tvecs_est[i].ptr<Point3d>();
if (norm(tvec_est - tvec) > eps* (norm(tvec) + dlt)) if (norm(tvec_est - tvec) > eps* (norm(tvec) + dlt))
{ {
if (err_count++ < errMsgNum) if (err_count++ < errMsgNum)
{ {
if (err_count == errMsgNum) if (err_count == errMsgNum)
ts->printf( cvtest::TS::LOG, "%d) ...\n", r); ts->printf( cvtest::TS::LOG, "%d) ...\n", r);
else else
{ {
ts->printf( cvtest::TS::LOG, "%d) Bad accuracy in returned tvecs. Index = %d\n", r, i); ts->printf( cvtest::TS::LOG, "%d) Bad accuracy in returned tvecs. Index = %d\n", r, i);
ts->printf( cvtest::TS::LOG, "%d) norm(tvec_est - tvec) = %f, norm(tvec_exp) = %f \n", r, norm(tvec_est - tvec), norm(tvec)); ts->printf( cvtest::TS::LOG, "%d) norm(tvec_est - tvec) = %f, norm(tvec_exp) = %f \n", r, norm(tvec_est - tvec), norm(tvec));
} }
} }
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
} }
} }
} }
@ -199,20 +199,20 @@ protected:
int err_count = 0; int err_count = 0;
const int errMsgNum = 4; const int errMsgNum = 4;
for(size_t i = 0; i < rvecs.size(); ++i) for(size_t i = 0; i < rvecs.size(); ++i)
{ {
Rodrigues(rvecs[i], rmat); Rodrigues(rvecs[i], rmat);
Rodrigues(rvecs_est[i], rmat_est); Rodrigues(rvecs_est[i], rmat_est);
if (norm(rmat_est, rmat) > eps* (norm(rmat) + dlt)) if (norm(rmat_est, rmat) > eps* (norm(rmat) + dlt))
{ {
if (err_count++ < errMsgNum) if (err_count++ < errMsgNum)
{ {
if (err_count == errMsgNum) if (err_count == errMsgNum)
ts->printf( cvtest::TS::LOG, "%d) ...\n", r); ts->printf( cvtest::TS::LOG, "%d) ...\n", r);
else else
{ {
ts->printf( cvtest::TS::LOG, "%d) Bad accuracy in returned rvecs (rotation matrs). Index = %d\n", r, i); ts->printf( cvtest::TS::LOG, "%d) Bad accuracy in returned rvecs (rotation matrs). Index = %d\n", r, i);
ts->printf( cvtest::TS::LOG, "%d) norm(rot_mat_est - rot_mat_exp) = %f, norm(rot_mat_exp) = %f \n", r, norm(rmat_est, rmat), norm(rmat)); ts->printf( cvtest::TS::LOG, "%d) norm(rot_mat_est - rot_mat_exp) = %f, norm(rot_mat_exp) = %f \n", r, norm(rmat_est, rmat), norm(rmat));
} }
} }
@ -221,19 +221,19 @@ protected:
} }
} }
double reprojectErrorWithoutIntrinsics(const vector<Point3f>& cb3d, const vector<Mat>& rvecs_exp, const vector<Mat>& tvecs_exp, double reprojectErrorWithoutIntrinsics(const vector<Point3f>& cb3d, const vector<Mat>& _rvecs_exp, const vector<Mat>& _tvecs_exp,
const vector<Mat>& rvecs_est, const vector<Mat>& tvecs_est) const vector<Mat>& rvecs_est, const vector<Mat>& tvecs_est)
{ {
const static Mat eye33 = Mat::eye(3, 3, CV_64F); const static Mat eye33 = Mat::eye(3, 3, CV_64F);
const static Mat zero15 = Mat::zeros(1, 5, CV_64F); const static Mat zero15 = Mat::zeros(1, 5, CV_64F);
Mat chessboard3D(cb3d); Mat _chessboard3D(cb3d);
vector<Point2f> uv_exp, uv_est; vector<Point2f> uv_exp, uv_est;
double res = 0; double res = 0;
for(size_t i = 0; i < rvecs_exp.size(); ++i) for(size_t i = 0; i < rvecs_exp.size(); ++i)
{ {
projectPoints(chessboard3D, rvecs_exp[i], tvecs_exp[i], eye33, zero15, uv_exp); projectPoints(_chessboard3D, _rvecs_exp[i], _tvecs_exp[i], eye33, zero15, uv_exp);
projectPoints(chessboard3D, rvecs_est[i], tvecs_est[i], eye33, zero15, uv_est); projectPoints(_chessboard3D, rvecs_est[i], tvecs_est[i], eye33, zero15, uv_est);
for(size_t j = 0; j < cb3d.size(); ++j) for(size_t j = 0; j < cb3d.size(); ++j)
res += norm(uv_exp[i] - uv_est[i]); res += norm(uv_exp[i] - uv_est[i]);
} }
@ -243,7 +243,7 @@ protected:
Size2f sqSile; Size2f sqSile;
vector<Point3f> chessboard3D; vector<Point3f> chessboard3D;
vector<Mat> boards, rvecs_exp, tvecs_exp, rvecs_spnp, tvecs_spnp; vector<Mat> boards, rvecs_exp, tvecs_exp, rvecs_spnp, tvecs_spnp;
vector< vector<Point3f> > objectPoints; vector< vector<Point3f> > objectPoints;
vector< vector<Point2f> > imagePoints_art; vector< vector<Point2f> > imagePoints_art;
vector< vector<Point2f> > imagePoints_findCb; vector< vector<Point2f> > imagePoints_findCb;
@ -268,29 +268,29 @@ protected:
imagePoints_findCb.clear(); imagePoints_findCb.clear();
vector<Point2f> corners_art, corners_fcb; vector<Point2f> corners_art, corners_fcb;
for(size_t i = 0; i < brdsNum; ++i) for(size_t i = 0; i < brdsNum; ++i)
{ {
for(;;) for(;;)
{ {
boards[i] = cbg(bg, camMat, distCoeffs, sqSile, corners_art); boards[i] = cbg(bg, camMat, distCoeffs, sqSile, corners_art);
if(findChessboardCorners(boards[i], cornersSize, corners_fcb)) if(findChessboardCorners(boards[i], cornersSize, corners_fcb))
break; break;
} }
//cv::namedWindow("CB"); imshow("CB", boards[i]); cv::waitKey(); //cv::namedWindow("CB"); imshow("CB", boards[i]); cv::waitKey();
imagePoints_art.push_back(corners_art); imagePoints_art.push_back(corners_art);
imagePoints_findCb.push_back(corners_fcb); imagePoints_findCb.push_back(corners_fcb);
tvecs_exp[i].create(1, 3, CV_64F); tvecs_exp[i].create(1, 3, CV_64F);
*tvecs_exp[i].ptr<Point3d>() = cbg.corners3d[0]; *tvecs_exp[i].ptr<Point3d>() = cbg.corners3d[0];
rvecs_exp[i] = calcRvec(cbg.corners3d, cbg.cornersSize()); rvecs_exp[i] = calcRvec(cbg.corners3d, cbg.cornersSize());
} }
} }
void runTest(const Size& imgSize, const Mat_<double>& camMat, const Mat_<double>& distCoeffs, size_t brdsNum, const Size& cornersSize, int flag = 0) void runTest(const Size& imgSize, const Mat_<double>& camMat, const Mat_<double>& distCoeffs, size_t brdsNum, const Size& cornersSize, int flag = 0)
{ {
const TermCriteria tc(TermCriteria::EPS|TermCriteria::MAX_ITER, 30, 0.1); const TermCriteria tc(TermCriteria::EPS|TermCriteria::MAX_ITER, 30, 0.1);
vector< vector<Point2f> > imagePoints; vector< vector<Point2f> > imagePoints;
@ -300,9 +300,9 @@ protected:
case JUST_FIND_CORNERS: imagePoints = imagePoints_findCb; break; case JUST_FIND_CORNERS: imagePoints = imagePoints_findCb; break;
case ARTIFICIAL_CORNERS: imagePoints = imagePoints_art; break; case ARTIFICIAL_CORNERS: imagePoints = imagePoints_art; break;
case USE_CORNERS_SUBPIX: case USE_CORNERS_SUBPIX:
for(size_t i = 0; i < brdsNum; ++i) for(size_t i = 0; i < brdsNum; ++i)
{ {
Mat gray; Mat gray;
cvtColor(boards[i], gray, CV_BGR2GRAY); cvtColor(boards[i], gray, CV_BGR2GRAY);
vector<Point2f> tmp = imagePoints_findCb[i]; vector<Point2f> tmp = imagePoints_findCb[i];
@ -312,9 +312,9 @@ protected:
break; break;
case USE_4QUAD_CORNERS: case USE_4QUAD_CORNERS:
for(size_t i = 0; i < brdsNum; ++i) for(size_t i = 0; i < brdsNum; ++i)
{ {
Mat gray; Mat gray;
cvtColor(boards[i], gray, CV_BGR2GRAY); cvtColor(boards[i], gray, CV_BGR2GRAY);
vector<Point2f> tmp = imagePoints_findCb[i]; vector<Point2f> tmp = imagePoints_findCb[i];
find4QuadCornerSubpix(gray, tmp, Size(5, 5)); find4QuadCornerSubpix(gray, tmp, Size(5, 5));
imagePoints.push_back(tmp); imagePoints.push_back(tmp);
@ -323,7 +323,7 @@ protected:
default: default:
throw std::exception(); throw std::exception();
} }
Mat camMat_est = Mat::eye(3, 3, CV_64F), distCoeffs_est = Mat::zeros(1, 5, CV_64F); Mat camMat_est = Mat::eye(3, 3, CV_64F), distCoeffs_est = Mat::zeros(1, 5, CV_64F);
vector<Mat> rvecs_est, tvecs_est; vector<Mat> rvecs_est, tvecs_est;
@ -342,9 +342,9 @@ protected:
compareCameraMatrs(camMat, camMat_est); compareCameraMatrs(camMat, camMat_est);
compareDistCoeffs(distCoeffs, distCoeffs_est); compareDistCoeffs(distCoeffs, distCoeffs_est);
compareShiftVecs(tvecs_exp, tvecs_est); compareShiftVecs(tvecs_exp, tvecs_est);
compareRotationVecs(rvecs_exp, rvecs_est); compareRotationVecs(rvecs_exp, rvecs_est);
double rep_errorWOI = reprojectErrorWithoutIntrinsics(chessboard3D, rvecs_exp, tvecs_exp, rvecs_est, tvecs_est); double rep_errorWOI = reprojectErrorWithoutIntrinsics(chessboard3D, rvecs_exp, tvecs_exp, rvecs_est, tvecs_est);
rep_errorWOI /= brdsNum * cornersSize.area(); rep_errorWOI /= brdsNum * cornersSize.area();
const double thres2 = 0.01; const double thres2 = 0.01;
@ -352,8 +352,8 @@ protected:
{ {
ts->printf( cvtest::TS::LOG, "%d) Too big reproject error without intrinsics = %f\n", r, rep_errorWOI); ts->printf( cvtest::TS::LOG, "%d) Too big reproject error without intrinsics = %f\n", r, rep_errorWOI);
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
} }
ts->printf( cvtest::TS::LOG, "%d) Testing solvePnP...\n", r); ts->printf( cvtest::TS::LOG, "%d) Testing solvePnP...\n", r);
rvecs_spnp.resize(brdsNum); rvecs_spnp.resize(brdsNum);
tvecs_spnp.resize(brdsNum); tvecs_spnp.resize(brdsNum);
@ -361,11 +361,11 @@ protected:
solvePnP(Mat(objectPoints[i]), Mat(imagePoints[i]), camMat, distCoeffs, rvecs_spnp[i], tvecs_spnp[i]); solvePnP(Mat(objectPoints[i]), Mat(imagePoints[i]), camMat, distCoeffs, rvecs_spnp[i], tvecs_spnp[i]);
compareShiftVecs(tvecs_exp, tvecs_spnp); compareShiftVecs(tvecs_exp, tvecs_spnp);
compareRotationVecs(rvecs_exp, rvecs_spnp); compareRotationVecs(rvecs_exp, rvecs_spnp);
} }
void run(int) void run(int)
{ {
ts->set_failed_test_info(cvtest::TS::OK); ts->set_failed_test_info(cvtest::TS::OK);
RNG& rng = theRNG(); RNG& rng = theRNG();
@ -373,11 +373,11 @@ protected:
int progress = 0; int progress = 0;
int repeat_num = 3; int repeat_num = 3;
for(r = 0; r < repeat_num; ++r) for(r = 0; r < repeat_num; ++r)
{ {
const int brds_num = 20; const int brds_num = 20;
Mat bg(Size(640, 480), CV_8UC3); Mat bg(Size(640, 480), CV_8UC3);
randu(bg, Scalar::all(32), Scalar::all(255)); randu(bg, Scalar::all(32), Scalar::all(255));
GaussianBlur(bg, bg, Size(5, 5), 2); GaussianBlur(bg, bg, Size(5, 5), 2);
double fx = 300 + (20 * (double)rng - 10); double fx = 300 + (20 * (double)rng - 10);
@ -399,20 +399,20 @@ protected:
Mat_<double> distCoeffs(1, 5, 0.0); Mat_<double> distCoeffs(1, 5, 0.0);
distCoeffs << k1, k2, p1, p2, k3; distCoeffs << k1, k2, p1, p2, k3;
ChessBoardGenerator cbg(Size(9, 8)); ChessBoardGenerator cbg(Size(9, 8));
cbg.min_cos = 0.9; cbg.min_cos = 0.9;
cbg.cov = 0.8; cbg.cov = 0.8;
progress = update_progress(progress, r, repeat_num, 0); progress = update_progress(progress, r, repeat_num, 0);
ts->printf( cvtest::TS::LOG, "\n"); ts->printf( cvtest::TS::LOG, "\n");
prepareForTest(bg, camMat, distCoeffs, brds_num, cbg); prepareForTest(bg, camMat, distCoeffs, brds_num, cbg);
ts->printf( cvtest::TS::LOG, "artificial corners\n"); ts->printf( cvtest::TS::LOG, "artificial corners\n");
runTest(bg.size(), camMat, distCoeffs, brds_num, cbg.cornersSize(), ARTIFICIAL_CORNERS); runTest(bg.size(), camMat, distCoeffs, brds_num, cbg.cornersSize(), ARTIFICIAL_CORNERS);
progress = update_progress(progress, r, repeat_num, 0); progress = update_progress(progress, r, repeat_num, 0);
ts->printf( cvtest::TS::LOG, "findChessboard corners\n"); ts->printf( cvtest::TS::LOG, "findChessboard corners\n");
runTest(bg.size(), camMat, distCoeffs, brds_num, cbg.cornersSize(), JUST_FIND_CORNERS); runTest(bg.size(), camMat, distCoeffs, brds_num, cbg.cornersSize(), JUST_FIND_CORNERS);
progress = update_progress(progress, r, repeat_num, 0); progress = update_progress(progress, r, repeat_num, 0);
ts->printf( cvtest::TS::LOG, "cornersSubPix corners\n"); ts->printf( cvtest::TS::LOG, "cornersSubPix corners\n");
@ -424,6 +424,6 @@ protected:
progress = update_progress(progress, r, repeat_num, 0); progress = update_progress(progress, r, repeat_num, 0);
} }
} }
}; };
TEST(Calib3d_CalibrateCamera_CPP, accuracy_on_artificial_data) { CV_CalibrateCameraArtificialTest test; test.safe_run(); } TEST(Calib3d_CalibrateCamera_CPP, accuracy_on_artificial_data) { CV_CalibrateCameraArtificialTest test; test.safe_run(); }

View File

@ -54,9 +54,9 @@ void show_points( const Mat& gray, const Mat& u, const vector<Point2f>& v, Size
{ {
Mat rgb( gray.size(), CV_8U); Mat rgb( gray.size(), CV_8U);
merge(vector<Mat>(3, gray), rgb); merge(vector<Mat>(3, gray), rgb);
for(size_t i = 0; i < v.size(); i++ ) for(size_t i = 0; i < v.size(); i++ )
circle( rgb, v[i], 3, CV_RGB(255, 0, 0), CV_FILLED); circle( rgb, v[i], 3, CV_RGB(255, 0, 0), CV_FILLED);
if( !u.empty() ) if( !u.empty() )
{ {
@ -67,7 +67,7 @@ void show_points( const Mat& gray, const Mat& u, const vector<Point2f>& v, Size
} }
if (!v.empty()) if (!v.empty())
{ {
Mat corners((int)v.size(), 1, CV_32FC2, (void*)&v[0]); Mat corners((int)v.size(), 1, CV_32FC2, (void*)&v[0]);
drawChessboardCorners( rgb, pattern_size, corners, was_found ); drawChessboardCorners( rgb, pattern_size, corners, was_found );
} }
//namedWindow( "test", 0 ); imshow( "test", rgb ); waitKey(0); //namedWindow( "test", 0 ); imshow( "test", rgb ); waitKey(0);
@ -122,11 +122,11 @@ double calcError(const vector<Point2f>& v, const Mat& u)
//printf("\n"); //printf("\n");
err = min(err, err1); err = min(err, err1);
} }
#if defined(_L2_ERR) #if defined(_L2_ERR)
err = sqrt(err/count_exp); err = sqrt(err/count_exp);
#endif //_L2_ERR #endif //_L2_ERR
return err; return err;
} }
@ -137,8 +137,7 @@ const double precise_success_error_level = 2;
/* ///////////////////// chess_corner_test ///////////////////////// */ /* ///////////////////// chess_corner_test ///////////////////////// */
void CV_ChessboardDetectorTest::run( int /*start_from */) void CV_ChessboardDetectorTest::run( int /*start_from */)
{ {
cvtest::TS& ts = *this->ts; ts->set_failed_test_info( cvtest::TS::OK );
ts.set_failed_test_info( cvtest::TS::OK );
/*if (!checkByGenerator()) /*if (!checkByGenerator())
return;*/ return;*/
@ -146,23 +145,23 @@ void CV_ChessboardDetectorTest::run( int /*start_from */)
{ {
case CHESSBOARD: case CHESSBOARD:
checkByGenerator(); checkByGenerator();
if (ts.get_err_code() != cvtest::TS::OK) if (ts->get_err_code() != cvtest::TS::OK)
{ {
break; break;
} }
run_batch("negative_list.dat"); run_batch("negative_list.dat");
if (ts.get_err_code() != cvtest::TS::OK) if (ts->get_err_code() != cvtest::TS::OK)
{ {
break; break;
} }
run_batch("chessboard_list.dat"); run_batch("chessboard_list.dat");
if (ts.get_err_code() != cvtest::TS::OK) if (ts->get_err_code() != cvtest::TS::OK)
{ {
break; break;
} }
run_batch("chessboard_list_subpixel.dat"); run_batch("chessboard_list_subpixel.dat");
break; break;
case CIRCLES_GRID: case CIRCLES_GRID:
@ -176,36 +175,34 @@ void CV_ChessboardDetectorTest::run( int /*start_from */)
void CV_ChessboardDetectorTest::run_batch( const string& filename ) void CV_ChessboardDetectorTest::run_batch( const string& filename )
{ {
cvtest::TS& ts = *this->ts; ts->printf(cvtest::TS::LOG, "\nRunning batch %s\n", filename.c_str());
ts.printf(cvtest::TS::LOG, "\nRunning batch %s\n", filename.c_str());
//#define WRITE_POINTS 1 //#define WRITE_POINTS 1
#ifndef WRITE_POINTS #ifndef WRITE_POINTS
double max_rough_error = 0, max_precise_error = 0; double max_rough_error = 0, max_precise_error = 0;
#endif #endif
string folder; string folder;
switch( pattern ) switch( pattern )
{ {
case CHESSBOARD: case CHESSBOARD:
folder = string(ts.get_data_path()) + "cameracalibration/"; folder = string(ts->get_data_path()) + "cameracalibration/";
break; break;
case CIRCLES_GRID: case CIRCLES_GRID:
folder = string(ts.get_data_path()) + "cameracalibration/circles/"; folder = string(ts->get_data_path()) + "cameracalibration/circles/";
break; break;
case ASYMMETRIC_CIRCLES_GRID: case ASYMMETRIC_CIRCLES_GRID:
folder = string(ts.get_data_path()) + "cameracalibration/asymmetric_circles/"; folder = string(ts->get_data_path()) + "cameracalibration/asymmetric_circles/";
break; break;
} }
FileStorage fs( folder + filename, FileStorage::READ ); FileStorage fs( folder + filename, FileStorage::READ );
FileNode board_list = fs["boards"]; FileNode board_list = fs["boards"];
if( !fs.isOpened() || board_list.empty() || !board_list.isSeq() || board_list.size() % 2 != 0 ) if( !fs.isOpened() || board_list.empty() || !board_list.isSeq() || board_list.size() % 2 != 0 )
{ {
ts.printf( cvtest::TS::LOG, "%s can not be readed or is not valid\n", (folder + filename).c_str() ); ts->printf( cvtest::TS::LOG, "%s can not be readed or is not valid\n", (folder + filename).c_str() );
ts.printf( cvtest::TS::LOG, "fs.isOpened=%d, board_list.empty=%d, board_list.isSeq=%d,board_list.size()%2=%d\n", ts->printf( cvtest::TS::LOG, "fs.isOpened=%d, board_list.empty=%d, board_list.isSeq=%d,board_list.size()%2=%d\n",
fs.isOpened(), (int)board_list.empty(), board_list.isSeq(), board_list.size()%2); fs.isOpened(), (int)board_list.empty(), board_list.isSeq(), board_list.size()%2);
ts.set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA ); ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
return; return;
} }
@ -216,29 +213,29 @@ void CV_ChessboardDetectorTest::run_batch( const string& filename )
for(int idx = 0; idx < max_idx; ++idx ) for(int idx = 0; idx < max_idx; ++idx )
{ {
ts.update_context( this, idx, true ); ts->update_context( this, idx, true );
/* read the image */ /* read the image */
string img_file = board_list[idx * 2]; string img_file = board_list[idx * 2];
Mat gray = imread( folder + img_file, 0); Mat gray = imread( folder + img_file, 0);
if( gray.empty() ) if( gray.empty() )
{ {
ts.printf( cvtest::TS::LOG, "one of chessboard images can't be read: %s\n", img_file.c_str() ); ts->printf( cvtest::TS::LOG, "one of chessboard images can't be read: %s\n", img_file.c_str() );
ts.set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA ); ts->set_failed_test_info( cvtest::TS::FAIL_MISSING_TEST_DATA );
return; return;
} }
string filename = folder + (string)board_list[idx * 2 + 1]; string _filename = folder + (string)board_list[idx * 2 + 1];
bool doesContatinChessboard; bool doesContatinChessboard;
Mat expected; Mat expected;
{ {
FileStorage fs(filename, FileStorage::READ); FileStorage fs1(_filename, FileStorage::READ);
fs["corners"] >> expected; fs1["corners"] >> expected;
fs["isFound"] >> doesContatinChessboard; fs1["isFound"] >> doesContatinChessboard;
fs.release(); fs1.release();
} }
size_t count_exp = static_cast<size_t>(expected.cols * expected.rows); size_t count_exp = static_cast<size_t>(expected.cols * expected.rows);
Size pattern_size = expected.size(); Size pattern_size = expected.size();
vector<Point2f> v; vector<Point2f> v;
@ -256,11 +253,11 @@ void CV_ChessboardDetectorTest::run_batch( const string& filename )
break; break;
} }
show_points( gray, Mat(), v, pattern_size, result ); show_points( gray, Mat(), v, pattern_size, result );
if( result ^ doesContatinChessboard || v.size() != count_exp ) if( result ^ doesContatinChessboard || v.size() != count_exp )
{ {
ts.printf( cvtest::TS::LOG, "chessboard is detected incorrectly in %s\n", img_file.c_str() ); ts->printf( cvtest::TS::LOG, "chessboard is detected incorrectly in %s\n", img_file.c_str() );
ts.set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT ); ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
return; return;
} }
@ -291,45 +288,45 @@ void CV_ChessboardDetectorTest::run_batch( const string& filename )
#if 1 #if 1
if( err > precise_success_error_level ) if( err > precise_success_error_level )
{ {
ts.printf( cvtest::TS::LOG, "Image %s: bad accuracy of adjusted corners %f\n", img_file.c_str(), err ); ts->printf( cvtest::TS::LOG, "Image %s: bad accuracy of adjusted corners %f\n", img_file.c_str(), err );
ts.set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return; return;
} }
#endif #endif
ts.printf(cvtest::TS::LOG, "Error on %s is %f\n", img_file.c_str(), err); ts->printf(cvtest::TS::LOG, "Error on %s is %f\n", img_file.c_str(), err);
max_precise_error = MAX( max_precise_error, err ); max_precise_error = MAX( max_precise_error, err );
#endif #endif
} }
#ifdef WRITE_POINTS #ifdef WRITE_POINTS
Mat mat_v(pattern_size, CV_32FC2, (void*)&v[0]); Mat mat_v(pattern_size, CV_32FC2, (void*)&v[0]);
FileStorage fs(filename, FileStorage::WRITE); FileStorage fs(_filename, FileStorage::WRITE);
fs << "isFound" << result; fs << "isFound" << result;
fs << "corners" << mat_v; fs << "corners" << mat_v;
fs.release(); fs.release();
#endif #endif
progress = update_progress( progress, idx, max_idx, 0 ); progress = update_progress( progress, idx, max_idx, 0 );
} }
sum_error /= count; sum_error /= count;
ts.printf(cvtest::TS::LOG, "Average error is %f\n", sum_error); ts->printf(cvtest::TS::LOG, "Average error is %f\n", sum_error);
} }
double calcErrorMinError(const Size& cornSz, const vector<Point2f>& corners_found, const vector<Point2f>& corners_generated) double calcErrorMinError(const Size& cornSz, const vector<Point2f>& corners_found, const vector<Point2f>& corners_generated)
{ {
Mat m1(cornSz, CV_32FC2, (Point2f*)&corners_generated[0]); Mat m1(cornSz, CV_32FC2, (Point2f*)&corners_generated[0]);
Mat m2; flip(m1, m2, 0); Mat m2; flip(m1, m2, 0);
Mat m3; flip(m1, m3, 1); m3 = m3.t(); flip(m3, m3, 1); Mat m3; flip(m1, m3, 1); m3 = m3.t(); flip(m3, m3, 1);
Mat m4 = m1.t(); flip(m4, m4, 1); Mat m4 = m1.t(); flip(m4, m4, 1);
double min1 = min(calcError(corners_found, m1), calcError(corners_found, m2)); double min1 = min(calcError(corners_found, m1), calcError(corners_found, m2));
double min2 = min(calcError(corners_found, m3), calcError(corners_found, m4)); double min2 = min(calcError(corners_found, m3), calcError(corners_found, m4));
return min(min1, min2); return min(min1, min2);
} }
bool validateData(const ChessBoardGenerator& cbg, const Size& imgSz, bool validateData(const ChessBoardGenerator& cbg, const Size& imgSz,
const vector<Point2f>& corners_generated) const vector<Point2f>& corners_generated)
{ {
Size cornersSize = cbg.cornersSize(); Size cornersSize = cbg.cornersSize();
@ -341,7 +338,7 @@ bool validateData(const ChessBoardGenerator& cbg, const Size& imgSz,
for(int j = 1; j < mat.cols - 2; ++j) for(int j = 1; j < mat.cols - 2; ++j)
{ {
const Point2f& cur = mat(i, j); const Point2f& cur = mat(i, j);
tmp = norm( cur - mat(i + 1, j + 1) ); tmp = norm( cur - mat(i + 1, j + 1) );
if (tmp < minNeibDist) if (tmp < minNeibDist)
tmp = minNeibDist; tmp = minNeibDist;
@ -361,33 +358,33 @@ bool validateData(const ChessBoardGenerator& cbg, const Size& imgSz,
const double threshold = 0.25; const double threshold = 0.25;
double cbsize = (max(cornersSize.width, cornersSize.height) + 1) * minNeibDist; double cbsize = (max(cornersSize.width, cornersSize.height) + 1) * minNeibDist;
int imgsize = min(imgSz.height, imgSz.width); int imgsize = min(imgSz.height, imgSz.width);
return imgsize * threshold < cbsize; return imgsize * threshold < cbsize;
} }
bool CV_ChessboardDetectorTest::checkByGenerator() bool CV_ChessboardDetectorTest::checkByGenerator()
{ {
bool res = true; bool res = true;
//theRNG() = 0x58e6e895b9913160; //theRNG() = 0x58e6e895b9913160;
//cv::DefaultRngAuto dra; //cv::DefaultRngAuto dra;
//theRNG() = *ts->get_rng(); //theRNG() = *ts->get_rng();
Mat bg(Size(800, 600), CV_8UC3, Scalar::all(255)); Mat bg(Size(800, 600), CV_8UC3, Scalar::all(255));
randu(bg, Scalar::all(0), Scalar::all(255)); randu(bg, Scalar::all(0), Scalar::all(255));
GaussianBlur(bg, bg, Size(7,7), 3.0); GaussianBlur(bg, bg, Size(7,7), 3.0);
Mat_<float> camMat(3, 3); Mat_<float> camMat(3, 3);
camMat << 300.f, 0.f, bg.cols/2.f, 0, 300.f, bg.rows/2.f, 0.f, 0.f, 1.f; camMat << 300.f, 0.f, bg.cols/2.f, 0, 300.f, bg.rows/2.f, 0.f, 0.f, 1.f;
Mat_<float> distCoeffs(1, 5); Mat_<float> distCoeffs(1, 5);
distCoeffs << 1.2f, 0.2f, 0.f, 0.f, 0.f; distCoeffs << 1.2f, 0.2f, 0.f, 0.f, 0.f;
const Size sizes[] = { Size(6, 6), Size(8, 6), Size(11, 12), Size(5, 4) }; const Size sizes[] = { Size(6, 6), Size(8, 6), Size(11, 12), Size(5, 4) };
const size_t sizes_num = sizeof(sizes)/sizeof(sizes[0]); const size_t sizes_num = sizeof(sizes)/sizeof(sizes[0]);
const int test_num = 16; const int test_num = 16;
int progress = 0; int progress = 0;
for(int i = 0; i < test_num; ++i) for(int i = 0; i < test_num; ++i)
{ {
progress = update_progress( progress, i, test_num, 0 ); progress = update_progress( progress, i, test_num, 0 );
ChessBoardGenerator cbg(sizes[i % sizes_num]); ChessBoardGenerator cbg(sizes[i % sizes_num]);
@ -398,37 +395,37 @@ bool CV_ChessboardDetectorTest::checkByGenerator()
if(!validateData(cbg, cb.size(), corners_generated)) if(!validateData(cbg, cb.size(), corners_generated))
{ {
ts->printf( cvtest::TS::LOG, "Chess board skipped - too small" ); ts->printf( cvtest::TS::LOG, "Chess board skipped - too small" );
continue; continue;
} }
/*cb = cb * 0.8 + Scalar::all(30); /*cb = cb * 0.8 + Scalar::all(30);
GaussianBlur(cb, cb, Size(3, 3), 0.8); */ GaussianBlur(cb, cb, Size(3, 3), 0.8); */
//cv::addWeighted(cb, 0.8, bg, 0.2, 20, cb); //cv::addWeighted(cb, 0.8, bg, 0.2, 20, cb);
//cv::namedWindow("CB"); cv::imshow("CB", cb); cv::waitKey(); //cv::namedWindow("CB"); cv::imshow("CB", cb); cv::waitKey();
vector<Point2f> corners_found; vector<Point2f> corners_found;
int flags = i % 8; // need to check branches for all flags int flags = i % 8; // need to check branches for all flags
bool found = findChessboardCorners(cb, cbg.cornersSize(), corners_found, flags); bool found = findChessboardCorners(cb, cbg.cornersSize(), corners_found, flags);
if (!found) if (!found)
{ {
ts->printf( cvtest::TS::LOG, "Chess board corners not found\n" ); ts->printf( cvtest::TS::LOG, "Chess board corners not found\n" );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
res = false; res = false;
return res; return res;
} }
double err = calcErrorMinError(cbg.cornersSize(), corners_found, corners_generated); double err = calcErrorMinError(cbg.cornersSize(), corners_found, corners_generated);
if( err > rough_success_error_level ) if( err > rough_success_error_level )
{ {
ts->printf( cvtest::TS::LOG, "bad accuracy of corner guesses" ); ts->printf( cvtest::TS::LOG, "bad accuracy of corner guesses" );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY ); ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
res = false; res = false;
return res; return res;
} }
} }
/* ***** negative ***** */ /* ***** negative ***** */
{ {
vector<Point2f> corners_found; vector<Point2f> corners_found;
bool found = findChessboardCorners(bg, Size(8, 7), corners_found); bool found = findChessboardCorners(bg, Size(8, 7), corners_found);
if (found) if (found)
@ -437,27 +434,27 @@ bool CV_ChessboardDetectorTest::checkByGenerator()
ChessBoardGenerator cbg(Size(8, 7)); ChessBoardGenerator cbg(Size(8, 7));
vector<Point2f> cg; vector<Point2f> cg;
Mat cb = cbg(bg, camMat, distCoeffs, cg); Mat cb = cbg(bg, camMat, distCoeffs, cg);
found = findChessboardCorners(cb, Size(3, 4), corners_found); found = findChessboardCorners(cb, Size(3, 4), corners_found);
if (found) if (found)
res = false; res = false;
Point2f c = std::accumulate(cg.begin(), cg.end(), Point2f(), plus<Point2f>()) * (1.f/cg.size()); Point2f c = std::accumulate(cg.begin(), cg.end(), Point2f(), plus<Point2f>()) * (1.f/cg.size());
Mat_<double> aff(2, 3); Mat_<double> aff(2, 3);
aff << 1.0, 0.0, -(double)c.x, 0.0, 1.0, 0.0; aff << 1.0, 0.0, -(double)c.x, 0.0, 1.0, 0.0;
Mat sh; Mat sh;
warpAffine(cb, sh, aff, cb.size()); warpAffine(cb, sh, aff, cb.size());
found = findChessboardCorners(sh, cbg.cornersSize(), corners_found); found = findChessboardCorners(sh, cbg.cornersSize(), corners_found);
if (found) if (found)
res = false; res = false;
vector< vector<Point> > cnts(1); vector< vector<Point> > cnts(1);
vector<Point>& cnt = cnts[0]; vector<Point>& cnt = cnts[0];
cnt.push_back(cg[ 0]); cnt.push_back(cg[0+2]); cnt.push_back(cg[ 0]); cnt.push_back(cg[0+2]);
cnt.push_back(cg[7+0]); cnt.push_back(cg[7+2]); cnt.push_back(cg[7+0]); cnt.push_back(cg[7+2]);
cv::drawContours(cb, cnts, -1, Scalar::all(128), CV_FILLED); cv::drawContours(cb, cnts, -1, Scalar::all(128), CV_FILLED);
found = findChessboardCorners(cb, cbg.cornersSize(), corners_found); found = findChessboardCorners(cb, cbg.cornersSize(), corners_found);
@ -466,7 +463,7 @@ bool CV_ChessboardDetectorTest::checkByGenerator()
cv::drawChessboardCorners(cb, cbg.cornersSize(), Mat(corners_found), found); cv::drawChessboardCorners(cb, cbg.cornersSize(), Mat(corners_found), found);
} }
return res; return res;
} }

View File

@ -47,87 +47,87 @@ using namespace std;
class Differential class Differential
{ {
public: public:
typedef Mat_<double> mat_t; typedef Mat_<double> mat_t;
Differential(double eps_, const mat_t& rv1_, const mat_t& tv1_, const mat_t& rv2_, const mat_t& tv2_) Differential(double eps_, const mat_t& rv1_, const mat_t& tv1_, const mat_t& rv2_, const mat_t& tv2_)
: rv1(rv1_), tv1(tv1_), rv2(rv2_), tv2(tv2_), eps(eps_), ev(3, 1) {} : rv1(rv1_), tv1(tv1_), rv2(rv2_), tv2(tv2_), eps(eps_), ev(3, 1) {}
void dRv1(mat_t& dr3_dr1, mat_t& dt3_dr1) void dRv1(mat_t& dr3_dr1, mat_t& dt3_dr1)
{ {
dr3_dr1.create(3, 3); dt3_dr1.create(3, 3); dr3_dr1.create(3, 3); dt3_dr1.create(3, 3);
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)
{ {
ev.setTo(Scalar(0)); ev(i, 0) = eps; ev.setTo(Scalar(0)); ev(i, 0) = eps;
composeRT( rv1 + ev, tv1, rv2, tv2, rv3_p, tv3_p); composeRT( rv1 + ev, tv1, rv2, tv2, rv3_p, tv3_p);
composeRT( rv1 - ev, tv1, rv2, tv2, rv3_m, tv3_m); composeRT( rv1 - ev, tv1, rv2, tv2, rv3_m, tv3_m);
dr3_dr1.col(i) = rv3_p - rv3_m; dr3_dr1.col(i) = rv3_p - rv3_m;
dt3_dr1.col(i) = tv3_p - tv3_m; dt3_dr1.col(i) = tv3_p - tv3_m;
} }
dr3_dr1 /= 2 * eps; dt3_dr1 /= 2 * eps; dr3_dr1 /= 2 * eps; dt3_dr1 /= 2 * eps;
} }
void dRv2(mat_t& dr3_dr2, mat_t& dt3_dr2) void dRv2(mat_t& dr3_dr2, mat_t& dt3_dr2)
{ {
dr3_dr2.create(3, 3); dt3_dr2.create(3, 3); dr3_dr2.create(3, 3); dt3_dr2.create(3, 3);
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)
{ {
ev.setTo(Scalar(0)); ev(i, 0) = eps; ev.setTo(Scalar(0)); ev(i, 0) = eps;
composeRT( rv1, tv1, rv2 + ev, tv2, rv3_p, tv3_p); composeRT( rv1, tv1, rv2 + ev, tv2, rv3_p, tv3_p);
composeRT( rv1, tv1, rv2 - ev, tv2, rv3_m, tv3_m); composeRT( rv1, tv1, rv2 - ev, tv2, rv3_m, tv3_m);
dr3_dr2.col(i) = rv3_p - rv3_m; dr3_dr2.col(i) = rv3_p - rv3_m;
dt3_dr2.col(i) = tv3_p - tv3_m; dt3_dr2.col(i) = tv3_p - tv3_m;
} }
dr3_dr2 /= 2 * eps; dt3_dr2 /= 2 * eps; dr3_dr2 /= 2 * eps; dt3_dr2 /= 2 * eps;
} }
void dTv1(mat_t& drt3_dt1, mat_t& dt3_dt1) void dTv1(mat_t& drt3_dt1, mat_t& dt3_dt1)
{ {
drt3_dt1.create(3, 3); dt3_dt1.create(3, 3); drt3_dt1.create(3, 3); dt3_dt1.create(3, 3);
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)
{ {
ev.setTo(Scalar(0)); ev(i, 0) = eps; ev.setTo(Scalar(0)); ev(i, 0) = eps;
composeRT( rv1, tv1 + ev, rv2, tv2, rv3_p, tv3_p); composeRT( rv1, tv1 + ev, rv2, tv2, rv3_p, tv3_p);
composeRT( rv1, tv1 - ev, rv2, tv2, rv3_m, tv3_m); composeRT( rv1, tv1 - ev, rv2, tv2, rv3_m, tv3_m);
drt3_dt1.col(i) = rv3_p - rv3_m; drt3_dt1.col(i) = rv3_p - rv3_m;
dt3_dt1.col(i) = tv3_p - tv3_m; dt3_dt1.col(i) = tv3_p - tv3_m;
} }
drt3_dt1 /= 2 * eps; dt3_dt1 /= 2 * eps; drt3_dt1 /= 2 * eps; dt3_dt1 /= 2 * eps;
} }
void dTv2(mat_t& dr3_dt2, mat_t& dt3_dt2) void dTv2(mat_t& dr3_dt2, mat_t& dt3_dt2)
{ {
dr3_dt2.create(3, 3); dt3_dt2.create(3, 3); dr3_dt2.create(3, 3); dt3_dt2.create(3, 3);
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)
{ {
ev.setTo(Scalar(0)); ev(i, 0) = eps; ev.setTo(Scalar(0)); ev(i, 0) = eps;
composeRT( rv1, tv1, rv2, tv2 + ev, rv3_p, tv3_p); composeRT( rv1, tv1, rv2, tv2 + ev, rv3_p, tv3_p);
composeRT( rv1, tv1, rv2, tv2 - ev, rv3_m, tv3_m); composeRT( rv1, tv1, rv2, tv2 - ev, rv3_m, tv3_m);
dr3_dt2.col(i) = rv3_p - rv3_m; dr3_dt2.col(i) = rv3_p - rv3_m;
dt3_dt2.col(i) = tv3_p - tv3_m; dt3_dt2.col(i) = tv3_p - tv3_m;
} }
dr3_dt2 /= 2 * eps; dt3_dt2 /= 2 * eps; dr3_dt2 /= 2 * eps; dt3_dt2 /= 2 * eps;
} }
private: private:
const mat_t& rv1, tv1, rv2, tv2; const mat_t& rv1, tv1, rv2, tv2;
double eps; double eps;
Mat_<double> ev; Mat_<double> ev;
Differential& operator=(const Differential&); Differential& operator=(const Differential&);
Mat rv3_m, tv3_m, rv3_p, tv3_p; Mat rv3_m, tv3_m, rv3_p, tv3_p;
}; };
class CV_composeRT_Test : public cvtest::BaseTest class CV_composeRT_Test : public cvtest::BaseTest
@ -135,24 +135,23 @@ class CV_composeRT_Test : public cvtest::BaseTest
public: public:
CV_composeRT_Test() {} CV_composeRT_Test() {}
~CV_composeRT_Test() {} ~CV_composeRT_Test() {}
protected: protected:
void run(int) void run(int)
{ {
cvtest::TS& ts = *this->ts; ts->set_failed_test_info(cvtest::TS::OK);
ts.set_failed_test_info(cvtest::TS::OK);
Mat_<double> rvec1(3, 1), tvec1(3, 1), rvec2(3, 1), tvec2(3, 1);
Mat_<double> rvec1(3, 1), tvec1(3, 1), rvec2(3, 1), tvec2(3, 1);
randu(rvec1, Scalar(0), Scalar(6.29)); randu(rvec1, Scalar(0), Scalar(6.29));
randu(rvec2, Scalar(0), Scalar(6.29)); randu(rvec2, Scalar(0), Scalar(6.29));
randu(tvec1, Scalar(-2), Scalar(2)); randu(tvec1, Scalar(-2), Scalar(2));
randu(tvec2, Scalar(-2), Scalar(2)); randu(tvec2, Scalar(-2), Scalar(2));
Mat rvec3, tvec3; Mat rvec3, tvec3;
composeRT(rvec1, tvec1, rvec2, tvec2, rvec3, tvec3); composeRT(rvec1, tvec1, rvec2, tvec2, rvec3, tvec3);
Mat rvec3_exp, tvec3_exp; Mat rvec3_exp, tvec3_exp;
Mat rmat1, rmat2; Mat rmat1, rmat2;
@ -164,53 +163,53 @@ protected:
const double thres = 1e-5; const double thres = 1e-5;
if (norm(rvec3_exp, rvec3) > thres || norm(tvec3_exp, tvec3) > thres) if (norm(rvec3_exp, rvec3) > thres || norm(tvec3_exp, tvec3) > thres)
ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
const double eps = 1e-3; const double eps = 1e-3;
Differential diff(eps, rvec1, tvec1, rvec2, tvec2); Differential diff(eps, rvec1, tvec1, rvec2, tvec2);
Mat dr3dr1, dr3dt1, dr3dr2, dr3dt2, dt3dr1, dt3dt1, dt3dr2, dt3dt2; Mat dr3dr1, dr3dt1, dr3dr2, dr3dt2, dt3dr1, dt3dt1, dt3dr2, dt3dt2;
composeRT(rvec1, tvec1, rvec2, tvec2, rvec3, tvec3, composeRT(rvec1, tvec1, rvec2, tvec2, rvec3, tvec3,
dr3dr1, dr3dt1, dr3dr2, dr3dt2, dt3dr1, dt3dt1, dt3dr2, dt3dt2); dr3dr1, dr3dt1, dr3dr2, dr3dt2, dt3dr1, dt3dt1, dt3dr2, dt3dt2);
Mat_<double> dr3_dr1, dt3_dr1; Mat_<double> dr3_dr1, dt3_dr1;
diff.dRv1(dr3_dr1, dt3_dr1); diff.dRv1(dr3_dr1, dt3_dr1);
if (norm(dr3_dr1, dr3dr1) > thres || norm(dt3_dr1, dt3dr1) > thres) if (norm(dr3_dr1, dr3dr1) > thres || norm(dt3_dr1, dt3dr1) > thres)
{ {
ts.printf( cvtest::TS::LOG, "Invalid derivates by r1\n" ); ts->printf( cvtest::TS::LOG, "Invalid derivates by r1\n" );
ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
} }
Mat_<double> dr3_dr2, dt3_dr2; Mat_<double> dr3_dr2, dt3_dr2;
diff.dRv2(dr3_dr2, dt3_dr2); diff.dRv2(dr3_dr2, dt3_dr2);
if (norm(dr3_dr2, dr3dr2) > thres || norm(dt3_dr2, dt3dr2) > thres) if (norm(dr3_dr2, dr3dr2) > thres || norm(dt3_dr2, dt3dr2) > thres)
{ {
ts.printf( cvtest::TS::LOG, "Invalid derivates by r2\n" ); ts->printf( cvtest::TS::LOG, "Invalid derivates by r2\n" );
ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
} }
Mat_<double> dr3_dt1, dt3_dt1; Mat_<double> dr3_dt1, dt3_dt1;
diff.dTv1(dr3_dt1, dt3_dt1); diff.dTv1(dr3_dt1, dt3_dt1);
if (norm(dr3_dt1, dr3dt1) > thres || norm(dt3_dt1, dt3dt1) > thres) if (norm(dr3_dt1, dr3dt1) > thres || norm(dt3_dt1, dt3dt1) > thres)
{ {
ts.printf( cvtest::TS::LOG, "Invalid derivates by t1\n" ); ts->printf( cvtest::TS::LOG, "Invalid derivates by t1\n" );
ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
} }
Mat_<double> dr3_dt2, dt3_dt2; Mat_<double> dr3_dt2, dt3_dt2;
diff.dTv2(dr3_dt2, dt3_dt2); diff.dTv2(dr3_dt2, dt3_dt2);
if (norm(dr3_dt2, dr3dt2) > thres || norm(dt3_dt2, dt3dt2) > thres) if (norm(dr3_dt2, dr3dt2) > thres || norm(dt3_dt2, dt3dt2) > thres)
{ {
ts.printf( cvtest::TS::LOG, "Invalid derivates by t2\n" ); ts->printf( cvtest::TS::LOG, "Invalid derivates by t2\n" );
ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
} }
} }
}; };
TEST(Calib3d_ComposeRT, accuracy) { CV_composeRT_Test test; test.safe_run(); } TEST(Calib3d_ComposeRT, accuracy) { CV_composeRT_Test test; test.safe_run(); }

View File

@ -86,20 +86,20 @@ protected:
double sigma; double sigma;
private: private:
float max_diff, max_2diff; float max_diff, max_2diff;
bool check_matrix_size(const cv::Mat& H); bool check_matrix_size(const cv::Mat& H);
bool check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff); bool check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff);
int check_ransac_mask_1(const Mat& src, const Mat& mask); int check_ransac_mask_1(const Mat& src, const Mat& mask);
int check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask); int check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask);
void print_information_1(int j, int N, int method, const Mat& H); void print_information_1(int j, int N, int method, const Mat& H);
void print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff); void print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff);
void print_information_3(int j, int N, const Mat& mask); void print_information_3(int j, int N, const Mat& mask);
void print_information_4(int method, int j, int N, int k, int l, double diff); void print_information_4(int method, int j, int N, int k, int l, double diff);
void print_information_5(int method, int j, int N, int l, double diff); void print_information_5(int method, int j, int N, int l, double diff);
void print_information_6(int j, int N, int k, double diff, bool value); void print_information_6(int j, int N, int k, double diff, bool value);
void print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value); void print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value);
void print_information_8(int j, int N, int k, int l, double diff); void print_information_8(int j, int N, int k, int l, double diff);
}; };
CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2f), max_2diff(2e-2f) CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2f), max_2diff(2e-2f)
@ -112,7 +112,7 @@ CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2f), max_2diff(2e-2f)
CV_HomographyTest::~CV_HomographyTest() {} CV_HomographyTest::~CV_HomographyTest() {}
bool CV_HomographyTest::check_matrix_size(const cv::Mat& H) bool CV_HomographyTest::check_matrix_size(const cv::Mat& H)
{ {
return (H.rows == 3) && (H.cols == 3); return (H.rows == 3) && (H.cols == 3);
} }
@ -138,25 +138,25 @@ int CV_HomographyTest::check_ransac_mask_2(const Mat& original_mask, const Mat&
return 0; return 0;
} }
void CV_HomographyTest::print_information_1(int j, int N, int method, const Mat& H) void CV_HomographyTest::print_information_1(int j, int N, int _method, const Mat& H)
{ {
cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl; cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl;
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl; cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
cout << "Count of points: " << N << endl; cout << endl; cout << "Count of points: " << N << endl; cout << endl;
cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl; cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;
cout << "Homography matrix:" << endl; cout << endl; cout << "Homography matrix:" << endl; cout << endl;
cout << H << endl; cout << endl; cout << H << endl; cout << endl;
cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl; cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl;
} }
void CV_HomographyTest::print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff) void CV_HomographyTest::print_information_2(int j, int N, int _method, const Mat& H, const Mat& H_res, int k, double diff)
{ {
cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl; cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl;
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl; cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
cout << "Count of points: " << N << endl; cout << endl; cout << "Count of points: " << N << endl; cout << endl;
cout << "Method: "; if (method == 0) cout << 0; else if (method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl; cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;
cout << "Original matrix:" << endl; cout << endl; cout << "Original matrix:" << endl; cout << endl;
cout << H << endl; cout << endl; cout << H << endl; cout << endl;
cout << "Found matrix:" << endl; cout << endl; cout << "Found matrix:" << endl; cout << endl;
@ -178,10 +178,10 @@ void CV_HomographyTest::print_information_3(int j, int N, const Mat& mask)
cout << "Number of rows: " << mask.rows << " Number of cols: " << mask.cols << endl; cout << endl; cout << "Number of rows: " << mask.rows << " Number of cols: " << mask.cols << endl; cout << endl;
} }
void CV_HomographyTest::print_information_4(int method, int j, int N, int k, int l, double diff) void CV_HomographyTest::print_information_4(int _method, int j, int N, int k, int l, double diff)
{ {
cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl; cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl;
cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl; cout << "Method: "; if (_method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl; cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
cout << "Sigma of normal noise: " << sigma << endl; cout << "Sigma of normal noise: " << sigma << endl;
@ -192,10 +192,10 @@ void CV_HomographyTest::print_information_4(int method, int j, int N, int k, int
cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl; cout << "Maxumum allowed difference: " << max_2diff << endl; cout << endl;
} }
void CV_HomographyTest::print_information_5(int method, int j, int N, int l, double diff) void CV_HomographyTest::print_information_5(int _method, int j, int N, int l, double diff)
{ {
cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl; cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl;
cout << "Method: "; if (method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl; cout << "Method: "; if (_method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl; cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
cout << "Sigma of normal noise: " << sigma << endl; cout << "Sigma of normal noise: " << sigma << endl;
@ -371,7 +371,7 @@ void CV_HomographyTest::run(int)
if (code) if (code)
{ {
print_information_3(j, N, mask[j]); print_information_3(j, N, mask[j]);
switch (code) switch (code)
{ {
case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; } case 1: { CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_1); break; }
@ -380,7 +380,7 @@ void CV_HomographyTest::run(int)
default: break; default: break;
} }
return; return;
} }
@ -412,7 +412,7 @@ void CV_HomographyTest::run(int)
{ {
case 0: case 0:
case CV_LMEDS: case CV_LMEDS:
{ {
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f), Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f),
cv::findHomography(src_mat_2f, dst_vec), cv::findHomography(src_mat_2f, dst_vec),
cv::findHomography(src_vec, dst_mat_2f), cv::findHomography(src_vec, dst_mat_2f),
@ -465,7 +465,7 @@ void CV_HomographyTest::run(int)
} }
continue; continue;
} }
case CV_RANSAC: case CV_RANSAC:
{ {
cv::Mat mask_res [4]; cv::Mat mask_res [4];
@ -555,7 +555,7 @@ void CV_HomographyTest::run(int)
} }
} }
} }
continue; continue;
} }

View File

@ -1,3 +1,7 @@
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
#endif
#ifndef __OPENCV_TEST_PRECOMP_HPP__ #ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__ #define __OPENCV_TEST_PRECOMP_HPP__

View File

@ -106,7 +106,7 @@ protected:
} }
} }
virtual bool runTest(RNG& rng, int mode, int method, const vector<Point3f>& points, const double* eps, double& maxError) virtual bool runTest(RNG& rng, int mode, int method, const vector<Point3f>& points, const double* epsilon, double& maxError)
{ {
Mat rvec, tvec; Mat rvec, tvec;
vector<int> inliers; vector<int> inliers;
@ -136,7 +136,7 @@ protected:
bool isTestSuccess = inliers.size() >= points.size()*0.95; bool isTestSuccess = inliers.size() >= points.size()*0.95;
double rvecDiff = norm(rvec-trueRvec), tvecDiff = norm(tvec-trueTvec); double rvecDiff = norm(rvec-trueRvec), tvecDiff = norm(tvec-trueTvec);
isTestSuccess = isTestSuccess && rvecDiff < eps[method] && tvecDiff < eps[method]; isTestSuccess = isTestSuccess && rvecDiff < epsilon[method] && tvecDiff < epsilon[method];
double error = rvecDiff > tvecDiff ? rvecDiff : tvecDiff; double error = rvecDiff > tvecDiff ? rvecDiff : tvecDiff;
//cout << error << " " << inliers.size() << " " << eps[method] << endl; //cout << error << " " << inliers.size() << " " << eps[method] << endl;
if (error > maxError) if (error > maxError)
@ -147,8 +147,7 @@ protected:
void run(int) void run(int)
{ {
cvtest::TS& ts = *this->ts; ts->set_failed_test_info(cvtest::TS::OK);
ts.set_failed_test_info(cvtest::TS::OK);
vector<Point3f> points; vector<Point3f> points;
const int pointsCount = 500; const int pointsCount = 500;
@ -157,7 +156,7 @@ protected:
const int methodsCount = 3; const int methodsCount = 3;
RNG rng = ts.get_rng(); RNG rng = ts->get_rng();
for (int mode = 0; mode < 2; mode++) for (int mode = 0; mode < 2; mode++)
@ -174,9 +173,9 @@ protected:
//cout << maxError << " " << successfulTestsCount << endl; //cout << maxError << " " << successfulTestsCount << endl;
if (successfulTestsCount < 0.7*totalTestsCount) if (successfulTestsCount < 0.7*totalTestsCount)
{ {
ts.printf( cvtest::TS::LOG, "Invalid accuracy for method %d, failed %d tests from %d, maximum error equals %f, distortion mode equals %d\n", ts->printf( cvtest::TS::LOG, "Invalid accuracy for method %d, failed %d tests from %d, maximum error equals %f, distortion mode equals %d\n",
method, totalTestsCount - successfulTestsCount, totalTestsCount, maxError, mode); method, totalTestsCount - successfulTestsCount, totalTestsCount, maxError, mode);
ts.set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
} }
} }
} }
@ -198,7 +197,7 @@ public:
~CV_solvePnP_Test() {} ~CV_solvePnP_Test() {}
protected: protected:
virtual bool runTest(RNG& rng, int mode, int method, const vector<Point3f>& points, const double* eps, double& maxError) virtual bool runTest(RNG& rng, int mode, int method, const vector<Point3f>& points, const double* epsilon, double& maxError)
{ {
Mat rvec, tvec; Mat rvec, tvec;
Mat trueRvec, trueTvec; Mat trueRvec, trueTvec;
@ -226,7 +225,7 @@ protected:
false, method); false, method);
double rvecDiff = norm(rvec-trueRvec), tvecDiff = norm(tvec-trueTvec); double rvecDiff = norm(rvec-trueRvec), tvecDiff = norm(tvec-trueTvec);
bool isTestSuccess = rvecDiff < eps[method] && tvecDiff < eps[method]; bool isTestSuccess = rvecDiff < epsilon[method] && tvecDiff < epsilon[method];
double error = rvecDiff > tvecDiff ? rvecDiff : tvecDiff; double error = rvecDiff > tvecDiff ? rvecDiff : tvecDiff;
if (error > maxError) if (error > maxError)

View File

@ -421,7 +421,7 @@ void CV_StereoMatchingTest::run(int)
ts->set_failed_test_info( code ); ts->set_failed_test_info( code );
return; return;
} }
string fullResultFilename = dataPath + ALGORITHMS_DIR + algorithmName + RESULT_FILE; string fullResultFilename = dataPath + ALGORITHMS_DIR + algorithmName + RESULT_FILE;
FileStorage resFS( fullResultFilename, FileStorage::READ ); FileStorage resFS( fullResultFilename, FileStorage::READ );
bool isWrite = true; // write or compare results bool isWrite = true; // write or compare results
@ -593,11 +593,11 @@ int CV_StereoMatchingTest::readDatasetsParams( FileStorage& fs )
assert(fn.isSeq()); assert(fn.isSeq());
for( int i = 0; i < (int)fn.size(); i+=3 ) for( int i = 0; i < (int)fn.size(); i+=3 )
{ {
string name = fn[i]; string _name = fn[i];
DatasetParams params; DatasetParams params;
string sf = fn[i+1]; params.dispScaleFactor = atoi(sf.c_str()); string sf = fn[i+1]; params.dispScaleFactor = atoi(sf.c_str());
string uv = fn[i+2]; params.dispUnknVal = atoi(uv.c_str()); string uv = fn[i+2]; params.dispUnknVal = atoi(uv.c_str());
datasetsParams[name] = params; datasetsParams[_name] = params;
} }
return cvtest::TS::OK; return cvtest::TS::OK;
} }
@ -713,7 +713,7 @@ class CV_StereoSGBMTest : public CV_StereoMatchingTest
public: public:
CV_StereoSGBMTest() CV_StereoSGBMTest()
{ {
name = "stereosgbm"; name = "stereosgbm";
fill(rmsEps.begin(), rmsEps.end(), 0.25f); fill(rmsEps.begin(), rmsEps.end(), 0.25f);
fill(fracEps.begin(), fracEps.end(), 0.01f); fill(fracEps.begin(), fracEps.end(), 0.01f);
} }

View File

@ -63,48 +63,48 @@ private:
GSD_INTENSITY_LT = 15, GSD_INTENSITY_LT = 15,
GSD_INTENSITY_UT = 250 GSD_INTENSITY_UT = 250
}; };
class CV_EXPORTS Histogram class CV_EXPORTS Histogram
{ {
private: private:
enum { enum {
HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1) HistogramSize = (GSD_HUE_UT - GSD_HUE_LT + 1)
}; };
protected: protected:
int findCoverageIndex(double surfaceToCover, int defaultValue = 0); int findCoverageIndex(double surfaceToCover, int defaultValue = 0);
public: public:
CvHistogram *fHistogram; CvHistogram *fHistogram;
Histogram(); Histogram();
virtual ~Histogram(); virtual ~Histogram();
void findCurveThresholds(int &x1, int &x2, double percent = 0.05); void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
void mergeWith(Histogram *source, double weight); void mergeWith(Histogram *source, double weight);
}; };
int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider; int nStartCounter, nFrameCount, nSkinHueLowerBound, nSkinHueUpperBound, nMorphingMethod, nSamplingDivider;
double fHistogramMergeFactor, fHuePercentCovered; double fHistogramMergeFactor, fHuePercentCovered;
Histogram histogramHueMotion, skinHueHistogram; Histogram histogramHueMotion, skinHueHistogram;
IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame; IplImage *imgHueFrame, *imgSaturationFrame, *imgLastGrayFrame, *imgMotionFrame, *imgFilteredFrame;
IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame; IplImage *imgShrinked, *imgTemp, *imgGrayFrame, *imgHSVFrame;
protected: protected:
void initData(IplImage *src, int widthDivider, int heightDivider); void initData(IplImage *src, int widthDivider, int heightDivider);
void adaptiveFilter(); void adaptiveFilter();
public: public:
enum { enum {
MORPHING_METHOD_NONE = 0, MORPHING_METHOD_NONE = 0,
MORPHING_METHOD_ERODE = 1, MORPHING_METHOD_ERODE = 1,
MORPHING_METHOD_ERODE_ERODE = 2, MORPHING_METHOD_ERODE_ERODE = 2,
MORPHING_METHOD_ERODE_DILATE = 3 MORPHING_METHOD_ERODE_DILATE = 3
}; };
CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE); CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);
virtual ~CvAdaptiveSkinDetector(); virtual ~CvAdaptiveSkinDetector();
virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask); virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);
}; };
@ -116,7 +116,7 @@ public:
class CV_EXPORTS CvFuzzyPoint { class CV_EXPORTS CvFuzzyPoint {
public: public:
double x, y, value; double x, y, value;
CvFuzzyPoint(double _x, double _y); CvFuzzyPoint(double _x, double _y);
}; };
@ -124,13 +124,13 @@ class CV_EXPORTS CvFuzzyCurve {
private: private:
std::vector<CvFuzzyPoint> points; std::vector<CvFuzzyPoint> points;
double value, centre; double value, centre;
bool between(double x, double x1, double x2); bool between(double x, double x1, double x2);
public: public:
CvFuzzyCurve(); CvFuzzyCurve();
~CvFuzzyCurve(); ~CvFuzzyCurve();
void setCentre(double _centre); void setCentre(double _centre);
double getCentre(); double getCentre();
void clear(); void clear();
@ -143,7 +143,7 @@ public:
class CV_EXPORTS CvFuzzyFunction { class CV_EXPORTS CvFuzzyFunction {
public: public:
std::vector<CvFuzzyCurve> curves; std::vector<CvFuzzyCurve> curves;
CvFuzzyFunction(); CvFuzzyFunction();
~CvFuzzyFunction(); ~CvFuzzyFunction();
void addCurve(CvFuzzyCurve *curve, double value = 0); void addCurve(CvFuzzyCurve *curve, double value = 0);
@ -186,7 +186,7 @@ private:
FuzzyResizer(); FuzzyResizer();
int calcOutput(double edgeDensity, double density); int calcOutput(double edgeDensity, double density);
}; };
class SearchWindow class SearchWindow
{ {
public: public:
@ -200,7 +200,7 @@ private:
double density; double density;
unsigned int depthLow, depthHigh; unsigned int depthLow, depthHigh;
int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom; int verticalEdgeLeft, verticalEdgeRight, horizontalEdgeTop, horizontalEdgeBottom;
SearchWindow(); SearchWindow();
~SearchWindow(); ~SearchWindow();
void setSize(int _x, int _y, int _width, int _height); void setSize(int _x, int _y, int _width, int _height);
@ -212,7 +212,7 @@ private:
void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh); void getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh);
bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth); bool meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth);
}; };
public: public:
enum TrackingState enum TrackingState
{ {
@ -222,40 +222,40 @@ public:
tsSetWindow = 3, tsSetWindow = 3,
tsDisabled = 10 tsDisabled = 10
}; };
enum ResizeMethod { enum ResizeMethod {
rmEdgeDensityLinear = 0, rmEdgeDensityLinear = 0,
rmEdgeDensityFuzzy = 1, rmEdgeDensityFuzzy = 1,
rmInnerDensity = 2 rmInnerDensity = 2
}; };
enum { enum {
MinKernelMass = 1000 MinKernelMass = 1000
}; };
SearchWindow kernel; SearchWindow kernel;
int searchMode; int searchMode;
private: private:
enum enum
{ {
MaxMeanShiftIteration = 5, MaxMeanShiftIteration = 5,
MaxSetSizeIteration = 5 MaxSetSizeIteration = 5
}; };
void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth); void findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth);
public: public:
CvFuzzyMeanShiftTracker(); CvFuzzyMeanShiftTracker();
~CvFuzzyMeanShiftTracker(); ~CvFuzzyMeanShiftTracker();
void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass); void track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass = MinKernelMass);
}; };
namespace cv namespace cv
{ {
class CV_EXPORTS Octree class CV_EXPORTS Octree
{ {
public: public:
@ -268,11 +268,11 @@ namespace cv
bool isLeaf; bool isLeaf;
int children[8]; int children[8];
}; };
Octree(); Octree();
Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 ); Octree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
virtual ~Octree(); virtual ~Octree();
virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 ); virtual void buildTree( const vector<Point3f>& points, int maxLevels = 10, int minPoints = 20 );
virtual void getPointsWithinSphere( const Point3f& center, float radius, virtual void getPointsWithinSphere( const Point3f& center, float radius,
vector<Point3f>& points ) const; vector<Point3f>& points ) const;
@ -281,85 +281,85 @@ namespace cv
int minPoints; int minPoints;
vector<Point3f> points; vector<Point3f> points;
vector<Node> nodes; vector<Node> nodes;
virtual void buildNext(size_t node_ind); virtual void buildNext(size_t node_ind);
}; };
class CV_EXPORTS Mesh3D class CV_EXPORTS Mesh3D
{ {
public: public:
struct EmptyMeshException {}; struct EmptyMeshException {};
Mesh3D(); Mesh3D();
Mesh3D(const vector<Point3f>& vtx); Mesh3D(const vector<Point3f>& vtx);
~Mesh3D(); ~Mesh3D();
void buildOctree(); void buildOctree();
void clearOctree(); void clearOctree();
float estimateResolution(float tryRatio = 0.1f); float estimateResolution(float tryRatio = 0.1f);
void computeNormals(float normalRadius, int minNeighbors = 20); void computeNormals(float normalRadius, int minNeighbors = 20);
void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20); void computeNormals(const vector<int>& subset, float normalRadius, int minNeighbors = 20);
void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const; void writeAsVrml(const String& file, const vector<Scalar>& colors = vector<Scalar>()) const;
vector<Point3f> vtx; vector<Point3f> vtx;
vector<Point3f> normals; vector<Point3f> normals;
float resolution; float resolution;
Octree octree; Octree octree;
const static Point3f allzero; const static Point3f allzero;
}; };
class CV_EXPORTS SpinImageModel class CV_EXPORTS SpinImageModel
{ {
public: public:
/* model parameters, leave unset for default or auto estimate */ /* model parameters, leave unset for default or auto estimate */
float normalRadius; float normalRadius;
int minNeighbors; int minNeighbors;
float binSize; float binSize;
int imageWidth; int imageWidth;
float lambda; float lambda;
float gamma; float gamma;
float T_GeometriccConsistency; float T_GeometriccConsistency;
float T_GroupingCorespondances; float T_GroupingCorespondances;
/* public interface */ /* public interface */
SpinImageModel(); SpinImageModel();
explicit SpinImageModel(const Mesh3D& mesh); explicit SpinImageModel(const Mesh3D& mesh);
~SpinImageModel(); ~SpinImageModel();
void setLogger(std::ostream* log); void setLogger(std::ostream* log);
void selectRandomSubset(float ratio); void selectRandomSubset(float ratio);
void setSubset(const vector<int>& subset); void setSubset(const vector<int>& subset);
void compute(); void compute();
void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result); void match(const SpinImageModel& scene, vector< vector<Vec2i> >& result);
Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const; Mat packRandomScaledSpins(bool separateScale = false, size_t xCount = 10, size_t yCount = 10) const;
size_t getSpinCount() const { return spinImages.rows; } size_t getSpinCount() const { return spinImages.rows; }
Mat getSpinImage(size_t index) const { return spinImages.row((int)index); } Mat getSpinImage(size_t index) const { return spinImages.row((int)index); }
const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; } const Point3f& getSpinVertex(size_t index) const { return mesh.vtx[subset[index]]; }
const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; } const Point3f& getSpinNormal(size_t index) const { return mesh.normals[subset[index]]; }
const Mesh3D& getMesh() const { return mesh; } const Mesh3D& getMesh() const { return mesh; }
Mesh3D& getMesh() { return mesh; } Mesh3D& getMesh() { return mesh; }
/* static utility functions */ /* static utility functions */
static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result); static bool spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result);
static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal); static Point2f calcSpinMapCoo(const Point3f& point, const Point3f& vertex, const Point3f& normal);
static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1, static float geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
const Point3f& pointModel1, const Point3f& normalModel1, const Point3f& pointModel1, const Point3f& normalModel1,
const Point3f& pointScene2, const Point3f& normalScene2, const Point3f& pointScene2, const Point3f& normalScene2,
const Point3f& pointModel2, const Point3f& normalModel2); const Point3f& pointModel2, const Point3f& normalModel2);
static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1, static float groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
const Point3f& pointModel1, const Point3f& normalModel1, const Point3f& pointModel1, const Point3f& normalModel1,
const Point3f& pointScene2, const Point3f& normalScene2, const Point3f& pointScene2, const Point3f& normalScene2,
@ -367,40 +367,40 @@ namespace cv
float gamma); float gamma);
protected: protected:
void defaultParams(); void defaultParams();
void matchSpinToModel(const Mat& spin, vector<int>& indeces, void matchSpinToModel(const Mat& spin, vector<int>& indeces,
vector<float>& corrCoeffs, bool useExtremeOutliers = true) const; vector<float>& corrCoeffs, bool useExtremeOutliers = true) const;
void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const; void repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc = true) const;
vector<int> subset; vector<int> subset;
Mesh3D mesh; Mesh3D mesh;
Mat spinImages; Mat spinImages;
std::ostream* out; std::ostream* out;
}; };
class CV_EXPORTS TickMeter class CV_EXPORTS TickMeter
{ {
public: public:
TickMeter(); TickMeter();
void start(); void start();
void stop(); void stop();
int64 getTimeTicks() const; int64 getTimeTicks() const;
double getTimeMicro() const; double getTimeMicro() const;
double getTimeMilli() const; double getTimeMilli() const;
double getTimeSec() const; double getTimeSec() const;
int64 getCounter() const; int64 getCounter() const;
void reset(); void reset();
private: private:
int64 counter; int64 counter;
int64 sumTime; int64 sumTime;
int64 startTime; int64 startTime;
}; };
CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm); CV_EXPORTS std::ostream& operator<<(std::ostream& out, const TickMeter& tm);
class CV_EXPORTS SelfSimDescriptor class CV_EXPORTS SelfSimDescriptor
{ {
public: public:
@ -412,29 +412,29 @@ namespace cv
SelfSimDescriptor(const SelfSimDescriptor& ss); SelfSimDescriptor(const SelfSimDescriptor& ss);
virtual ~SelfSimDescriptor(); virtual ~SelfSimDescriptor();
SelfSimDescriptor& operator = (const SelfSimDescriptor& ss); SelfSimDescriptor& operator = (const SelfSimDescriptor& ss);
size_t getDescriptorSize() const; size_t getDescriptorSize() const;
Size getGridSize( Size imgsize, Size winStride ) const; Size getGridSize( Size imgsize, Size winStride ) const;
virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(), virtual void compute(const Mat& img, vector<float>& descriptors, Size winStride=Size(),
const vector<Point>& locations=vector<Point>()) const; const vector<Point>& locations=vector<Point>()) const;
virtual void computeLogPolarMapping(Mat& mappingMask) const; virtual void computeLogPolarMapping(Mat& mappingMask) const;
virtual void SSD(const Mat& img, Point pt, Mat& ssd) const; virtual void SSD(const Mat& img, Point pt, Mat& ssd) const;
int smallSize; int smallSize;
int largeSize; int largeSize;
int startDistanceBucket; int startDistanceBucket;
int numberOfDistanceBuckets; int numberOfDistanceBuckets;
int numberOfAngles; int numberOfAngles;
enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41, enum { DEFAULT_SMALL_SIZE = 5, DEFAULT_LARGE_SIZE = 41,
DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3, DEFAULT_NUM_ANGLES = 20, DEFAULT_START_DISTANCE_BUCKET = 3,
DEFAULT_NUM_DISTANCE_BUCKETS = 7 }; DEFAULT_NUM_DISTANCE_BUCKETS = 7 };
}; };
typedef bool (*BundleAdjustCallback)(int iteration, double norm_error, void* user_data); typedef bool (*BundleAdjustCallback)(int iteration, double norm_error, void* user_data);
class LevMarqSparse { class LevMarqSparse {
public: public:
LevMarqSparse(); LevMarqSparse();
@ -447,9 +447,9 @@ namespace cv
Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
// 1 - point is visible for the camera, 0 - invisible // 1 - point is visible for the camera, 0 - invisible
Mat& P0, // starting vector of parameters, first cameras then points Mat& P0, // starting vector of parameters, first cameras then points
Mat& X, // measurements, in order of visibility. non visible cases are skipped Mat& X, // measurements, in order of visibility. non visible cases are skipped
TermCriteria criteria, // termination criteria TermCriteria criteria, // termination criteria
// callback for estimation of Jacobian matrices // callback for estimation of Jacobian matrices
void (CV_CDECL * fjac)(int i, int j, Mat& point_params, void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
Mat& cam_params, Mat& A, Mat& B, void* data), Mat& cam_params, Mat& A, Mat& B, void* data),
@ -459,9 +459,9 @@ namespace cv
void* data, // user-specific data passed to the callbacks void* data, // user-specific data passed to the callbacks
BundleAdjustCallback cb, void* user_data BundleAdjustCallback cb, void* user_data
); );
virtual ~LevMarqSparse(); virtual ~LevMarqSparse();
virtual void run( int npoints, // number of points virtual void run( int npoints, // number of points
int ncameras, // number of cameras int ncameras, // number of cameras
int nPointParams, // number of params per one point (3 in case of 3D points) int nPointParams, // number of params per one point (3 in case of 3D points)
@ -471,9 +471,9 @@ namespace cv
Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras Mat& visibility, // visibility matrix. rows correspond to points, columns correspond to cameras
// 1 - point is visible for the camera, 0 - invisible // 1 - point is visible for the camera, 0 - invisible
Mat& P0, // starting vector of parameters, first cameras then points Mat& P0, // starting vector of parameters, first cameras then points
Mat& X, // measurements, in order of visibility. non visible cases are skipped Mat& X, // measurements, in order of visibility. non visible cases are skipped
TermCriteria criteria, // termination criteria TermCriteria criteria, // termination criteria
// callback for estimation of Jacobian matrices // callback for estimation of Jacobian matrices
void (CV_CDECL * fjac)(int i, int j, Mat& point_params, void (CV_CDECL * fjac)(int i, int j, Mat& point_params,
Mat& cam_params, Mat& A, Mat& B, void* data), Mat& cam_params, Mat& A, Mat& B, void* data),
@ -482,13 +482,13 @@ namespace cv
Mat& cam_params, Mat& estim, void* data), Mat& cam_params, Mat& estim, void* data),
void* data // user-specific data passed to the callbacks void* data // user-specific data passed to the callbacks
); );
virtual void clear(); virtual void clear();
// useful function to do simple bundle adjustment tasks // useful function to do simple bundle adjustment tasks
static void bundleAdjust(vector<Point3d>& points, // positions of points in global coordinate system (input and output) static void bundleAdjust(vector<Point3d>& points, // positions of points in global coordinate system (input and output)
const vector<vector<Point2d> >& imagePoints, // projections of 3d points for every camera const vector<vector<Point2d> >& imagePoints, // projections of 3d points for every camera
const vector<vector<int> >& visibility, // visibility of 3d points for every camera const vector<vector<int> >& visibility, // visibility of 3d points for every camera
vector<Mat>& cameraMatrix, // intrinsic matrices of all cameras (input and output) vector<Mat>& cameraMatrix, // intrinsic matrices of all cameras (input and output)
vector<Mat>& R, // rotation matrices of all cameras (input and output) vector<Mat>& R, // rotation matrices of all cameras (input and output)
vector<Mat>& T, // translation vector of all cameras (input and output) vector<Mat>& T, // translation vector of all cameras (input and output)
@ -496,123 +496,123 @@ namespace cv
const TermCriteria& criteria= const TermCriteria& criteria=
TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON), TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, DBL_EPSILON),
BundleAdjustCallback cb = 0, void* user_data = 0); BundleAdjustCallback cb = 0, void* user_data = 0);
public: public:
virtual void optimize(CvMat &_vis); //main function that runs minimization virtual void optimize(CvMat &_vis); //main function that runs minimization
//iteratively asks for measurement for visible camera-point pairs //iteratively asks for measurement for visible camera-point pairs
void ask_for_proj(CvMat &_vis,bool once=false); void ask_for_proj(CvMat &_vis,bool once=false);
//iteratively asks for Jacobians for every camera_point pair //iteratively asks for Jacobians for every camera_point pair
void ask_for_projac(CvMat &_vis); void ask_for_projac(CvMat &_vis);
CvMat* err; //error X-hX CvMat* err; //error X-hX
double prevErrNorm, errNorm; double prevErrNorm, errNorm;
double lambda; double lambda;
CvTermCriteria criteria; CvTermCriteria criteria;
int iters; int iters;
CvMat** U; //size of array is equal to number of cameras CvMat** U; //size of array is equal to number of cameras
CvMat** V; //size of array is equal to number of points CvMat** V; //size of array is equal to number of points
CvMat** inv_V_star; //inverse of V* CvMat** inv_V_star; //inverse of V*
CvMat** A; CvMat** A;
CvMat** B; CvMat** B;
CvMat** W; CvMat** W;
CvMat* X; //measurement CvMat* X; //measurement
CvMat* hX; //current measurement extimation given new parameter vector CvMat* hX; //current measurement extimation given new parameter vector
CvMat* prevP; //current already accepted parameter. CvMat* prevP; //current already accepted parameter.
CvMat* P; // parameters used to evaluate function with new params CvMat* P; // parameters used to evaluate function with new params
// this parameters may be rejected // this parameters may be rejected
CvMat* deltaP; //computed increase of parameters (result of normal system solution ) CvMat* deltaP; //computed increase of parameters (result of normal system solution )
CvMat** ea; // sum_i AijT * e_ij , used as right part of normal equation CvMat** ea; // sum_i AijT * e_ij , used as right part of normal equation
// length of array is j = number of cameras // length of array is j = number of cameras
CvMat** eb; // sum_j BijT * e_ij , used as right part of normal equation CvMat** eb; // sum_j BijT * e_ij , used as right part of normal equation
// length of array is i = number of points // length of array is i = number of points
CvMat** Yj; //length of array is i = num_points CvMat** Yj; //length of array is i = num_points
CvMat* S; //big matrix of block Sjk , each block has size num_cam_params x num_cam_params CvMat* S; //big matrix of block Sjk , each block has size num_cam_params x num_cam_params
CvMat* JtJ_diag; //diagonal of JtJ, used to backup diagonal elements before augmentation CvMat* JtJ_diag; //diagonal of JtJ, used to backup diagonal elements before augmentation
CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j CvMat* Vis_index; // matrix which element is index of measurement for point i and camera j
int num_cams; int num_cams;
int num_points; int num_points;
int num_err_param; int num_err_param;
int num_cam_param; int num_cam_param;
int num_point_param; int num_point_param;
//target function and jacobian pointers, which needs to be initialized //target function and jacobian pointers, which needs to be initialized
void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data); void (*fjac)(int i, int j, Mat& point_params, Mat& cam_params, Mat& A, Mat& B, void* data);
void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data); void (*func)(int i, int j, Mat& point_params, Mat& cam_params, Mat& estim, void* data);
void* data; void* data;
BundleAdjustCallback cb; BundleAdjustCallback cb;
void* user_data; void* user_data;
}; };
CV_EXPORTS int chamerMatching( Mat& img, Mat& templ, CV_EXPORTS int chamerMatching( Mat& img, Mat& templ,
vector<vector<Point> >& results, vector<float>& cost, vector<vector<Point> >& results, vector<float>& cost,
double templScale=1, int maxMatches = 20, double templScale=1, int maxMatches = 20,
double minMatchDistance = 1.0, int padX = 3, double minMatchDistance = 1.0, int padX = 3,
int padY = 3, int scales = 5, double minScale = 0.6, double maxScale = 1.6, int padY = 3, int scales = 5, double minScale = 0.6, double maxScale = 1.6,
double orientationWeight = 0.5, double truncate = 20); double orientationWeight = 0.5, double truncate = 20);
class CV_EXPORTS StereoVar class CV_EXPORTS StereoVar
{ {
public: public:
// Flags // Flags
enum {USE_INITIAL_DISPARITY = 1, USE_EQUALIZE_HIST = 2, USE_SMART_ID = 4, USE_AUTO_PARAMS = 8, USE_MEDIAN_FILTERING = 16}; enum {USE_INITIAL_DISPARITY = 1, USE_EQUALIZE_HIST = 2, USE_SMART_ID = 4, USE_AUTO_PARAMS = 8, USE_MEDIAN_FILTERING = 16};
enum {CYCLE_O, CYCLE_V}; enum {CYCLE_O, CYCLE_V};
enum {PENALIZATION_TICHONOV, PENALIZATION_CHARBONNIER, PENALIZATION_PERONA_MALIK}; enum {PENALIZATION_TICHONOV, PENALIZATION_CHARBONNIER, PENALIZATION_PERONA_MALIK};
//! the default constructor //! the default constructor
CV_WRAP StereoVar(); CV_WRAP StereoVar();
//! the full constructor taking all the necessary algorithm parameters //! the full constructor taking all the necessary algorithm parameters
CV_WRAP StereoVar(int levels, double pyrScale, int nIt, int minDisp, int maxDisp, int poly_n, double poly_sigma, float fi, float lambda, int penalization, int cycle, int flags); CV_WRAP StereoVar(int levels, double pyrScale, int nIt, int minDisp, int maxDisp, int poly_n, double poly_sigma, float fi, float lambda, int penalization, int cycle, int flags);
//! the destructor //! the destructor
virtual ~StereoVar(); virtual ~StereoVar();
//! the stereo correspondence operator that computes disparity map for the specified rectified stereo pair //! the stereo correspondence operator that computes disparity map for the specified rectified stereo pair
CV_WRAP_AS(compute) virtual void operator()(const Mat& left, const Mat& right, Mat& disp); CV_WRAP_AS(compute) virtual void operator()(const Mat& left, const Mat& right, Mat& disp);
CV_PROP_RW int levels; CV_PROP_RW int levels;
CV_PROP_RW double pyrScale; CV_PROP_RW double pyrScale;
CV_PROP_RW int nIt; CV_PROP_RW int nIt;
CV_PROP_RW int minDisp; CV_PROP_RW int minDisp;
CV_PROP_RW int maxDisp; CV_PROP_RW int maxDisp;
CV_PROP_RW int poly_n; CV_PROP_RW int poly_n;
CV_PROP_RW double poly_sigma; CV_PROP_RW double poly_sigma;
CV_PROP_RW float fi; CV_PROP_RW float fi;
CV_PROP_RW float lambda; CV_PROP_RW float lambda;
CV_PROP_RW int penalization; CV_PROP_RW int penalization;
CV_PROP_RW int cycle; CV_PROP_RW int cycle;
CV_PROP_RW int flags; CV_PROP_RW int flags;
private: private:
void autoParams(); void autoParams();
void FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level); void FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level);
void VCycle_MyFAS(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level); void VCycle_MyFAS(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level);
void VariationalSolver(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level); void VariationalSolver(Mat &I1_h, Mat &I2_h, Mat &I2x_h, Mat &u_h, int level);
}; };
CV_EXPORTS void polyfit(const Mat& srcx, const Mat& srcy, Mat& dst, int order); CV_EXPORTS void polyfit(const Mat& srcx, const Mat& srcy, Mat& dst, int order);
class CV_EXPORTS Directory class CV_EXPORTS Directory
{ {
public: public:
static std::vector<std::string> GetListFiles ( const std::string& path, const std::string & exten = "*", bool addPath = true ); static std::vector<std::string> GetListFiles ( const std::string& path, const std::string & exten = "*", bool addPath = true );
static std::vector<std::string> GetListFilesR ( const std::string& path, const std::string & exten = "*", bool addPath = true ); static std::vector<std::string> GetListFilesR ( const std::string& path, const std::string & exten = "*", bool addPath = true );
static std::vector<std::string> GetListFolders( const std::string& path, const std::string & exten = "*", bool addPath = true ); static std::vector<std::string> GetListFolders( const std::string& path, const std::string & exten = "*", bool addPath = true );
}; };
/* /*
@ -654,7 +654,7 @@ namespace cv
class CV_EXPORTS LogPolar_Interp class CV_EXPORTS LogPolar_Interp
{ {
public: public:
LogPolar_Interp() {} LogPolar_Interp() {}
/** /**
@ -664,11 +664,11 @@ namespace cv
*\param center the transformation center: where the output precision is maximal *\param center the transformation center: where the output precision is maximal
*\param R the number of rings of the cortical image (default value 70 pixel) *\param R the number of rings of the cortical image (default value 70 pixel)
*\param ro0 the radius of the blind spot (default value 3 pixel) *\param ro0 the radius of the blind spot (default value 3 pixel)
*\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle. *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
* \a 0 means that the retinal image is computed within the inscribed circle. * \a 0 means that the retinal image is computed within the inscribed circle.
*\param S the number of sectors of the cortical image (default value 70 pixel). *\param S the number of sectors of the cortical image (default value 70 pixel).
* Its value is usually internally computed to obtain a pixel aspect ratio equals to 1. * Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
*\param sp \a 1 (default value) means that the parameter \a S is internally computed. *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
* \a 0 means that the parameter \a S is provided by the user. * \a 0 means that the parameter \a S is provided by the user.
*/ */
LogPolar_Interp(int w, int h, Point2i center, int R=70, double ro0=3.0, LogPolar_Interp(int w, int h, Point2i center, int R=70, double ro0=3.0,
@ -689,9 +689,9 @@ namespace cv
*Destructor *Destructor
*/ */
~LogPolar_Interp(); ~LogPolar_Interp();
protected: protected:
Mat Rsri; Mat Rsri;
Mat Csri; Mat Csri;
@ -716,10 +716,10 @@ namespace cv
*More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5 *More details can be found in http://dx.doi.org/10.1007/978-3-642-23968-7_5
*/ */
class CV_EXPORTS LogPolar_Overlapping class CV_EXPORTS LogPolar_Overlapping
{ {
public: public:
LogPolar_Overlapping() {} LogPolar_Overlapping() {}
/** /**
*Constructor *Constructor
*\param w the width of the input image *\param w the width of the input image
@ -727,11 +727,11 @@ namespace cv
*\param center the transformation center: where the output precision is maximal *\param center the transformation center: where the output precision is maximal
*\param R the number of rings of the cortical image (default value 70 pixel) *\param R the number of rings of the cortical image (default value 70 pixel)
*\param ro0 the radius of the blind spot (default value 3 pixel) *\param ro0 the radius of the blind spot (default value 3 pixel)
*\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle. *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
* \a 0 means that the retinal image is computed within the inscribed circle. * \a 0 means that the retinal image is computed within the inscribed circle.
*\param S the number of sectors of the cortical image (default value 70 pixel). *\param S the number of sectors of the cortical image (default value 70 pixel).
* Its value is usually internally computed to obtain a pixel aspect ratio equals to 1. * Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
*\param sp \a 1 (default value) means that the parameter \a S is internally computed. *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
* \a 0 means that the parameter \a S is provided by the user. * \a 0 means that the parameter \a S is provided by the user.
*/ */
LogPolar_Overlapping(int w, int h, Point2i center, int R=70, LogPolar_Overlapping(int w, int h, Point2i center, int R=70,
@ -752,9 +752,9 @@ namespace cv
*Destructor *Destructor
*/ */
~LogPolar_Overlapping(); ~LogPolar_Overlapping();
protected: protected:
Mat Rsri; Mat Rsri;
Mat Csri; Mat Csri;
vector<int> Rsr; vector<int> Rsr;
@ -793,7 +793,7 @@ namespace cv
{ {
public: public:
LogPolar_Adjacent() {} LogPolar_Adjacent() {}
/** /**
*Constructor *Constructor
*\param w the width of the input image *\param w the width of the input image
@ -802,13 +802,13 @@ namespace cv
*\param R the number of rings of the cortical image (default value 70 pixel) *\param R the number of rings of the cortical image (default value 70 pixel)
*\param ro0 the radius of the blind spot (default value 3 pixel) *\param ro0 the radius of the blind spot (default value 3 pixel)
*\param smin the size of the subpixel (default value 0.25 pixel) *\param smin the size of the subpixel (default value 0.25 pixel)
*\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle. *\param full \a 1 (default value) means that the retinal image (the inverse transform) is computed within the circumscribing circle.
* \a 0 means that the retinal image is computed within the inscribed circle. * \a 0 means that the retinal image is computed within the inscribed circle.
*\param S the number of sectors of the cortical image (default value 70 pixel). *\param S the number of sectors of the cortical image (default value 70 pixel).
* Its value is usually internally computed to obtain a pixel aspect ratio equals to 1. * Its value is usually internally computed to obtain a pixel aspect ratio equals to 1.
*\param sp \a 1 (default value) means that the parameter \a S is internally computed. *\param sp \a 1 (default value) means that the parameter \a S is internally computed.
* \a 0 means that the parameter \a S is provided by the user. * \a 0 means that the parameter \a S is provided by the user.
*/ */
LogPolar_Adjacent(int w, int h, Point2i center, int R=70, double ro0=3.0, double smin=0.25, int full=1, int S=117, int sp=1); LogPolar_Adjacent(int w, int h, Point2i center, int R=70, double ro0=3.0, double smin=0.25, int full=1, int S=117, int sp=1);
/** /**
*Transformation from Cartesian image to cortical (log-polar) image. *Transformation from Cartesian image to cortical (log-polar) image.
@ -845,10 +845,10 @@ namespace cv
bool get_uv(double x, double y, int&u, int&v); bool get_uv(double x, double y, int&u, int&v);
void create_map(int M, int N, int R, int S, double ro0, double smin); void create_map(int M, int N, int R, int S, double ro0, double smin);
}; };
CV_EXPORTS Mat subspaceProject(InputArray W, InputArray mean, InputArray src); CV_EXPORTS Mat subspaceProject(InputArray W, InputArray mean, InputArray src);
CV_EXPORTS Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src); CV_EXPORTS Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src);
class CV_EXPORTS LDA class CV_EXPORTS LDA
{ {
public: public:
@ -908,7 +908,7 @@ namespace cv
// Returns the eigenvalues of this LDA. // Returns the eigenvalues of this LDA.
Mat eigenvalues() const { return _eigenvalues; } Mat eigenvalues() const { return _eigenvalues; }
protected: protected:
bool _dataAsRow; bool _dataAsRow;
int _num_components; int _num_components;
@ -917,7 +917,7 @@ namespace cv
void lda(InputArray src, InputArray labels); void lda(InputArray src, InputArray labels);
}; };
class CV_EXPORTS FaceRecognizer class CV_EXPORTS FaceRecognizer
{ {
public: public:
@ -941,16 +941,16 @@ namespace cv
// Deserializes this object from a given cv::FileStorage. // Deserializes this object from a given cv::FileStorage.
virtual void load(const FileStorage& fs) = 0; virtual void load(const FileStorage& fs) = 0;
// Returns eigenvectors (if any) // Returns eigenvectors (if any)
virtual Mat eigenvectors() const { return Mat(); } virtual Mat eigenvectors() const { return Mat(); }
}; };
CV_EXPORTS Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components = 0); CV_EXPORTS Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components = 0);
CV_EXPORTS Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components = 0); CV_EXPORTS Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components = 0);
CV_EXPORTS Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8, CV_EXPORTS Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius=1, int neighbors=8,
int grid_x=8, int grid_y=8); int grid_x=8, int grid_y=8);
enum enum
{ {
COLORMAP_AUTUMN = 0, COLORMAP_AUTUMN = 0,
@ -968,9 +968,9 @@ namespace cv
COLORMAP_MKPJ1 = 12, COLORMAP_MKPJ1 = 12,
COLORMAP_MKPJ2 = 13 COLORMAP_MKPJ2 = 13
}; };
CV_EXPORTS void applyColorMap(InputArray src, OutputArray dst, int colormap); CV_EXPORTS void applyColorMap(InputArray src, OutputArray dst, int colormap);
CV_EXPORTS bool initModule_contrib(); CV_EXPORTS bool initModule_contrib();
} }

View File

@ -86,10 +86,10 @@ struct CV_EXPORTS CvMeanShiftTrackerParams
struct CV_EXPORTS CvFeatureTrackerParams struct CV_EXPORTS CvFeatureTrackerParams
{ {
enum { SIFT = 0, SURF = 1, OPTICAL_FLOW = 2 }; enum { SIFT = 0, SURF = 1, OPTICAL_FLOW = 2 };
CvFeatureTrackerParams(int feature_type = 0, int window_size = 0) CvFeatureTrackerParams(int featureType = 0, int windowSize = 0)
{ {
feature_type = 0; featureType = 0;
window_size = 0; windowSize = 0;
} }
int feature_type; // Feature type to use int feature_type; // Feature type to use

File diff suppressed because it is too large Load Diff

View File

@ -180,13 +180,13 @@ void BasicRetinaFilter::setLPfilterParameters(const float beta, const float tau,
} }
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha); float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
float _a = _filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f); float a = _filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
_filteringCoeficientsTable[1+tableOffset]=(1.0f-_a)*(1.0f-_a)*(1.0f-_a)*(1.0f-_a)/(1.0f+_beta); _filteringCoeficientsTable[1+tableOffset]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[2+tableOffset] =tau; _filteringCoeficientsTable[2+tableOffset] =tau;
//std::cout<<"BasicRetinaFilter::normal:"<<(1.0-_a)*(1.0-_a)*(1.0-_a)*(1.0-_a)/(1.0+_beta)<<" -> old:"<<(1-_a)*(1-_a)*(1-_a)*(1-_a)/(1+_beta)<<std::endl; //std::cout<<"BasicRetinaFilter::normal:"<<(1.0-a)*(1.0-a)*(1.0-a)*(1.0-a)/(1.0+_beta)<<" -> old:"<<(1-a)*(1-a)*(1-a)*(1-a)/(1+_beta)<<std::endl;
//std::cout<<"BasicRetinaFilter::_a="<<_a<<", gain="<<_filteringCoeficientsTable[1+tableOffset]<<", tau="<<tau<<std::endl; //std::cout<<"BasicRetinaFilter::a="<<a<<", gain="<<_filteringCoeficientsTable[1+tableOffset]<<", tau="<<tau<<std::endl;
} }
void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const float beta, const float tau, const float alpha0, const unsigned int filterIndex) void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const float beta, const float tau, const float alpha0, const unsigned int filterIndex)
@ -210,8 +210,8 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CentredAccuracy(const floa
float _alpha=0.8f; float _alpha=0.8f;
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha); float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
float _a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f); float a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
_filteringCoeficientsTable[tableOffset+1]=(1.0f-_a)*(1.0f-_a)*(1.0f-_a)*(1.0f-_a)/(1.0f+_beta); _filteringCoeficientsTable[tableOffset+1]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[tableOffset+2] =tau; _filteringCoeficientsTable[tableOffset+2] =tau;
float commonFactor=alpha0/(float)sqrt(_halfNBcolumns*_halfNBcolumns+_halfNBrows*_halfNBrows+1.0f); float commonFactor=alpha0/(float)sqrt(_halfNBcolumns*_halfNBcolumns+_halfNBrows*_halfNBrows+1.0f);
@ -266,8 +266,8 @@ void BasicRetinaFilter::setProgressiveFilterConstants_CustomAccuracy(const float
} }
unsigned int tableOffset=filterIndex*3; unsigned int tableOffset=filterIndex*3;
float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha); float _temp = (1.0f+_beta)/(2.0f*_mu*_alpha);
float _a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f); float a=_filteringCoeficientsTable[tableOffset] = 1.0f + _temp - (float)sqrt( (1.0f+_temp)*(1.0f+_temp) - 1.0f);
_filteringCoeficientsTable[tableOffset+1]=(1.0f-_a)*(1.0f-_a)*(1.0f-_a)*(1.0f-_a)/(1.0f+_beta); _filteringCoeficientsTable[tableOffset+1]=(1.0f-a)*(1.0f-a)*(1.0f-a)*(1.0f-a)/(1.0f+_beta);
_filteringCoeficientsTable[tableOffset+2] =tau; _filteringCoeficientsTable[tableOffset+2] =tau;
//memset(_progressiveSpatialConstant, 255, _filterOutput.getNBpixels()); //memset(_progressiveSpatialConstant, 255, _filterOutput.getNBpixels());
@ -335,7 +335,7 @@ void BasicRetinaFilter::_localLuminanceAdaptation(const float *inputFrame, const
{ {
float X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon; float X0=*(localLuminancePTR++)*_localLuminanceFactor+_localLuminanceAddon;
// TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values... // TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values...
*(outputFramePTR++) = (_maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0+0.00000000001); *(outputFramePTR++) = (_maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0+0.00000000001f);
//std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]); //std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]);
} }
} }

View File

@ -81,6 +81,7 @@ private:
{ {
public: public:
virtual ImageIterator* iterator() const = 0; virtual ImageIterator* iterator() const = 0;
virtual ~ImageRange() {}
}; };
// Sliding window // Sliding window

View File

@ -18,7 +18,7 @@
#include "precomp.hpp" #include "precomp.hpp"
#include <iostream> #include <iostream>
#if defined _MSC_VER && _MSC_VER >= 1400 #ifdef _MSC_VER
#pragma warning( disable: 4305 ) #pragma warning( disable: 4305 )
#endif #endif
@ -59,8 +59,8 @@ static Mat sortMatrixRowsByIndices(InputArray src, InputArray indices)
return dst; return dst;
} }
Mat argsort(InputArray _src, bool ascending=true) static Mat argsort(InputArray _src, bool ascending=true)
{ {
Mat src = _src.getMat(); Mat src = _src.getMat();
if (src.rows != 1 && src.cols != 1) if (src.rows != 1 && src.cols != 1)
@ -70,14 +70,14 @@ Mat argsort(InputArray _src, bool ascending=true)
sortIdx(src.reshape(1,1),sorted_indices,flags); sortIdx(src.reshape(1,1),sorted_indices,flags);
return sorted_indices; return sorted_indices;
} }
template <typename _Tp> static template <typename _Tp> static
Mat interp1_(const Mat& X_, const Mat& Y_, const Mat& XI) Mat interp1_(const Mat& X_, const Mat& Y_, const Mat& XI)
{ {
int n = XI.rows; int n = XI.rows;
// sort input table // sort input table
vector<int> sort_indices = argsort(X_); vector<int> sort_indices = argsort(X_);
Mat X = sortMatrixRowsByIndices(X_,sort_indices); Mat X = sortMatrixRowsByIndices(X_,sort_indices);
Mat Y = sortMatrixRowsByIndices(Y_,sort_indices); Mat Y = sortMatrixRowsByIndices(Y_,sort_indices);
// interpolated values // interpolated values
@ -131,7 +131,7 @@ static Mat interp1(InputArray _x, InputArray _Y, InputArray _xi)
} }
return Mat(); return Mat();
} }
namespace colormap namespace colormap
{ {
@ -531,7 +531,7 @@ namespace colormap
n); // number of sample points n); // number of sample points
} }
}; };
void ColorMap::operator()(InputArray _src, OutputArray _dst) const void ColorMap::operator()(InputArray _src, OutputArray _dst) const
{ {
if(_lut.total() != 256) if(_lut.total() != 256)
@ -550,7 +550,7 @@ namespace colormap
// Apply the ColorMap. // Apply the ColorMap.
LUT(src, _lut, _dst); LUT(src, _lut, _dst);
} }
Mat ColorMap::linear_colormap(InputArray X, Mat ColorMap::linear_colormap(InputArray X,
InputArray r, InputArray g, InputArray b, InputArray r, InputArray g, InputArray b,
InputArray xi) { InputArray xi) {
@ -581,12 +581,12 @@ namespace colormap
colormap == COLORMAP_HOT ? (colormap::ColorMap*)(new colormap::Hot) : colormap == COLORMAP_HOT ? (colormap::ColorMap*)(new colormap::Hot) :
colormap == COLORMAP_MKPJ1 ? (colormap::ColorMap*)(new colormap::MKPJ1) : colormap == COLORMAP_MKPJ1 ? (colormap::ColorMap*)(new colormap::MKPJ1) :
colormap == COLORMAP_MKPJ2 ? (colormap::ColorMap*)(new colormap::MKPJ2) : 0; colormap == COLORMAP_MKPJ2 ? (colormap::ColorMap*)(new colormap::MKPJ2) : 0;
if( !cm ) if( !cm )
CV_Error( CV_StsBadArg, "Unknown colormap id; use one of COLORMAP_*"); CV_Error( CV_StsBadArg, "Unknown colormap id; use one of COLORMAP_*");
(*cm)(src, dst); (*cm)(src, dst);
delete cm; delete cm;
} }
} }

View File

@ -68,10 +68,10 @@ void CvMeanShiftTracker::newTrackingWindow(Mat image, Rect selection)
mixChannels(&hsv, 1, &hue, 1, channels, 2); mixChannels(&hsv, 1, &hue, 1, channels, 2);
Mat roi(hue, selection); Mat roi(hue, selection);
Mat maskroi(mask, selection); Mat mskroi(mask, selection);
int ch[] = {0, 1}; int ch[] = {0, 1};
int chsize[] = {32, 32}; int chsize[] = {32, 32};
calcHist(&roi, 1, ch, maskroi, hist, 1, chsize, ranges); calcHist(&roi, 1, ch, mskroi, hist, 1, chsize, ranges);
normalize(hist, hist, 0, 255, CV_MINMAX); normalize(hist, hist, 0, 255, CV_MINMAX);
prev_trackwindow = selection; prev_trackwindow = selection;

View File

@ -3,7 +3,7 @@
#define DEBUGLOGS 1 #define DEBUGLOGS 1
#if ANDROID #ifdef ANDROID
#include <android/log.h> #include <android/log.h>
#define LOG_TAG "OBJECT_DETECTOR" #define LOG_TAG "OBJECT_DETECTOR"
#define LOGD0(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) #define LOGD0(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
@ -25,7 +25,7 @@
#define LOGI(_str, ...) LOGI0(_str , ## __VA_ARGS__) #define LOGI(_str, ...) LOGI0(_str , ## __VA_ARGS__)
#define LOGW(_str, ...) LOGW0(_str , ## __VA_ARGS__) #define LOGW(_str, ...) LOGW0(_str , ## __VA_ARGS__)
#define LOGE(_str, ...) LOGE0(_str , ## __VA_ARGS__) #define LOGE(_str, ...) LOGE0(_str , ## __VA_ARGS__)
#else #else
#define LOGD(...) do{} while(0) #define LOGD(...) do{} while(0)
#define LOGI(...) do{} while(0) #define LOGI(...) do{} while(0)
#define LOGW(...) do{} while(0) #define LOGW(...) do{} while(0)
@ -193,7 +193,7 @@ do {
} catch(...) { \ } catch(...) { \
LOGE0("\n ERROR: UNKNOWN Exception caught\n\n"); \ LOGE0("\n ERROR: UNKNOWN Exception caught\n\n"); \
} \ } \
} while(0) } while(0)
#endif #endif
void* workcycleObjectDetectorFunction(void* p) void* workcycleObjectDetectorFunction(void* p)
@ -214,7 +214,7 @@ void DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
vector<Rect> objects; vector<Rect> objects;
CV_Assert(stateThread==STATE_THREAD_WORKING_SLEEPING); CV_Assert(stateThread==STATE_THREAD_WORKING_SLEEPING);
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
{ {
pthread_cond_signal(&objectDetectorThreadStartStop); pthread_cond_signal(&objectDetectorThreadStartStop);
@ -268,7 +268,7 @@ void DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector()
LOGD("DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- imageSeparateDetecting is empty, continue"); LOGD("DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- imageSeparateDetecting is empty, continue");
continue; continue;
} }
LOGD("DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- start handling imageSeparateDetecting, img.size=%dx%d, img.data=0x%p", LOGD("DetectionBasedTracker::SeparateDetectionWork::workcycleObjectDetector() --- start handling imageSeparateDetecting, img.size=%dx%d, img.data=0x%p",
imageSeparateDetecting.size().width, imageSeparateDetecting.size().height, (void*)imageSeparateDetecting.data); imageSeparateDetecting.size().width, imageSeparateDetecting.size().height, (void*)imageSeparateDetecting.data);
@ -368,7 +368,7 @@ void DetectionBasedTracker::SeparateDetectionWork::resetTracking()
pthread_mutex_unlock(&mutex); pthread_mutex_unlock(&mutex);
} }
bool DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThread(const Mat& imageGray, vector<Rect>& rectsWhereRegions) bool DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThread(const Mat& imageGray, vector<Rect>& rectsWhereRegions)
@ -398,7 +398,7 @@ bool DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThrea
if (timeWhenDetectingThreadStartedWork > 0) { if (timeWhenDetectingThreadStartedWork > 0) {
double time_from_previous_launch_in_ms=1000.0 * (((double)(getTickCount() - timeWhenDetectingThreadStartedWork )) / freq); //the same formula as for lastBigDetectionDuration double time_from_previous_launch_in_ms=1000.0 * (((double)(getTickCount() - timeWhenDetectingThreadStartedWork )) / freq); //the same formula as for lastBigDetectionDuration
shouldSendNewDataToWorkThread = (time_from_previous_launch_in_ms >= detectionBasedTracker.parameters.minDetectionPeriod); shouldSendNewDataToWorkThread = (time_from_previous_launch_in_ms >= detectionBasedTracker.parameters.minDetectionPeriod);
LOGD("DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThread: shouldSendNewDataToWorkThread was 1, now it is %d, since time_from_previous_launch_in_ms=%.2f, minDetectionPeriod=%d", LOGD("DetectionBasedTracker::SeparateDetectionWork::communicateWithDetectingThread: shouldSendNewDataToWorkThread was 1, now it is %d, since time_from_previous_launch_in_ms=%.2f, minDetectionPeriod=%d",
(shouldSendNewDataToWorkThread?1:0), time_from_previous_launch_in_ms, detectionBasedTracker.parameters.minDetectionPeriod); (shouldSendNewDataToWorkThread?1:0), time_from_previous_launch_in_ms, detectionBasedTracker.parameters.minDetectionPeriod);
} }
@ -454,7 +454,7 @@ DetectionBasedTracker::DetectionBasedTracker(const std::string& cascadeFilename,
&& (params.scaleFactor > 1.0) && (params.scaleFactor > 1.0)
&& (params.maxTrackLifetime >= 0) ); && (params.maxTrackLifetime >= 0) );
if (!cascadeForTracking.load(cascadeFilename)) { if (!cascadeForTracking.load(cascadeFilename)) {
CV_Error(CV_StsBadArg, "DetectionBasedTracker::DetectionBasedTracker: Cannot load a cascade from the file '"+cascadeFilename+"'"); CV_Error(CV_StsBadArg, "DetectionBasedTracker::DetectionBasedTracker: Cannot load a cascade from the file '"+cascadeFilename+"'");
} }
@ -495,7 +495,7 @@ void DetectionBasedTracker::process(const Mat& imageGray)
Mat imageDetect=imageGray; Mat imageDetect=imageGray;
int D=parameters.minObjectSize; int D=parameters.minObjectSize;
if (D < 1) if (D < 1)
D=1; D=1;
vector<Rect> rectsWhereRegions; vector<Rect> rectsWhereRegions;
@ -633,7 +633,7 @@ void DetectionBasedTracker::updateTrackedObjects(const vector<Rect>& detectedObj
LOGD("DetectionBasedTracker::updateTrackedObjects: j=%d is rejected, because it is intersected with another rectangle", j); LOGD("DetectionBasedTracker::updateTrackedObjects: j=%d is rejected, because it is intersected with another rectangle", j);
continue; continue;
} }
LOGD("DetectionBasedTracker::updateTrackedObjects: detectedObjects[%d]={%d, %d, %d x %d}", LOGD("DetectionBasedTracker::updateTrackedObjects: detectedObjects[%d]={%d, %d, %d x %d}",
j, detectedObjects[j].x, detectedObjects[j].y, detectedObjects[j].width, detectedObjects[j].height); j, detectedObjects[j].x, detectedObjects[j].y, detectedObjects[j].width, detectedObjects[j].height);
Rect r=prevRect & detectedObjects[j]; Rect r=prevRect & detectedObjects[j];
@ -691,9 +691,9 @@ void DetectionBasedTracker::updateTrackedObjects(const vector<Rect>& detectedObj
std::vector<TrackedObject>::iterator it=trackedObjects.begin(); std::vector<TrackedObject>::iterator it=trackedObjects.begin();
while( it != trackedObjects.end() ) { while( it != trackedObjects.end() ) {
if ( (it->numFramesNotDetected > parameters.maxTrackLifetime) if ( (it->numFramesNotDetected > parameters.maxTrackLifetime)
|| ||
( (
(it->numDetectedFrames <= innerParameters.numStepsToWaitBeforeFirstShow) (it->numDetectedFrames <= innerParameters.numStepsToWaitBeforeFirstShow)
&& &&
(it->numFramesNotDetected > innerParameters.numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown) (it->numFramesNotDetected > innerParameters.numStepsToTrackWithoutDetectingIfObjectHasNotBeenShown)
@ -718,7 +718,7 @@ Rect DetectionBasedTracker::calcTrackedObjectPositionToShow(int i) const
return Rect(); return Rect();
} }
if (trackedObjects[i].numDetectedFrames <= innerParameters.numStepsToWaitBeforeFirstShow){ if (trackedObjects[i].numDetectedFrames <= innerParameters.numStepsToWaitBeforeFirstShow){
LOGI("DetectionBasedTracker::calcTrackedObjectPositionToShow: trackedObjects[%d].numDetectedFrames=%d <= numStepsToWaitBeforeFirstShow=%d --- return empty Rect()", LOGI("DetectionBasedTracker::calcTrackedObjectPositionToShow: trackedObjects[%d].numDetectedFrames=%d <= numStepsToWaitBeforeFirstShow=%d --- return empty Rect()",
i, trackedObjects[i].numDetectedFrames, innerParameters.numStepsToWaitBeforeFirstShow); i, trackedObjects[i].numDetectedFrames, innerParameters.numStepsToWaitBeforeFirstShow);
return Rect(); return Rect();
} }

View File

@ -22,7 +22,7 @@ namespace cv
{ {
using std::set; using std::set;
// Reads a sequence from a FileNode::SEQ with type _Tp into a result vector. // Reads a sequence from a FileNode::SEQ with type _Tp into a result vector.
template<typename _Tp> template<typename _Tp>
inline void readFileNodeList(const FileNode& fn, vector<_Tp>& result) { inline void readFileNodeList(const FileNode& fn, vector<_Tp>& result) {
@ -48,7 +48,7 @@ inline void writeFileNodeList(FileStorage& fs, const string& name,
} }
fs << "]"; fs << "]";
} }
static Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0) static Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0)
{ {
// number of samples // number of samples
@ -67,7 +67,7 @@ static Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double
} }
return data; return data;
} }
// Removes duplicate elements in a given vector. // Removes duplicate elements in a given vector.
template<typename _Tp> template<typename _Tp>
inline vector<_Tp> remove_dups(const vector<_Tp>& src) { inline vector<_Tp> remove_dups(const vector<_Tp>& src) {
@ -82,7 +82,7 @@ inline vector<_Tp> remove_dups(const vector<_Tp>& src) {
return elems; return elems;
} }
// Turk, M., and Pentland, A. "Eigenfaces for recognition.". Journal of // Turk, M., and Pentland, A. "Eigenfaces for recognition.". Journal of
// Cognitive Neuroscience 3 (1991), 7186. // Cognitive Neuroscience 3 (1991), 7186.
class Eigenfaces : public FaceRecognizer class Eigenfaces : public FaceRecognizer
@ -100,15 +100,15 @@ public:
using FaceRecognizer::load; using FaceRecognizer::load;
// Initializes an empty Eigenfaces model. // Initializes an empty Eigenfaces model.
Eigenfaces(int num_components = 0) : Eigenfaces(int numComponents = 0) :
_num_components(num_components) { } _num_components(numComponents) { }
// Initializes and computes an Eigenfaces model with images in src and // Initializes and computes an Eigenfaces model with images in src and
// corresponding labels in labels. num_components will be kept for // corresponding labels in labels. num_components will be kept for
// classification. // classification.
Eigenfaces(InputArray src, InputArray labels, Eigenfaces(InputArray src, InputArray labels,
int num_components = 0) : int numComponents = 0) :
_num_components(num_components) { _num_components(numComponents) {
train(src, labels); train(src, labels);
} }
@ -157,16 +157,16 @@ public:
using FaceRecognizer::load; using FaceRecognizer::load;
// Initializes an empty Fisherfaces model. // Initializes an empty Fisherfaces model.
Fisherfaces(int num_components = 0) : Fisherfaces(int numComponents = 0) :
_num_components(num_components) {} _num_components(numComponents) {}
// Initializes and computes a Fisherfaces model with images in src and // Initializes and computes a Fisherfaces model with images in src and
// corresponding labels in labels. num_components will be kept for // corresponding labels in labels. num_components will be kept for
// classification. // classification.
Fisherfaces(InputArray src, Fisherfaces(InputArray src,
InputArray labels, InputArray labels,
int num_components = 0) : int numComponents = 0) :
_num_components(num_components) { _num_components(numComponents) {
train(src, labels); train(src, labels);
} }
@ -228,11 +228,11 @@ public:
// //
// radius, neighbors are used in the local binary patterns creation. // radius, neighbors are used in the local binary patterns creation.
// grid_x, grid_y control the grid size of the spatial histograms. // grid_x, grid_y control the grid size of the spatial histograms.
LBPH(int radius=1, int neighbors=8, int grid_x=8, int grid_y=8) : LBPH(int radius_=1, int neighbors_=8, int grid_x_=8, int grid_y_=8) :
_grid_x(grid_x), _grid_x(grid_x_),
_grid_y(grid_y), _grid_y(grid_y_),
_radius(radius), _radius(radius_),
_neighbors(neighbors) {} _neighbors(neighbors_) {}
// Initializes and computes this LBPH Model. The current implementation is // Initializes and computes this LBPH Model. The current implementation is
// rather fixed as it uses the Extended Local Binary Patterns per default. // rather fixed as it uses the Extended Local Binary Patterns per default.
@ -241,12 +241,12 @@ public:
// (grid_x=8), (grid_y=8) controls the grid size of the spatial histograms. // (grid_x=8), (grid_y=8) controls the grid size of the spatial histograms.
LBPH(InputArray src, LBPH(InputArray src,
InputArray labels, InputArray labels,
int radius=1, int neighbors=8, int radius_=1, int neighbors_=8,
int grid_x=8, int grid_y=8) : int grid_x_=8, int grid_y_=8) :
_grid_x(grid_x), _grid_x(grid_x_),
_grid_y(grid_y), _grid_y(grid_y_),
_radius(radius), _radius(radius_),
_neighbors(neighbors) { _neighbors(neighbors_) {
train(src, labels); train(src, labels);
} }
@ -582,7 +582,7 @@ static Mat histc(InputArray _src, int minVal, int maxVal, bool normed)
return Mat(); return Mat();
} }
static Mat spatial_histogram(InputArray _src, int numPatterns, static Mat spatial_histogram(InputArray _src, int numPatterns,
int grid_x, int grid_y, bool normed) int grid_x, int grid_y, bool normed)
{ {
@ -622,7 +622,7 @@ static Mat elbp(InputArray src, int radius, int neighbors) {
elbp(src, dst, radius, neighbors); elbp(src, dst, radius, neighbors);
return dst; return dst;
} }
void LBPH::load(const FileStorage& fs) { void LBPH::load(const FileStorage& fs) {
fs["radius"] >> _radius; fs["radius"] >> _radius;
fs["neighbors"] >> _neighbors; fs["neighbors"] >> _neighbors;
@ -695,18 +695,18 @@ int LBPH::predict(InputArray _src) const {
} }
return minClass; return minClass;
} }
Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components) Ptr<FaceRecognizer> createEigenFaceRecognizer(int num_components)
{ {
return new Eigenfaces(num_components); return new Eigenfaces(num_components);
} }
Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components) Ptr<FaceRecognizer> createFisherFaceRecognizer(int num_components)
{ {
return new Fisherfaces(num_components); return new Fisherfaces(num_components);
} }
Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius, int neighbors, Ptr<FaceRecognizer> createLBPHFaceRecognizer(int radius, int neighbors,
int grid_x, int grid_y) int grid_x, int grid_y)
{ {

View File

@ -46,7 +46,7 @@
using namespace cv; using namespace cv;
void downsamplePoints( const Mat& src, Mat& dst, size_t count ) static void downsamplePoints( const Mat& src, Mat& dst, size_t count )
{ {
CV_Assert( count >= 2 ); CV_Assert( count >= 2 );
CV_Assert( src.cols == 1 || src.rows == 1 ); CV_Assert( src.cols == 1 || src.rows == 1 );

File diff suppressed because it is too large Load Diff

View File

@ -60,9 +60,9 @@ ICVS 2011, Sophia Antipolis, France, September 20-22, 2011
namespace cv namespace cv
{ {
//------------------------------------interp------------------------------------------- //------------------------------------interp-------------------------------------------
LogPolar_Interp::LogPolar_Interp(int w, int h, Point2i center, int R, double ro0, int interp, int full, int S, int sp) LogPolar_Interp::LogPolar_Interp(int w, int h, Point2i center, int _R, double _ro0, int _interp, int full, int _s, int sp)
{ {
if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1; if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1;
@ -97,23 +97,23 @@ LogPolar_Interp::LogPolar_Interp(int w, int h, Point2i center, int R, double ro0
if (sp){ if (sp){
int jc=M/2-1, ic=N/2-1; int jc=M/2-1, ic=N/2-1;
int romax=min(ic, jc); int _romax=min(ic, jc);
double a=exp(log((double)(romax/2-1)/(double)ro0)/(double)R); double _a=exp(log((double)(_romax/2-1)/(double)ro0)/(double)R);
S=(int) floor(2*CV_PI/(a-1)+0.5); S=(int) floor(2*CV_PI/(_a-1)+0.5);
} }
this->interp=interp; interp=_interp;
create_map(M, N, R, S, ro0); create_map(M, N, _R, _s, _ro0);
} }
void LogPolar_Interp::create_map(int M, int N, int R, int S, double ro0) void LogPolar_Interp::create_map(int _M, int _n, int _R, int _s, double _ro0)
{ {
this->M=M; M=_M;
this->N=N; N=_n;
this->R=R; R=_R;
this->S=S; S=_s;
this->ro0=ro0; ro0=_ro0;
int jc=N/2-1, ic=M/2-1; int jc=N/2-1, ic=M/2-1;
romax=min(ic, jc); romax=min(ic, jc);
@ -130,7 +130,7 @@ void LogPolar_Interp::create_map(int M, int N, int R, int S, double ro0)
for(int u=0; u<R; u++) for(int u=0; u<R; u++)
{ {
Rsri.at<float>(v,u)=(float)(ro0*pow(a,u)*sin(v/q)+jc); Rsri.at<float>(v,u)=(float)(ro0*pow(a,u)*sin(v/q)+jc);
Csri.at<float>(v,u)=(float)(ro0*pow(a,u)*cos(v/q)+ic); Csri.at<float>(v,u)=(float)(ro0*pow(a,u)*cos(v/q)+ic);
} }
} }
@ -158,7 +158,7 @@ void LogPolar_Interp::create_map(int M, int N, int R, int S, double ro0)
const Mat LogPolar_Interp::to_cortical(const Mat &source) const Mat LogPolar_Interp::to_cortical(const Mat &source)
{ {
Mat out(S,R,CV_8UC1,Scalar(0)); Mat out(S,R,CV_8UC1,Scalar(0));
Mat source_border; Mat source_border;
copyMakeBorder(source,source_border,top,bottom,left,right,BORDER_CONSTANT,Scalar(0)); copyMakeBorder(source,source_border,top,bottom,left,right,BORDER_CONSTANT,Scalar(0));
@ -173,7 +173,7 @@ const Mat LogPolar_Interp::to_cartesian(const Mat &source)
Mat out(N,M,CV_8UC1,Scalar(0)); Mat out(N,M,CV_8UC1,Scalar(0));
Mat source_border; Mat source_border;
if (interp==INTER_NEAREST || interp==INTER_LINEAR){ if (interp==INTER_NEAREST || interp==INTER_LINEAR){
copyMakeBorder(source,source_border,0,1,0,0,BORDER_CONSTANT,Scalar(0)); copyMakeBorder(source,source_border,0,1,0,0,BORDER_CONSTANT,Scalar(0));
Mat rowS0 = source_border.row(S); Mat rowS0 = source_border.row(S);
@ -208,7 +208,7 @@ LogPolar_Interp::~LogPolar_Interp()
//------------------------------------overlapping---------------------------------- //------------------------------------overlapping----------------------------------
LogPolar_Overlapping::LogPolar_Overlapping(int w, int h, Point2i center, int R, double ro0, int full, int S, int sp) LogPolar_Overlapping::LogPolar_Overlapping(int w, int h, Point2i center, int _R, double _ro0, int full, int _s, int sp)
{ {
if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1; if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1;
@ -244,21 +244,21 @@ LogPolar_Overlapping::LogPolar_Overlapping(int w, int h, Point2i center, int R,
if (sp){ if (sp){
int jc=M/2-1, ic=N/2-1; int jc=M/2-1, ic=N/2-1;
int romax=min(ic, jc); int _romax=min(ic, jc);
double a=exp(log((double)(romax/2-1)/(double)ro0)/(double)R); double _a=exp(log((double)(_romax/2-1)/(double)ro0)/(double)R);
S=(int) floor(2*CV_PI/(a-1)+0.5); S=(int) floor(2*CV_PI/(_a-1)+0.5);
} }
create_map(M, N, R, S, ro0); create_map(M, N, _R, _s, _ro0);
} }
void LogPolar_Overlapping::create_map(int M, int N, int R, int S, double ro0) void LogPolar_Overlapping::create_map(int _M, int _n, int _R, int _s, double _ro0)
{ {
this->M=M; M=_M;
this->N=N; N=_n;
this->R=R; R=_R;
this->S=S; S=_s;
this->ro0=ro0; ro0=_ro0;
int jc=N/2-1, ic=M/2-1; int jc=N/2-1, ic=M/2-1;
romax=min(ic, jc); romax=min(ic, jc);
@ -280,14 +280,14 @@ void LogPolar_Overlapping::create_map(int M, int N, int R, int S, double ro0)
for(int u=0; u<R; u++) for(int u=0; u<R; u++)
{ {
Rsri.at<float>(v,u)=(float)(ro0*pow(a,u)*sin(v/q)+jc); Rsri.at<float>(v,u)=(float)(ro0*pow(a,u)*sin(v/q)+jc);
Csri.at<float>(v,u)=(float)(ro0*pow(a,u)*cos(v/q)+ic); Csri.at<float>(v,u)=(float)(ro0*pow(a,u)*cos(v/q)+ic);
Rsr[v*R+u]=(int)floor(Rsri.at<float>(v,u)); Rsr[v*R+u]=(int)floor(Rsri.at<float>(v,u));
Csr[v*R+u]=(int)floor(Csri.at<float>(v,u)); Csr[v*R+u]=(int)floor(Csri.at<float>(v,u));
} }
} }
bool done=false; bool done=false;
for(int i=0; i<R; i++) for(int i=0; i<R; i++)
{ {
Wsr[i]=ro0*(a-1)*pow(a,i-1); Wsr[i]=ro0*(a-1)*pow(a,i-1);
@ -297,7 +297,7 @@ void LogPolar_Overlapping::create_map(int M, int N, int R, int S, double ro0)
done =true; done =true;
} }
} }
for(int j=0; j<N; j++) for(int j=0; j<N; j++)
{ {
for(int i=0; i<M; i++)//mdf for(int i=0; i<M; i++)//mdf
@ -312,7 +312,7 @@ void LogPolar_Overlapping::create_map(int M, int N, int R, int S, double ro0)
theta+=2*CV_PI; theta+=2*CV_PI;
ETAyx.at<float>(j,i)=(float)(q*theta); ETAyx.at<float>(j,i)=(float)(q*theta);
double ro2=(j-jc)*(j-jc)+(i-ic)*(i-ic); double ro2=(j-jc)*(j-jc)+(i-ic)*(i-ic);
CSIyx.at<float>(j,i)=(float)(0.5*log(ro2/(ro0*ro0))/log(a)); CSIyx.at<float>(j,i)=(float)(0.5*log(ro2/(ro0*ro0))/log(a));
} }
@ -387,7 +387,7 @@ const Mat LogPolar_Overlapping::to_cartesian(const Mat &source)
remap(source_border,out,CSIyx,ETAyx,INTER_LINEAR); remap(source_border,out,CSIyx,ETAyx,INTER_LINEAR);
int wm=w_ker_2D[R-1].w; int wm=w_ker_2D[R-1].w;
vector<double> IMG((N+2*wm+1)*(M+2*wm+1), 0.); vector<double> IMG((N+2*wm+1)*(M+2*wm+1), 0.);
vector<double> NOR((N+2*wm+1)*(M+2*wm+1), 0.); vector<double> NOR((N+2*wm+1)*(M+2*wm+1), 0.);
@ -426,14 +426,14 @@ const Mat LogPolar_Overlapping::to_cartesian(const Mat &source)
Mat out_cropped=out(Range(top,N-1-bottom),Range(left,M-1-right)); Mat out_cropped=out(Range(top,N-1-bottom),Range(left,M-1-right));
return out_cropped; return out_cropped;
} }
LogPolar_Overlapping::~LogPolar_Overlapping() LogPolar_Overlapping::~LogPolar_Overlapping()
{ {
} }
//----------------------------------------adjacent--------------------------------------- //----------------------------------------adjacent---------------------------------------
LogPolar_Adjacent::LogPolar_Adjacent(int w, int h, Point2i center, int R, double ro0, double smin, int full, int S, int sp) LogPolar_Adjacent::LogPolar_Adjacent(int w, int h, Point2i center, int _R, double _ro0, double smin, int full, int _s, int sp)
{ {
if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1; if ( (center.x!=w/2 || center.y!=h/2) && full==0) full=1;
@ -468,22 +468,22 @@ LogPolar_Adjacent::LogPolar_Adjacent(int w, int h, Point2i center, int R, double
if (sp){ if (sp){
int jc=M/2-1, ic=N/2-1; int jc=M/2-1, ic=N/2-1;
int romax=min(ic, jc); int _romax=min(ic, jc);
double a=exp(log((double)(romax/2-1)/(double)ro0)/(double)R); double _a=exp(log((double)(_romax/2-1)/(double)ro0)/(double)R);
S=(int) floor(2*CV_PI/(a-1)+0.5); S=(int) floor(2*CV_PI/(_a-1)+0.5);
} }
create_map(M, N, R, S, ro0, smin); create_map(M, N, _R, _s, _ro0, smin);
} }
void LogPolar_Adjacent::create_map(int M, int N, int R, int S, double ro0, double smin) void LogPolar_Adjacent::create_map(int _M, int _n, int _R, int _s, double _ro0, double smin)
{ {
LogPolar_Adjacent::M=M; M=_M;
LogPolar_Adjacent::N=N; N=_n;
LogPolar_Adjacent::R=R; R=_R;
LogPolar_Adjacent::S=S; S=_s;
LogPolar_Adjacent::ro0=ro0; ro0=_ro0;
romax=min(M/2.0, N/2.0); romax=min(M/2.0, N/2.0);
a=exp(log(romax/ro0)/(double)R); a=exp(log(romax/ro0)/(double)R);
@ -507,7 +507,7 @@ void LogPolar_Adjacent::create_map(int M, int N, int R, int S, double ro0, doubl
void LogPolar_Adjacent::subdivide_recursively(double x, double y, int i, int j, double length, double smin) void LogPolar_Adjacent::subdivide_recursively(double x, double y, int i, int j, double length, double smin)
{ {
if(length<=smin) if(length<=smin)
{ {
int u, v; int u, v;
@ -576,7 +576,7 @@ const Mat LogPolar_Adjacent::to_cortical(const Mat &source)
for(int j=0; j<N; j++) for(int j=0; j<N; j++)
for(int i=0; i<M; i++) for(int i=0; i<M; i++)
{ {
for(size_t z=0; z<(L[M*j+i]).size(); z++) for(size_t z=0; z<(L[M*j+i]).size(); z++)
{ {
map[R*((L[M*j+i])[z].v)+((L[M*j+i])[z].u)]+=((L[M*j+i])[z].a)*(source_border.at<uchar>(j,i)); map[R*((L[M*j+i])[z].v)+((L[M*j+i])[z].u)]+=((L[M*j+i])[z].a)*(source_border.at<uchar>(j,i));
@ -641,7 +641,7 @@ bool LogPolar_Adjacent::get_uv(double x, double y, int&u, int&v)
else else
v= (int) floor(q*(theta+2*CV_PI)); v= (int) floor(q*(theta+2*CV_PI));
return true; return true;
} }
} }
LogPolar_Adjacent::~LogPolar_Adjacent() LogPolar_Adjacent::~LogPolar_Adjacent()

View File

@ -43,98 +43,99 @@
#include "precomp.hpp" #include "precomp.hpp"
#include <limits> #include <limits>
namespace cv namespace
{ {
using namespace cv;
const size_t MAX_STACK_SIZE = 255; const size_t MAX_STACK_SIZE = 255;
const size_t MAX_LEAFS = 8; const size_t MAX_LEAFS = 8;
bool checkIfNodeOutsideSphere(const Octree::Node& node, const Point3f& c, float r) bool checkIfNodeOutsideSphere(const Octree::Node& node, const Point3f& c, float r)
{ {
if (node.x_max < (c.x - r) || node.y_max < (c.y - r) || node.z_max < (c.z - r)) if (node.x_max < (c.x - r) || node.y_max < (c.y - r) || node.z_max < (c.z - r))
return true; return true;
if ((c.x + r) < node.x_min || (c.y + r) < node.y_min || (c.z + r) < node.z_min) if ((c.x + r) < node.x_min || (c.y + r) < node.y_min || (c.z + r) < node.z_min)
return true; return true;
return false; return false;
} }
bool checkIfNodeInsideSphere(const Octree::Node& node, const Point3f& c, float r) bool checkIfNodeInsideSphere(const Octree::Node& node, const Point3f& c, float r)
{ {
r *= r; r *= r;
float d2_xmin = (node.x_min - c.x) * (node.x_min - c.x); float d2_xmin = (node.x_min - c.x) * (node.x_min - c.x);
float d2_ymin = (node.y_min - c.y) * (node.y_min - c.y); float d2_ymin = (node.y_min - c.y) * (node.y_min - c.y);
float d2_zmin = (node.z_min - c.z) * (node.z_min - c.z); float d2_zmin = (node.z_min - c.z) * (node.z_min - c.z);
if (d2_xmin + d2_ymin + d2_zmin > r) if (d2_xmin + d2_ymin + d2_zmin > r)
return false; return false;
float d2_zmax = (node.z_max - c.z) * (node.z_max - c.z); float d2_zmax = (node.z_max - c.z) * (node.z_max - c.z);
if (d2_xmin + d2_ymin + d2_zmax > r) if (d2_xmin + d2_ymin + d2_zmax > r)
return false; return false;
float d2_ymax = (node.y_max - c.y) * (node.y_max - c.y); float d2_ymax = (node.y_max - c.y) * (node.y_max - c.y);
if (d2_xmin + d2_ymax + d2_zmin > r) if (d2_xmin + d2_ymax + d2_zmin > r)
return false; return false;
if (d2_xmin + d2_ymax + d2_zmax > r) if (d2_xmin + d2_ymax + d2_zmax > r)
return false; return false;
float d2_xmax = (node.x_max - c.x) * (node.x_max - c.x); float d2_xmax = (node.x_max - c.x) * (node.x_max - c.x);
if (d2_xmax + d2_ymin + d2_zmin > r) if (d2_xmax + d2_ymin + d2_zmin > r)
return false; return false;
if (d2_xmax + d2_ymin + d2_zmax > r) if (d2_xmax + d2_ymin + d2_zmax > r)
return false; return false;
if (d2_xmax + d2_ymax + d2_zmin > r) if (d2_xmax + d2_ymax + d2_zmin > r)
return false; return false;
if (d2_xmax + d2_ymax + d2_zmax > r) if (d2_xmax + d2_ymax + d2_zmax > r)
return false; return false;
return true; return true;
} }
void fillMinMax(const vector<Point3f>& points, Octree::Node& node) void fillMinMax(const vector<Point3f>& points, Octree::Node& node)
{ {
node.x_max = node.y_max = node.z_max = std::numeric_limits<float>::min(); node.x_max = node.y_max = node.z_max = std::numeric_limits<float>::min();
node.x_min = node.y_min = node.z_min = std::numeric_limits<float>::max(); node.x_min = node.y_min = node.z_min = std::numeric_limits<float>::max();
for (size_t i = 0; i < points.size(); ++i) for (size_t i = 0; i < points.size(); ++i)
{ {
const Point3f& point = points[i]; const Point3f& point = points[i];
if (node.x_max < point.x) if (node.x_max < point.x)
node.x_max = point.x; node.x_max = point.x;
if (node.y_max < point.y) if (node.y_max < point.y)
node.y_max = point.y; node.y_max = point.y;
if (node.z_max < point.z) if (node.z_max < point.z)
node.z_max = point.z; node.z_max = point.z;
if (node.x_min > point.x) if (node.x_min > point.x)
node.x_min = point.x; node.x_min = point.x;
if (node.y_min > point.y) if (node.y_min > point.y)
node.y_min = point.y; node.y_min = point.y;
if (node.z_min > point.z) if (node.z_min > point.z)
node.z_min = point.z; node.z_min = point.z;
} }
} }
size_t findSubboxForPoint(const Point3f& point, const Octree::Node& node) size_t findSubboxForPoint(const Point3f& point, const Octree::Node& node)
{ {
size_t ind_x = point.x < (node.x_max + node.x_min) / 2 ? 0 : 1; size_t ind_x = point.x < (node.x_max + node.x_min) / 2 ? 0 : 1;
size_t ind_y = point.y < (node.y_max + node.y_min) / 2 ? 0 : 1; size_t ind_y = point.y < (node.y_max + node.y_min) / 2 ? 0 : 1;
size_t ind_z = point.z < (node.z_max + node.z_min) / 2 ? 0 : 1; size_t ind_z = point.z < (node.z_max + node.z_min) / 2 ? 0 : 1;
return (ind_x << 2) + (ind_y << 1) + (ind_z << 0); return (ind_x << 2) + (ind_y << 1) + (ind_z << 0);
} }
void initChildBox(const Octree::Node& parent, size_t boxIndex, Octree::Node& child) void initChildBox(const Octree::Node& parent, size_t boxIndex, Octree::Node& child)
@ -142,58 +143,61 @@ namespace cv
child.x_min = child.x_max = (parent.x_max + parent.x_min) / 2; child.x_min = child.x_max = (parent.x_max + parent.x_min) / 2;
child.y_min = child.y_max = (parent.y_max + parent.y_min) / 2; child.y_min = child.y_max = (parent.y_max + parent.y_min) / 2;
child.z_min = child.z_max = (parent.z_max + parent.z_min) / 2; child.z_min = child.z_max = (parent.z_max + parent.z_min) / 2;
if ((boxIndex >> 0) & 1) if ((boxIndex >> 0) & 1)
child.z_max = parent.z_max; child.z_max = parent.z_max;
else else
child.z_min = parent.z_min; child.z_min = parent.z_min;
if ((boxIndex >> 1) & 1) if ((boxIndex >> 1) & 1)
child.y_max = parent.y_max; child.y_max = parent.y_max;
else else
child.y_min = parent.y_min; child.y_min = parent.y_min;
if ((boxIndex >> 2) & 1) if ((boxIndex >> 2) & 1)
child.x_max = parent.x_max; child.x_max = parent.x_max;
else else
child.x_min = parent.x_min; child.x_min = parent.x_min;
} }
}//namespace
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// Octree ////////////////////////////////////// /////////////////////////// Octree //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
namespace cv
{
Octree::Octree() Octree::Octree()
{ {
} }
Octree::Octree(const vector<Point3f>& points3d, int maxLevels, int minPoints) Octree::Octree(const vector<Point3f>& points3d, int maxLevels, int _minPoints)
{ {
buildTree(points3d, maxLevels, minPoints); buildTree(points3d, maxLevels, _minPoints);
} }
Octree::~Octree() Octree::~Octree()
{ {
} }
void Octree::getPointsWithinSphere(const Point3f& center, float radius, vector<Point3f>& out) const void Octree::getPointsWithinSphere(const Point3f& center, float radius, vector<Point3f>& out) const
{ {
out.clear(); out.clear();
if (nodes.empty()) if (nodes.empty())
return; return;
int stack[MAX_STACK_SIZE]; int stack[MAX_STACK_SIZE];
int pos = 0; int pos = 0;
stack[pos] = 0; stack[pos] = 0;
while (pos >= 0) while (pos >= 0)
{ {
const Node& cur = nodes[stack[pos--]]; const Node& cur = nodes[stack[pos--]];
if (checkIfNodeOutsideSphere(cur, center, radius)) if (checkIfNodeOutsideSphere(cur, center, radius))
continue; continue;
if (checkIfNodeInsideSphere(cur, center, radius)) if (checkIfNodeInsideSphere(cur, center, radius))
{ {
size_t sz = out.size(); size_t sz = out.size();
@ -202,133 +206,133 @@ namespace cv
out[sz++] = points[i]; out[sz++] = points[i];
continue; continue;
} }
if (cur.isLeaf) if (cur.isLeaf)
{ {
double r2 = radius * radius; double r2 = radius * radius;
size_t sz = out.size(); size_t sz = out.size();
out.resize(sz + (cur.end - cur.begin)); out.resize(sz + (cur.end - cur.begin));
for (int i = cur.begin; i < cur.end; ++i) for (int i = cur.begin; i < cur.end; ++i)
{ {
const Point3f& point = points[i]; const Point3f& point = points[i];
double dx = (point.x - center.x); double dx = (point.x - center.x);
double dy = (point.y - center.y); double dy = (point.y - center.y);
double dz = (point.z - center.z); double dz = (point.z - center.z);
double dist2 = dx * dx + dy * dy + dz * dz; double dist2 = dx * dx + dy * dy + dz * dz;
if (dist2 < r2) if (dist2 < r2)
out[sz++] = point; out[sz++] = point;
}; };
out.resize(sz); out.resize(sz);
continue; continue;
} }
if (cur.children[0]) if (cur.children[0])
stack[++pos] = cur.children[0]; stack[++pos] = cur.children[0];
if (cur.children[1]) if (cur.children[1])
stack[++pos] = cur.children[1]; stack[++pos] = cur.children[1];
if (cur.children[2]) if (cur.children[2])
stack[++pos] = cur.children[2]; stack[++pos] = cur.children[2];
if (cur.children[3]) if (cur.children[3])
stack[++pos] = cur.children[3]; stack[++pos] = cur.children[3];
if (cur.children[4]) if (cur.children[4])
stack[++pos] = cur.children[4]; stack[++pos] = cur.children[4];
if (cur.children[5]) if (cur.children[5])
stack[++pos] = cur.children[5]; stack[++pos] = cur.children[5];
if (cur.children[6]) if (cur.children[6])
stack[++pos] = cur.children[6]; stack[++pos] = cur.children[6];
if (cur.children[7]) if (cur.children[7])
stack[++pos] = cur.children[7]; stack[++pos] = cur.children[7];
} }
} }
void Octree::buildTree(const vector<Point3f>& points3d, int maxLevels, int minPoints) void Octree::buildTree(const vector<Point3f>& points3d, int maxLevels, int _minPoints)
{ {
assert((size_t)maxLevels * 8 < MAX_STACK_SIZE); assert((size_t)maxLevels * 8 < MAX_STACK_SIZE);
points.resize(points3d.size()); points.resize(points3d.size());
std::copy(points3d.begin(), points3d.end(), points.begin()); std::copy(points3d.begin(), points3d.end(), points.begin());
this->minPoints = minPoints; minPoints = _minPoints;
nodes.clear(); nodes.clear();
nodes.push_back(Node()); nodes.push_back(Node());
Node& root = nodes[0]; Node& root = nodes[0];
fillMinMax(points, root); fillMinMax(points, root);
root.isLeaf = true; root.isLeaf = true;
root.maxLevels = maxLevels; root.maxLevels = maxLevels;
root.begin = 0; root.begin = 0;
root.end = (int)points.size(); root.end = (int)points.size();
for (size_t i = 0; i < MAX_LEAFS; i++) for (size_t i = 0; i < MAX_LEAFS; i++)
root.children[i] = 0; root.children[i] = 0;
if (maxLevels != 1 && (root.end - root.begin) > minPoints) if (maxLevels != 1 && (root.end - root.begin) > _minPoints)
{ {
root.isLeaf = false; root.isLeaf = false;
buildNext(0); buildNext(0);
} }
} }
void Octree::buildNext(size_t nodeInd) void Octree::buildNext(size_t nodeInd)
{ {
size_t size = nodes[nodeInd].end - nodes[nodeInd].begin; size_t size = nodes[nodeInd].end - nodes[nodeInd].begin;
vector<size_t> boxBorders(MAX_LEAFS+1, 0); vector<size_t> boxBorders(MAX_LEAFS+1, 0);
vector<size_t> boxIndices(size); vector<size_t> boxIndices(size);
vector<Point3f> tempPoints(size); vector<Point3f> tempPoints(size);
for (int i = nodes[nodeInd].begin, j = 0; i < nodes[nodeInd].end; ++i, ++j) for (int i = nodes[nodeInd].begin, j = 0; i < nodes[nodeInd].end; ++i, ++j)
{ {
const Point3f& p = points[i]; const Point3f& p = points[i];
size_t subboxInd = findSubboxForPoint(p, nodes[nodeInd]); size_t subboxInd = findSubboxForPoint(p, nodes[nodeInd]);
boxBorders[subboxInd+1]++; boxBorders[subboxInd+1]++;
boxIndices[j] = subboxInd; boxIndices[j] = subboxInd;
tempPoints[j] = p; tempPoints[j] = p;
} }
for (size_t i = 1; i < boxBorders.size(); ++i) for (size_t i = 1; i < boxBorders.size(); ++i)
boxBorders[i] += boxBorders[i-1]; boxBorders[i] += boxBorders[i-1];
vector<size_t> writeInds(boxBorders.begin(), boxBorders.end()); vector<size_t> writeInds(boxBorders.begin(), boxBorders.end());
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
{ {
size_t boxIndex = boxIndices[i]; size_t boxIndex = boxIndices[i];
Point3f& curPoint = tempPoints[i]; Point3f& curPoint = tempPoints[i];
size_t copyTo = nodes[nodeInd].begin + writeInds[boxIndex]++; size_t copyTo = nodes[nodeInd].begin + writeInds[boxIndex]++;
points[copyTo] = curPoint; points[copyTo] = curPoint;
} }
for (size_t i = 0; i < MAX_LEAFS; ++i) for (size_t i = 0; i < MAX_LEAFS; ++i)
{ {
if (boxBorders[i] == boxBorders[i+1]) if (boxBorders[i] == boxBorders[i+1])
continue; continue;
nodes.push_back(Node()); nodes.push_back(Node());
Node& child = nodes.back(); Node& child = nodes.back();
initChildBox(nodes[nodeInd], i, child); initChildBox(nodes[nodeInd], i, child);
child.isLeaf = true; child.isLeaf = true;
child.maxLevels = nodes[nodeInd].maxLevels - 1; child.maxLevels = nodes[nodeInd].maxLevels - 1;
child.begin = nodes[nodeInd].begin + (int)boxBorders[i+0]; child.begin = nodes[nodeInd].begin + (int)boxBorders[i+0];
child.end = nodes[nodeInd].begin + (int)boxBorders[i+1]; child.end = nodes[nodeInd].begin + (int)boxBorders[i+1];
for (size_t k = 0; k < MAX_LEAFS; k++) for (size_t k = 0; k < MAX_LEAFS; k++)
child.children[k] = 0; child.children[k] = 0;
nodes[nodeInd].children[i] = (int)(nodes.size() - 1); nodes[nodeInd].children[i] = (int)(nodes.size() - 1);
if (child.maxLevels != 1 && (child.end - child.begin) > minPoints) if (child.maxLevels != 1 && (child.end - child.begin) > minPoints)
{ {
child.isLeaf = false; child.isLeaf = false;
@ -336,5 +340,5 @@ namespace cv
} }
} }
} }
} }

View File

@ -43,11 +43,7 @@
#ifndef __OPENCV_PRECOMP_H__ #ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__ #define __OPENCV_PRECOMP_H__
#if _MSC_VER >= 1200 #ifdef HAVE_CVCONFIG_H
#pragma warning( disable: 4251 4710 4711 4514 4996 )
#endif
#ifdef HAVE_CVCONFIG_H
#include "cvconfig.h" #include "cvconfig.h"
#endif #endif

View File

@ -74,17 +74,17 @@
namespace cv namespace cv
{ {
Retina::Retina(const cv::Size inputSize) Retina::Retina(const cv::Size inputSz)
{ {
_retinaFilter = 0; _retinaFilter = 0;
_init(inputSize, true, RETINA_COLOR_BAYER, false); _init(inputSz, true, RETINA_COLOR_BAYER, false);
} }
Retina::Retina(const cv::Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght) Retina::Retina(const cv::Size inputSz, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
{ {
_retinaFilter = 0; _retinaFilter = 0;
_init(inputSize, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght); _init(inputSz, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
}; };
Retina::~Retina() Retina::~Retina()
@ -94,19 +94,19 @@ Retina::~Retina()
} }
/** /**
* retreive retina input buffer size * retreive retina input buffer size
*/ */
Size Retina::inputSize(){return cv::Size(_retinaFilter->getInputNBcolumns(), _retinaFilter->getInputNBrows());} Size Retina::inputSize(){return cv::Size(_retinaFilter->getInputNBcolumns(), _retinaFilter->getInputNBrows());}
/** /**
* retreive retina output buffer size * retreive retina output buffer size
*/ */
Size Retina::outputSize(){return cv::Size(_retinaFilter->getOutputNBcolumns(), _retinaFilter->getOutputNBrows());} Size Retina::outputSize(){return cv::Size(_retinaFilter->getOutputNBcolumns(), _retinaFilter->getOutputNBrows());}
void Retina::setColorSaturation(const bool saturateColors, const float colorSaturationValue) void Retina::setColorSaturation(const bool saturateColors, const float colorSaturationValue)
{ {
_retinaFilter->setColorSaturation(saturateColors, colorSaturationValue); _retinaFilter->setColorSaturation(saturateColors, colorSaturationValue);
} }
struct Retina::RetinaParameters Retina::getParameters(){return _retinaParameters;} struct Retina::RetinaParameters Retina::getParameters(){return _retinaParameters;}
@ -121,71 +121,71 @@ void Retina::setup(std::string retinaParameterFile, const bool applyDefaultSetup
setup(fs, applyDefaultSetupOnFailure); setup(fs, applyDefaultSetupOnFailure);
}catch(Exception &e) }catch(Exception &e)
{ {
std::cout<<"Retina::setup: wrong/unappropriate xml parameter file : error report :`n=>"<<e.what()<<std::endl; std::cout<<"Retina::setup: wrong/unappropriate xml parameter file : error report :`n=>"<<e.what()<<std::endl;
if (applyDefaultSetupOnFailure) if (applyDefaultSetupOnFailure)
{ {
std::cout<<"Retina::setup: resetting retina with default parameters"<<std::endl; std::cout<<"Retina::setup: resetting retina with default parameters"<<std::endl;
setupOPLandIPLParvoChannel(); setupOPLandIPLParvoChannel();
setupIPLMagnoChannel(); setupIPLMagnoChannel();
} }
else else
{ {
std::cout<<"=> keeping current parameters"<<std::endl; std::cout<<"=> keeping current parameters"<<std::endl;
} }
} }
} }
void Retina::setup(cv::FileStorage &fs, const bool applyDefaultSetupOnFailure) void Retina::setup(cv::FileStorage &fs, const bool applyDefaultSetupOnFailure)
{ {
try try
{ {
// read parameters file if it exists or apply default setup if asked for // read parameters file if it exists or apply default setup if asked for
if (!fs.isOpened()) if (!fs.isOpened())
{ {
std::cout<<"Retina::setup: provided parameters file could not be open... skeeping configuration"<<std::endl; std::cout<<"Retina::setup: provided parameters file could not be open... skeeping configuration"<<std::endl;
return; return;
// implicit else case : retinaParameterFile could be open (it exists at least) // implicit else case : retinaParameterFile could be open (it exists at least)
} }
// OPL and Parvo init first... update at the same time the parameters structure and the retina core // OPL and Parvo init first... update at the same time the parameters structure and the retina core
cv::FileNode rootFn = fs.root(), currFn=rootFn["OPLandIPLparvo"]; cv::FileNode rootFn = fs.root(), currFn=rootFn["OPLandIPLparvo"];
currFn["colorMode"]>>_retinaParameters.OPLandIplParvo.colorMode; currFn["colorMode"]>>_retinaParameters.OPLandIplParvo.colorMode;
currFn["normaliseOutput"]>>_retinaParameters.OPLandIplParvo.normaliseOutput; currFn["normaliseOutput"]>>_retinaParameters.OPLandIplParvo.normaliseOutput;
currFn["photoreceptorsLocalAdaptationSensitivity"]>>_retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity; currFn["photoreceptorsLocalAdaptationSensitivity"]>>_retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity;
currFn["photoreceptorsTemporalConstant"]>>_retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant; currFn["photoreceptorsTemporalConstant"]>>_retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant;
currFn["photoreceptorsSpatialConstant"]>>_retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant; currFn["photoreceptorsSpatialConstant"]>>_retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant;
currFn["horizontalCellsGain"]>>_retinaParameters.OPLandIplParvo.horizontalCellsGain; currFn["horizontalCellsGain"]>>_retinaParameters.OPLandIplParvo.horizontalCellsGain;
currFn["hcellsTemporalConstant"]>>_retinaParameters.OPLandIplParvo.hcellsTemporalConstant; currFn["hcellsTemporalConstant"]>>_retinaParameters.OPLandIplParvo.hcellsTemporalConstant;
currFn["hcellsSpatialConstant"]>>_retinaParameters.OPLandIplParvo.hcellsSpatialConstant; currFn["hcellsSpatialConstant"]>>_retinaParameters.OPLandIplParvo.hcellsSpatialConstant;
currFn["ganglionCellsSensitivity"]>>_retinaParameters.OPLandIplParvo.ganglionCellsSensitivity; currFn["ganglionCellsSensitivity"]>>_retinaParameters.OPLandIplParvo.ganglionCellsSensitivity;
setupOPLandIPLParvoChannel(_retinaParameters.OPLandIplParvo.colorMode, _retinaParameters.OPLandIplParvo.normaliseOutput, _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity, _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant, _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant, _retinaParameters.OPLandIplParvo.horizontalCellsGain, _retinaParameters.OPLandIplParvo.hcellsTemporalConstant, _retinaParameters.OPLandIplParvo.hcellsSpatialConstant, _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity); setupOPLandIPLParvoChannel(_retinaParameters.OPLandIplParvo.colorMode, _retinaParameters.OPLandIplParvo.normaliseOutput, _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity, _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant, _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant, _retinaParameters.OPLandIplParvo.horizontalCellsGain, _retinaParameters.OPLandIplParvo.hcellsTemporalConstant, _retinaParameters.OPLandIplParvo.hcellsSpatialConstant, _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity);
// init retina IPL magno setup... update at the same time the parameters structure and the retina core // init retina IPL magno setup... update at the same time the parameters structure and the retina core
currFn=rootFn["IPLmagno"]; currFn=rootFn["IPLmagno"];
currFn["normaliseOutput"]>>_retinaParameters.IplMagno.normaliseOutput; currFn["normaliseOutput"]>>_retinaParameters.IplMagno.normaliseOutput;
currFn["parasolCells_beta"]>>_retinaParameters.IplMagno.parasolCells_beta; currFn["parasolCells_beta"]>>_retinaParameters.IplMagno.parasolCells_beta;
currFn["parasolCells_tau"]>>_retinaParameters.IplMagno.parasolCells_tau; currFn["parasolCells_tau"]>>_retinaParameters.IplMagno.parasolCells_tau;
currFn["parasolCells_k"]>>_retinaParameters.IplMagno.parasolCells_k; currFn["parasolCells_k"]>>_retinaParameters.IplMagno.parasolCells_k;
currFn["amacrinCellsTemporalCutFrequency"]>>_retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency; currFn["amacrinCellsTemporalCutFrequency"]>>_retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency;
currFn["V0CompressionParameter"]>>_retinaParameters.IplMagno.V0CompressionParameter; currFn["V0CompressionParameter"]>>_retinaParameters.IplMagno.V0CompressionParameter;
currFn["localAdaptintegration_tau"]>>_retinaParameters.IplMagno.localAdaptintegration_tau; currFn["localAdaptintegration_tau"]>>_retinaParameters.IplMagno.localAdaptintegration_tau;
currFn["localAdaptintegration_k"]>>_retinaParameters.IplMagno.localAdaptintegration_k; currFn["localAdaptintegration_k"]>>_retinaParameters.IplMagno.localAdaptintegration_k;
setupIPLMagnoChannel(_retinaParameters.IplMagno.normaliseOutput, _retinaParameters.IplMagno.parasolCells_beta, _retinaParameters.IplMagno.parasolCells_tau, _retinaParameters.IplMagno.parasolCells_k, _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency,_retinaParameters.IplMagno.V0CompressionParameter, _retinaParameters.IplMagno.localAdaptintegration_tau, _retinaParameters.IplMagno.localAdaptintegration_k); setupIPLMagnoChannel(_retinaParameters.IplMagno.normaliseOutput, _retinaParameters.IplMagno.parasolCells_beta, _retinaParameters.IplMagno.parasolCells_tau, _retinaParameters.IplMagno.parasolCells_k, _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency,_retinaParameters.IplMagno.V0CompressionParameter, _retinaParameters.IplMagno.localAdaptintegration_tau, _retinaParameters.IplMagno.localAdaptintegration_k);
}catch(Exception &e) }catch(Exception &e)
{ {
std::cout<<"Retina::setup: resetting retina with default parameters"<<std::endl; std::cout<<"Retina::setup: resetting retina with default parameters"<<std::endl;
if (applyDefaultSetupOnFailure) if (applyDefaultSetupOnFailure)
{ {
setupOPLandIPLParvoChannel(); setupOPLandIPLParvoChannel();
setupIPLMagnoChannel(); setupIPLMagnoChannel();
} }
std::cout<<"Retina::setup: wrong/unappropriate xml parameter file : error report :`n=>"<<e.what()<<std::endl; std::cout<<"Retina::setup: wrong/unappropriate xml parameter file : error report :`n=>"<<e.what()<<std::endl;
std::cout<<"=> keeping current parameters"<<std::endl; std::cout<<"=> keeping current parameters"<<std::endl;
} }
// report current configuration // report current configuration
std::cout<<printSetup()<<std::endl; std::cout<<printSetup()<<std::endl;
} }
void Retina::setup(cv::Retina::RetinaParameters newConfiguration) void Retina::setup(cv::Retina::RetinaParameters newConfiguration)
@ -201,35 +201,35 @@ void Retina::setup(cv::Retina::RetinaParameters newConfiguration)
const std::string Retina::printSetup() const std::string Retina::printSetup()
{ {
std::stringstream outmessage; std::stringstream outmessage;
// displaying OPL and IPL parvo setup // displaying OPL and IPL parvo setup
outmessage<<"Current Retina instance setup :" outmessage<<"Current Retina instance setup :"
<<"\nOPLandIPLparvo"<<"{" <<"\nOPLandIPLparvo"<<"{"
<< "\n==> colorMode : " << _retinaParameters.OPLandIplParvo.colorMode << "\n==> colorMode : " << _retinaParameters.OPLandIplParvo.colorMode
<< "\n==> normalizeParvoOutput :" << _retinaParameters.OPLandIplParvo.normaliseOutput << "\n==> normalizeParvoOutput :" << _retinaParameters.OPLandIplParvo.normaliseOutput
<< "\n==> photoreceptorsLocalAdaptationSensitivity : " << _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity << "\n==> photoreceptorsLocalAdaptationSensitivity : " << _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity
<< "\n==> photoreceptorsTemporalConstant : " << _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant << "\n==> photoreceptorsTemporalConstant : " << _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant
<< "\n==> photoreceptorsSpatialConstant : " << _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant << "\n==> photoreceptorsSpatialConstant : " << _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant
<< "\n==> horizontalCellsGain : " << _retinaParameters.OPLandIplParvo.horizontalCellsGain << "\n==> horizontalCellsGain : " << _retinaParameters.OPLandIplParvo.horizontalCellsGain
<< "\n==> hcellsTemporalConstant : " << _retinaParameters.OPLandIplParvo.hcellsTemporalConstant << "\n==> hcellsTemporalConstant : " << _retinaParameters.OPLandIplParvo.hcellsTemporalConstant
<< "\n==> hcellsSpatialConstant : " << _retinaParameters.OPLandIplParvo.hcellsSpatialConstant << "\n==> hcellsSpatialConstant : " << _retinaParameters.OPLandIplParvo.hcellsSpatialConstant
<< "\n==> parvoGanglionCellsSensitivity : " << _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity << "\n==> parvoGanglionCellsSensitivity : " << _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity
<<"}\n"; <<"}\n";
// displaying IPL magno setup // displaying IPL magno setup
outmessage<<"Current Retina instance setup :" outmessage<<"Current Retina instance setup :"
<<"\nIPLmagno"<<"{" <<"\nIPLmagno"<<"{"
<< "\n==> normaliseOutput : " << _retinaParameters.IplMagno.normaliseOutput << "\n==> normaliseOutput : " << _retinaParameters.IplMagno.normaliseOutput
<< "\n==> parasolCells_beta : " << _retinaParameters.IplMagno.parasolCells_beta << "\n==> parasolCells_beta : " << _retinaParameters.IplMagno.parasolCells_beta
<< "\n==> parasolCells_tau : " << _retinaParameters.IplMagno.parasolCells_tau << "\n==> parasolCells_tau : " << _retinaParameters.IplMagno.parasolCells_tau
<< "\n==> parasolCells_k : " << _retinaParameters.IplMagno.parasolCells_k << "\n==> parasolCells_k : " << _retinaParameters.IplMagno.parasolCells_k
<< "\n==> amacrinCellsTemporalCutFrequency : " << _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency << "\n==> amacrinCellsTemporalCutFrequency : " << _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency
<< "\n==> V0CompressionParameter : " << _retinaParameters.IplMagno.V0CompressionParameter << "\n==> V0CompressionParameter : " << _retinaParameters.IplMagno.V0CompressionParameter
<< "\n==> localAdaptintegration_tau : " << _retinaParameters.IplMagno.localAdaptintegration_tau << "\n==> localAdaptintegration_tau : " << _retinaParameters.IplMagno.localAdaptintegration_tau
<< "\n==> localAdaptintegration_k : " << _retinaParameters.IplMagno.localAdaptintegration_k << "\n==> localAdaptintegration_k : " << _retinaParameters.IplMagno.localAdaptintegration_k
<<"}"; <<"}";
return outmessage.str(); return outmessage.str();
} }
void Retina::write( std::string fs ) const void Retina::write( std::string fs ) const
@ -240,98 +240,98 @@ void Retina::write( std::string fs ) const
void Retina::write( FileStorage& fs ) const void Retina::write( FileStorage& fs ) const
{ {
if (!fs.isOpened()) if (!fs.isOpened())
return; // basic error case return; // basic error case
fs<<"OPLandIPLparvo"<<"{"; fs<<"OPLandIPLparvo"<<"{";
fs << "colorMode" << _retinaParameters.OPLandIplParvo.colorMode; fs << "colorMode" << _retinaParameters.OPLandIplParvo.colorMode;
fs << "normaliseOutput" << _retinaParameters.OPLandIplParvo.normaliseOutput; fs << "normaliseOutput" << _retinaParameters.OPLandIplParvo.normaliseOutput;
fs << "photoreceptorsLocalAdaptationSensitivity" << _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity; fs << "photoreceptorsLocalAdaptationSensitivity" << _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity;
fs << "photoreceptorsTemporalConstant" << _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant; fs << "photoreceptorsTemporalConstant" << _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant;
fs << "photoreceptorsSpatialConstant" << _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant; fs << "photoreceptorsSpatialConstant" << _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant;
fs << "horizontalCellsGain" << _retinaParameters.OPLandIplParvo.horizontalCellsGain; fs << "horizontalCellsGain" << _retinaParameters.OPLandIplParvo.horizontalCellsGain;
fs << "hcellsTemporalConstant" << _retinaParameters.OPLandIplParvo.hcellsTemporalConstant; fs << "hcellsTemporalConstant" << _retinaParameters.OPLandIplParvo.hcellsTemporalConstant;
fs << "hcellsSpatialConstant" << _retinaParameters.OPLandIplParvo.hcellsSpatialConstant; fs << "hcellsSpatialConstant" << _retinaParameters.OPLandIplParvo.hcellsSpatialConstant;
fs << "ganglionCellsSensitivity" << _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity; fs << "ganglionCellsSensitivity" << _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity;
fs << "}"; fs << "}";
fs<<"IPLmagno"<<"{"; fs<<"IPLmagno"<<"{";
fs << "normaliseOutput" << _retinaParameters.IplMagno.normaliseOutput; fs << "normaliseOutput" << _retinaParameters.IplMagno.normaliseOutput;
fs << "parasolCells_beta" << _retinaParameters.IplMagno.parasolCells_beta; fs << "parasolCells_beta" << _retinaParameters.IplMagno.parasolCells_beta;
fs << "parasolCells_tau" << _retinaParameters.IplMagno.parasolCells_tau; fs << "parasolCells_tau" << _retinaParameters.IplMagno.parasolCells_tau;
fs << "parasolCells_k" << _retinaParameters.IplMagno.parasolCells_k; fs << "parasolCells_k" << _retinaParameters.IplMagno.parasolCells_k;
fs << "amacrinCellsTemporalCutFrequency" << _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency; fs << "amacrinCellsTemporalCutFrequency" << _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency;
fs << "V0CompressionParameter" << _retinaParameters.IplMagno.V0CompressionParameter; fs << "V0CompressionParameter" << _retinaParameters.IplMagno.V0CompressionParameter;
fs << "localAdaptintegration_tau" << _retinaParameters.IplMagno.localAdaptintegration_tau; fs << "localAdaptintegration_tau" << _retinaParameters.IplMagno.localAdaptintegration_tau;
fs << "localAdaptintegration_k" << _retinaParameters.IplMagno.localAdaptintegration_k; fs << "localAdaptintegration_k" << _retinaParameters.IplMagno.localAdaptintegration_k;
fs<<"}"; fs<<"}";
} }
void Retina::setupOPLandIPLParvoChannel(const bool colorMode, const bool normaliseOutput, const float photoreceptorsLocalAdaptationSensitivity, const float photoreceptorsTemporalConstant, const float photoreceptorsSpatialConstant, const float horizontalCellsGain, const float HcellsTemporalConstant, const float HcellsSpatialConstant, const float ganglionCellsSensitivity) void Retina::setupOPLandIPLParvoChannel(const bool colorMode, const bool normaliseOutput, const float photoreceptorsLocalAdaptationSensitivity, const float photoreceptorsTemporalConstant, const float photoreceptorsSpatialConstant, const float horizontalCellsGain, const float HcellsTemporalConstant, const float HcellsSpatialConstant, const float ganglionCellsSensitivity)
{ {
// retina core parameters setup // retina core parameters setup
_retinaFilter->setColorMode(colorMode); _retinaFilter->setColorMode(colorMode);
_retinaFilter->setPhotoreceptorsLocalAdaptationSensitivity(photoreceptorsLocalAdaptationSensitivity); _retinaFilter->setPhotoreceptorsLocalAdaptationSensitivity(photoreceptorsLocalAdaptationSensitivity);
_retinaFilter->setOPLandParvoParameters(0, photoreceptorsTemporalConstant, photoreceptorsSpatialConstant, horizontalCellsGain, HcellsTemporalConstant, HcellsSpatialConstant, ganglionCellsSensitivity); _retinaFilter->setOPLandParvoParameters(0, photoreceptorsTemporalConstant, photoreceptorsSpatialConstant, horizontalCellsGain, HcellsTemporalConstant, HcellsSpatialConstant, ganglionCellsSensitivity);
_retinaFilter->setParvoGanglionCellsLocalAdaptationSensitivity(ganglionCellsSensitivity); _retinaFilter->setParvoGanglionCellsLocalAdaptationSensitivity(ganglionCellsSensitivity);
_retinaFilter->activateNormalizeParvoOutput_0_maxOutputValue(normaliseOutput); _retinaFilter->activateNormalizeParvoOutput_0_maxOutputValue(normaliseOutput);
// update parameters struture // update parameters struture
_retinaParameters.OPLandIplParvo.colorMode = colorMode; _retinaParameters.OPLandIplParvo.colorMode = colorMode;
_retinaParameters.OPLandIplParvo.normaliseOutput = normaliseOutput; _retinaParameters.OPLandIplParvo.normaliseOutput = normaliseOutput;
_retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity = photoreceptorsLocalAdaptationSensitivity; _retinaParameters.OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity = photoreceptorsLocalAdaptationSensitivity;
_retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant = photoreceptorsTemporalConstant; _retinaParameters.OPLandIplParvo.photoreceptorsTemporalConstant = photoreceptorsTemporalConstant;
_retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant = photoreceptorsSpatialConstant; _retinaParameters.OPLandIplParvo.photoreceptorsSpatialConstant = photoreceptorsSpatialConstant;
_retinaParameters.OPLandIplParvo.horizontalCellsGain = horizontalCellsGain; _retinaParameters.OPLandIplParvo.horizontalCellsGain = horizontalCellsGain;
_retinaParameters.OPLandIplParvo.hcellsTemporalConstant = HcellsTemporalConstant; _retinaParameters.OPLandIplParvo.hcellsTemporalConstant = HcellsTemporalConstant;
_retinaParameters.OPLandIplParvo.hcellsSpatialConstant = HcellsSpatialConstant; _retinaParameters.OPLandIplParvo.hcellsSpatialConstant = HcellsSpatialConstant;
_retinaParameters.OPLandIplParvo.ganglionCellsSensitivity = ganglionCellsSensitivity; _retinaParameters.OPLandIplParvo.ganglionCellsSensitivity = ganglionCellsSensitivity;
} }
void Retina::setupIPLMagnoChannel(const bool normaliseOutput, const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float V0CompressionParameter, const float localAdaptintegration_tau, const float localAdaptintegration_k) void Retina::setupIPLMagnoChannel(const bool normaliseOutput, const float parasolCells_beta, const float parasolCells_tau, const float parasolCells_k, const float amacrinCellsTemporalCutFrequency, const float V0CompressionParameter, const float localAdaptintegration_tau, const float localAdaptintegration_k)
{ {
_retinaFilter->setMagnoCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k); _retinaFilter->setMagnoCoefficientsTable(parasolCells_beta, parasolCells_tau, parasolCells_k, amacrinCellsTemporalCutFrequency, V0CompressionParameter, localAdaptintegration_tau, localAdaptintegration_k);
_retinaFilter->activateNormalizeMagnoOutput_0_maxOutputValue(normaliseOutput); _retinaFilter->activateNormalizeMagnoOutput_0_maxOutputValue(normaliseOutput);
// update parameters struture // update parameters struture
_retinaParameters.IplMagno.normaliseOutput = normaliseOutput; _retinaParameters.IplMagno.normaliseOutput = normaliseOutput;
_retinaParameters.IplMagno.parasolCells_beta = parasolCells_beta; _retinaParameters.IplMagno.parasolCells_beta = parasolCells_beta;
_retinaParameters.IplMagno.parasolCells_tau = parasolCells_tau; _retinaParameters.IplMagno.parasolCells_tau = parasolCells_tau;
_retinaParameters.IplMagno.parasolCells_k = parasolCells_k; _retinaParameters.IplMagno.parasolCells_k = parasolCells_k;
_retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency = amacrinCellsTemporalCutFrequency; _retinaParameters.IplMagno.amacrinCellsTemporalCutFrequency = amacrinCellsTemporalCutFrequency;
_retinaParameters.IplMagno.V0CompressionParameter = V0CompressionParameter; _retinaParameters.IplMagno.V0CompressionParameter = V0CompressionParameter;
_retinaParameters.IplMagno.localAdaptintegration_tau = localAdaptintegration_tau; _retinaParameters.IplMagno.localAdaptintegration_tau = localAdaptintegration_tau;
_retinaParameters.IplMagno.localAdaptintegration_k = localAdaptintegration_k; _retinaParameters.IplMagno.localAdaptintegration_k = localAdaptintegration_k;
} }
void Retina::run(const cv::Mat &inputMatToConvert) void Retina::run(const cv::Mat &inputMatToConvert)
{ {
// first convert input image to the compatible format : std::valarray<float> // first convert input image to the compatible format : std::valarray<float>
const bool colorMode = _convertCvMat2ValarrayBuffer(inputMatToConvert, _inputBuffer); const bool colorMode = _convertCvMat2ValarrayBuffer(inputMatToConvert, _inputBuffer);
// process the retina // process the retina
if (!_retinaFilter->runFilter(_inputBuffer, colorMode, false, _retinaParameters.OPLandIplParvo.colorMode && colorMode, false)) if (!_retinaFilter->runFilter(_inputBuffer, colorMode, false, _retinaParameters.OPLandIplParvo.colorMode && colorMode, false))
throw cv::Exception(-1, "Retina cannot be applied, wrong input buffer size", "Retina::run", "Retina.h", 0); throw cv::Exception(-1, "Retina cannot be applied, wrong input buffer size", "Retina::run", "Retina.h", 0);
} }
void Retina::getParvo(cv::Mat &retinaOutput_parvo) void Retina::getParvo(cv::Mat &retinaOutput_parvo)
{ {
if (_retinaFilter->getColorMode()) if (_retinaFilter->getColorMode())
{ {
// reallocate output buffer (if necessary) // reallocate output buffer (if necessary)
_convertValarrayBuffer2cvMat(_retinaFilter->getColorOutput(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), true, retinaOutput_parvo); _convertValarrayBuffer2cvMat(_retinaFilter->getColorOutput(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), true, retinaOutput_parvo);
}else }else
{ {
// reallocate output buffer (if necessary) // reallocate output buffer (if necessary)
_convertValarrayBuffer2cvMat(_retinaFilter->getContours(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), false, retinaOutput_parvo); _convertValarrayBuffer2cvMat(_retinaFilter->getContours(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), false, retinaOutput_parvo);
} }
//retinaOutput_parvo/=255.0; //retinaOutput_parvo/=255.0;
} }
void Retina::getMagno(cv::Mat &retinaOutput_magno) void Retina::getMagno(cv::Mat &retinaOutput_magno)
{ {
// reallocate output buffer (if necessary) // reallocate output buffer (if necessary)
_convertValarrayBuffer2cvMat(_retinaFilter->getMovingContours(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), false, retinaOutput_magno); _convertValarrayBuffer2cvMat(_retinaFilter->getMovingContours(), _retinaFilter->getOutputNBrows(), _retinaFilter->getOutputNBcolumns(), false, retinaOutput_magno);
//retinaOutput_magno/=255.0; //retinaOutput_magno/=255.0;
} }
// original API level data accessors : copy buffers if size matches // original API level data accessors : copy buffers if size matches
@ -342,112 +342,114 @@ const std::valarray<float> & Retina::getMagno() const {return _retinaFilter->get
const std::valarray<float> & Retina::getParvo() const {if (_retinaFilter->getColorMode())return _retinaFilter->getColorOutput(); /* implicite else */return _retinaFilter->getContours();} const std::valarray<float> & Retina::getParvo() const {if (_retinaFilter->getColorMode())return _retinaFilter->getColorOutput(); /* implicite else */return _retinaFilter->getContours();}
// private method called by constructirs // private method called by constructirs
void Retina::_init(const cv::Size inputSize, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght) void Retina::_init(const cv::Size inputSz, const bool colorMode, RETINA_COLORSAMPLINGMETHOD colorSamplingMethod, const bool useRetinaLogSampling, const double reductionFactor, const double samplingStrenght)
{ {
// basic error check // basic error check
if (inputSize.height*inputSize.width <= 0) if (inputSz.height*inputSz.width <= 0)
throw cv::Exception(-1, "Bad retina size setup : size height and with must be superior to zero", "Retina::setup", "Retina.h", 0); throw cv::Exception(-1, "Bad retina size setup : size height and with must be superior to zero", "Retina::setup", "Retina.h", 0);
unsigned int nbPixels=inputSize.height*inputSize.width; unsigned int nbPixels=inputSz.height*inputSz.width;
// resize buffers if size does not match // resize buffers if size does not match
_inputBuffer.resize(nbPixels*3); // buffer supports gray images but also 3 channels color buffers... (larger is better...) _inputBuffer.resize(nbPixels*3); // buffer supports gray images but also 3 channels color buffers... (larger is better...)
// allocate the retina model // allocate the retina model
if (_retinaFilter) if (_retinaFilter)
delete _retinaFilter; delete _retinaFilter;
_retinaFilter = new RetinaFilter(inputSize.height, inputSize.width, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght); _retinaFilter = new RetinaFilter(inputSz.height, inputSz.width, colorMode, colorSamplingMethod, useRetinaLogSampling, reductionFactor, samplingStrenght);
// prepare the default parameter XML file with default setup // prepare the default parameter XML file with default setup
setup(_retinaParameters); setup(_retinaParameters);
// init retina // init retina
_retinaFilter->clearAllBuffers(); _retinaFilter->clearAllBuffers();
// report current configuration // report current configuration
std::cout<<printSetup()<<std::endl; std::cout<<printSetup()<<std::endl;
} }
void Retina::_convertValarrayBuffer2cvMat(const std::valarray<float> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, cv::Mat &outBuffer) void Retina::_convertValarrayBuffer2cvMat(const std::valarray<float> &grayMatrixToConvert, const unsigned int nbRows, const unsigned int nbColumns, const bool colorMode, cv::Mat &outBuffer)
{ {
// fill output buffer with the valarray buffer // fill output buffer with the valarray buffer
const float *valarrayPTR=get_data(grayMatrixToConvert); const float *valarrayPTR=get_data(grayMatrixToConvert);
if (!colorMode) if (!colorMode)
{ {
outBuffer.create(cv::Size(nbColumns, nbRows), CV_8U); outBuffer.create(cv::Size(nbColumns, nbRows), CV_8U);
for (unsigned int i=0;i<nbRows;++i) for (unsigned int i=0;i<nbRows;++i)
{ {
for (unsigned int j=0;j<nbColumns;++j) for (unsigned int j=0;j<nbColumns;++j)
{ {
cv::Point2d pixel(j,i); cv::Point2d pixel(j,i);
outBuffer.at<unsigned char>(pixel)=(unsigned char)*(valarrayPTR++); outBuffer.at<unsigned char>(pixel)=(unsigned char)*(valarrayPTR++);
} }
} }
}else }else
{ {
const unsigned int doubleNBpixels=_retinaFilter->getOutputNBpixels()*2; const unsigned int doubleNBpixels=_retinaFilter->getOutputNBpixels()*2;
outBuffer.create(cv::Size(nbColumns, nbRows), CV_8UC3); outBuffer.create(cv::Size(nbColumns, nbRows), CV_8UC3);
for (unsigned int i=0;i<nbRows;++i) for (unsigned int i=0;i<nbRows;++i)
{ {
for (unsigned int j=0;j<nbColumns;++j,++valarrayPTR) for (unsigned int j=0;j<nbColumns;++j,++valarrayPTR)
{ {
cv::Point2d pixel(j,i); cv::Point2d pixel(j,i);
cv::Vec3b pixelValues; cv::Vec3b pixelValues;
pixelValues[2]=(unsigned char)*(valarrayPTR); pixelValues[2]=(unsigned char)*(valarrayPTR);
pixelValues[1]=(unsigned char)*(valarrayPTR+_retinaFilter->getOutputNBpixels()); pixelValues[1]=(unsigned char)*(valarrayPTR+_retinaFilter->getOutputNBpixels());
pixelValues[0]=(unsigned char)*(valarrayPTR+doubleNBpixels); pixelValues[0]=(unsigned char)*(valarrayPTR+doubleNBpixels);
outBuffer.at<cv::Vec3b>(pixel)=pixelValues; outBuffer.at<cv::Vec3b>(pixel)=pixelValues;
} }
} }
} }
} }
bool Retina::_convertCvMat2ValarrayBuffer(const cv::Mat inputMatToConvert, std::valarray<float> &outputValarrayMatrix) bool Retina::_convertCvMat2ValarrayBuffer(const cv::Mat inputMatToConvert, std::valarray<float> &outputValarrayMatrix)
{ {
// first check input consistency // first check input consistency
if (inputMatToConvert.empty()) if (inputMatToConvert.empty())
throw cv::Exception(-1, "Retina cannot be applied, input buffer is empty", "Retina::run", "Retina.h", 0); throw cv::Exception(-1, "Retina cannot be applied, input buffer is empty", "Retina::run", "Retina.h", 0);
// retreive color mode from image input
int imageNumberOfChannels = inputMatToConvert.channels();
// retreive color mode from image input
int imageNumberOfChannels = inputMatToConvert.channels();
// convert to float AND fill the valarray buffer // convert to float AND fill the valarray buffer
typedef float T; // define here the target pixel format, here, float typedef float T; // define here the target pixel format, here, float
const int dsttype = DataType<T>::depth; // output buffer is float format const int dsttype = DataType<T>::depth; // output buffer is float format
if(imageNumberOfChannels==4) if(imageNumberOfChannels==4)
{
// create a cv::Mat table (for RGBA planes)
cv::Mat planes[4] =
{ {
// create a cv::Mat table (for RGBA planes) cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[_retinaFilter->getInputNBpixels()*2]),
cv::Mat planes[] = cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[_retinaFilter->getInputNBpixels()]),
{ cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0])
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[_retinaFilter->getInputNBpixels()*2]), };
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[_retinaFilter->getInputNBpixels()]), planes[3] = cv::Mat(inputMatToConvert.size(), dsttype); // last channel (alpha) does not point on the valarray (not usefull in our case)
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]), // split color cv::Mat in 4 planes... it fills valarray directely
cv::Mat(inputMatToConvert.size(), dsttype) // last channel (alpha) does not point on the valarray (not usefull in our case) cv::split(cv::Mat_<Vec<T, 4> >(inputMatToConvert), planes);
}; }
// split color cv::Mat in 4 planes... it fills valarray directely else if (imageNumberOfChannels==3)
cv::split(cv::Mat_<Vec<T, 4> >(inputMatToConvert), planes); {
}else if (imageNumberOfChannels==3) // create a cv::Mat table (for RGB planes)
{ cv::Mat planes[] =
// create a cv::Mat table (for RGB planes) {
cv::Mat planes[] = cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[_retinaFilter->getInputNBpixels()*2]),
{ cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[_retinaFilter->getInputNBpixels()]),
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[_retinaFilter->getInputNBpixels()*2]), cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0])
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[_retinaFilter->getInputNBpixels()]), };
cv::Mat(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]) // split color cv::Mat in 3 planes... it fills valarray directely
}; cv::split(cv::Mat_<Vec<T, 3> >(inputMatToConvert), planes);
// split color cv::Mat in 3 planes... it fills valarray directely }
cv::split(cv::Mat_<Vec<T, 3> >(inputMatToConvert), planes); else if(imageNumberOfChannels==1)
}else if(imageNumberOfChannels==1) {
{ // create a cv::Mat header for the valarray
// create a cv::Mat header for the valarray cv::Mat dst(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]);
cv::Mat dst(inputMatToConvert.size(), dsttype, &outputValarrayMatrix[0]); inputMatToConvert.convertTo(dst, dsttype);
inputMatToConvert.convertTo(dst, dsttype); }
}
else else
CV_Error(CV_StsUnsupportedFormat, "input image must be single channel (gray levels), bgr format (color) or bgra (color with transparency which won't be considered"); CV_Error(CV_StsUnsupportedFormat, "input image must be single channel (gray levels), bgr format (color) or bgra (color with transparency which won't be considered");
return imageNumberOfChannels>1; // return bool : false for gray level image processing, true for color mode return imageNumberOfChannels>1; // return bool : false for gray level image processing, true for color mode
} }

View File

@ -325,15 +325,15 @@ void RetinaColor::runColorDemultiplexing(const std::valarray<float> &multiplexed
}else }else
{ {
register const float *multiplexedColorFramePTR= get_data(multiplexedColorFrame); register const float *multiplexedColorFramePTR1= get_data(multiplexedColorFrame);
for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance, ++multiplexedColorFramePTR) for (unsigned int indexc=0; indexc<_filterOutput.getNBpixels() ; ++indexc, ++chrominancePTR, ++colorLocalDensityPTR, ++luminance, ++multiplexedColorFramePTR1)
{ {
// normalize by photoreceptors density // normalize by photoreceptors density
float Cr=*(chrominancePTR)*_colorLocalDensity[indexc]; float Cr=*(chrominancePTR)*_colorLocalDensity[indexc];
float Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()]; float Cg=*(chrominancePTR+_filterOutput.getNBpixels())*_colorLocalDensity[indexc+_filterOutput.getNBpixels()];
float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()]; float Cb=*(chrominancePTR+_filterOutput.getDoubleNBpixels())*_colorLocalDensity[indexc+_filterOutput.getDoubleNBpixels()];
*luminance=(Cr+Cg+Cb)*_pG; *luminance=(Cr+Cg+Cb)*_pG;
_demultiplexedTempBuffer[_colorSampling[indexc]] = *multiplexedColorFramePTR - *luminance; _demultiplexedTempBuffer[_colorSampling[indexc]] = *multiplexedColorFramePTR1 - *luminance;
} }

View File

@ -60,9 +60,9 @@ namespace cv
using std::min; using std::min;
using std::sqrt; using std::sqrt;
} }
namespace namespace
{ {
const static Scalar colors[] = const static Scalar colors[] =
{ {
CV_RGB(255, 0, 0), CV_RGB(255, 0, 0),
CV_RGB( 0, 255, 0), CV_RGB( 0, 255, 0),
@ -87,21 +87,21 @@ namespace
template<class FwIt, class T> void iota(FwIt first, FwIt last, T value) { while(first != last) *first++ = value++; } template<class FwIt, class T> void iota(FwIt first, FwIt last, T value) { while(first != last) *first++ = value++; }
void computeNormals( const Octree& Octree, const vector<Point3f>& centers, vector<Point3f>& normals, void computeNormals( const Octree& Octree, const vector<Point3f>& centers, vector<Point3f>& normals,
vector<uchar>& mask, float normalRadius, int minNeighbors = 20) vector<uchar>& mask, float normalRadius, int minNeighbors = 20)
{ {
size_t normals_size = centers.size(); size_t normals_size = centers.size();
normals.resize(normals_size); normals.resize(normals_size);
if (mask.size() != normals_size) if (mask.size() != normals_size)
{ {
size_t m = mask.size(); size_t m = mask.size();
mask.resize(normals_size); mask.resize(normals_size);
if (normals_size > m) if (normals_size > m)
for(; m < normals_size; ++m) for(; m < normals_size; ++m)
mask[m] = 1; mask[m] = 1;
} }
vector<Point3f> buffer; vector<Point3f> buffer;
buffer.reserve(128); buffer.reserve(128);
SVD svd; SVD svd;
@ -132,7 +132,7 @@ void computeNormals( const Octree& Octree, const vector<Point3f>& centers, vecto
mean.x /= buf_size; mean.x /= buf_size;
mean.y /= buf_size; mean.y /= buf_size;
mean.z /= buf_size; mean.z /= buf_size;
double pxpx = 0; double pxpx = 0;
double pypy = 0; double pypy = 0;
double pzpz = 0; double pzpz = 0;
@ -162,9 +162,9 @@ void computeNormals( const Octree& Octree, const vector<Point3f>& centers, vecto
/*normals[n] = Point3f( (float)((double*)svd.vt.data)[6], /*normals[n] = Point3f( (float)((double*)svd.vt.data)[6],
(float)((double*)svd.vt.data)[7], (float)((double*)svd.vt.data)[7],
(float)((double*)svd.vt.data)[8] );*/ (float)((double*)svd.vt.data)[8] );*/
normals[n] = reinterpret_cast<Point3d*>(svd.vt.data)[2]; normals[n] = reinterpret_cast<Point3d*>(svd.vt.data)[2];
mask[n] = 1; mask[n] = 1;
} }
} }
@ -213,22 +213,22 @@ inline __m128 transformSSE(const __m128* matrix, const __m128& in)
} }
inline __m128i _mm_mullo_epi32_emul(const __m128i& a, __m128i& b) inline __m128i _mm_mullo_epi32_emul(const __m128i& a, __m128i& b)
{ {
__m128i pack = _mm_packs_epi32(a, a); __m128i pack = _mm_packs_epi32(a, a);
return _mm_unpacklo_epi16(_mm_mullo_epi16(pack, b), _mm_mulhi_epi16(pack, b)); return _mm_unpacklo_epi16(_mm_mullo_epi16(pack, b), _mm_mulhi_epi16(pack, b));
} }
#endif #endif
void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, const vector<Point3f>& normals, void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, const vector<Point3f>& normals,
vector<uchar>& mask, Mat& spinImages, int imageWidth, float binSize) vector<uchar>& mask, Mat& spinImages, int imageWidth, float binSize)
{ {
float pixelsPerMeter = 1.f / binSize; float pixelsPerMeter = 1.f / binSize;
float support = imageWidth * binSize; float support = imageWidth * binSize;
assert(normals.size() == points.size()); assert(normals.size() == points.size());
assert(mask.size() == points.size()); assert(mask.size() == points.size());
size_t points_size = points.size(); size_t points_size = points.size();
mask.resize(points_size); mask.resize(points_size);
@ -257,7 +257,7 @@ void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, con
int t = cvGetThreadNum(); int t = cvGetThreadNum();
vector<Point3f>& pointsInSphere = pointsInSpherePool[t]; vector<Point3f>& pointsInSphere = pointsInSpherePool[t];
const Point3f& center = points[i]; const Point3f& center = points[i];
Octree.getPointsWithinSphere(center, searchRad, pointsInSphere); Octree.getPointsWithinSphere(center, searchRad, pointsInSphere);
@ -269,7 +269,7 @@ void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, con
} }
const Point3f& normal = normals[i]; const Point3f& normal = normals[i];
float rotmat[9]; float rotmat[9];
initRotationMat(normal, rotmat); initRotationMat(normal, rotmat);
Point3f new_center; Point3f new_center;
@ -287,7 +287,7 @@ void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, con
{ {
__m128 rotmatSSE[3]; __m128 rotmatSSE[3];
convertTransformMatrix(rotmat, (float*)rotmatSSE); convertTransformMatrix(rotmat, (float*)rotmatSSE);
__m128 center_x4 = _mm_set1_ps(new_center.x); __m128 center_x4 = _mm_set1_ps(new_center.x);
__m128 center_y4 = _mm_set1_ps(new_center.y); __m128 center_y4 = _mm_set1_ps(new_center.y);
__m128 center_z4 = _mm_set1_ps(new_center.z + halfSuppport); __m128 center_z4 = _mm_set1_ps(new_center.z + halfSuppport);
@ -313,7 +313,7 @@ void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, con
__m128 z0 = _mm_unpackhi_ps(pt0, pt1); // z0 z1 . . __m128 z0 = _mm_unpackhi_ps(pt0, pt1); // z0 z1 . .
__m128 z1 = _mm_unpackhi_ps(pt2, pt3); // z2 z3 . . __m128 z1 = _mm_unpackhi_ps(pt2, pt3); // z2 z3 . .
__m128 beta4 = _mm_sub_ps(center_z4, _mm_movelh_ps(z0, z1)); // b0 b1 b2 b3 __m128 beta4 = _mm_sub_ps(center_z4, _mm_movelh_ps(z0, z1)); // b0 b1 b2 b3
__m128 xy0 = _mm_unpacklo_ps(pt0, pt1); // x0 x1 y0 y1 __m128 xy0 = _mm_unpacklo_ps(pt0, pt1); // x0 x1 y0 y1
__m128 xy1 = _mm_unpacklo_ps(pt2, pt3); // x2 x3 y2 y3 __m128 xy1 = _mm_unpacklo_ps(pt2, pt3); // x2 x3 y2 y3
__m128 x4 = _mm_movelh_ps(xy0, xy1); // x0 x1 x2 x3 __m128 x4 = _mm_movelh_ps(xy0, xy1); // x0 x1 x2 x3
@ -322,7 +322,7 @@ void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, con
x4 = _mm_sub_ps(x4, center_x4); x4 = _mm_sub_ps(x4, center_x4);
y4 = _mm_sub_ps(y4, center_y4); y4 = _mm_sub_ps(y4, center_y4);
__m128 alpha4 = _mm_sqrt_ps(_mm_add_ps(_mm_mul_ps(x4,x4),_mm_mul_ps(y4,y4))); __m128 alpha4 = _mm_sqrt_ps(_mm_add_ps(_mm_mul_ps(x4,x4),_mm_mul_ps(y4,y4)));
__m128 n1f4 = _mm_mul_ps( beta4, ppm4); /* beta4 float */ __m128 n1f4 = _mm_mul_ps( beta4, ppm4); /* beta4 float */
__m128 n2f4 = _mm_mul_ps(alpha4, ppm4); /* alpha4 float */ __m128 n2f4 = _mm_mul_ps(alpha4, ppm4); /* alpha4 float */
@ -333,21 +333,21 @@ void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, con
__m128 f1 = _mm_sub_ps( n1f4, _mm_cvtepi32_ps(n1) ); /* { beta4 } */ __m128 f1 = _mm_sub_ps( n1f4, _mm_cvtepi32_ps(n1) ); /* { beta4 } */
__m128 f2 = _mm_sub_ps( n2f4, _mm_cvtepi32_ps(n2) ); /* { alpha4 } */ __m128 f2 = _mm_sub_ps( n2f4, _mm_cvtepi32_ps(n2) ); /* { alpha4 } */
__m128 f1f2 = _mm_mul_ps(f1, f2); // f1 * f2 __m128 f1f2 = _mm_mul_ps(f1, f2); // f1 * f2
__m128 omf1omf2 = _mm_add_ps(_mm_sub_ps(_mm_sub_ps(one4f, f2), f1), f1f2); // (1-f1) * (1-f2) __m128 omf1omf2 = _mm_add_ps(_mm_sub_ps(_mm_sub_ps(one4f, f2), f1), f1f2); // (1-f1) * (1-f2)
__m128i mask = _mm_and_si128( __m128i _mask = _mm_and_si128(
_mm_andnot_si128(_mm_cmpgt_epi32(zero4, n1), _mm_cmpgt_epi32(height4m1, n1)), _mm_andnot_si128(_mm_cmpgt_epi32(zero4, n1), _mm_cmpgt_epi32(height4m1, n1)),
_mm_andnot_si128(_mm_cmpgt_epi32(zero4, n2), _mm_cmpgt_epi32(width4m1, n2))); _mm_andnot_si128(_mm_cmpgt_epi32(zero4, n2), _mm_cmpgt_epi32(width4m1, n2)));
__m128 maskf = _mm_cmpneq_ps(_mm_cvtepi32_ps(mask), zero4f); __m128 maskf = _mm_cmpneq_ps(_mm_cvtepi32_ps(_mask), zero4f);
__m128 v00 = _mm_and_ps( omf1omf2 , maskf); // a00 b00 c00 d00 __m128 v00 = _mm_and_ps( omf1omf2 , maskf); // a00 b00 c00 d00
__m128 v01 = _mm_and_ps( _mm_sub_ps( f2, f1f2 ), maskf); // a01 b01 c01 d01 __m128 v01 = _mm_and_ps( _mm_sub_ps( f2, f1f2 ), maskf); // a01 b01 c01 d01
__m128 v10 = _mm_and_ps( _mm_sub_ps( f1, f1f2 ), maskf); // a10 b10 c10 d10 __m128 v10 = _mm_and_ps( _mm_sub_ps( f1, f1f2 ), maskf); // a10 b10 c10 d10
__m128 v11 = _mm_and_ps( f1f2 , maskf); // a11 b11 c11 d11 __m128 v11 = _mm_and_ps( f1f2 , maskf); // a11 b11 c11 d11
__m128i ofs4 = _mm_and_si128(_mm_add_epi32(_mm_mullo_epi32_emul(n1, step4), n2), mask); __m128i ofs4 = _mm_and_si128(_mm_add_epi32(_mm_mullo_epi32_emul(n1, step4), n2), _mask);
_mm_store_si128((__m128i*)o, ofs4); _mm_store_si128((__m128i*)o, ofs4);
__m128 t0 = _mm_unpacklo_ps(v00, v01); // a00 a01 b00 b01 __m128 t0 = _mm_unpacklo_ps(v00, v01); // a00 a01 b00 b01
@ -395,9 +395,9 @@ void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, con
if (beta >= support || beta < 0) if (beta >= support || beta < 0)
continue; continue;
alpha = sqrt( (new_center.x - pt.x) * (new_center.x - pt.x) + alpha = sqrt( (new_center.x - pt.x) * (new_center.x - pt.x) +
(new_center.y - pt.y) * (new_center.y - pt.y) ); (new_center.y - pt.y) * (new_center.y - pt.y) );
float n1f = beta * pixelsPerMeter; float n1f = beta * pixelsPerMeter;
float n2f = alpha * pixelsPerMeter; float n2f = alpha * pixelsPerMeter;
@ -407,7 +407,7 @@ void computeSpinImages( const Octree& Octree, const vector<Point3f>& points, con
float f1 = n1f - n1; float f1 = n1f - n1;
float f2 = n2f - n2; float f2 = n2f - n2;
if ((unsigned)n1 >= (unsigned)(spinImage.rows-1) || if ((unsigned)n1 >= (unsigned)(spinImage.rows-1) ||
(unsigned)n2 >= (unsigned)(spinImage.cols-1)) (unsigned)n2 >= (unsigned)(spinImage.cols-1))
continue; continue;
@ -454,27 +454,27 @@ float cv::Mesh3D::estimateResolution(float /*tryRatio*/)
vector<double> dist(tryNum * neighbors); vector<double> dist(tryNum * neighbors);
vector<int> inds(tryNum * neighbors); vector<int> inds(tryNum * neighbors);
vector<Point3f> query; vector<Point3f> query;
RNG& rng = theRNG(); RNG& rng = theRNG();
for(int i = 0; i < tryNum; ++i) for(int i = 0; i < tryNum; ++i)
query.push_back(vtx[rng.next() % vtx.size()]); query.push_back(vtx[rng.next() % vtx.size()]);
CvMat cvinds = cvMat( (int)tryNum, neighbors, CV_32S, &inds[0] ); CvMat cvinds = cvMat( (int)tryNum, neighbors, CV_32S, &inds[0] );
CvMat cvdist = cvMat( (int)tryNum, neighbors, CV_64F, &dist[0] ); CvMat cvdist = cvMat( (int)tryNum, neighbors, CV_64F, &dist[0] );
CvMat cvquery = cvMat( (int)tryNum, 3, CV_32F, &query[0] ); CvMat cvquery = cvMat( (int)tryNum, 3, CV_32F, &query[0] );
cvFindFeatures(tr, &cvquery, &cvinds, &cvdist, neighbors, 50); cvFindFeatures(tr, &cvquery, &cvinds, &cvdist, neighbors, 50);
cvReleaseFeatureTree(tr); cvReleaseFeatureTree(tr);
const int invalid_dist = -2; const int invalid_dist = -2;
for(int i = 0; i < tryNum; ++i) for(int i = 0; i < tryNum; ++i)
if (inds[i] == -1) if (inds[i] == -1)
dist[i] = invalid_dist; dist[i] = invalid_dist;
dist.resize(remove(dist.begin(), dist.end(), invalid_dist) - dist.begin()); dist.resize(remove(dist.begin(), dist.end(), invalid_dist) - dist.begin());
sort(dist, less<double>()); sort(dist, less<double>());
return resolution = (float)dist[ dist.size() / 2 ]; return resolution = (float)dist[ dist.size() / 2 ];
#else #else
CV_Error(CV_StsNotImplemented, ""); CV_Error(CV_StsNotImplemented, "");
@ -494,7 +494,7 @@ void cv::Mesh3D::computeNormals(const vector<int>& subset, float normalRadius, i
{ {
buildOctree(); buildOctree();
vector<uchar> mask(vtx.size(), 0); vector<uchar> mask(vtx.size(), 0);
for(size_t i = 0; i < subset.size(); ++i) for(size_t i = 0; i < subset.size(); ++i)
mask[subset[i]] = 1; mask[subset[i]] = 1;
::computeNormals(octree, vtx, normals, mask, normalRadius, minNeighbors); ::computeNormals(octree, vtx, normals, mask, normalRadius, minNeighbors);
} }
@ -504,31 +504,31 @@ void cv::Mesh3D::writeAsVrml(const String& file, const vector<Scalar>& _colors)
ofstream ofs(file.c_str()); ofstream ofs(file.c_str());
ofs << "#VRML V2.0 utf8" << endl; ofs << "#VRML V2.0 utf8" << endl;
ofs << "Shape" << std::endl << "{" << endl; ofs << "Shape" << std::endl << "{" << endl;
ofs << "geometry PointSet" << endl << "{" << endl; ofs << "geometry PointSet" << endl << "{" << endl;
ofs << "coord Coordinate" << endl << "{" << endl; ofs << "coord Coordinate" << endl << "{" << endl;
ofs << "point[" << endl; ofs << "point[" << endl;
for(size_t i = 0; i < vtx.size(); ++i) for(size_t i = 0; i < vtx.size(); ++i)
ofs << vtx[i].x << " " << vtx[i].y << " " << vtx[i].z << endl; ofs << vtx[i].x << " " << vtx[i].y << " " << vtx[i].z << endl;
ofs << "]" << endl; //point[ ofs << "]" << endl; //point[
ofs << "}" << endl; //Coordinate{ ofs << "}" << endl; //Coordinate{
if (vtx.size() == _colors.size()) if (vtx.size() == _colors.size())
{ {
ofs << "color Color" << endl << "{" << endl; ofs << "color Color" << endl << "{" << endl;
ofs << "color[" << endl; ofs << "color[" << endl;
for(size_t i = 0; i < _colors.size(); ++i) for(size_t i = 0; i < _colors.size(); ++i)
ofs << (float)_colors[i][2] << " " << (float)_colors[i][1] << " " << (float)_colors[i][0] << endl; ofs << (float)_colors[i][2] << " " << (float)_colors[i][1] << " " << (float)_colors[i][0] << endl;
ofs << "]" << endl; //color[ ofs << "]" << endl; //color[
ofs << "}" << endl; //color Color{ ofs << "}" << endl; //color Color{
} }
ofs << "}" << endl; //PointSet{ ofs << "}" << endl; //PointSet{
ofs << "}" << endl; //Shape{ ofs << "}" << endl; //Shape{
} }
@ -538,45 +538,45 @@ void cv::Mesh3D::writeAsVrml(const String& file, const vector<Scalar>& _colors)
bool cv::SpinImageModel::spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result) bool cv::SpinImageModel::spinCorrelation(const Mat& spin1, const Mat& spin2, float lambda, float& result)
{ {
struct Math { static double atanh(double x) { return 0.5 * std::log( (1 + x) / (1 - x) ); } }; struct Math { static double atanh(double x) { return 0.5 * std::log( (1 + x) / (1 - x) ); } };
const float* s1 = spin1.ptr<float>(); const float* s1 = spin1.ptr<float>();
const float* s2 = spin2.ptr<float>(); const float* s2 = spin2.ptr<float>();
int spin_sz = spin1.cols * spin1.rows; int spin_sz = spin1.cols * spin1.rows;
double sum1 = 0.0, sum2 = 0.0, sum12 = 0.0, sum11 = 0.0, sum22 = 0.0; double sum1 = 0.0, sum2 = 0.0, sum12 = 0.0, sum11 = 0.0, sum22 = 0.0;
int N = 0; int N = 0;
int i = 0; int i = 0;
#if CV_SSE2//____________TEMPORARY_DISABLED_____________ #if CV_SSE2//____________TEMPORARY_DISABLED_____________
float CV_DECL_ALIGNED(16) su1[4], su2[4], su11[4], su22[4], su12[4], n[4]; float CV_DECL_ALIGNED(16) su1[4], su2[4], su11[4], su22[4], su12[4], n[4];
__m128 zerof4 = _mm_setzero_ps(); __m128 zerof4 = _mm_setzero_ps();
__m128 onef4 = _mm_set1_ps(1.f); __m128 onef4 = _mm_set1_ps(1.f);
__m128 Nf4 = zerof4; __m128 Nf4 = zerof4;
__m128 sum1f4 = zerof4; __m128 sum1f4 = zerof4;
__m128 sum2f4 = zerof4; __m128 sum2f4 = zerof4;
__m128 sum11f4 = zerof4; __m128 sum11f4 = zerof4;
__m128 sum22f4 = zerof4; __m128 sum22f4 = zerof4;
__m128 sum12f4 = zerof4; __m128 sum12f4 = zerof4;
for(; i < spin_sz - 5; i += 4) for(; i < spin_sz - 5; i += 4)
{ {
__m128 v1f4 = _mm_loadu_ps(s1 + i); __m128 v1f4 = _mm_loadu_ps(s1 + i);
__m128 v2f4 = _mm_loadu_ps(s2 + i); __m128 v2f4 = _mm_loadu_ps(s2 + i);
__m128 mskf4 = _mm_and_ps(_mm_cmpneq_ps(v1f4, zerof4), _mm_cmpneq_ps(v2f4, zerof4)); __m128 mskf4 = _mm_and_ps(_mm_cmpneq_ps(v1f4, zerof4), _mm_cmpneq_ps(v2f4, zerof4));
if( !_mm_movemask_ps(mskf4) ) if( !_mm_movemask_ps(mskf4) )
continue; continue;
Nf4 = _mm_add_ps(Nf4, _mm_and_ps(onef4, mskf4)); Nf4 = _mm_add_ps(Nf4, _mm_and_ps(onef4, mskf4));
v1f4 = _mm_and_ps(v1f4, mskf4); v1f4 = _mm_and_ps(v1f4, mskf4);
v2f4 = _mm_and_ps(v2f4, mskf4); v2f4 = _mm_and_ps(v2f4, mskf4);
sum1f4 = _mm_add_ps(sum1f4, v1f4); sum1f4 = _mm_add_ps(sum1f4, v1f4);
sum2f4 = _mm_add_ps(sum2f4, v2f4); sum2f4 = _mm_add_ps(sum2f4, v2f4);
sum11f4 = _mm_add_ps(sum11f4, _mm_mul_ps(v1f4, v1f4)); sum11f4 = _mm_add_ps(sum11f4, _mm_mul_ps(v1f4, v1f4));
sum22f4 = _mm_add_ps(sum22f4, _mm_mul_ps(v2f4, v2f4)); sum22f4 = _mm_add_ps(sum22f4, _mm_mul_ps(v2f4, v2f4));
sum12f4 = _mm_add_ps(sum12f4, _mm_mul_ps(v1f4, v2f4)); sum12f4 = _mm_add_ps(sum12f4, _mm_mul_ps(v1f4, v2f4));
} }
_mm_store_ps( su1, sum1f4 ); _mm_store_ps( su1, sum1f4 );
_mm_store_ps( su2, sum2f4 ); _mm_store_ps( su2, sum2f4 );
@ -601,11 +601,11 @@ bool cv::SpinImageModel::spinCorrelation(const Mat& spin1, const Mat& spin2, flo
if( !v1 || !v2 ) if( !v1 || !v2 )
continue; continue;
N++; N++;
sum1 += v1; sum1 += v1;
sum2 += v2; sum2 += v2;
sum11 += v1 * v1; sum11 += v1 * v1;
sum22 += v2 * v2; sum22 += v2 * v2;
sum12 += v1 * v2; sum12 += v1 * v2;
} }
if( N < 4 ) if( N < 4 )
@ -624,13 +624,13 @@ bool cv::SpinImageModel::spinCorrelation(const Mat& spin1, const Mat& spin2, flo
double corr = (Nsum12 - sum1 * sum2) / sqrt( (Nsum11 - sum1sum1) * (Nsum22 - sum2sum2) ); double corr = (Nsum12 - sum1 * sum2) / sqrt( (Nsum11 - sum1sum1) * (Nsum22 - sum2sum2) );
double atanh = Math::atanh(corr); double atanh = Math::atanh(corr);
result = (float)( atanh * atanh - lambda * ( 1.0 / (N - 3) ) ); result = (float)( atanh * atanh - lambda * ( 1.0 / (N - 3) ) );
return true; return true;
} }
inline Point2f cv::SpinImageModel::calcSpinMapCoo(const Point3f& p, const Point3f& v, const Point3f& n) inline Point2f cv::SpinImageModel::calcSpinMapCoo(const Point3f& p, const Point3f& v, const Point3f& n)
{ {
/*Point3f PmV(p.x - v.x, p.y - v.y, p.z - v.z); /*Point3f PmV(p.x - v.x, p.y - v.y, p.z - v.z);
float normalNorm = (float)norm(n); float normalNorm = (float)norm(n);
float beta = PmV.dot(n) / normalNorm; float beta = PmV.dot(n) / normalNorm;
float pmcNorm = (float)norm(PmV); float pmcNorm = (float)norm(PmV);
float alpha = sqrt( pmcNorm * pmcNorm - beta * beta); float alpha = sqrt( pmcNorm * pmcNorm - beta * beta);
@ -639,23 +639,23 @@ inline Point2f cv::SpinImageModel::calcSpinMapCoo(const Point3f& p, const Point3
float pmv_x = p.x - v.x, pmv_y = p.y - v.y, pmv_z = p.z - v.z; float pmv_x = p.x - v.x, pmv_y = p.y - v.y, pmv_z = p.z - v.z;
float beta = (pmv_x * n.x + pmv_y + n.y + pmv_z * n.z) / sqrt(n.x * n.x + n.y * n.y + n.z * n.z); float beta = (pmv_x * n.x + pmv_y + n.y + pmv_z * n.z) / sqrt(n.x * n.x + n.y * n.y + n.z * n.z);
float alpha = sqrt( pmv_x * pmv_x + pmv_y * pmv_y + pmv_z * pmv_z - beta * beta); float alpha = sqrt( pmv_x * pmv_x + pmv_y * pmv_y + pmv_z * pmv_z - beta * beta);
return Point2f(alpha, beta); return Point2f(alpha, beta);
} }
inline float cv::SpinImageModel::geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1, inline float cv::SpinImageModel::geometricConsistency(const Point3f& pointScene1, const Point3f& normalScene1,
const Point3f& pointModel1, const Point3f& normalModel1, const Point3f& pointModel1, const Point3f& normalModel1,
const Point3f& pointScene2, const Point3f& normalScene2, const Point3f& pointScene2, const Point3f& normalScene2,
const Point3f& pointModel2, const Point3f& normalModel2) const Point3f& pointModel2, const Point3f& normalModel2)
{ {
Point2f Sm2_to_m1, Ss2_to_s1; Point2f Sm2_to_m1, Ss2_to_s1;
Point2f Sm1_to_m2, Ss1_to_s2; Point2f Sm1_to_m2, Ss1_to_s2;
double n_Sm2_to_m1 = norm(Sm2_to_m1 = calcSpinMapCoo(pointModel2, pointModel1, normalModel1)); double n_Sm2_to_m1 = norm(Sm2_to_m1 = calcSpinMapCoo(pointModel2, pointModel1, normalModel1));
double n_Ss2_to_s1 = norm(Ss2_to_s1 = calcSpinMapCoo(pointScene2, pointScene1, normalScene1)); double n_Ss2_to_s1 = norm(Ss2_to_s1 = calcSpinMapCoo(pointScene2, pointScene1, normalScene1));
double gc21 = 2 * norm(Sm2_to_m1 - Ss2_to_s1) / (n_Sm2_to_m1 + n_Ss2_to_s1 ) ; double gc21 = 2 * norm(Sm2_to_m1 - Ss2_to_s1) / (n_Sm2_to_m1 + n_Ss2_to_s1 ) ;
double n_Sm1_to_m2 = norm(Sm1_to_m2 = calcSpinMapCoo(pointModel1, pointModel2, normalModel2)); double n_Sm1_to_m2 = norm(Sm1_to_m2 = calcSpinMapCoo(pointModel1, pointModel2, normalModel2));
double n_Ss1_to_s2 = norm(Ss1_to_s2 = calcSpinMapCoo(pointScene1, pointScene2, normalScene2)); double n_Ss1_to_s2 = norm(Ss1_to_s2 = calcSpinMapCoo(pointScene1, pointScene2, normalScene2));
@ -666,10 +666,10 @@ inline float cv::SpinImageModel::geometricConsistency(const Point3f& pointScene1
inline float cv::SpinImageModel::groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1, inline float cv::SpinImageModel::groupingCreteria(const Point3f& pointScene1, const Point3f& normalScene1,
const Point3f& pointModel1, const Point3f& normalModel1, const Point3f& pointModel1, const Point3f& normalModel1,
const Point3f& pointScene2, const Point3f& normalScene2, const Point3f& pointScene2, const Point3f& normalScene2,
const Point3f& pointModel2, const Point3f& normalModel2, const Point3f& pointModel2, const Point3f& normalModel2,
float gamma) float gamma)
{ {
Point2f Sm2_to_m1, Ss2_to_s1; Point2f Sm2_to_m1, Ss2_to_s1;
Point2f Sm1_to_m2, Ss1_to_s2; Point2f Sm1_to_m2, Ss1_to_s2;
@ -680,7 +680,7 @@ inline float cv::SpinImageModel::groupingCreteria(const Point3f& pointScene1, co
double gc21 = 2 * norm(Sm2_to_m1 - Ss2_to_s1) / (n_Sm2_to_m1 + n_Ss2_to_s1 ); double gc21 = 2 * norm(Sm2_to_m1 - Ss2_to_s1) / (n_Sm2_to_m1 + n_Ss2_to_s1 );
double wgc21 = gc21 / (1 - exp( -(n_Sm2_to_m1 + n_Ss2_to_s1) * gamma05_inv ) ); double wgc21 = gc21 / (1 - exp( -(n_Sm2_to_m1 + n_Ss2_to_s1) * gamma05_inv ) );
double n_Sm1_to_m2 = norm(Sm1_to_m2 = calcSpinMapCoo(pointModel1, pointModel2, normalModel2)); double n_Sm1_to_m2 = norm(Sm1_to_m2 = calcSpinMapCoo(pointModel1, pointModel2, normalModel2));
double n_Ss1_to_s2 = norm(Ss1_to_s2 = calcSpinMapCoo(pointScene1, pointScene2, normalScene2)); double n_Ss1_to_s2 = norm(Ss1_to_s2 = calcSpinMapCoo(pointScene1, pointScene2, normalScene2));
@ -692,10 +692,10 @@ inline float cv::SpinImageModel::groupingCreteria(const Point3f& pointScene1, co
cv::SpinImageModel::SpinImageModel(const Mesh3D& _mesh) : mesh(_mesh) , out(0) cv::SpinImageModel::SpinImageModel(const Mesh3D& _mesh) : mesh(_mesh) , out(0)
{ {
if (mesh.vtx.empty()) if (mesh.vtx.empty())
throw Mesh3D::EmptyMeshException(); throw Mesh3D::EmptyMeshException();
defaultParams(); defaultParams();
} }
cv::SpinImageModel::SpinImageModel() : out(0) { defaultParams(); } cv::SpinImageModel::SpinImageModel() : out(0) { defaultParams(); }
cv::SpinImageModel::~SpinImageModel() {} cv::SpinImageModel::~SpinImageModel() {}
@ -708,8 +708,8 @@ void cv::SpinImageModel::defaultParams()
minNeighbors = 20; minNeighbors = 20;
binSize = 0.f; /* autodetect according to mesh resolution */ binSize = 0.f; /* autodetect according to mesh resolution */
imageWidth = 32; imageWidth = 32;
lambda = 0.f; /* autodetect according to medan non zero images bin */ lambda = 0.f; /* autodetect according to medan non zero images bin */
gamma = 0.f; /* autodetect according to mesh resolution */ gamma = 0.f; /* autodetect according to mesh resolution */
@ -725,28 +725,28 @@ Mat cv::SpinImageModel::packRandomScaledSpins(bool separateScale, size_t xCount,
if (num == 0) if (num == 0)
return Mat(); return Mat();
RNG& rng = theRNG(); RNG& rng = theRNG();
vector<Mat> spins; vector<Mat> spins;
for(int i = 0; i < num; ++i) for(int i = 0; i < num; ++i)
spins.push_back(getSpinImage( rng.next() % spinNum ).reshape(1, imageWidth)); spins.push_back(getSpinImage( rng.next() % spinNum ).reshape(1, imageWidth));
if (separateScale) if (separateScale)
for(int i = 0; i < num; ++i) for(int i = 0; i < num; ++i)
{ {
double max; double max;
Mat spin8u; Mat spin8u;
minMaxLoc(spins[i], 0, &max); minMaxLoc(spins[i], 0, &max);
spins[i].convertTo(spin8u, CV_8U, -255.0/max, 255.0); spins[i].convertTo(spin8u, CV_8U, -255.0/max, 255.0);
spins[i] = spin8u; spins[i] = spin8u;
} }
else else
{ {
double totalMax = 0; double totalMax = 0;
for(int i = 0; i < num; ++i) for(int i = 0; i < num; ++i)
{ {
double m; double m;
minMaxLoc(spins[i], 0, &m); minMaxLoc(spins[i], 0, &m);
totalMax = max(m, totalMax); totalMax = max(m, totalMax);
} }
@ -760,12 +760,12 @@ Mat cv::SpinImageModel::packRandomScaledSpins(bool separateScale, size_t xCount,
int sz = spins.front().cols; int sz = spins.front().cols;
Mat result((int)(yCount * sz + (yCount - 1)), (int)(xCount * sz + (xCount - 1)), CV_8UC3); Mat result((int)(yCount * sz + (yCount - 1)), (int)(xCount * sz + (xCount - 1)), CV_8UC3);
result = colors[(static_cast<int64>(cvGetTickCount()/cvGetTickFrequency())/1000) % colors_mum]; result = colors[(static_cast<int64>(cvGetTickCount()/cvGetTickFrequency())/1000) % colors_mum];
int pos = 0; int pos = 0;
for(int y = 0; y < (int)yCount; ++y) for(int y = 0; y < (int)yCount; ++y)
for(int x = 0; x < (int)xCount; ++x) for(int x = 0; x < (int)xCount; ++x)
if (pos < num) if (pos < num)
{ {
int starty = (y + 0) * sz + y; int starty = (y + 0) * sz + y;
@ -778,7 +778,7 @@ Mat cv::SpinImageModel::packRandomScaledSpins(bool separateScale, size_t xCount,
cvtColor(spins[pos++], color, CV_GRAY2BGR); cvtColor(spins[pos++], color, CV_GRAY2BGR);
Mat roi = result(Range(starty, endy), Range(startx, endx)); Mat roi = result(Range(starty, endy), Range(startx, endx));
color.copyTo(roi); color.copyTo(roi);
} }
return result; return result;
} }
@ -808,11 +808,11 @@ void cv::SpinImageModel::selectRandomSubset(float ratio)
subset.resize(setSize); subset.resize(setSize);
for(size_t i = 0; i < setSize; ++i) for(size_t i = 0; i < setSize; ++i)
{ {
int pos = rnd.next() % left.size(); int pos = rnd.next() % (int)left.size();
subset[i] = (int)left[pos]; subset[i] = (int)left[pos];
left[pos] = left.back(); left[pos] = left.back();
left.resize(left.size() - 1); left.resize(left.size() - 1);
} }
sort(subset, less<int>()); sort(subset, less<int>());
} }
@ -823,21 +823,21 @@ void cv::SpinImageModel::setSubset(const vector<int>& ss)
subset = ss; subset = ss;
} }
void cv::SpinImageModel::repackSpinImages(const vector<uchar>& mask, Mat& spinImages, bool reAlloc) const void cv::SpinImageModel::repackSpinImages(const vector<uchar>& mask, Mat& _spinImages, bool reAlloc) const
{ {
if (reAlloc) if (reAlloc)
{ {
size_t spinCount = mask.size() - count(mask.begin(), mask.end(), (uchar)0); size_t spinCount = mask.size() - count(mask.begin(), mask.end(), (uchar)0);
Mat newImgs((int)spinCount, spinImages.cols, spinImages.type()); Mat newImgs((int)spinCount, _spinImages.cols, _spinImages.type());
int pos = 0; int pos = 0;
for(size_t t = 0; t < mask.size(); ++t) for(size_t t = 0; t < mask.size(); ++t)
if (mask[t]) if (mask[t])
{ {
Mat row = newImgs.row(pos++); Mat row = newImgs.row(pos++);
spinImages.row((int)t).copyTo(row); _spinImages.row((int)t).copyTo(row);
} }
spinImages = newImgs; _spinImages = newImgs;
} }
else else
{ {
@ -849,13 +849,13 @@ void cv::SpinImageModel::repackSpinImages(const vector<uchar>& mask, Mat& spinIm
int first = dest + 1; int first = dest + 1;
for (; first != last; ++first) for (; first != last; ++first)
if (mask[first] != 0) if (mask[first] != 0)
{ {
Mat row = spinImages.row(dest); Mat row = _spinImages.row(dest);
spinImages.row(first).copyTo(row); _spinImages.row(first).copyTo(row);
++dest; ++dest;
} }
spinImages = spinImages.rowRange(0, dest); _spinImages = _spinImages.rowRange(0, dest);
} }
} }
@ -865,13 +865,13 @@ void cv::SpinImageModel::compute()
if (binSize == 0.f) if (binSize == 0.f)
{ {
if (mesh.resolution == -1.f) if (mesh.resolution == -1.f)
mesh.estimateResolution(); mesh.estimateResolution();
binSize = mesh.resolution; binSize = mesh.resolution;
} }
/* estimate normalRadius */ /* estimate normalRadius */
normalRadius = normalRadius != 0.f ? normalRadius : binSize * imageWidth / 2; normalRadius = normalRadius != 0.f ? normalRadius : binSize * imageWidth / 2;
mesh.buildOctree(); mesh.buildOctree();
if (subset.empty()) if (subset.empty())
{ {
mesh.computeNormals(normalRadius, minNeighbors); mesh.computeNormals(normalRadius, minNeighbors);
@ -881,16 +881,16 @@ void cv::SpinImageModel::compute()
else else
mesh.computeNormals(subset, normalRadius, minNeighbors); mesh.computeNormals(subset, normalRadius, minNeighbors);
vector<uchar> mask(mesh.vtx.size(), 0); vector<uchar> mask(mesh.vtx.size(), 0);
for(size_t i = 0; i < subset.size(); ++i) for(size_t i = 0; i < subset.size(); ++i)
if (mesh.normals[subset[i]] == Mesh3D::allzero) if (mesh.normals[subset[i]] == Mesh3D::allzero)
subset[i] = -1; subset[i] = -1;
else else
mask[subset[i]] = 1; mask[subset[i]] = 1;
subset.resize( remove(subset.begin(), subset.end(), -1) - subset.begin() ); subset.resize( remove(subset.begin(), subset.end(), -1) - subset.begin() );
vector<Point3f> vtx; vector<Point3f> vtx;
vector<Point3f> normals; vector<Point3f> normals;
for(size_t i = 0; i < mask.size(); ++i) for(size_t i = 0; i < mask.size(); ++i)
if(mask[i]) if(mask[i])
{ {
@ -906,7 +906,7 @@ void cv::SpinImageModel::compute()
for(size_t i = 0; i < mask.size(); ++i) for(size_t i = 0; i < mask.size(); ++i)
if(mask[i]) if(mask[i])
if (spinMask[mask_pos++] == 0) if (spinMask[mask_pos++] == 0)
subset.resize( remove(subset.begin(), subset.end(), (int)i) - subset.begin() ); subset.resize( remove(subset.begin(), subset.end(), (int)i) - subset.begin() );
} }
void cv::SpinImageModel::matchSpinToModel(const Mat& spin, vector<int>& indeces, vector<float>& corrCoeffs, bool useExtremeOutliers) const void cv::SpinImageModel::matchSpinToModel(const Mat& spin, vector<int>& indeces, vector<float>& corrCoeffs, bool useExtremeOutliers) const
@ -920,46 +920,46 @@ void cv::SpinImageModel::matchSpinToModel(const Mat& spin, vector<int>& indeces,
vector<uchar> masks(model.spinImages.rows); vector<uchar> masks(model.spinImages.rows);
vector<float> cleanCorrs; vector<float> cleanCorrs;
cleanCorrs.reserve(model.spinImages.rows); cleanCorrs.reserve(model.spinImages.rows);
for(int i = 0; i < model.spinImages.rows; ++i) for(int i = 0; i < model.spinImages.rows; ++i)
{ {
masks[i] = spinCorrelation(spin, model.spinImages.row(i), model.lambda, corrs[i]); masks[i] = spinCorrelation(spin, model.spinImages.row(i), model.lambda, corrs[i]);
if (masks[i]) if (masks[i])
cleanCorrs.push_back(corrs[i]); cleanCorrs.push_back(corrs[i]);
} }
/* Filtering by measure histogram */ /* Filtering by measure histogram */
size_t total = cleanCorrs.size(); size_t total = cleanCorrs.size();
if(total < 5) if(total < 5)
return; return;
sort(cleanCorrs, less<float>()); sort(cleanCorrs, less<float>());
float lower_fourth = cleanCorrs[(1 * total) / 4 - 1]; float lower_fourth = cleanCorrs[(1 * total) / 4 - 1];
float upper_fourth = cleanCorrs[(3 * total) / 4 - 0]; float upper_fourth = cleanCorrs[(3 * total) / 4 - 0];
float fourth_spread = upper_fourth - lower_fourth; float fourth_spread = upper_fourth - lower_fourth;
//extreme or moderate? //extreme or moderate?
float coef = useExtremeOutliers ? 3.0f : 1.5f; float coef = useExtremeOutliers ? 3.0f : 1.5f;
float histThresHi = upper_fourth + coef * fourth_spread;
//float histThresLo = lower_fourth - coef * fourth_spread;
float histThresHi = upper_fourth + coef * fourth_spread;
//float histThresLo = lower_fourth - coef * fourth_spread;
for(size_t i = 0; i < corrs.size(); ++i) for(size_t i = 0; i < corrs.size(); ++i)
if (masks[i]) if (masks[i])
if (/* corrs[i] < histThresLo || */ corrs[i] > histThresHi) if (/* corrs[i] < histThresLo || */ corrs[i] > histThresHi)
{ {
indeces.push_back((int)i); indeces.push_back((int)i);
corrCoeffs.push_back(corrs[i]); corrCoeffs.push_back(corrs[i]);
} }
} }
namespace namespace
{ {
struct Match struct Match
{ {
int sceneInd; int sceneInd;
int modelInd; int modelInd;
float measure; float measure;
@ -984,7 +984,7 @@ struct WgcHelper
{ {
const float* wgcLine = mat.ptr<float>((int)corespInd); const float* wgcLine = mat.ptr<float>((int)corespInd);
float maximum = numeric_limits<float>::min(); float maximum = numeric_limits<float>::min();
for(citer pos = group.begin(); pos != group.end(); ++pos) for(citer pos = group.begin(); pos != group.end(); ++pos)
maximum = max(wgcLine[*pos], maximum); maximum = max(wgcLine[*pos], maximum);
@ -997,7 +997,7 @@ private:
} }
void cv::SpinImageModel::match(const SpinImageModel& scene, vector< vector<Vec2i> >& result) void cv::SpinImageModel::match(const SpinImageModel& scene, vector< vector<Vec2i> >& result)
{ {
if (mesh.vtx.empty()) if (mesh.vtx.empty())
throw Mesh3D::EmptyMeshException(); throw Mesh3D::EmptyMeshException();
@ -1006,25 +1006,25 @@ private:
SpinImageModel& model = *this; SpinImageModel& model = *this;
const float infinity = numeric_limits<float>::infinity(); const float infinity = numeric_limits<float>::infinity();
const float float_max = numeric_limits<float>::max(); const float float_max = numeric_limits<float>::max();
/* estimate gamma */ /* estimate gamma */
if (model.gamma == 0.f) if (model.gamma == 0.f)
{ {
if (model.mesh.resolution == -1.f) if (model.mesh.resolution == -1.f)
model.mesh.estimateResolution(); model.mesh.estimateResolution();
model.gamma = 4 * model.mesh.resolution; model.gamma = 4 * model.mesh.resolution;
} }
/* estimate lambda */ /* estimate lambda */
if (model.lambda == 0.f) if (model.lambda == 0.f)
{ {
vector<int> nonzero(model.spinImages.rows); vector<int> nonzero(model.spinImages.rows);
for(int i = 0; i < model.spinImages.rows; ++i) for(int i = 0; i < model.spinImages.rows; ++i)
nonzero[i] = countNonZero(model.spinImages.row(i)); nonzero[i] = countNonZero(model.spinImages.row(i));
sort(nonzero, less<int>()); sort(nonzero, less<int>());
model.lambda = static_cast<float>( nonzero[ nonzero.size()/2 ] ) / 2; model.lambda = static_cast<float>( nonzero[ nonzero.size()/2 ] ) / 2;
} }
TickMeter corr_timer; TickMeter corr_timer;
corr_timer.start(); corr_timer.start();
vector<Match> allMatches; vector<Match> allMatches;
@ -1032,37 +1032,37 @@ private:
{ {
vector<int> indeces; vector<int> indeces;
vector<float> coeffs; vector<float> coeffs;
matchSpinToModel(scene.spinImages.row(i), indeces, coeffs); matchSpinToModel(scene.spinImages.row(i), indeces, coeffs);
for(size_t t = 0; t < indeces.size(); ++t) for(size_t t = 0; t < indeces.size(); ++t)
allMatches.push_back(Match(i, indeces[t], coeffs[t])); allMatches.push_back(Match(i, indeces[t], coeffs[t]));
if (out) if (i % 100 == 0) *out << "Comparing scene spinimage " << i << " of " << scene.spinImages.rows << endl; if (out) if (i % 100 == 0) *out << "Comparing scene spinimage " << i << " of " << scene.spinImages.rows << endl;
} }
corr_timer.stop(); corr_timer.stop();
if (out) *out << "Spin correlation time = " << corr_timer << endl; if (out) *out << "Spin correlation time = " << corr_timer << endl;
if (out) *out << "Matches number = " << allMatches.size() << endl; if (out) *out << "Matches number = " << allMatches.size() << endl;
if(allMatches.empty()) if(allMatches.empty())
return; return;
/* filtering by similarity measure */ /* filtering by similarity measure */
const float fraction = 0.5f; const float fraction = 0.5f;
float maxMeasure = max_element(allMatches.begin(), allMatches.end(), less<float>())->measure; float maxMeasure = max_element(allMatches.begin(), allMatches.end(), less<float>())->measure;
allMatches.erase( allMatches.erase(
remove_if(allMatches.begin(), allMatches.end(), bind2nd(less<float>(), maxMeasure * fraction)), remove_if(allMatches.begin(), allMatches.end(), bind2nd(less<float>(), maxMeasure * fraction)),
allMatches.end()); allMatches.end());
if (out) *out << "Matches number [filtered by similarity measure] = " << allMatches.size() << endl; if (out) *out << "Matches number [filtered by similarity measure] = " << allMatches.size() << endl;
int matchesSize = (int)allMatches.size(); int matchesSize = (int)allMatches.size();
if(matchesSize == 0) if(matchesSize == 0)
return; return;
/* filtering by geometric consistency */ /* filtering by geometric consistency */
for(int i = 0; i < matchesSize; ++i) for(int i = 0; i < matchesSize; ++i)
{ {
int consistNum = 1; int consistNum = 1;
float gc = float_max; float gc = float_max;
for(int j = 0; j < matchesSize; ++j) for(int j = 0; j < matchesSize; ++j)
if (i != j) if (i != j)
{ {
@ -1075,31 +1075,31 @@ private:
{ {
const Point3f& pointSceneI = scene.getSpinVertex(mi.sceneInd); const Point3f& pointSceneI = scene.getSpinVertex(mi.sceneInd);
const Point3f& normalSceneI = scene.getSpinNormal(mi.sceneInd); const Point3f& normalSceneI = scene.getSpinNormal(mi.sceneInd);
const Point3f& pointModelI = model.getSpinVertex(mi.modelInd); const Point3f& pointModelI = model.getSpinVertex(mi.modelInd);
const Point3f& normalModelI = model.getSpinNormal(mi.modelInd); const Point3f& normalModelI = model.getSpinNormal(mi.modelInd);
const Point3f& pointSceneJ = scene.getSpinVertex(mj.sceneInd); const Point3f& pointSceneJ = scene.getSpinVertex(mj.sceneInd);
const Point3f& normalSceneJ = scene.getSpinNormal(mj.sceneInd); const Point3f& normalSceneJ = scene.getSpinNormal(mj.sceneInd);
const Point3f& pointModelJ = model.getSpinVertex(mj.modelInd); const Point3f& pointModelJ = model.getSpinVertex(mj.modelInd);
const Point3f& normalModelJ = model.getSpinNormal(mj.modelInd); const Point3f& normalModelJ = model.getSpinNormal(mj.modelInd);
gc = geometricConsistency(pointSceneI, normalSceneI, pointModelI, normalModelI, gc = geometricConsistency(pointSceneI, normalSceneI, pointModelI, normalModelI,
pointSceneJ, normalSceneJ, pointModelJ, normalModelJ); pointSceneJ, normalSceneJ, pointModelJ, normalModelJ);
} }
if (gc < model.T_GeometriccConsistency) if (gc < model.T_GeometriccConsistency)
++consistNum; ++consistNum;
} }
if (consistNum < matchesSize / 4) /* failed consistensy test */ if (consistNum < matchesSize / 4) /* failed consistensy test */
allMatches[i].measure = infinity; allMatches[i].measure = infinity;
} }
allMatches.erase( allMatches.erase(
remove_if(allMatches.begin(), allMatches.end(), bind2nd(equal_to<float>(), infinity)), remove_if(allMatches.begin(), allMatches.end(), bind2nd(equal_to<float>(), infinity)),
allMatches.end()); allMatches.end());
if (out) *out << "Matches number [filtered by geometric consistency] = " << allMatches.size() << endl; if (out) *out << "Matches number [filtered by geometric consistency] = " << allMatches.size() << endl;
@ -1110,11 +1110,11 @@ private:
if (out) *out << "grouping ..." << endl; if (out) *out << "grouping ..." << endl;
Mat groupingMat((int)matchesSize, (int)matchesSize, CV_32F); Mat groupingMat((int)matchesSize, (int)matchesSize, CV_32F);
groupingMat = Scalar(0); groupingMat = Scalar(0);
/* grouping */ /* grouping */
for(int j = 0; j < matchesSize; ++j) for(int j = 0; j < matchesSize; ++j)
for(int i = j + 1; i < matchesSize; ++i) for(int i = j + 1; i < matchesSize; ++i)
{ {
const Match& mi = allMatches[i]; const Match& mi = allMatches[i];
const Match& mj = allMatches[j]; const Match& mj = allMatches[j];
@ -1128,20 +1128,20 @@ private:
const Point3f& pointSceneI = scene.getSpinVertex(mi.sceneInd); const Point3f& pointSceneI = scene.getSpinVertex(mi.sceneInd);
const Point3f& normalSceneI = scene.getSpinNormal(mi.sceneInd); const Point3f& normalSceneI = scene.getSpinNormal(mi.sceneInd);
const Point3f& pointModelI = model.getSpinVertex(mi.modelInd); const Point3f& pointModelI = model.getSpinVertex(mi.modelInd);
const Point3f& normalModelI = model.getSpinNormal(mi.modelInd); const Point3f& normalModelI = model.getSpinNormal(mi.modelInd);
const Point3f& pointSceneJ = scene.getSpinVertex(mj.sceneInd); const Point3f& pointSceneJ = scene.getSpinVertex(mj.sceneInd);
const Point3f& normalSceneJ = scene.getSpinNormal(mj.sceneInd); const Point3f& normalSceneJ = scene.getSpinNormal(mj.sceneInd);
const Point3f& pointModelJ = model.getSpinVertex(mj.modelInd); const Point3f& pointModelJ = model.getSpinVertex(mj.modelInd);
const Point3f& normalModelJ = model.getSpinNormal(mj.modelInd); const Point3f& normalModelJ = model.getSpinNormal(mj.modelInd);
float wgc = groupingCreteria(pointSceneI, normalSceneI, pointModelI, normalModelI, float wgc = groupingCreteria(pointSceneI, normalSceneI, pointModelI, normalModelI,
pointSceneJ, normalSceneJ, pointModelJ, normalModelJ, pointSceneJ, normalSceneJ, pointModelJ, normalModelJ,
model.gamma); model.gamma);
groupingMat.ptr<float>(i)[j] = wgc; groupingMat.ptr<float>(i)[j] = wgc;
groupingMat.ptr<float>(j)[i] = wgc; groupingMat.ptr<float>(j)[i] = wgc;
} }
@ -1149,35 +1149,35 @@ private:
group_t allMatchesInds; group_t allMatchesInds;
for(int i = 0; i < matchesSize; ++i) for(int i = 0; i < matchesSize; ++i)
allMatchesInds.insert(i); allMatchesInds.insert(i);
vector<float> buf(matchesSize); vector<float> buf(matchesSize);
float *buf_beg = &buf[0]; float *buf_beg = &buf[0];
vector<group_t> groups; vector<group_t> groups;
for(int g = 0; g < matchesSize; ++g) for(int g = 0; g < matchesSize; ++g)
{ {
if (out) if (g % 100 == 0) *out << "G = " << g << endl; if (out) if (g % 100 == 0) *out << "G = " << g << endl;
group_t left = allMatchesInds; group_t left = allMatchesInds;
group_t group; group_t group;
left.erase(g); left.erase(g);
group.insert(g); group.insert(g);
for(;;) for(;;)
{ {
size_t left_size = left.size(); size_t left_size = left.size();
if (left_size == 0) if (left_size == 0)
break; break;
std::transform(left.begin(), left.end(), buf_beg, WgcHelper(group, groupingMat)); std::transform(left.begin(), left.end(), buf_beg, WgcHelper(group, groupingMat));
size_t minInd = min_element(buf_beg, buf_beg + left_size) - buf_beg; size_t minInd = min_element(buf_beg, buf_beg + left_size) - buf_beg;
if (buf[minInd] < model.T_GroupingCorespondances) /* can add corespondance to group */ if (buf[minInd] < model.T_GroupingCorespondances) /* can add corespondance to group */
{ {
iter pos = left.begin(); iter pos = left.begin();
advance(pos, minInd); advance(pos, minInd);
group.insert(*pos); group.insert(*pos);
left.erase(pos); left.erase(pos);
} }
@ -1199,16 +1199,16 @@ private:
{ {
const Match& m = allMatches[*pos]; const Match& m = allMatches[*pos];
outgrp.push_back(Vec2i(subset[m.modelInd], scene.subset[m.sceneInd])); outgrp.push_back(Vec2i(subset[m.modelInd], scene.subset[m.sceneInd]));
} }
result.push_back(outgrp); result.push_back(outgrp);
} }
} }
cv::TickMeter::TickMeter() { reset(); } cv::TickMeter::TickMeter() { reset(); }
int64 cv::TickMeter::getTimeTicks() const { return sumTime; } int64 cv::TickMeter::getTimeTicks() const { return sumTime; }
double cv::TickMeter::getTimeMicro() const { return (double)getTimeTicks()/cvGetTickFrequency(); } double cv::TickMeter::getTimeMicro() const { return (double)getTimeTicks()/cvGetTickFrequency(); }
double cv::TickMeter::getTimeMilli() const { return getTimeMicro()*1e-3; } double cv::TickMeter::getTimeMilli() const { return getTimeMicro()*1e-3; }
double cv::TickMeter::getTimeSec() const { return getTimeMilli()*1e-3; } double cv::TickMeter::getTimeSec() const { return getTimeMilli()*1e-3; }
int64 cv::TickMeter::getCounter() const { return counter; } int64 cv::TickMeter::getCounter() const { return counter; }
void cv::TickMeter::reset() {startTime = 0; sumTime = 0; counter = 0; } void cv::TickMeter::reset() {startTime = 0; sumTime = 0; counter = 0; }

View File

@ -46,14 +46,14 @@
Proceedings of the 5th International Symposium on Visual Computing, Vegas, USA Proceedings of the 5th International Symposium on Visual Computing, Vegas, USA
This code is written by Sergey G. Kosov for "Visir PX" application as part of Project X (www.project-10.de) This code is written by Sergey G. Kosov for "Visir PX" application as part of Project X (www.project-10.de)
*/ */
#include "precomp.hpp" #include "precomp.hpp"
#include <limits.h> #include <limits.h>
namespace cv namespace cv
{ {
StereoVar::StereoVar() : levels(3), pyrScale(0.5), nIt(5), minDisp(0), maxDisp(16), poly_n(3), poly_sigma(0), fi(25.0f), lambda(0.03f), penalization(PENALIZATION_TICHONOV), cycle(CYCLE_V), flags(USE_SMART_ID | USE_AUTO_PARAMS) StereoVar::StereoVar() : levels(3), pyrScale(0.5), nIt(5), minDisp(0), maxDisp(16), poly_n(3), poly_sigma(0), fi(25.0f), lambda(0.03f), penalization(PENALIZATION_TICHONOV), cycle(CYCLE_V), flags(USE_SMART_ID | USE_AUTO_PARAMS)
{ {
} }
@ -67,9 +67,9 @@ StereoVar::~StereoVar()
static Mat diffX(Mat &src) static Mat diffX(Mat &src)
{ {
register int x, y, cols = src.cols - 1; register int x, y, cols = src.cols - 1;
Mat dst(src.size(), src.type()); Mat dst(src.size(), src.type());
for(y = 0; y < src.rows; y++){ for(y = 0; y < src.rows; y++){
const float* pSrc = src.ptr<float>(y); const float* pSrc = src.ptr<float>(y);
float* pDst = dst.ptr<float>(y); float* pDst = dst.ptr<float>(y);
#if CV_SSE2 #if CV_SSE2
@ -92,319 +92,319 @@ static Mat diffX(Mat &src)
static Mat getGradient(Mat &src) static Mat getGradient(Mat &src)
{ {
register int x, y; register int x, y;
Mat dst(src.size(), src.type()); Mat dst(src.size(), src.type());
dst.setTo(0); dst.setTo(0);
for (y = 0; y < src.rows - 1; y++) { for (y = 0; y < src.rows - 1; y++) {
float *pSrc = src.ptr<float>(y); float *pSrc = src.ptr<float>(y);
float *pSrcF = src.ptr<float>(y + 1); float *pSrcF = src.ptr<float>(y + 1);
float *pDst = dst.ptr<float>(y); float *pDst = dst.ptr<float>(y);
for (x = 0; x < src.cols - 1; x++) for (x = 0; x < src.cols - 1; x++)
pDst[x] = fabs(pSrc[x + 1] - pSrc[x]) + fabs(pSrcF[x] - pSrc[x]); pDst[x] = fabs(pSrc[x + 1] - pSrc[x]) + fabs(pSrcF[x] - pSrc[x]);
} }
return dst; return dst;
} }
static Mat getG_c(Mat &src, float l) static Mat getG_c(Mat &src, float l)
{ {
Mat dst(src.size(), src.type()); Mat dst(src.size(), src.type());
for (register int y = 0; y < src.rows; y++) { for (register int y = 0; y < src.rows; y++) {
float *pSrc = src.ptr<float>(y); float *pSrc = src.ptr<float>(y);
float *pDst = dst.ptr<float>(y); float *pDst = dst.ptr<float>(y);
for (register int x = 0; x < src.cols; x++) for (register int x = 0; x < src.cols; x++)
pDst[x] = 0.5f*l / sqrtf(l*l + pSrc[x]*pSrc[x]); pDst[x] = 0.5f*l / sqrtf(l*l + pSrc[x]*pSrc[x]);
} }
return dst; return dst;
} }
static Mat getG_p(Mat &src, float l) static Mat getG_p(Mat &src, float l)
{ {
Mat dst(src.size(), src.type()); Mat dst(src.size(), src.type());
for (register int y = 0; y < src.rows; y++) { for (register int y = 0; y < src.rows; y++) {
float *pSrc = src.ptr<float>(y); float *pSrc = src.ptr<float>(y);
float *pDst = dst.ptr<float>(y); float *pDst = dst.ptr<float>(y);
for (register int x = 0; x < src.cols; x++) for (register int x = 0; x < src.cols; x++)
pDst[x] = 0.5f*l*l / (l*l + pSrc[x]*pSrc[x]); pDst[x] = 0.5f*l*l / (l*l + pSrc[x]*pSrc[x]);
} }
return dst; return dst;
} }
void StereoVar::VariationalSolver(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level) void StereoVar::VariationalSolver(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level)
{ {
register int n, x, y; register int n, x, y;
float gl = 1, gr = 1, gu = 1, gd = 1, gc = 4; float gl = 1, gr = 1, gu = 1, gd = 1, gc = 4;
Mat g_c, g_p; Mat g_c, g_p;
Mat U; Mat U;
u.copyTo(U); u.copyTo(U);
int N = nIt; int N = nIt;
float l = lambda; float l = lambda;
float Fi = fi; float Fi = fi;
if (flags & USE_SMART_ID) {
double scale = pow(pyrScale, (double) level) * (1 + pyrScale);
N = (int) (N / scale);
}
double scale = pow(pyrScale, (double) level); if (flags & USE_SMART_ID) {
Fi /= (float) scale; double scale = pow(pyrScale, (double) level) * (1 + pyrScale);
l *= (float) scale; N = (int) (N / scale);
}
int width = u.cols - 1; double scale = pow(pyrScale, (double) level);
int height = u.rows - 1; Fi /= (float) scale;
for (n = 0; n < N; n++) { l *= (float) scale;
if (penalization != PENALIZATION_TICHONOV) {
Mat gradient = getGradient(U);
switch (penalization) {
case PENALIZATION_CHARBONNIER: g_c = getG_c(gradient, l); break;
case PENALIZATION_PERONA_MALIK: g_p = getG_p(gradient, l); break;
}
gradient.release();
}
for (y = 1 ; y < height; y++) {
float *pU = U.ptr<float>(y);
float *pUu = U.ptr<float>(y + 1);
float *pUd = U.ptr<float>(y - 1);
float *pu = u.ptr<float>(y);
float *pI1 = I1.ptr<float>(y);
float *pI2 = I2.ptr<float>(y);
float *pI2x = I2x.ptr<float>(y);
float *pG_c = NULL, *pG_cu = NULL, *pG_cd = NULL;
float *pG_p = NULL, *pG_pu = NULL, *pG_pd = NULL;
switch (penalization) {
case PENALIZATION_CHARBONNIER:
pG_c = g_c.ptr<float>(y);
pG_cu = g_c.ptr<float>(y + 1);
pG_cd = g_c.ptr<float>(y - 1);
break;
case PENALIZATION_PERONA_MALIK:
pG_p = g_p.ptr<float>(y);
pG_pu = g_p.ptr<float>(y + 1);
pG_pd = g_p.ptr<float>(y - 1);
break;
}
for (x = 1; x < width; x++) {
switch (penalization) {
case PENALIZATION_CHARBONNIER:
gc = pG_c[x];
gl = gc + pG_c[x - 1];
gr = gc + pG_c[x + 1];
gu = gc + pG_cu[x];
gd = gc + pG_cd[x];
gc = gl + gr + gu + gd;
break;
case PENALIZATION_PERONA_MALIK:
gc = pG_p[x];
gl = gc + pG_p[x - 1];
gr = gc + pG_p[x + 1];
gu = gc + pG_pu[x];
gd = gc + pG_pd[x];
gc = gl + gr + gu + gd;
break;
}
float fi = Fi; int width = u.cols - 1;
if (maxDisp > minDisp) { int height = u.rows - 1;
if (pU[x] > maxDisp * scale) {fi *= 1000; pU[x] = static_cast<float>(maxDisp * scale);} for (n = 0; n < N; n++) {
if (pU[x] < minDisp * scale) {fi *= 1000; pU[x] = static_cast<float>(minDisp * scale);} if (penalization != PENALIZATION_TICHONOV) {
} Mat gradient = getGradient(U);
switch (penalization) {
case PENALIZATION_CHARBONNIER: g_c = getG_c(gradient, l); break;
case PENALIZATION_PERONA_MALIK: g_p = getG_p(gradient, l); break;
}
gradient.release();
}
for (y = 1 ; y < height; y++) {
float *pU = U.ptr<float>(y);
float *pUu = U.ptr<float>(y + 1);
float *pUd = U.ptr<float>(y - 1);
float *pu = u.ptr<float>(y);
float *pI1 = I1.ptr<float>(y);
float *pI2 = I2.ptr<float>(y);
float *pI2x = I2x.ptr<float>(y);
float *pG_c = NULL, *pG_cu = NULL, *pG_cd = NULL;
float *pG_p = NULL, *pG_pu = NULL, *pG_pd = NULL;
switch (penalization) {
case PENALIZATION_CHARBONNIER:
pG_c = g_c.ptr<float>(y);
pG_cu = g_c.ptr<float>(y + 1);
pG_cd = g_c.ptr<float>(y - 1);
break;
case PENALIZATION_PERONA_MALIK:
pG_p = g_p.ptr<float>(y);
pG_pu = g_p.ptr<float>(y + 1);
pG_pd = g_p.ptr<float>(y - 1);
break;
}
for (x = 1; x < width; x++) {
switch (penalization) {
case PENALIZATION_CHARBONNIER:
gc = pG_c[x];
gl = gc + pG_c[x - 1];
gr = gc + pG_c[x + 1];
gu = gc + pG_cu[x];
gd = gc + pG_cd[x];
gc = gl + gr + gu + gd;
break;
case PENALIZATION_PERONA_MALIK:
gc = pG_p[x];
gl = gc + pG_p[x - 1];
gr = gc + pG_p[x + 1];
gu = gc + pG_pu[x];
gd = gc + pG_pd[x];
gc = gl + gr + gu + gd;
break;
}
int A = static_cast<int>(pU[x]); float _fi = Fi;
int neg = 0; if (pU[x] <= 0) neg = -1; if (maxDisp > minDisp) {
if (pU[x] > maxDisp * scale) {_fi *= 1000; pU[x] = static_cast<float>(maxDisp * scale);}
if (pU[x] < minDisp * scale) {_fi *= 1000; pU[x] = static_cast<float>(minDisp * scale);}
}
if (x + A > width) int A = static_cast<int>(pU[x]);
pu[x] = pU[width - A]; int neg = 0; if (pU[x] <= 0) neg = -1;
else if (x + A + neg < 0)
pu[x] = pU[- A + 2]; if (x + A > width)
else { pu[x] = pU[width - A];
pu[x] = A + (pI2x[x + A + neg] * (pI1[x] - pI2[x + A]) else if (x + A + neg < 0)
+ fi * (gr * pU[x + 1] + gl * pU[x - 1] + gu * pUu[x] + gd * pUd[x] - gc * A)) pu[x] = pU[- A + 2];
/ (pI2x[x + A + neg] * pI2x[x + A + neg] + gc * fi) ; else {
} pu[x] = A + (pI2x[x + A + neg] * (pI1[x] - pI2[x + A])
}// x + _fi * (gr * pU[x + 1] + gl * pU[x - 1] + gu * pUu[x] + gd * pUd[x] - gc * A))
pu[0] = pu[1]; / (pI2x[x + A + neg] * pI2x[x + A + neg] + gc * _fi) ;
pu[width] = pu[width - 1]; }
}// y }// x
for (x = 0; x <= width; x++) { pu[0] = pu[1];
u.at<float>(0, x) = u.at<float>(1, x); pu[width] = pu[width - 1];
u.at<float>(height, x) = u.at<float>(height - 1, x); }// y
} for (x = 0; x <= width; x++) {
u.copyTo(U); u.at<float>(0, x) = u.at<float>(1, x);
if (!g_c.empty()) g_c.release(); u.at<float>(height, x) = u.at<float>(height - 1, x);
if (!g_p.empty()) g_p.release(); }
}//n u.copyTo(U);
if (!g_c.empty()) g_c.release();
if (!g_p.empty()) g_p.release();
}//n
} }
void StereoVar::VCycle_MyFAS(Mat &I1, Mat &I2, Mat &I2x, Mat &_u, int level) void StereoVar::VCycle_MyFAS(Mat &I1, Mat &I2, Mat &I2x, Mat &_u, int level)
{ {
CvSize imgSize = _u.size(); CvSize imgSize = _u.size();
CvSize frmSize = cvSize((int) (imgSize.width * pyrScale + 0.5), (int) (imgSize.height * pyrScale + 0.5)); CvSize frmSize = cvSize((int) (imgSize.width * pyrScale + 0.5), (int) (imgSize.height * pyrScale + 0.5));
Mat I1_h, I2_h, I2x_h, u_h, U, U_h; Mat I1_h, I2_h, I2x_h, u_h, U, U_h;
//PRE relaxation //PRE relaxation
VariationalSolver(I1, I2, I2x, _u, level); VariationalSolver(I1, I2, I2x, _u, level);
if (level >= levels - 1) return; if (level >= levels - 1) return;
level ++; level ++;
//scaling DOWN //scaling DOWN
resize(I1, I1_h, frmSize, 0, 0, INTER_AREA); resize(I1, I1_h, frmSize, 0, 0, INTER_AREA);
resize(I2, I2_h, frmSize, 0, 0, INTER_AREA); resize(I2, I2_h, frmSize, 0, 0, INTER_AREA);
resize(_u, u_h, frmSize, 0, 0, INTER_AREA); resize(_u, u_h, frmSize, 0, 0, INTER_AREA);
u_h.convertTo(u_h, u_h.type(), pyrScale); u_h.convertTo(u_h, u_h.type(), pyrScale);
I2x_h = diffX(I2_h); I2x_h = diffX(I2_h);
//Next level //Next level
U_h = u_h.clone(); U_h = u_h.clone();
VCycle_MyFAS(I1_h, I2_h, I2x_h, U_h, level); VCycle_MyFAS(I1_h, I2_h, I2x_h, U_h, level);
subtract(U_h, u_h, U_h); subtract(U_h, u_h, U_h);
U_h.convertTo(U_h, U_h.type(), 1.0 / pyrScale); U_h.convertTo(U_h, U_h.type(), 1.0 / pyrScale);
//scaling UP //scaling UP
resize(U_h, U, imgSize); resize(U_h, U, imgSize);
//correcting the solution //correcting the solution
add(_u, U, _u); add(_u, U, _u);
//POST relaxation //POST relaxation
VariationalSolver(I1, I2, I2x, _u, level - 1); VariationalSolver(I1, I2, I2x, _u, level - 1);
if (flags & USE_MEDIAN_FILTERING) medianBlur(_u, _u, 3); if (flags & USE_MEDIAN_FILTERING) medianBlur(_u, _u, 3);
I1_h.release(); I1_h.release();
I2_h.release(); I2_h.release();
I2x_h.release(); I2x_h.release();
u_h.release(); u_h.release();
U.release(); U.release();
U_h.release(); U_h.release();
} }
void StereoVar::FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level) void StereoVar::FMG(Mat &I1, Mat &I2, Mat &I2x, Mat &u, int level)
{ {
double scale = pow(pyrScale, (double) level); double scale = pow(pyrScale, (double) level);
CvSize frmSize = cvSize((int) (u.cols * scale + 0.5), (int) (u.rows * scale + 0.5)); CvSize frmSize = cvSize((int) (u.cols * scale + 0.5), (int) (u.rows * scale + 0.5));
Mat I1_h, I2_h, I2x_h, u_h; Mat I1_h, I2_h, I2x_h, u_h;
//scaling DOWN //scaling DOWN
resize(I1, I1_h, frmSize, 0, 0, INTER_AREA); resize(I1, I1_h, frmSize, 0, 0, INTER_AREA);
resize(I2, I2_h, frmSize, 0, 0, INTER_AREA); resize(I2, I2_h, frmSize, 0, 0, INTER_AREA);
resize(u, u_h, frmSize, 0, 0, INTER_AREA); resize(u, u_h, frmSize, 0, 0, INTER_AREA);
u_h.convertTo(u_h, u_h.type(), scale); u_h.convertTo(u_h, u_h.type(), scale);
I2x_h = diffX(I2_h); I2x_h = diffX(I2_h);
switch (cycle) { switch (cycle) {
case CYCLE_O: case CYCLE_O:
VariationalSolver(I1_h, I2_h, I2x_h, u_h, level); VariationalSolver(I1_h, I2_h, I2x_h, u_h, level);
break; break;
case CYCLE_V: case CYCLE_V:
VCycle_MyFAS(I1_h, I2_h, I2x_h, u_h, level); VCycle_MyFAS(I1_h, I2_h, I2x_h, u_h, level);
break; break;
} }
u_h.convertTo(u_h, u_h.type(), 1.0 / scale); u_h.convertTo(u_h, u_h.type(), 1.0 / scale);
//scaling UP //scaling UP
resize(u_h, u, u.size(), 0, 0, INTER_CUBIC); resize(u_h, u, u.size(), 0, 0, INTER_CUBIC);
I1_h.release(); I1_h.release();
I2_h.release(); I2_h.release();
I2x_h.release(); I2x_h.release();
u_h.release(); u_h.release();
level--; level--;
if ((flags & USE_AUTO_PARAMS) && (level < levels / 3)) { if ((flags & USE_AUTO_PARAMS) && (level < levels / 3)) {
penalization = PENALIZATION_PERONA_MALIK; penalization = PENALIZATION_PERONA_MALIK;
fi *= 100; fi *= 100;
flags -= USE_AUTO_PARAMS; flags -= USE_AUTO_PARAMS;
autoParams(); autoParams();
} }
if (flags & USE_MEDIAN_FILTERING) medianBlur(u, u, 3); if (flags & USE_MEDIAN_FILTERING) medianBlur(u, u, 3);
if (level >= 0) FMG(I1, I2, I2x, u, level); if (level >= 0) FMG(I1, I2, I2x, u, level);
} }
void StereoVar::autoParams() void StereoVar::autoParams()
{ {
int maxD = MAX(labs(maxDisp), labs(minDisp)); int maxD = MAX(labs(maxDisp), labs(minDisp));
if (!maxD) pyrScale = 0.85;
else if (maxD < 8) pyrScale = 0.5;
else if (maxD < 64) pyrScale = 0.5 + static_cast<double>(maxD - 8) * 0.00625;
else pyrScale = 0.85;
if (maxD) {
levels = 0;
while ( pow(pyrScale, levels) * maxD > 1.5) levels ++;
levels++;
}
switch(penalization) { if (!maxD) pyrScale = 0.85;
case PENALIZATION_TICHONOV: cycle = CYCLE_V; break; else if (maxD < 8) pyrScale = 0.5;
case PENALIZATION_CHARBONNIER: cycle = CYCLE_O; break; else if (maxD < 64) pyrScale = 0.5 + static_cast<double>(maxD - 8) * 0.00625;
case PENALIZATION_PERONA_MALIK: cycle = CYCLE_O; break; else pyrScale = 0.85;
}
if (maxD) {
levels = 0;
while ( pow(pyrScale, levels) * maxD > 1.5) levels ++;
levels++;
}
switch(penalization) {
case PENALIZATION_TICHONOV: cycle = CYCLE_V; break;
case PENALIZATION_CHARBONNIER: cycle = CYCLE_O; break;
case PENALIZATION_PERONA_MALIK: cycle = CYCLE_O; break;
}
} }
void StereoVar::operator ()( const Mat& left, const Mat& right, Mat& disp ) void StereoVar::operator ()( const Mat& left, const Mat& right, Mat& disp )
{ {
CV_Assert(left.size() == right.size() && left.type() == right.type()); CV_Assert(left.size() == right.size() && left.type() == right.type());
CvSize imgSize = left.size(); CvSize imgSize = left.size();
int MaxD = MAX(labs(minDisp), labs(maxDisp)); int MaxD = MAX(labs(minDisp), labs(maxDisp));
int SignD = 1; if (MIN(minDisp, maxDisp) < 0) SignD = -1; int SignD = 1; if (MIN(minDisp, maxDisp) < 0) SignD = -1;
if (minDisp >= maxDisp) {MaxD = 256; SignD = 1;} if (minDisp >= maxDisp) {MaxD = 256; SignD = 1;}
Mat u;
if ((flags & USE_INITIAL_DISPARITY) && (!disp.empty())) {
CV_Assert(disp.size() == left.size() && disp.type() == CV_8UC1);
disp.convertTo(u, CV_32FC1, static_cast<double>(SignD * MaxD) / 256);
} else {
u.create(imgSize, CV_32FC1);
u.setTo(0);
}
// Preprocessing Mat u;
Mat leftgray, rightgray; if ((flags & USE_INITIAL_DISPARITY) && (!disp.empty())) {
if (left.type() != CV_8UC1) { CV_Assert(disp.size() == left.size() && disp.type() == CV_8UC1);
cvtColor(left, leftgray, CV_BGR2GRAY); disp.convertTo(u, CV_32FC1, static_cast<double>(SignD * MaxD) / 256);
cvtColor(right, rightgray, CV_BGR2GRAY); } else {
} else { u.create(imgSize, CV_32FC1);
left.copyTo(leftgray); u.setTo(0);
right.copyTo(rightgray); }
}
if (flags & USE_EQUALIZE_HIST) {
equalizeHist(leftgray, leftgray);
equalizeHist(rightgray, rightgray);
}
if (poly_sigma > 0.0001) {
GaussianBlur(leftgray, leftgray, cvSize(poly_n, poly_n), poly_sigma);
GaussianBlur(rightgray, rightgray, cvSize(poly_n, poly_n), poly_sigma);
}
if (flags & USE_AUTO_PARAMS) {
penalization = PENALIZATION_TICHONOV;
autoParams();
}
Mat I1, I2; // Preprocessing
leftgray.convertTo(I1, CV_32FC1); Mat leftgray, rightgray;
rightgray.convertTo(I2, CV_32FC1); if (left.type() != CV_8UC1) {
leftgray.release(); cvtColor(left, leftgray, CV_BGR2GRAY);
rightgray.release(); cvtColor(right, rightgray, CV_BGR2GRAY);
} else {
left.copyTo(leftgray);
right.copyTo(rightgray);
}
if (flags & USE_EQUALIZE_HIST) {
equalizeHist(leftgray, leftgray);
equalizeHist(rightgray, rightgray);
}
if (poly_sigma > 0.0001) {
GaussianBlur(leftgray, leftgray, cvSize(poly_n, poly_n), poly_sigma);
GaussianBlur(rightgray, rightgray, cvSize(poly_n, poly_n), poly_sigma);
}
Mat I2x = diffX(I2); if (flags & USE_AUTO_PARAMS) {
penalization = PENALIZATION_TICHONOV;
FMG(I1, I2, I2x, u, levels - 1); autoParams();
}
I1.release();
I2.release();
I2x.release();
disp.create( left.size(), CV_8UC1 );
u = abs(u);
u.convertTo(disp, disp.type(), 256 / MaxD, 0);
u.release(); Mat I1, I2;
leftgray.convertTo(I1, CV_32FC1);
rightgray.convertTo(I2, CV_32FC1);
leftgray.release();
rightgray.release();
Mat I2x = diffX(I2);
FMG(I1, I2, I2x, u, levels - 1);
I1.release();
I2.release();
I2x.release();
disp.create( left.size(), CV_8UC1 );
u = abs(u);
u.convertTo(disp, disp.type(), 256 / MaxD, 0);
u.release();
} }
} // namespace } // namespace

View File

@ -1,3 +1,7 @@
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
#endif
#ifndef __OPENCV_TEST_PRECOMP_HPP__ #ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__ #define __OPENCV_TEST_PRECOMP_HPP__

View File

@ -5,10 +5,11 @@ ocv_module_include_directories(${ZLIB_INCLUDE_DIR})
if(HAVE_CUDA) if(HAVE_CUDA)
file(GLOB lib_cuda "src/cuda/*.cu") file(GLOB lib_cuda "src/cuda/*.cu")
source_group("Cuda" FILES "${lib_cuda}") source_group("Cuda" FILES "${lib_cuda}")
ocv_include_directories(${CUDA_INCLUDE_DIRS} "${OpenCV_SOURCE_DIR}/modules/gpu/src" "${OpenCV_SOURCE_DIR}/modules/gpu/src/cuda") ocv_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/src" "${OpenCV_SOURCE_DIR}/modules/gpu/src/cuda" ${CUDA_INCLUDE_DIRS})
OCV_CUDA_COMPILE(cuda_objs ${lib_cuda}) ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
ocv_cuda_compile(cuda_objs ${lib_cuda})
set(cuda_link_libs ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY}) set(cuda_link_libs ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
else() else()
set(lib_cuda "") set(lib_cuda "")

View File

@ -1299,6 +1299,7 @@ public:
GPU_MAT = 9 << KIND_SHIFT GPU_MAT = 9 << KIND_SHIFT
}; };
_InputArray(); _InputArray();
_InputArray(const Mat& m); _InputArray(const Mat& m);
_InputArray(const MatExpr& expr); _InputArray(const MatExpr& expr);
template<typename _Tp> _InputArray(const _Tp* vec, int n); template<typename _Tp> _InputArray(const _Tp* vec, int n);
@ -1328,6 +1329,10 @@ public:
virtual int channels(int i=-1) const; virtual int channels(int i=-1) const;
virtual bool empty() const; virtual bool empty() const;
#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
virtual ~_InputArray();
#endif
int flags; int flags;
void* obj; void* obj;
Size sz; Size sz;
@ -1384,6 +1389,10 @@ public:
virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const; virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
virtual void release() const; virtual void release() const;
virtual void clear() const; virtual void clear() const;
#ifdef OPENCV_CAN_BREAK_BINARY_COMPATIBILITY
virtual ~_OutputArray();
#endif
}; };
typedef const _InputArray& InputArray; typedef const _InputArray& InputArray;
@ -3970,7 +3979,7 @@ public:
CV_WRAP virtual bool isOpened() const; CV_WRAP virtual bool isOpened() const;
//! closes the file and releases all the memory buffers //! closes the file and releases all the memory buffers
CV_WRAP virtual void release(); CV_WRAP virtual void release();
//! closes the file, releases all the memory buffers and returns the text string //! closes the file, releases all the memory buffers and returns the text string
CV_WRAP string releaseAndGetString(); CV_WRAP string releaseAndGetString();
//! returns the first element of the top-level mapping //! returns the first element of the top-level mapping

View File

@ -666,7 +666,7 @@ CVAPI(int) cvSolveCubic( const CvMat* coeffs, CvMat* roots );
/* Finds all real and complex roots of a polynomial equation */ /* Finds all real and complex roots of a polynomial equation */
CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2, CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2,
int maxiter CV_DEFAULT(20), int fig CV_DEFAULT(100)); int maxiter CV_DEFAULT(20), int fig CV_DEFAULT(100));
/****************************************************************************************\ /****************************************************************************************\
* Matrix operations * * Matrix operations *
@ -1127,9 +1127,9 @@ CVAPI(void) cvSetRemove( CvSet* set_header, int index );
/* Returns a set element by index. If the element doesn't belong to the set, /* Returns a set element by index. If the element doesn't belong to the set,
NULL is returned */ NULL is returned */
CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int index ) CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int idx )
{ {
CvSetElem* elem = (CvSetElem*)cvGetSeqElem( (CvSeq*)set_header, index ); CvSetElem* elem = (CvSetElem*)cvGetSeqElem( (CvSeq*)set_header, idx );
return elem && CV_IS_SET_ELEM( elem ) ? elem : 0; return elem && CV_IS_SET_ELEM( elem ) ? elem : 0;
} }
@ -1283,8 +1283,8 @@ CVAPI(void) cvRectangleR( CvArr* img, CvRect r,
CvScalar color, int thickness CV_DEFAULT(1), CvScalar color, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8), int line_type CV_DEFAULT(8),
int shift CV_DEFAULT(0)); int shift CV_DEFAULT(0));
/* Draws a circle with specified center and radius. /* Draws a circle with specified center and radius.
Thickness works in the same way as with cvRectangle */ Thickness works in the same way as with cvRectangle */
CVAPI(void) cvCircle( CvArr* img, CvPoint center, int radius, CVAPI(void) cvCircle( CvArr* img, CvPoint center, int radius,
@ -1374,17 +1374,17 @@ CVAPI(int) cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2,
/* Font structure */ /* Font structure */
typedef struct CvFont typedef struct CvFont
{ {
const char* nameFont; //Qt:nameFont const char* nameFont; //Qt:nameFont
CvScalar color; //Qt:ColorFont -> cvScalar(blue_component, green_component, red\_component[, alpha_component]) CvScalar color; //Qt:ColorFont -> cvScalar(blue_component, green_component, red\_component[, alpha_component])
int font_face; //Qt: bool italic /* =CV_FONT_* */ int font_face; //Qt: bool italic /* =CV_FONT_* */
const int* ascii; /* font data and metrics */ const int* ascii; /* font data and metrics */
const int* greek; const int* greek;
const int* cyrillic; const int* cyrillic;
float hscale, vscale; float hscale, vscale;
float shear; /* slope coefficient: 0 - normal, >0 - italic */ float shear; /* slope coefficient: 0 - normal, >0 - italic */
int thickness; //Qt: weight /* letters thickness */ int thickness; //Qt: weight /* letters thickness */
float dx; /* horizontal interval between letters */ float dx; /* horizontal interval between letters */
int line_type; //Qt: PointSize int line_type; //Qt: PointSize
} }
CvFont; CvFont;
@ -1696,7 +1696,7 @@ CVAPI(double) cvGetTickFrequency( void );
/*********************************** CPU capabilities ***********************************/ /*********************************** CPU capabilities ***********************************/
#define CV_CPU_NONE 0 #define CV_CPU_NONE 0
#define CV_CPU_MMX 1 #define CV_CPU_MMX 1
#define CV_CPU_SSE 2 #define CV_CPU_SSE 2
#define CV_CPU_SSE2 3 #define CV_CPU_SSE2 3
@ -1718,9 +1718,9 @@ CVAPI(void) cvSetNumThreads( int threads CV_DEFAULT(0) );
/* get index of the thread being executed */ /* get index of the thread being executed */
CVAPI(int) cvGetThreadNum( void ); CVAPI(int) cvGetThreadNum( void );
/********************************** Error Handling **************************************/ /********************************** Error Handling **************************************/
/* Get current OpenCV error status */ /* Get current OpenCV error status */
CVAPI(int) cvGetErrStatus( void ); CVAPI(int) cvGetErrStatus( void );
@ -1774,37 +1774,37 @@ CVAPI(int) cvStdErrReport( int status, const char* func_name, const char* err_ms
const char* file_name, int line, void* userdata ); const char* file_name, int line, void* userdata );
CVAPI(int) cvGuiBoxReport( int status, const char* func_name, const char* err_msg, CVAPI(int) cvGuiBoxReport( int status, const char* func_name, const char* err_msg,
const char* file_name, int line, void* userdata ); const char* file_name, int line, void* userdata );
#define OPENCV_ERROR(status,func,context) \ #define OPENCV_ERROR(status,func,context) \
cvError((status),(func),(context),__FILE__,__LINE__) cvError((status),(func),(context),__FILE__,__LINE__)
#define OPENCV_ERRCHK(func,context) \ #define OPENCV_ERRCHK(func,context) \
{if (cvGetErrStatus() >= 0) \ {if (cvGetErrStatus() >= 0) \
{OPENCV_ERROR(CV_StsBackTrace,(func),(context));}} {OPENCV_ERROR(CV_StsBackTrace,(func),(context));}}
#define OPENCV_ASSERT(expr,func,context) \ #define OPENCV_ASSERT(expr,func,context) \
{if (! (expr)) \ {if (! (expr)) \
{OPENCV_ERROR(CV_StsInternal,(func),(context));}} {OPENCV_ERROR(CV_StsInternal,(func),(context));}}
#define OPENCV_RSTERR() (cvSetErrStatus(CV_StsOk)) #define OPENCV_RSTERR() (cvSetErrStatus(CV_StsOk))
#define OPENCV_CALL( Func ) \ #define OPENCV_CALL( Func ) \
{ \ { \
Func; \ Func; \
} }
/* CV_FUNCNAME macro defines icvFuncName constant which is used by CV_ERROR macro */ /* CV_FUNCNAME macro defines icvFuncName constant which is used by CV_ERROR macro */
#ifdef CV_NO_FUNC_NAMES #ifdef CV_NO_FUNC_NAMES
#define CV_FUNCNAME( Name ) #define CV_FUNCNAME( Name )
#define cvFuncName "" #define cvFuncName ""
#else #else
#define CV_FUNCNAME( Name ) \ #define CV_FUNCNAME( Name ) \
static char cvFuncName[] = Name static char cvFuncName[] = Name
#endif #endif
/* /*
CV_ERROR macro unconditionally raises error with passed code and message. CV_ERROR macro unconditionally raises error with passed code and message.
After raising error, control will be transferred to the exit label. After raising error, control will be transferred to the exit label.
@ -1814,11 +1814,11 @@ static char cvFuncName[] = Name
cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \ cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \
__CV_EXIT__; \ __CV_EXIT__; \
} }
/* Simplified form of CV_ERROR */ /* Simplified form of CV_ERROR */
#define CV_ERROR_FROM_CODE( code ) \ #define CV_ERROR_FROM_CODE( code ) \
CV_ERROR( code, "" ) CV_ERROR( code, "" )
/* /*
CV_CHECK macro checks error status after CV (or IPL) CV_CHECK macro checks error status after CV (or IPL)
function call. If error detected, control will be transferred to the exit function call. If error detected, control will be transferred to the exit
@ -1829,8 +1829,8 @@ static char cvFuncName[] = Name
if( cvGetErrStatus() < 0 ) \ if( cvGetErrStatus() < 0 ) \
CV_ERROR( CV_StsBackTrace, "Inner function failed." ); \ CV_ERROR( CV_StsBackTrace, "Inner function failed." ); \
} }
/* /*
CV_CALL macro calls CV (or IPL) function, checks error status and CV_CALL macro calls CV (or IPL) function, checks error status and
signals a error if the function failed. Useful in "parent node" signals a error if the function failed. Useful in "parent node"
@ -1841,19 +1841,19 @@ static char cvFuncName[] = Name
Func; \ Func; \
CV_CHECK(); \ CV_CHECK(); \
} }
/* Runtime assertion macro */ /* Runtime assertion macro */
#define CV_ASSERT( Condition ) \ #define CV_ASSERT( Condition ) \
{ \ { \
if( !(Condition) ) \ if( !(Condition) ) \
CV_ERROR( CV_StsInternal, "Assertion: " #Condition " failed" ); \ CV_ERROR( CV_StsInternal, "Assertion: " #Condition " failed" ); \
} }
#define __CV_BEGIN__ { #define __CV_BEGIN__ {
#define __CV_END__ goto exit; exit: ; } #define __CV_END__ goto exit; exit: ; }
#define __CV_EXIT__ goto exit #define __CV_EXIT__ goto exit
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -48,6 +48,11 @@
#include "opencv2/core/core_c.h" #include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
#if defined _MSC_VER && _MSC_VER >= 1200
#pragma warning( disable: 4714 ) //__forceinline is not inlined
#pragma warning( disable: 4127 ) //conditional expression is constant
#endif
namespace cv namespace cv
{ {

View File

@ -366,12 +366,12 @@ namespace cv { namespace gpu
return m; return m;
} }
inline void GpuMat::assignTo(GpuMat& m, int type) const inline void GpuMat::assignTo(GpuMat& m, int _type) const
{ {
if (type < 0) if (_type < 0)
m = *this; m = *this;
else else
convertTo(m, type); convertTo(m, _type);
} }
inline size_t GpuMat::step1() const inline size_t GpuMat::step1() const
@ -434,9 +434,9 @@ namespace cv { namespace gpu
create(size_.height, size_.width, type_); create(size_.height, size_.width, type_);
} }
inline GpuMat GpuMat::operator()(Range rowRange, Range colRange) const inline GpuMat GpuMat::operator()(Range _rowRange, Range _colRange) const
{ {
return GpuMat(*this, rowRange, colRange); return GpuMat(*this, _rowRange, _colRange);
} }
inline GpuMat GpuMat::operator()(Rect roi) const inline GpuMat GpuMat::operator()(Rect roi) const

View File

@ -60,34 +60,34 @@
#endif #endif
#if defined WIN32 || defined WINCE #if defined WIN32 || defined WINCE
#ifndef _WIN32_WINNT // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?) # ifndef _WIN32_WINNT // This is needed for the declaration of TryEnterCriticalSection in winbase.h with Visual Studio 2005 (and older?)
#define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx # define _WIN32_WINNT 0x0400 // http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
#endif # endif
#include <windows.h> # include <windows.h>
#undef small # undef small
#undef min # undef min
#undef max # undef max
#else #else
#include <pthread.h> # include <pthread.h>
#endif #endif
#ifdef __BORLANDC__ #ifdef __BORLANDC__
#ifndef WIN32 # ifndef WIN32
#define WIN32 # define WIN32
#endif # endif
#ifndef _WIN32 # ifndef _WIN32
#define _WIN32 # define _WIN32
#endif # endif
#define CV_DLL # define CV_DLL
#undef _CV_ALWAYS_PROFILE_ # undef _CV_ALWAYS_PROFILE_
#define _CV_ALWAYS_NO_PROFILE_ # define _CV_ALWAYS_NO_PROFILE_
#endif #endif
#ifndef FALSE #ifndef FALSE
#define FALSE 0 # define FALSE 0
#endif #endif
#ifndef TRUE #ifndef TRUE
#define TRUE 1 # define TRUE 1
#endif #endif
#define __BEGIN__ __CV_BEGIN__ #define __BEGIN__ __CV_BEGIN__
@ -95,7 +95,7 @@
#define EXIT __CV_EXIT__ #define EXIT __CV_EXIT__
#ifdef HAVE_IPP #ifdef HAVE_IPP
#include "ipp.h" # include "ipp.h"
CV_INLINE IppiSize ippiSize(int width, int height) CV_INLINE IppiSize ippiSize(int width, int height)
{ {
@ -104,137 +104,132 @@ CV_INLINE IppiSize ippiSize(int width, int height)
} }
#endif #endif
#if defined __SSE2__ || _MSC_VER >= 1300 #if defined __SSE2__ || (defined _MSC_VER && _MSC_VER >= 1300)
#include "emmintrin.h" # include "emmintrin.h"
#define CV_SSE 1 # define CV_SSE 1
#define CV_SSE2 1 # define CV_SSE2 1
#if defined __SSE3__ || _MSC_VER >= 1500 # if defined __SSE3__ || (defined _MSC_VER && _MSC_VER >= 1500)
#include "pmmintrin.h" # include "pmmintrin.h"
#define CV_SSE3 1 # define CV_SSE3 1
#endif # else
#if defined __SSSE3__ # define CV_SSE3 0
#include "tmmintrin.h" # endif
#define CV_SSSE3 1 # if defined __SSSE3__
#endif # include "tmmintrin.h"
# define CV_SSSE3 1
# else
# define CV_SSSE3 0
# endif
#else #else
#define CV_SSE 0 # define CV_SSE 0
#define CV_SSE2 0 # define CV_SSE2 0
#define CV_SSE3 0 # define CV_SSE3 0
#define CV_SSSE3 0 # define CV_SSSE3 0
#endif #endif
#if defined ANDROID && defined __ARM_NEON__ && defined __GNUC__ #if defined ANDROID && defined __ARM_NEON__
#include "arm_neon.h" # include "arm_neon.h"
#define CV_NEON 1 # define CV_NEON 1
#define CPU_HAS_NEON_FEATURE (true) # define CPU_HAS_NEON_FEATURE (true)
//TODO: make real check using stuff from "cpu-features.h" //TODO: make real check using stuff from "cpu-features.h"
//((bool)android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) //((bool)android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON)
#else #else
#define CV_NEON 0 # define CV_NEON 0
#define CPU_HAS_NEON_FEATURE (false) # define CPU_HAS_NEON_FEATURE (false)
#endif
#ifdef CV_ICC
#define CV_ENABLE_UNROLLED 0
#else
#define CV_ENABLE_UNROLLED 1
#endif #endif
#ifndef IPPI_CALL #ifndef IPPI_CALL
#define IPPI_CALL(func) CV_Assert((func) >= 0) # define IPPI_CALL(func) CV_Assert((func) >= 0)
#endif #endif
#ifdef HAVE_TBB #ifdef HAVE_TBB
#include "tbb/tbb_stddef.h" # include "tbb/tbb_stddef.h"
#if TBB_VERSION_MAJOR*100 + TBB_VERSION_MINOR >= 202 # if TBB_VERSION_MAJOR*100 + TBB_VERSION_MINOR >= 202
#include "tbb/tbb.h" # include "tbb/tbb.h"
#include "tbb/task.h" # include "tbb/task.h"
#undef min # undef min
#undef max # undef max
#else # else
#undef HAVE_TBB # undef HAVE_TBB
#endif # endif
#endif #endif
#ifdef HAVE_EIGEN #ifdef HAVE_EIGEN
#include <Eigen/Core> # include <Eigen/Core>
#include "opencv2/core/eigen.hpp" # include "opencv2/core/eigen.hpp"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
namespace cv
{
#ifdef HAVE_TBB #ifdef HAVE_TBB
namespace cv
{
typedef tbb::blocked_range<int> BlockedRange;
template<typename Body> static inline
void parallel_for( const BlockedRange& range, const Body& body )
{
tbb::parallel_for(range, body);
}
template<typename Iterator, typename Body> static inline
void parallel_do( Iterator first, Iterator last, const Body& body )
{
tbb::parallel_do(first, last, body);
}
typedef tbb::split Split;
template<typename Body> static inline
void parallel_reduce( const BlockedRange& range, Body& body )
{
tbb::parallel_reduce(range, body);
}
typedef tbb::concurrent_vector<Rect> ConcurrentRectVector;
typedef tbb::concurrent_vector<double> ConcurrentDoubleVector;
}
#else
namespace cv
{
class BlockedRange
{
public:
BlockedRange() : _begin(0), _end(0), _grainsize(0) {}
BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {}
int begin() const { return _begin; }
int end() const { return _end; }
int grainsize() const { return _grainsize; }
protected:
int _begin, _end, _grainsize;
};
template<typename Body> static inline typedef tbb::blocked_range<int> BlockedRange;
void parallel_for( const BlockedRange& range, const Body& body )
{ template<typename Body> static inline
body(range); void parallel_for( const BlockedRange& range, const Body& body )
} {
typedef std::vector<Rect> ConcurrentRectVector; tbb::parallel_for(range, body);
typedef std::vector<double> ConcurrentDoubleVector; }
template<typename Iterator, typename Body> static inline template<typename Iterator, typename Body> static inline
void parallel_do( Iterator first, Iterator last, const Body& body ) void parallel_do( Iterator first, Iterator last, const Body& body )
{ {
for( ; first != last; ++first ) tbb::parallel_do(first, last, body);
body(*first); }
}
typedef tbb::split Split;
class Split {};
template<typename Body> static inline
template<typename Body> static inline void parallel_reduce( const BlockedRange& range, Body& body )
void parallel_reduce( const BlockedRange& range, Body& body ) {
{ tbb::parallel_reduce(range, body);
body(range); }
}
typedef tbb::concurrent_vector<Rect> ConcurrentRectVector;
typedef tbb::concurrent_vector<double> ConcurrentDoubleVector;
#else
class BlockedRange
{
public:
BlockedRange() : _begin(0), _end(0), _grainsize(0) {}
BlockedRange(int b, int e, int g=1) : _begin(b), _end(e), _grainsize(g) {}
int begin() const { return _begin; }
int end() const { return _end; }
int grainsize() const { return _grainsize; }
protected:
int _begin, _end, _grainsize;
};
template<typename Body> static inline
void parallel_for( const BlockedRange& range, const Body& body )
{
body(range);
}
typedef std::vector<Rect> ConcurrentRectVector;
typedef std::vector<double> ConcurrentDoubleVector;
template<typename Iterator, typename Body> static inline
void parallel_do( Iterator first, Iterator last, const Body& body )
{
for( ; first != last; ++first )
body(*first);
}
class Split {};
template<typename Body> static inline
void parallel_reduce( const BlockedRange& range, Body& body )
{
body(range);
} }
#endif #endif
} //namespace cv
#define CV_INIT_ALGORITHM(classname, algname, memberinit) \ #define CV_INIT_ALGORITHM(classname, algname, memberinit) \
static Algorithm* create##classname() \ static Algorithm* create##classname() \
{ \ { \
return new classname; \ return new classname; \
@ -261,7 +256,7 @@ CV_INLINE IppiSize ippiSize(int width, int height)
return &classname##_info(); \ return &classname##_info(); \
} }
#endif #endif //__cplusplus
/* maximal size of vector to run matrix operations on it inline (i.e. w/o ipp calls) */ /* maximal size of vector to run matrix operations on it inline (i.e. w/o ipp calls) */
#define CV_MAX_INLINE_MAT_OP_SIZE 10 #define CV_MAX_INLINE_MAT_OP_SIZE 10
@ -305,9 +300,9 @@ CV_INLINE IppiSize ippiSize(int width, int height)
#define CV_MAX_STRLEN 1024 #define CV_MAX_STRLEN 1024
#if 0 /*def CV_CHECK_FOR_NANS*/ #if 0 /*def CV_CHECK_FOR_NANS*/
#define CV_CHECK_NANS( arr ) cvCheckArray((arr)) # define CV_CHECK_NANS( arr ) cvCheckArray((arr))
#else #else
#define CV_CHECK_NANS( arr ) # define CV_CHECK_NANS( arr )
#endif #endif
/****************************************************************************************\ /****************************************************************************************\
@ -316,38 +311,38 @@ CV_INLINE IppiSize ippiSize(int width, int height)
/* get alloca declaration */ /* get alloca declaration */
#ifdef __GNUC__ #ifdef __GNUC__
#undef alloca # undef alloca
#define alloca __builtin_alloca # define alloca __builtin_alloca
#define CV_HAVE_ALLOCA 1 # define CV_HAVE_ALLOCA 1
#elif defined WIN32 || defined _WIN32 || \ #elif defined WIN32 || defined _WIN32 || \
defined WINCE || defined _MSC_VER || defined __BORLANDC__ defined WINCE || defined _MSC_VER || defined __BORLANDC__
#include <malloc.h> # include <malloc.h>
#define CV_HAVE_ALLOCA 1 # define CV_HAVE_ALLOCA 1
#elif defined HAVE_ALLOCA_H #elif defined HAVE_ALLOCA_H
#include <alloca.h> # include <alloca.h>
#define CV_HAVE_ALLOCA 1 # define CV_HAVE_ALLOCA 1
#elif defined HAVE_ALLOCA #elif defined HAVE_ALLOCA
#include <stdlib.h> # include <stdlib.h>
#define CV_HAVE_ALLOCA 1 # define CV_HAVE_ALLOCA 1
#else #else
#undef CV_HAVE_ALLOCA # undef CV_HAVE_ALLOCA
#endif #endif
#ifdef __GNUC__ #ifdef __GNUC__
#define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x))) # define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x)))
#elif defined _MSC_VER #elif defined _MSC_VER
#define CV_DECL_ALIGNED(x) __declspec(align(x)) # define CV_DECL_ALIGNED(x) __declspec(align(x))
#else #else
#define CV_DECL_ALIGNED(x) # define CV_DECL_ALIGNED(x)
#endif #endif
#if CV_HAVE_ALLOCA #if CV_HAVE_ALLOCA
/* ! DO NOT make it an inline function */ /* ! DO NOT make it an inline function */
#define cvStackAlloc(size) cvAlignPtr( alloca((size) + CV_MALLOC_ALIGN), CV_MALLOC_ALIGN ) # define cvStackAlloc(size) cvAlignPtr( alloca((size) + CV_MALLOC_ALIGN), CV_MALLOC_ALIGN )
#endif #endif
#ifndef CV_IMPL #ifndef CV_IMPL
#define CV_IMPL CV_EXTERN_C # define CV_IMPL CV_EXTERN_C
#endif #endif
#define CV_DBG_BREAK() { volatile int* crashMe = 0; *crashMe = 0; } #define CV_DBG_BREAK() { volatile int* crashMe = 0; *crashMe = 0; }
@ -687,25 +682,25 @@ typedef enum CvStatus
CV_UNSUPPORTED_DEPTH_ERR = -101, CV_UNSUPPORTED_DEPTH_ERR = -101,
CV_UNSUPPORTED_FORMAT_ERR = -100, CV_UNSUPPORTED_FORMAT_ERR = -100,
CV_BADARG_ERR = -49, //ipp comp CV_BADARG_ERR = -49, //ipp comp
CV_NOTDEFINED_ERR = -48, //ipp comp CV_NOTDEFINED_ERR = -48, //ipp comp
CV_BADCHANNELS_ERR = -47, //ipp comp CV_BADCHANNELS_ERR = -47, //ipp comp
CV_BADRANGE_ERR = -44, //ipp comp CV_BADRANGE_ERR = -44, //ipp comp
CV_BADSTEP_ERR = -29, //ipp comp CV_BADSTEP_ERR = -29, //ipp comp
CV_BADFLAG_ERR = -12, CV_BADFLAG_ERR = -12,
CV_DIV_BY_ZERO_ERR = -11, //ipp comp CV_DIV_BY_ZERO_ERR = -11, //ipp comp
CV_BADCOEF_ERR = -10, CV_BADCOEF_ERR = -10,
CV_BADFACTOR_ERR = -7, CV_BADFACTOR_ERR = -7,
CV_BADPOINT_ERR = -6, CV_BADPOINT_ERR = -6,
CV_BADSCALE_ERR = -4, CV_BADSCALE_ERR = -4,
CV_OUTOFMEM_ERR = -3, CV_OUTOFMEM_ERR = -3,
CV_NULLPTR_ERR = -2, CV_NULLPTR_ERR = -2,
CV_BADSIZE_ERR = -1, CV_BADSIZE_ERR = -1,
CV_NO_ERR = 0, CV_NO_ERR = 0,
CV_OK = CV_NO_ERR CV_OK = CV_NO_ERR
} }
CvStatus; CvStatus;
@ -720,8 +715,7 @@ CvFuncTable;
typedef struct CvBigFuncTable typedef struct CvBigFuncTable
{ {
void* fn_2d[CV_DEPTH_MAX*4]; void* fn_2d[CV_DEPTH_MAX*4];
} } CvBigFuncTable;
CvBigFuncTable;
#define CV_INIT_FUNC_TAB( tab, FUNCNAME, FLAG ) \ #define CV_INIT_FUNC_TAB( tab, FUNCNAME, FLAG ) \
(tab).fn_2d[CV_8U] = (void*)FUNCNAME##_8u##FLAG; \ (tab).fn_2d[CV_8U] = (void*)FUNCNAME##_8u##FLAG; \
@ -732,13 +726,14 @@ CvBigFuncTable;
(tab).fn_2d[CV_32F] = (void*)FUNCNAME##_32f##FLAG; \ (tab).fn_2d[CV_32F] = (void*)FUNCNAME##_32f##FLAG; \
(tab).fn_2d[CV_64F] = (void*)FUNCNAME##_64f##FLAG (tab).fn_2d[CV_64F] = (void*)FUNCNAME##_64f##FLAG
#ifdef __cplusplus
//! OpenGL extension table //! OpenGL extension table
class CV_EXPORTS CvOpenGlFuncTab class CV_EXPORTS CvOpenGlFuncTab
{ {
public: public:
virtual ~CvOpenGlFuncTab(); virtual ~CvOpenGlFuncTab();
virtual void genBuffers(int n, unsigned int* buffers) const = 0; virtual void genBuffers(int n, unsigned int* buffers) const = 0;
virtual void deleteBuffers(int n, const unsigned int* buffers) const = 0; virtual void deleteBuffers(int n, const unsigned int* buffers) const = 0;
virtual void bufferData(unsigned int target, ptrdiff_t size, const void* data, unsigned int usage) const = 0; virtual void bufferData(unsigned int target, ptrdiff_t size, const void* data, unsigned int usage) const = 0;
@ -764,4 +759,6 @@ CV_EXPORTS bool icvCheckGlError(const char* file, const int line, const char* fu
#define CV_CheckGlError() CV_DbgAssert( (::icvCheckGlError(__FILE__, __LINE__)) ) #define CV_CheckGlError() CV_DbgAssert( (::icvCheckGlError(__FILE__, __LINE__)) )
#endif #endif
#endif #endif //__cplusplus
#endif // __OPENCV_CORE_INTERNAL_HPP__

File diff suppressed because it is too large Load Diff

View File

@ -47,282 +47,287 @@
#include "opencv2/core/core.hpp" #include "opencv2/core/core.hpp"
namespace cv namespace cv
{ {
//! Smart pointer for OpenGL buffer memory with reference counting. //! Smart pointer for OpenGL buffer memory with reference counting.
class CV_EXPORTS GlBuffer class CV_EXPORTS GlBuffer
{
public:
enum Usage
{ {
public: ARRAY_BUFFER = 0x8892, // buffer will use for OpenGL arrays (vertices, colors, normals, etc)
enum Usage TEXTURE_BUFFER = 0x88EC // buffer will ise for OpenGL textures
{
ARRAY_BUFFER = 0x8892, // buffer will use for OpenGL arrays (vertices, colors, normals, etc)
TEXTURE_BUFFER = 0x88EC // buffer will ise for OpenGL textures
};
//! create empty buffer
explicit GlBuffer(Usage usage);
//! create buffer
GlBuffer(int rows, int cols, int type, Usage usage);
GlBuffer(Size size, int type, Usage usage);
//! copy from host/device memory
GlBuffer(InputArray mat, Usage usage);
void create(int rows, int cols, int type, Usage usage);
inline void create(Size size, int type, Usage usage) { create(size.height, size.width, type, usage); }
inline void create(int rows, int cols, int type) { create(rows, cols, type, usage()); }
inline void create(Size size, int type) { create(size.height, size.width, type, usage()); }
void release();
//! copy from host/device memory
void copyFrom(InputArray mat);
void bind() const;
void unbind() const;
//! map to host memory
Mat mapHost();
void unmapHost();
//! map to device memory
gpu::GpuMat mapDevice();
void unmapDevice();
inline int rows() const { return rows_; }
inline int cols() const { return cols_; }
inline Size size() const { return Size(cols_, rows_); }
inline bool empty() const { return rows_ == 0 || cols_ == 0; }
inline int type() const { return type_; }
inline int depth() const { return CV_MAT_DEPTH(type_); }
inline int channels() const { return CV_MAT_CN(type_); }
inline int elemSize() const { return CV_ELEM_SIZE(type_); }
inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }
inline Usage usage() const { return usage_; }
class Impl;
private:
int rows_;
int cols_;
int type_;
Usage usage_;
Ptr<Impl> impl_;
}; };
template <> CV_EXPORTS void Ptr<GlBuffer::Impl>::delete_obj(); //! create empty buffer
explicit GlBuffer(Usage usage);
//! Smart pointer for OpenGL 2d texture memory with reference counting. //! create buffer
class CV_EXPORTS GlTexture GlBuffer(int rows, int cols, int type, Usage usage);
GlBuffer(Size size, int type, Usage usage);
//! copy from host/device memory
GlBuffer(InputArray mat, Usage usage);
void create(int rows, int cols, int type, Usage usage);
void create(Size size, int type, Usage usage);
void create(int rows, int cols, int type);
void create(Size size, int type);
void release();
//! copy from host/device memory
void copyFrom(InputArray mat);
void bind() const;
void unbind() const;
//! map to host memory
Mat mapHost();
void unmapHost();
//! map to device memory
gpu::GpuMat mapDevice();
void unmapDevice();
inline int rows() const { return rows_; }
inline int cols() const { return cols_; }
inline Size size() const { return Size(cols_, rows_); }
inline bool empty() const { return rows_ == 0 || cols_ == 0; }
inline int type() const { return type_; }
inline int depth() const { return CV_MAT_DEPTH(type_); }
inline int channels() const { return CV_MAT_CN(type_); }
inline int elemSize() const { return CV_ELEM_SIZE(type_); }
inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }
inline Usage usage() const { return usage_; }
class Impl;
private:
int rows_;
int cols_;
int type_;
Usage usage_;
Ptr<Impl> impl_;
};
template <> CV_EXPORTS void Ptr<GlBuffer::Impl>::delete_obj();
//! Smart pointer for OpenGL 2d texture memory with reference counting.
class CV_EXPORTS GlTexture
{
public:
//! create empty texture
GlTexture();
//! create texture
GlTexture(int rows, int cols, int type);
GlTexture(Size size, int type);
//! copy from host/device memory
explicit GlTexture(InputArray mat, bool bgra = true);
void create(int rows, int cols, int type);
void create(Size size, int type);
void release();
//! copy from host/device memory
void copyFrom(InputArray mat, bool bgra = true);
void bind() const;
void unbind() const;
inline int rows() const { return rows_; }
inline int cols() const { return cols_; }
inline Size size() const { return Size(cols_, rows_); }
inline bool empty() const { return rows_ == 0 || cols_ == 0; }
inline int type() const { return type_; }
inline int depth() const { return CV_MAT_DEPTH(type_); }
inline int channels() const { return CV_MAT_CN(type_); }
inline int elemSize() const { return CV_ELEM_SIZE(type_); }
inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }
class Impl;
private:
int rows_;
int cols_;
int type_;
Ptr<Impl> impl_;
GlBuffer buf_;
};
template <> CV_EXPORTS void Ptr<GlTexture::Impl>::delete_obj();
//! OpenGL Arrays
class CV_EXPORTS GlArrays
{
public:
inline GlArrays()
: vertex_(GlBuffer::ARRAY_BUFFER), color_(GlBuffer::ARRAY_BUFFER), bgra_(true), normal_(GlBuffer::ARRAY_BUFFER), texCoord_(GlBuffer::ARRAY_BUFFER)
{ {
public:
//! create empty texture
GlTexture();
//! create texture
GlTexture(int rows, int cols, int type);
GlTexture(Size size, int type);
//! copy from host/device memory
explicit GlTexture(InputArray mat, bool bgra = true);
void create(int rows, int cols, int type);
inline void create(Size size, int type) { create(size.height, size.width, type); }
void release();
//! copy from host/device memory
void copyFrom(InputArray mat, bool bgra = true);
void bind() const;
void unbind() const;
inline int rows() const { return rows_; }
inline int cols() const { return cols_; }
inline Size size() const { return Size(cols_, rows_); }
inline bool empty() const { return rows_ == 0 || cols_ == 0; }
inline int type() const { return type_; }
inline int depth() const { return CV_MAT_DEPTH(type_); }
inline int channels() const { return CV_MAT_CN(type_); }
inline int elemSize() const { return CV_ELEM_SIZE(type_); }
inline int elemSize1() const { return CV_ELEM_SIZE1(type_); }
class Impl;
private:
int rows_;
int cols_;
int type_;
Ptr<Impl> impl_;
GlBuffer buf_;
};
template <> CV_EXPORTS void Ptr<GlTexture::Impl>::delete_obj();
//! OpenGL Arrays
class CV_EXPORTS GlArrays
{
public:
inline GlArrays()
: vertex_(GlBuffer::ARRAY_BUFFER), color_(GlBuffer::ARRAY_BUFFER), bgra_(true), normal_(GlBuffer::ARRAY_BUFFER), texCoord_(GlBuffer::ARRAY_BUFFER)
{
}
void setVertexArray(InputArray vertex);
inline void resetVertexArray() { vertex_.release(); }
void setColorArray(InputArray color, bool bgra = true);
inline void resetColorArray() { color_.release(); }
void setNormalArray(InputArray normal);
inline void resetNormalArray() { normal_.release(); }
void setTexCoordArray(InputArray texCoord);
inline void resetTexCoordArray() { texCoord_.release(); }
void bind() const;
void unbind() const;
inline int rows() const { return vertex_.rows(); }
inline int cols() const { return vertex_.cols(); }
inline Size size() const { return vertex_.size(); }
inline bool empty() const { return vertex_.empty(); }
private:
GlBuffer vertex_;
GlBuffer color_;
bool bgra_;
GlBuffer normal_;
GlBuffer texCoord_;
};
//! OpenGL Font
class CV_EXPORTS GlFont
{
public:
enum Weight
{
WEIGHT_LIGHT = 300,
WEIGHT_NORMAL = 400,
WEIGHT_SEMIBOLD = 600,
WEIGHT_BOLD = 700,
WEIGHT_BLACK = 900
};
enum Style
{
STYLE_NORMAL = 0,
STYLE_ITALIC = 1,
STYLE_UNDERLINE = 2
};
static Ptr<GlFont> get(const std::string& family, int height = 12, Weight weight = WEIGHT_NORMAL, Style style = STYLE_NORMAL);
void draw(const char* str, int len) const;
inline const std::string& family() const { return family_; }
inline int height() const { return height_; }
inline Weight weight() const { return weight_; }
inline Style style() const { return style_; }
private:
GlFont(const std::string& family, int height, Weight weight, Style style);
std::string family_;
int height_;
Weight weight_;
Style style_;
unsigned int base_;
GlFont(const GlFont&);
GlFont& operator =(const GlFont&);
};
//! render functions
//! render texture rectangle in window
CV_EXPORTS void render(const GlTexture& tex,
Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0),
Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0));
//! render mode
namespace RenderMode {
enum {
POINTS = 0x0000,
LINES = 0x0001,
LINE_LOOP = 0x0002,
LINE_STRIP = 0x0003,
TRIANGLES = 0x0004,
TRIANGLE_STRIP = 0x0005,
TRIANGLE_FAN = 0x0006,
QUADS = 0x0007,
QUAD_STRIP = 0x0008,
POLYGON = 0x0009
};
} }
//! render OpenGL arrays void setVertexArray(InputArray vertex);
CV_EXPORTS void render(const GlArrays& arr, int mode = RenderMode::POINTS, Scalar color = Scalar::all(255)); inline void resetVertexArray() { vertex_.release(); }
CV_EXPORTS void render(const std::string& str, const Ptr<GlFont>& font, Scalar color, Point2d pos); void setColorArray(InputArray color, bool bgra = true);
inline void resetColorArray() { color_.release(); }
//! OpenGL camera void setNormalArray(InputArray normal);
class CV_EXPORTS GlCamera inline void resetNormalArray() { normal_.release(); }
void setTexCoordArray(InputArray texCoord);
inline void resetTexCoordArray() { texCoord_.release(); }
void bind() const;
void unbind() const;
inline int rows() const { return vertex_.rows(); }
inline int cols() const { return vertex_.cols(); }
inline Size size() const { return vertex_.size(); }
inline bool empty() const { return vertex_.empty(); }
private:
GlBuffer vertex_;
GlBuffer color_;
bool bgra_;
GlBuffer normal_;
GlBuffer texCoord_;
};
//! OpenGL Font
class CV_EXPORTS GlFont
{
public:
enum Weight
{ {
public: WEIGHT_LIGHT = 300,
GlCamera(); WEIGHT_NORMAL = 400,
WEIGHT_SEMIBOLD = 600,
void lookAt(Point3d eye, Point3d center, Point3d up); WEIGHT_BOLD = 700,
void setCameraPos(Point3d pos, double yaw, double pitch, double roll); WEIGHT_BLACK = 900
void setScale(Point3d scale);
void setProjectionMatrix(const Mat& projectionMatrix, bool transpose = true);
void setPerspectiveProjection(double fov, double aspect, double zNear, double zFar);
void setOrthoProjection(double left, double right, double bottom, double top, double zNear, double zFar);
void setupProjectionMatrix() const;
void setupModelViewMatrix() const;
private:
Point3d eye_;
Point3d center_;
Point3d up_;
Point3d pos_;
double yaw_;
double pitch_;
double roll_;
bool useLookAtParams_;
Point3d scale_;
Mat projectionMatrix_;
double fov_;
double aspect_;
double left_;
double right_;
double bottom_;
double top_;
double zNear_;
double zFar_;
bool perspectiveProjection_;
}; };
namespace gpu enum Style
{ {
//! set a CUDA device to use OpenGL interoperability STYLE_NORMAL = 0,
CV_EXPORTS void setGlDevice(int device = 0); STYLE_ITALIC = 1,
} STYLE_UNDERLINE = 2
};
static Ptr<GlFont> get(const std::string& family, int height = 12, Weight weight = WEIGHT_NORMAL, Style style = STYLE_NORMAL);
void draw(const char* str, int len) const;
inline const std::string& family() const { return family_; }
inline int height() const { return height_; }
inline Weight weight() const { return weight_; }
inline Style style() const { return style_; }
private:
GlFont(const std::string& family, int height, Weight weight, Style style);
std::string family_;
int height_;
Weight weight_;
Style style_;
unsigned int base_;
GlFont(const GlFont&);
GlFont& operator =(const GlFont&);
};
//! render functions
//! render texture rectangle in window
CV_EXPORTS void render(const GlTexture& tex,
Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0),
Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0));
//! render mode
namespace RenderMode {
enum {
POINTS = 0x0000,
LINES = 0x0001,
LINE_LOOP = 0x0002,
LINE_STRIP = 0x0003,
TRIANGLES = 0x0004,
TRIANGLE_STRIP = 0x0005,
TRIANGLE_FAN = 0x0006,
QUADS = 0x0007,
QUAD_STRIP = 0x0008,
POLYGON = 0x0009
};
}
//! render OpenGL arrays
CV_EXPORTS void render(const GlArrays& arr, int mode = RenderMode::POINTS, Scalar color = Scalar::all(255));
CV_EXPORTS void render(const std::string& str, const Ptr<GlFont>& font, Scalar color, Point2d pos);
//! OpenGL camera
class CV_EXPORTS GlCamera
{
public:
GlCamera();
void lookAt(Point3d eye, Point3d center, Point3d up);
void setCameraPos(Point3d pos, double yaw, double pitch, double roll);
void setScale(Point3d scale);
void setProjectionMatrix(const Mat& projectionMatrix, bool transpose = true);
void setPerspectiveProjection(double fov, double aspect, double zNear, double zFar);
void setOrthoProjection(double left, double right, double bottom, double top, double zNear, double zFar);
void setupProjectionMatrix() const;
void setupModelViewMatrix() const;
private:
Point3d eye_;
Point3d center_;
Point3d up_;
Point3d pos_;
double yaw_;
double pitch_;
double roll_;
bool useLookAtParams_;
Point3d scale_;
Mat projectionMatrix_;
double fov_;
double aspect_;
double left_;
double right_;
double bottom_;
double top_;
double zNear_;
double zFar_;
bool perspectiveProjection_;
};
inline void GlBuffer::create(Size _size, int _type, Usage _usage) { create(_size.height, _size.width, _type, _usage); }
inline void GlBuffer::create(int _rows, int _cols, int _type) { create(_rows, _cols, _type, usage()); }
inline void GlBuffer::create(Size _size, int _type) { create(_size.height, _size.width, _type, usage()); }
inline void GlTexture::create(Size _size, int _type) { create(_size.height, _size.width, _type); }
namespace gpu
{
//! set a CUDA device to use OpenGL interoperability
CV_EXPORTS void setGlDevice(int device = 0);
}
} // namespace cv } // namespace cv
#endif // __cplusplus #endif // __cplusplus

File diff suppressed because it is too large Load Diff

View File

@ -43,122 +43,132 @@
#ifndef __OPENCV_CORE_TYPES_H__ #ifndef __OPENCV_CORE_TYPES_H__
#define __OPENCV_CORE_TYPES_H__ #define __OPENCV_CORE_TYPES_H__
#if !defined _CRT_SECURE_NO_DEPRECATE && _MSC_VER > 1300 #if !defined _CRT_SECURE_NO_DEPRECATE && defined _MSC_VER
#define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio 2005 warnings */ # if _MSC_VER > 1300
# define _CRT_SECURE_NO_DEPRECATE /* to avoid multiple Visual Studio 2005 warnings */
# endif
#endif #endif
#ifndef SKIP_INCLUDES #ifndef SKIP_INCLUDES
#include <assert.h>
#include <stdlib.h> #include <assert.h>
#include <string.h> #include <stdlib.h>
#include <float.h> #include <string.h>
#include <float.h>
#if !defined _MSC_VER && !defined __BORLANDC__ #if !defined _MSC_VER && !defined __BORLANDC__
#include <stdint.h> # include <stdint.h>
#endif #endif
#if defined __ICL #if defined __ICL
#define CV_ICC __ICL # define CV_ICC __ICL
#elif defined __ICC #elif defined __ICC
#define CV_ICC __ICC # define CV_ICC __ICC
#elif defined __ECL #elif defined __ECL
#define CV_ICC __ECL # define CV_ICC __ECL
#elif defined __ECC #elif defined __ECC
#define CV_ICC __ECC # define CV_ICC __ECC
#elif defined __INTEL_COMPILER #elif defined __INTEL_COMPILER
#define CV_ICC __INTEL_COMPILER # define CV_ICC __INTEL_COMPILER
#endif #endif
#if (_MSC_VER >= 1400 && defined _M_X64) || (__GNUC__ >= 4 && defined __x86_64__) #if defined CV_ICC && !defined CV_ENABLE_UNROLLED
#if defined WIN32 # define CV_ENABLE_UNROLLED 0
#include <intrin.h> #else
#endif # define CV_ENABLE_UNROLLED 1
#if __SSE2__ || !defined __GNUC__ #endif
#include <emmintrin.h>
#endif
#endif
#if defined __BORLANDC__ #if (defined _M_X64 && defined _MSC_VER && _MSC_VER >= 1400) || (__GNUC__ >= 4 && defined __x86_64__)
#include <fastmath.h> # if defined WIN32
#else # include <intrin.h>
#include <math.h> # endif
#endif # if __SSE2__ || !defined __GNUC__
# include <emmintrin.h>
# endif
#endif
#if defined __BORLANDC__
# include <fastmath.h>
#else
# include <math.h>
#endif
#ifdef HAVE_IPL
# ifndef __IPL_H__
# if defined WIN32 || defined _WIN32
# include <ipl.h>
# else
# include <ipl/ipl.h>
# endif
# endif
#elif defined __IPL_H__
# define HAVE_IPL
#endif
#ifdef HAVE_IPL
#ifndef __IPL_H__
#if defined WIN32 || defined _WIN32
#include <ipl.h>
#else
#include <ipl/ipl.h>
#endif
#endif
#elif defined __IPL_H__
#define HAVE_IPL
#endif
#endif // SKIP_INCLUDES #endif // SKIP_INCLUDES
#if defined WIN32 || defined _WIN32 #if defined WIN32 || defined _WIN32
#define CV_CDECL __cdecl # define CV_CDECL __cdecl
#define CV_STDCALL __stdcall # define CV_STDCALL __stdcall
#else #else
#define CV_CDECL # define CV_CDECL
#define CV_STDCALL # define CV_STDCALL
#endif #endif
#ifndef CV_EXTERN_C #ifndef CV_EXTERN_C
#ifdef __cplusplus # ifdef __cplusplus
#define CV_EXTERN_C extern "C" # define CV_EXTERN_C extern "C"
#define CV_DEFAULT(val) = val # define CV_DEFAULT(val) = val
#else # else
#define CV_EXTERN_C # define CV_EXTERN_C
#define CV_DEFAULT(val) # define CV_DEFAULT(val)
#endif # endif
#endif #endif
#ifndef CV_EXTERN_C_FUNCPTR #ifndef CV_EXTERN_C_FUNCPTR
#ifdef __cplusplus # ifdef __cplusplus
#define CV_EXTERN_C_FUNCPTR(x) extern "C" { typedef x; } # define CV_EXTERN_C_FUNCPTR(x) extern "C" { typedef x; }
#else # else
#define CV_EXTERN_C_FUNCPTR(x) typedef x # define CV_EXTERN_C_FUNCPTR(x) typedef x
#endif # endif
#endif #endif
#ifndef CV_INLINE #ifndef CV_INLINE
#if defined __cplusplus # if defined __cplusplus
#define CV_INLINE inline # define CV_INLINE inline
#elif (defined WIN32 || defined _WIN32 || defined WINCE) && !defined __GNUC__ # elif (defined WIN32 || defined _WIN32 || defined WINCE) && !defined __GNUC__
#define CV_INLINE __inline # define CV_INLINE __inline
#else # else
#define CV_INLINE static # define CV_INLINE static
#endif # endif
#endif /* CV_INLINE */ #endif /* CV_INLINE */
#if (defined WIN32 || defined _WIN32 || defined WINCE) && defined CVAPI_EXPORTS #if (defined WIN32 || defined _WIN32 || defined WINCE) && defined CVAPI_EXPORTS
#define CV_EXPORTS __declspec(dllexport) # define CV_EXPORTS __declspec(dllexport)
#else #else
#define CV_EXPORTS # define CV_EXPORTS
#endif #endif
#ifndef CVAPI #ifndef CVAPI
#define CVAPI(rettype) CV_EXTERN_C CV_EXPORTS rettype CV_CDECL # define CVAPI(rettype) CV_EXTERN_C CV_EXPORTS rettype CV_CDECL
#endif #endif
#if defined _MSC_VER || defined __BORLANDC__ #if defined _MSC_VER || defined __BORLANDC__
typedef __int64 int64; typedef __int64 int64;
typedef unsigned __int64 uint64; typedef unsigned __int64 uint64;
#define CV_BIG_INT(n) n##I64 # define CV_BIG_INT(n) n##I64
#define CV_BIG_UINT(n) n##UI64 # define CV_BIG_UINT(n) n##UI64
#else #else
typedef int64_t int64; typedef int64_t int64;
typedef uint64_t uint64; typedef uint64_t uint64;
#define CV_BIG_INT(n) n##LL # define CV_BIG_INT(n) n##LL
#define CV_BIG_UINT(n) n##ULL # define CV_BIG_UINT(n) n##ULL
#endif #endif
#ifndef HAVE_IPL #ifndef HAVE_IPL
typedef unsigned char uchar; typedef unsigned char uchar;
typedef unsigned short ushort; typedef unsigned short ushort;
#endif #endif
typedef signed char schar; typedef signed char schar;
@ -203,7 +213,7 @@ Cv64suf;
typedef int CVStatus; typedef int CVStatus;
enum { enum {
CV_StsOk= 0, /* everithing is ok */ CV_StsOk= 0, /* everithing is ok */
CV_StsBackTrace= -1, /* pseudo error for back trace */ CV_StsBackTrace= -1, /* pseudo error for back trace */
CV_StsError= -2, /* unknown /unspecified error */ CV_StsError= -2, /* unknown /unspecified error */
@ -241,8 +251,8 @@ enum {
CV_StsInplaceNotSupported= -203, /* in-place operation is not supported */ CV_StsInplaceNotSupported= -203, /* in-place operation is not supported */
CV_StsObjectNotFound= -204, /* request can't be completed */ CV_StsObjectNotFound= -204, /* request can't be completed */
CV_StsUnmatchedFormats= -205, /* formats of input/output arrays differ */ CV_StsUnmatchedFormats= -205, /* formats of input/output arrays differ */
CV_StsBadFlag= -206, /* flag is wrong or not supported */ CV_StsBadFlag= -206, /* flag is wrong or not supported */
CV_StsBadPoint= -207, /* bad CvPoint */ CV_StsBadPoint= -207, /* bad CvPoint */
CV_StsBadMask= -208, /* bad format of mask (neither 8uC1 nor 8sC1)*/ CV_StsBadMask= -208, /* bad format of mask (neither 8uC1 nor 8sC1)*/
CV_StsUnmatchedSizes= -209, /* sizes of input/output structures do not match */ CV_StsUnmatchedSizes= -209, /* sizes of input/output structures do not match */
CV_StsUnsupportedFormat= -210, /* the data format/type is not supported by the function*/ CV_StsUnsupportedFormat= -210, /* the data format/type is not supported by the function*/
@ -250,8 +260,8 @@ enum {
CV_StsParseError= -212, /* invalid syntax/structure of the parsed file */ CV_StsParseError= -212, /* invalid syntax/structure of the parsed file */
CV_StsNotImplemented= -213, /* the requested function/feature is not implemented */ CV_StsNotImplemented= -213, /* the requested function/feature is not implemented */
CV_StsBadMemBlock= -214, /* an allocated block has been corrupted */ CV_StsBadMemBlock= -214, /* an allocated block has been corrupted */
CV_StsAssert= -215, /* assertion failed */ CV_StsAssert= -215, /* assertion failed */
CV_GpuNotSupported= -216, CV_GpuNotSupported= -216,
CV_GpuApiCallError= -217, CV_GpuApiCallError= -217,
CV_OpenGlNotSupported= -218, CV_OpenGlNotSupported= -218,
CV_OpenGlApiCallError= -219 CV_OpenGlApiCallError= -219
@ -262,7 +272,7 @@ enum {
\****************************************************************************************/ \****************************************************************************************/
#ifdef HAVE_TEGRA_OPTIMIZATION #ifdef HAVE_TEGRA_OPTIMIZATION
# include "tegra_round.hpp" # include "tegra_round.hpp"
#endif #endif
#define CV_PI 3.1415926535897932384626433832795 #define CV_PI 3.1415926535897932384626433832795
@ -271,11 +281,11 @@ enum {
#define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t)) #define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t))
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a) > (b) ? (b) : (a)) # define MIN(a,b) ((a) > (b) ? (b) : (a))
#endif #endif
#ifndef MAX #ifndef MAX
#define MAX(a,b) ((a) < (b) ? (b) : (a)) # define MAX(a,b) ((a) < (b) ? (b) : (a))
#endif #endif
/* min & max without jumps */ /* min & max without jumps */
@ -285,9 +295,9 @@ enum {
/* absolute value without jumps */ /* absolute value without jumps */
#ifndef __cplusplus #ifndef __cplusplus
#define CV_IABS(a) (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0)) # define CV_IABS(a) (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0))
#else #else
#define CV_IABS(a) abs(a) # define CV_IABS(a) abs(a)
#endif #endif
#define CV_CMP(a,b) (((a) > (b)) - ((a) < (b))) #define CV_CMP(a,b) (((a) > (b)) - ((a) < (b)))
#define CV_SIGN(a) CV_CMP((a),0) #define CV_SIGN(a) CV_CMP((a),0)
@ -306,11 +316,11 @@ CV_INLINE int cvRound( double value )
} }
return t; return t;
#elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__ #elif defined HAVE_LRINT || defined CV_ICC || defined __GNUC__
# ifdef HAVE_TEGRA_OPTIMIZATION # ifdef HAVE_TEGRA_OPTIMIZATION
TEGRA_ROUND(value); TEGRA_ROUND(value);
# else # else
return (int)lrint(value); return (int)lrint(value);
# endif # endif
#else #else
// while this is not IEEE754-compliant rounding, it's usually a good enough approximation // while this is not IEEE754-compliant rounding, it's usually a good enough approximation
return (int)(value + (value >= 0 ? 0.5 : -0.5)); return (int)(value + (value >= 0 ? 0.5 : -0.5));
@ -318,7 +328,7 @@ CV_INLINE int cvRound( double value )
} }
#if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP) #if defined __SSE2__ || (defined _M_IX86_FP && 2 == _M_IX86_FP)
#include "emmintrin.h" # include "emmintrin.h"
#endif #endif
CV_INLINE int cvFloor( double value ) CV_INLINE int cvFloor( double value )
@ -1886,6 +1896,6 @@ typedef struct CvModuleInfo
} }
CvModuleInfo; CvModuleInfo;
#endif /*_CXCORE_TYPES_H_*/ #endif /*__OPENCV_CORE_TYPES_H__*/
/* End of file. */ /* End of file. */

View File

@ -1,9 +1,13 @@
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
#endif
#ifndef __OPENCV_PERF_PRECOMP_HPP__ #ifndef __OPENCV_PERF_PRECOMP_HPP__
#define __OPENCV_PERF_PRECOMP_HPP__ #define __OPENCV_PERF_PRECOMP_HPP__
#include "opencv2/ts/ts.hpp" #include "opencv2/ts/ts.hpp"
#if GTEST_CREATE_SHARED_LIBRARY #ifdef GTEST_CREATE_SHARED_LIBRARY
#error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined #error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined
#endif #endif

View File

@ -28,11 +28,11 @@ PERF_TEST_P(Size_MatType, mean, TYPICAL_MATS)
Mat src(sz, type); Mat src(sz, type);
Scalar s; Scalar s;
declare.in(src, WARMUP_RNG).out(s); declare.in(src, WARMUP_RNG).out(s);
TEST_CYCLE() s = mean(src); TEST_CYCLE() s = mean(src);
SANITY_CHECK(s, 1e-6); SANITY_CHECK(s, 1e-6);
} }
@ -44,11 +44,11 @@ PERF_TEST_P(Size_MatType, mean_mask, TYPICAL_MATS)
Mat src(sz, type); Mat src(sz, type);
Mat mask = Mat::ones(src.size(), CV_8U); Mat mask = Mat::ones(src.size(), CV_8U);
Scalar s; Scalar s;
declare.in(src, WARMUP_RNG).in(mask).out(s); declare.in(src, WARMUP_RNG).in(mask).out(s);
TEST_CYCLE() s = mean(src, mask); TEST_CYCLE() s = mean(src, mask);
SANITY_CHECK(s, 1e-6); SANITY_CHECK(s, 1e-6);
} }
@ -64,7 +64,7 @@ PERF_TEST_P(Size_MatType, meanStdDev, TYPICAL_MATS)
declare.in(src, WARMUP_RNG).out(mean, dev); declare.in(src, WARMUP_RNG).out(mean, dev);
TEST_CYCLE() meanStdDev(src, mean, dev); TEST_CYCLE() meanStdDev(src, mean, dev);
SANITY_CHECK(mean, 1e-6); SANITY_CHECK(mean, 1e-6);
SANITY_CHECK(dev, 1e-6); SANITY_CHECK(dev, 1e-6);
} }
@ -80,9 +80,9 @@ PERF_TEST_P(Size_MatType, meanStdDev_mask, TYPICAL_MATS)
Scalar dev; Scalar dev;
declare.in(src, WARMUP_RNG).in(mask).out(mean, dev); declare.in(src, WARMUP_RNG).in(mask).out(mean, dev);
TEST_CYCLE() meanStdDev(src, mean, dev, mask); TEST_CYCLE() meanStdDev(src, mean, dev, mask);
SANITY_CHECK(mean, 1e-6); SANITY_CHECK(mean, 1e-6);
SANITY_CHECK(dev, 1e-6); SANITY_CHECK(dev, 1e-6);
} }
@ -96,8 +96,8 @@ PERF_TEST_P(Size_MatType, countNonZero, testing::Combine( testing::Values( TYPIC
int cnt = 0; int cnt = 0;
declare.in(src, WARMUP_RNG); declare.in(src, WARMUP_RNG);
TEST_CYCLE() cnt = countNonZero(src); TEST_CYCLE() cnt = countNonZero(src);
SANITY_CHECK(cnt); SANITY_CHECK(cnt);
} }

View File

@ -46,7 +46,7 @@ namespace cv
{ {
using std::pair; using std::pair;
template<typename _KeyTp, typename _ValueTp> struct sorted_vector template<typename _KeyTp, typename _ValueTp> struct sorted_vector
{ {
sorted_vector() {} sorted_vector() {}
@ -54,7 +54,7 @@ template<typename _KeyTp, typename _ValueTp> struct sorted_vector
size_t size() const { return vec.size(); } size_t size() const { return vec.size(); }
_ValueTp& operator [](size_t idx) { return vec[idx]; } _ValueTp& operator [](size_t idx) { return vec[idx]; }
const _ValueTp& operator [](size_t idx) const { return vec[idx]; } const _ValueTp& operator [](size_t idx) const { return vec[idx]; }
void add(const _KeyTp& k, const _ValueTp& val) void add(const _KeyTp& k, const _ValueTp& val)
{ {
pair<_KeyTp, _ValueTp> p(k, val); pair<_KeyTp, _ValueTp> p(k, val);
@ -64,7 +64,7 @@ template<typename _KeyTp, typename _ValueTp> struct sorted_vector
std::swap(vec[i-1], vec[i]); std::swap(vec[i-1], vec[i]);
CV_Assert( i == 0 || vec[i].first != vec[i-1].first ); CV_Assert( i == 0 || vec[i].first != vec[i-1].first );
} }
bool find(const _KeyTp& key, _ValueTp& value) const bool find(const _KeyTp& key, _ValueTp& value) const
{ {
size_t a = 0, b = vec.size(); size_t a = 0, b = vec.size();
@ -76,7 +76,7 @@ template<typename _KeyTp, typename _ValueTp> struct sorted_vector
else else
b = c; b = c;
} }
if( a < vec.size() && vec[a].first == key ) if( a < vec.size() && vec[a].first == key )
{ {
value = vec[a].second; value = vec[a].second;
@ -84,26 +84,26 @@ template<typename _KeyTp, typename _ValueTp> struct sorted_vector
} }
return false; return false;
} }
void get_keys(vector<_KeyTp>& keys) const void get_keys(vector<_KeyTp>& keys) const
{ {
size_t i = 0, n = vec.size(); size_t i = 0, n = vec.size();
keys.resize(n); keys.resize(n);
for( i = 0; i < n; i++ ) for( i = 0; i < n; i++ )
keys[i] = vec[i].first; keys[i] = vec[i].first;
} }
vector<pair<_KeyTp, _ValueTp> > vec; vector<pair<_KeyTp, _ValueTp> > vec;
}; };
template<typename _ValueTp> inline const _ValueTp* findstr(const sorted_vector<string, _ValueTp>& vec, template<typename _ValueTp> inline const _ValueTp* findstr(const sorted_vector<string, _ValueTp>& vec,
const char* key) const char* key)
{ {
if( !key ) if( !key )
return 0; return 0;
size_t a = 0, b = vec.vec.size(); size_t a = 0, b = vec.vec.size();
while( b > a ) while( b > a )
{ {
@ -113,13 +113,13 @@ template<typename _ValueTp> inline const _ValueTp* findstr(const sorted_vector<s
else else
b = c; b = c;
} }
if( strcmp(vec.vec[a].first.c_str(), key) == 0 ) if( strcmp(vec.vec[a].first.c_str(), key) == 0 )
return &vec.vec[a].second; return &vec.vec[a].second;
return 0; return 0;
} }
Param::Param() Param::Param()
{ {
type = 0; type = 0;
@ -129,7 +129,7 @@ Param::Param()
setter = 0; setter = 0;
} }
Param::Param(int _type, bool _readonly, int _offset, Param::Param(int _type, bool _readonly, int _offset,
Algorithm::Getter _getter, Algorithm::Setter _setter, Algorithm::Getter _getter, Algorithm::Setter _setter,
const string& _help) const string& _help)
@ -148,7 +148,7 @@ struct CV_EXPORTS AlgorithmInfoData
string _name; string _name;
}; };
static sorted_vector<string, Algorithm::Constructor>& alglist() static sorted_vector<string, Algorithm::Constructor>& alglist()
{ {
static sorted_vector<string, Algorithm::Constructor> alglist_var; static sorted_vector<string, Algorithm::Constructor> alglist_var;
@ -171,152 +171,152 @@ Ptr<Algorithm> Algorithm::_create(const string& name)
Algorithm::Algorithm() Algorithm::Algorithm()
{ {
} }
Algorithm::~Algorithm() Algorithm::~Algorithm()
{ {
} }
string Algorithm::name() const string Algorithm::name() const
{ {
return info()->name(); return info()->name();
} }
void Algorithm::set(const string& name, int value) void Algorithm::set(const string& parameter, int value)
{ {
info()->set(this, name.c_str(), ParamType<int>::type, &value); info()->set(this, parameter.c_str(), ParamType<int>::type, &value);
} }
void Algorithm::set(const string& name, double value) void Algorithm::set(const string& parameter, double value)
{ {
info()->set(this, name.c_str(), ParamType<double>::type, &value); info()->set(this, parameter.c_str(), ParamType<double>::type, &value);
} }
void Algorithm::set(const string& name, bool value) void Algorithm::set(const string& parameter, bool value)
{ {
info()->set(this, name.c_str(), ParamType<bool>::type, &value); info()->set(this, parameter.c_str(), ParamType<bool>::type, &value);
} }
void Algorithm::set(const string& name, const string& value) void Algorithm::set(const string& parameter, const string& value)
{ {
info()->set(this, name.c_str(), ParamType<string>::type, &value); info()->set(this, parameter.c_str(), ParamType<string>::type, &value);
} }
void Algorithm::set(const string& name, const Mat& value) void Algorithm::set(const string& parameter, const Mat& value)
{ {
info()->set(this, name.c_str(), ParamType<Mat>::type, &value); info()->set(this, parameter.c_str(), ParamType<Mat>::type, &value);
} }
void Algorithm::set(const string& name, const vector<Mat>& value) void Algorithm::set(const string& parameter, const vector<Mat>& value)
{ {
info()->set(this, name.c_str(), ParamType<vector<Mat> >::type, &value); info()->set(this, parameter.c_str(), ParamType<vector<Mat> >::type, &value);
}
void Algorithm::set(const string& name, const Ptr<Algorithm>& value)
{
info()->set(this, name.c_str(), ParamType<Algorithm>::type, &value);
} }
void Algorithm::set(const char* name, int value) void Algorithm::set(const string& parameter, const Ptr<Algorithm>& value)
{ {
info()->set(this, name, ParamType<int>::type, &value); info()->set(this, parameter.c_str(), ParamType<Algorithm>::type, &value);
} }
void Algorithm::set(const char* name, double value) void Algorithm::set(const char* parameter, int value)
{ {
info()->set(this, name, ParamType<double>::type, &value); info()->set(this, parameter, ParamType<int>::type, &value);
} }
void Algorithm::set(const char* name, bool value) void Algorithm::set(const char* parameter, double value)
{ {
info()->set(this, name, ParamType<bool>::type, &value); info()->set(this, parameter, ParamType<double>::type, &value);
} }
void Algorithm::set(const char* name, const string& value) void Algorithm::set(const char* parameter, bool value)
{ {
info()->set(this, name, ParamType<string>::type, &value); info()->set(this, parameter, ParamType<bool>::type, &value);
} }
void Algorithm::set(const char* name, const Mat& value) void Algorithm::set(const char* parameter, const string& value)
{ {
info()->set(this, name, ParamType<Mat>::type, &value); info()->set(this, parameter, ParamType<string>::type, &value);
} }
void Algorithm::set(const char* name, const vector<Mat>& value) void Algorithm::set(const char* parameter, const Mat& value)
{ {
info()->set(this, name, ParamType<vector<Mat> >::type, &value); info()->set(this, parameter, ParamType<Mat>::type, &value);
}
void Algorithm::set(const char* name, const Ptr<Algorithm>& value)
{
info()->set(this, name, ParamType<Algorithm>::type, &value);
}
int Algorithm::getInt(const string& name) const
{
return get<int>(name);
}
double Algorithm::getDouble(const string& name) const
{
return get<double>(name);
} }
bool Algorithm::getBool(const string& name) const void Algorithm::set(const char* parameter, const vector<Mat>& value)
{ {
return get<bool>(name); info()->set(this, parameter, ParamType<vector<Mat> >::type, &value);
} }
string Algorithm::getString(const string& name) const void Algorithm::set(const char* parameter, const Ptr<Algorithm>& value)
{ {
return get<string>(name); info()->set(this, parameter, ParamType<Algorithm>::type, &value);
} }
Mat Algorithm::getMat(const string& name) const int Algorithm::getInt(const string& parameter) const
{ {
return get<Mat>(name); return get<int>(parameter);
} }
vector<Mat> Algorithm::getMatVector(const string& name) const double Algorithm::getDouble(const string& parameter) const
{ {
return get<vector<Mat> >(name); return get<double>(parameter);
} }
Ptr<Algorithm> Algorithm::getAlgorithm(const string& name) const bool Algorithm::getBool(const string& parameter) const
{ {
return get<Algorithm>(name); return get<bool>(parameter);
}
string Algorithm::paramHelp(const string& name) const
{
return info()->paramHelp(name.c_str());
}
int Algorithm::paramType(const string& name) const
{
return info()->paramType(name.c_str());
} }
int Algorithm::paramType(const char* name) const string Algorithm::getString(const string& parameter) const
{ {
return info()->paramType(name); return get<string>(parameter);
} }
Mat Algorithm::getMat(const string& parameter) const
{
return get<Mat>(parameter);
}
vector<Mat> Algorithm::getMatVector(const string& parameter) const
{
return get<vector<Mat> >(parameter);
}
Ptr<Algorithm> Algorithm::getAlgorithm(const string& parameter) const
{
return get<Algorithm>(parameter);
}
string Algorithm::paramHelp(const string& parameter) const
{
return info()->paramHelp(parameter.c_str());
}
int Algorithm::paramType(const string& parameter) const
{
return info()->paramType(parameter.c_str());
}
int Algorithm::paramType(const char* parameter) const
{
return info()->paramType(parameter);
}
void Algorithm::getParams(vector<string>& names) const void Algorithm::getParams(vector<string>& names) const
{ {
info()->getParams(names); info()->getParams(names);
} }
void Algorithm::write(FileStorage& fs) const void Algorithm::write(FileStorage& fs) const
{ {
info()->write(this, fs); info()->write(this, fs);
} }
void Algorithm::read(const FileNode& fn) void Algorithm::read(const FileNode& fn)
{ {
info()->read(this, fn); info()->read(this, fn);
} }
AlgorithmInfo::AlgorithmInfo(const string& _name, Algorithm::Constructor create) AlgorithmInfo::AlgorithmInfo(const string& _name, Algorithm::Constructor create)
{ {
data = new AlgorithmInfoData; data = new AlgorithmInfoData;
@ -327,8 +327,8 @@ AlgorithmInfo::AlgorithmInfo(const string& _name, Algorithm::Constructor create)
AlgorithmInfo::~AlgorithmInfo() AlgorithmInfo::~AlgorithmInfo()
{ {
delete data; delete data;
} }
void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const
{ {
size_t i = 0, nparams = data->params.vec.size(); size_t i = 0, nparams = data->params.vec.size();
@ -364,7 +364,7 @@ void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const
{ {
size_t i = 0, nparams = data->params.vec.size(); size_t i = 0, nparams = data->params.vec.size();
AlgorithmInfo* info = algo->info(); AlgorithmInfo* info = algo->info();
for( i = 0; i < nparams; i++ ) for( i = 0; i < nparams; i++ )
{ {
const Param& p = data->params.vec[i].second; const Param& p = data->params.vec[i].second;
@ -414,13 +414,13 @@ void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const
else else
CV_Error( CV_StsUnsupportedFormat, "unknown/unsupported parameter type"); CV_Error( CV_StsUnsupportedFormat, "unknown/unsupported parameter type");
} }
} }
string AlgorithmInfo::name() const string AlgorithmInfo::name() const
{ {
return data->_name; return data->_name;
} }
union GetSetParam union GetSetParam
{ {
int (Algorithm::*get_int)() const; int (Algorithm::*get_int)() const;
@ -430,7 +430,7 @@ union GetSetParam
Mat (Algorithm::*get_mat)() const; Mat (Algorithm::*get_mat)() const;
vector<Mat> (Algorithm::*get_mat_vector)() const; vector<Mat> (Algorithm::*get_mat_vector)() const;
Ptr<Algorithm> (Algorithm::*get_algo)() const; Ptr<Algorithm> (Algorithm::*get_algo)() const;
void (Algorithm::*set_int)(int); void (Algorithm::*set_int)(int);
void (Algorithm::*set_bool)(bool); void (Algorithm::*set_bool)(bool);
void (Algorithm::*set_double)(double); void (Algorithm::*set_double)(double);
@ -440,15 +440,15 @@ union GetSetParam
void (Algorithm::*set_algo)(const Ptr<Algorithm>&); void (Algorithm::*set_algo)(const Ptr<Algorithm>&);
}; };
void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const void* value, bool force) const void AlgorithmInfo::set(Algorithm* algo, const char* parameter, int argType, const void* value, bool force) const
{ {
const Param* p = findstr(data->params, name); const Param* p = findstr(data->params, parameter);
if( !p ) if( !p )
CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") ); CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
if( !force && p->readonly ) if( !force && p->readonly )
CV_Error_( CV_StsError, ("Parameter '%s' is readonly", name)); CV_Error_( CV_StsError, ("Parameter '%s' is readonly", parameter));
GetSetParam f; GetSetParam f;
f.set_int = p->setter; f.set_int = p->setter;
@ -531,23 +531,23 @@ void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const vo
else else
CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type"); CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type");
} }
void AlgorithmInfo::get(const Algorithm* algo, const char* name, int argType, void* value) const void AlgorithmInfo::get(const Algorithm* algo, const char* parameter, int argType, void* value) const
{ {
const Param* p = findstr(data->params, name); const Param* p = findstr(data->params, parameter);
if( !p ) if( !p )
CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") ); CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
GetSetParam f; GetSetParam f;
f.get_int = p->getter; f.get_int = p->getter;
if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL ) if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL )
{ {
if( p->type == Param::INT ) if( p->type == Param::INT )
{ {
CV_Assert( argType == Param::INT || argType == Param::REAL ); CV_Assert( argType == Param::INT || argType == Param::REAL );
int val = p->getter ? (algo->*f.get_int)() : *(int*)((uchar*)algo + p->offset); int val = p->getter ? (algo->*f.get_int)() : *(int*)((uchar*)algo + p->offset);
if( argType == Param::INT ) if( argType == Param::INT )
*(int*)value = val; *(int*)value = val;
else else
@ -557,7 +557,7 @@ void AlgorithmInfo::get(const Algorithm* algo, const char* name, int argType, vo
{ {
CV_Assert( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL ); CV_Assert( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL );
bool val = p->getter ? (algo->*f.get_bool)() : *(bool*)((uchar*)algo + p->offset); bool val = p->getter ? (algo->*f.get_bool)() : *(bool*)((uchar*)algo + p->offset);
if( argType == Param::INT ) if( argType == Param::INT )
*(int*)value = (int)val; *(int*)value = (int)val;
else if( argType == Param::BOOLEAN ) else if( argType == Param::BOOLEAN )
@ -569,35 +569,35 @@ void AlgorithmInfo::get(const Algorithm* algo, const char* name, int argType, vo
{ {
CV_Assert( argType == Param::REAL ); CV_Assert( argType == Param::REAL );
double val = p->getter ? (algo->*f.get_double)() : *(double*)((uchar*)algo + p->offset); double val = p->getter ? (algo->*f.get_double)() : *(double*)((uchar*)algo + p->offset);
*(double*)value = val; *(double*)value = val;
} }
} }
else if( argType == Param::STRING ) else if( argType == Param::STRING )
{ {
CV_Assert( p->type == Param::STRING ); CV_Assert( p->type == Param::STRING );
*(string*)value = p->getter ? (algo->*f.get_string)() : *(string*)value = p->getter ? (algo->*f.get_string)() :
*(string*)((uchar*)algo + p->offset); *(string*)((uchar*)algo + p->offset);
} }
else if( argType == Param::MAT ) else if( argType == Param::MAT )
{ {
CV_Assert( p->type == Param::MAT ); CV_Assert( p->type == Param::MAT );
*(Mat*)value = p->getter ? (algo->*f.get_mat)() : *(Mat*)value = p->getter ? (algo->*f.get_mat)() :
*(Mat*)((uchar*)algo + p->offset); *(Mat*)((uchar*)algo + p->offset);
} }
else if( argType == Param::MAT_VECTOR ) else if( argType == Param::MAT_VECTOR )
{ {
CV_Assert( p->type == Param::MAT_VECTOR ); CV_Assert( p->type == Param::MAT_VECTOR );
*(vector<Mat>*)value = p->getter ? (algo->*f.get_mat_vector)() : *(vector<Mat>*)value = p->getter ? (algo->*f.get_mat_vector)() :
*(vector<Mat>*)((uchar*)algo + p->offset); *(vector<Mat>*)((uchar*)algo + p->offset);
} }
else if( argType == Param::ALGORITHM ) else if( argType == Param::ALGORITHM )
{ {
CV_Assert( p->type == Param::ALGORITHM ); CV_Assert( p->type == Param::ALGORITHM );
*(Ptr<Algorithm>*)value = p->getter ? (algo->*f.get_algo)() : *(Ptr<Algorithm>*)value = p->getter ? (algo->*f.get_algo)() :
*(Ptr<Algorithm>*)((uchar*)algo + p->offset); *(Ptr<Algorithm>*)((uchar*)algo + p->offset);
} }
@ -605,21 +605,21 @@ void AlgorithmInfo::get(const Algorithm* algo, const char* name, int argType, vo
CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type"); CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type");
} }
int AlgorithmInfo::paramType(const char* name) const int AlgorithmInfo::paramType(const char* parameter) const
{ {
const Param* p = findstr(data->params, name); const Param* p = findstr(data->params, parameter);
if( !p ) if( !p )
CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") ); CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
return p->type; return p->type;
} }
string AlgorithmInfo::paramHelp(const char* name) const string AlgorithmInfo::paramHelp(const char* parameter) const
{ {
const Param* p = findstr(data->params, name); const Param* p = findstr(data->params, parameter);
if( !p ) if( !p )
CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "<NULL>") ); CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", parameter ? parameter : "<NULL>") );
return p->help; return p->help;
} }
@ -628,10 +628,10 @@ void AlgorithmInfo::getParams(vector<string>& names) const
{ {
data->params.get_keys(names); data->params.get_keys(names);
} }
void AlgorithmInfo::addParam_(Algorithm& algo, const char* name, int argType, void AlgorithmInfo::addParam_(Algorithm& algo, const char* parameter, int argType,
void* value, bool readOnly, void* value, bool readOnly,
Algorithm::Getter getter, Algorithm::Setter setter, Algorithm::Getter getter, Algorithm::Setter setter,
const string& help) const string& help)
{ {
@ -639,82 +639,82 @@ void AlgorithmInfo::addParam_(Algorithm& algo, const char* name, int argType,
argType == Param::REAL || argType == Param::STRING || argType == Param::REAL || argType == Param::STRING ||
argType == Param::MAT || argType == Param::MAT_VECTOR || argType == Param::MAT || argType == Param::MAT_VECTOR ||
argType == Param::ALGORITHM ); argType == Param::ALGORITHM );
data->params.add(string(name), Param(argType, readOnly, data->params.add(string(parameter), Param(argType, readOnly,
(int)((size_t)value - (size_t)(void*)&algo), (int)((size_t)value - (size_t)(void*)&algo),
getter, setter, help)); getter, setter, help));
} }
void AlgorithmInfo::addParam(Algorithm& algo, const char* name, void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
int& value, bool readOnly, int& value, bool readOnly,
int (Algorithm::*getter)(), int (Algorithm::*getter)(),
void (Algorithm::*setter)(int), void (Algorithm::*setter)(int),
const string& help) const string& help)
{ {
addParam_(algo, name, ParamType<int>::type, &value, readOnly, addParam_(algo, parameter, ParamType<int>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help); (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
} }
void AlgorithmInfo::addParam(Algorithm& algo, const char* name, void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
bool& value, bool readOnly, bool& value, bool readOnly,
int (Algorithm::*getter)(), int (Algorithm::*getter)(),
void (Algorithm::*setter)(int), void (Algorithm::*setter)(int),
const string& help) const string& help)
{ {
addParam_(algo, name, ParamType<bool>::type, &value, readOnly, addParam_(algo, parameter, ParamType<bool>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help); (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
} }
void AlgorithmInfo::addParam(Algorithm& algo, const char* name, void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
double& value, bool readOnly, double& value, bool readOnly,
double (Algorithm::*getter)(), double (Algorithm::*getter)(),
void (Algorithm::*setter)(double), void (Algorithm::*setter)(double),
const string& help) const string& help)
{ {
addParam_(algo, name, ParamType<double>::type, &value, readOnly, addParam_(algo, parameter, ParamType<double>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help); (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
} }
void AlgorithmInfo::addParam(Algorithm& algo, const char* name, void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
string& value, bool readOnly, string& value, bool readOnly,
string (Algorithm::*getter)(), string (Algorithm::*getter)(),
void (Algorithm::*setter)(const string&), void (Algorithm::*setter)(const string&),
const string& help) const string& help)
{ {
addParam_(algo, name, ParamType<string>::type, &value, readOnly, addParam_(algo, parameter, ParamType<string>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help); (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
} }
void AlgorithmInfo::addParam(Algorithm& algo, const char* name, void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
Mat& value, bool readOnly, Mat& value, bool readOnly,
Mat (Algorithm::*getter)(), Mat (Algorithm::*getter)(),
void (Algorithm::*setter)(const Mat&), void (Algorithm::*setter)(const Mat&),
const string& help) const string& help)
{ {
addParam_(algo, name, ParamType<Mat>::type, &value, readOnly, addParam_(algo, parameter, ParamType<Mat>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help); (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
} }
void AlgorithmInfo::addParam(Algorithm& algo, const char* name, void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
vector<Mat>& value, bool readOnly, vector<Mat>& value, bool readOnly,
vector<Mat> (Algorithm::*getter)(), vector<Mat> (Algorithm::*getter)(),
void (Algorithm::*setter)(const vector<Mat>&), void (Algorithm::*setter)(const vector<Mat>&),
const string& help) const string& help)
{ {
addParam_(algo, name, ParamType<vector<Mat> >::type, &value, readOnly, addParam_(algo, parameter, ParamType<vector<Mat> >::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help); (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
} }
void AlgorithmInfo::addParam(Algorithm& algo, const char* name, void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
Ptr<Algorithm>& value, bool readOnly, Ptr<Algorithm>& value, bool readOnly,
Ptr<Algorithm> (Algorithm::*getter)(), Ptr<Algorithm> (Algorithm::*getter)(),
void (Algorithm::*setter)(const Ptr<Algorithm>&), void (Algorithm::*setter)(const Ptr<Algorithm>&),
const string& help) const string& help)
{ {
addParam_(algo, name, ParamType<Algorithm>::type, &value, readOnly, addParam_(algo, parameter, ParamType<Algorithm>::type, &value, readOnly,
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help); (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
} }
} }
/* End of file. */ /* End of file. */

View File

@ -55,7 +55,9 @@ static void* OutOfMemoryError(size_t size)
#if CV_USE_SYSTEM_MALLOC #if CV_USE_SYSTEM_MALLOC
#if defined WIN32 || defined _WIN32
void deleteThreadAllocData() {} void deleteThreadAllocData() {}
#endif
void* fastMalloc( size_t size ) void* fastMalloc( size_t size )
{ {
@ -66,14 +68,14 @@ void* fastMalloc( size_t size )
adata[-1] = udata; adata[-1] = udata;
return adata; return adata;
} }
void fastFree(void* ptr) void fastFree(void* ptr)
{ {
if(ptr) if(ptr)
{ {
uchar* udata = ((uchar**)ptr)[-1]; uchar* udata = ((uchar**)ptr)[-1];
CV_DbgAssert(udata < (uchar*)ptr && CV_DbgAssert(udata < (uchar*)ptr &&
((uchar*)ptr - udata) <= (ptrdiff_t)(sizeof(void*)+CV_MALLOC_ALIGN)); ((uchar*)ptr - udata) <= (ptrdiff_t)(sizeof(void*)+CV_MALLOC_ALIGN));
free(udata); free(udata);
} }
} }
@ -388,7 +390,7 @@ struct ThreadData
#ifdef WIN32 #ifdef WIN32
#ifdef WINCE #ifdef WINCE
# define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) # define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
#endif //WINCE #endif //WINCE
static DWORD tlsKey; static DWORD tlsKey;
@ -535,7 +537,7 @@ void* fastMalloc( size_t size )
freePtr = block; freePtr = block;
if( !data ) if( !data )
{ {
block = gcPtr; block = gcPtr;
for( int k = 0; k < 2; k++ ) for( int k = 0; k < 2; k++ )
{ {
SANITY_CHECK(block); SANITY_CHECK(block);
@ -620,7 +622,7 @@ void fastFree( void* ptr )
Block*& startPtr = tls->bins[idx][START]; Block*& startPtr = tls->bins[idx][START];
Block*& freePtr = tls->bins[idx][FREE]; Block*& freePtr = tls->bins[idx][FREE];
Block*& gcPtr = tls->bins[idx][GC]; Block*& gcPtr = tls->bins[idx][GC];
if( block == block->next ) if( block == block->next )
{ {
CV_DbgAssert( startPtr == block && freePtr == block && gcPtr == block ); CV_DbgAssert( startPtr == block && freePtr == block && gcPtr == block );

View File

@ -974,7 +974,7 @@ void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t bl
scbuf[i] = scbuf[i - esz]; scbuf[i] = scbuf[i - esz];
} }
void binary_op(InputArray _src1, InputArray _src2, OutputArray _dst, static void binary_op(InputArray _src1, InputArray _src2, OutputArray _dst,
InputArray _mask, const BinaryFunc* tab, bool bitwise) InputArray _mask, const BinaryFunc* tab, bool bitwise)
{ {
int kind1 = _src1.kind(), kind2 = _src2.kind(); int kind1 = _src1.kind(), kind2 = _src2.kind();
@ -1216,7 +1216,7 @@ void cv::min(const Mat& src1, double src2, Mat& dst)
namespace cv namespace cv
{ {
void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst, static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
InputArray _mask, int dtype, BinaryFunc* tab, bool muldiv=false, void* usrdata=0) InputArray _mask, int dtype, BinaryFunc* tab, bool muldiv=false, void* usrdata=0)
{ {
int kind1 = _src1.kind(), kind2 = _src2.kind(); int kind1 = _src1.kind(), kind2 = _src2.kind();

View File

@ -6,6 +6,7 @@
using namespace std; using namespace std;
using namespace cv; using namespace cv;
namespace {
void helpParser() void helpParser()
{ {
printf("\nThe CommandLineParser class is designed for command line arguments parsing\n" printf("\nThe CommandLineParser class is designed for command line arguments parsing\n"
@ -89,6 +90,8 @@ string del_space(string name)
return name; return name;
} }
}//namespace
CommandLineParser::CommandLineParser(int argc, const char* const argv[], const char* keys) CommandLineParser::CommandLineParser(int argc, const char* const argv[], const char* keys)
{ {
std::string keys_buffer; std::string keys_buffer;

View File

@ -88,7 +88,7 @@ split_( const T* src, T** dst, int len, int cn )
dst2[i] = src[j+2]; dst3[i] = src[j+3]; dst2[i] = src[j+2]; dst3[i] = src[j+3];
} }
} }
for( ; k < cn; k += 4 ) for( ; k < cn; k += 4 )
{ {
T *dst0 = dst[k], *dst1 = dst[k+1], *dst2 = dst[k+2], *dst3 = dst[k+3]; T *dst0 = dst[k], *dst1 = dst[k+1], *dst2 = dst[k+2], *dst3 = dst[k+3];
@ -99,7 +99,7 @@ split_( const T* src, T** dst, int len, int cn )
} }
} }
} }
template<typename T> static void template<typename T> static void
merge_( const T** src, T* dst, int len, int cn ) merge_( const T** src, T* dst, int len, int cn )
{ {
@ -139,7 +139,7 @@ merge_( const T** src, T* dst, int len, int cn )
dst[j+2] = src2[i]; dst[j+3] = src3[i]; dst[j+2] = src2[i]; dst[j+3] = src3[i];
} }
} }
for( ; k < cn; k += 4 ) for( ; k < cn; k += 4 )
{ {
const T *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3]; const T *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
@ -165,7 +165,7 @@ static void split32s(const int* src, int** dst, int len, int cn )
{ {
split_(src, dst, len, cn); split_(src, dst, len, cn);
} }
static void split64s(const int64* src, int64** dst, int len, int cn ) static void split64s(const int64* src, int64** dst, int len, int cn )
{ {
split_(src, dst, len, cn); split_(src, dst, len, cn);
@ -189,7 +189,7 @@ static void merge32s(const int** src, int* dst, int len, int cn )
static void merge64s(const int64** src, int64* dst, int len, int cn ) static void merge64s(const int64** src, int64* dst, int len, int cn )
{ {
merge_(src, dst, len, cn); merge_(src, dst, len, cn);
} }
typedef void (*SplitFunc)(const uchar* src, uchar** dst, int len, int cn); typedef void (*SplitFunc)(const uchar* src, uchar** dst, int len, int cn);
typedef void (*MergeFunc)(const uchar** src, uchar* dst, int len, int cn); typedef void (*MergeFunc)(const uchar** src, uchar* dst, int len, int cn);
@ -205,9 +205,9 @@ static MergeFunc mergeTab[] =
(MergeFunc)GET_OPTIMIZED(merge8u), (MergeFunc)GET_OPTIMIZED(merge8u), (MergeFunc)GET_OPTIMIZED(merge16u), (MergeFunc)GET_OPTIMIZED(merge16u), (MergeFunc)GET_OPTIMIZED(merge8u), (MergeFunc)GET_OPTIMIZED(merge8u), (MergeFunc)GET_OPTIMIZED(merge16u), (MergeFunc)GET_OPTIMIZED(merge16u),
(MergeFunc)GET_OPTIMIZED(merge32s), (MergeFunc)GET_OPTIMIZED(merge32s), (MergeFunc)GET_OPTIMIZED(merge64s), 0 (MergeFunc)GET_OPTIMIZED(merge32s), (MergeFunc)GET_OPTIMIZED(merge32s), (MergeFunc)GET_OPTIMIZED(merge64s), 0
}; };
} }
void cv::split(const Mat& src, Mat* mv) void cv::split(const Mat& src, Mat* mv)
{ {
int k, depth = src.depth(), cn = src.channels(); int k, depth = src.depth(), cn = src.channels();
@ -219,30 +219,30 @@ void cv::split(const Mat& src, Mat* mv)
SplitFunc func = splitTab[depth]; SplitFunc func = splitTab[depth];
CV_Assert( func != 0 ); CV_Assert( func != 0 );
int esz = (int)src.elemSize(), esz1 = (int)src.elemSize1(); int esz = (int)src.elemSize(), esz1 = (int)src.elemSize1();
int blocksize0 = (BLOCK_SIZE + esz-1)/esz; int blocksize0 = (BLOCK_SIZE + esz-1)/esz;
AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16); AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
const Mat** arrays = (const Mat**)(uchar*)_buf; const Mat** arrays = (const Mat**)(uchar*)_buf;
uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16); uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
arrays[0] = &src; arrays[0] = &src;
for( k = 0; k < cn; k++ ) for( k = 0; k < cn; k++ )
{ {
mv[k].create(src.dims, src.size, depth); mv[k].create(src.dims, src.size, depth);
arrays[k+1] = &mv[k]; arrays[k+1] = &mv[k];
} }
NAryMatIterator it(arrays, ptrs, cn+1); NAryMatIterator it(arrays, ptrs, cn+1);
int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0); int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
for( size_t i = 0; i < it.nplanes; i++, ++it ) for( size_t i = 0; i < it.nplanes; i++, ++it )
{ {
for( int j = 0; j < total; j += blocksize ) for( int j = 0; j < total; j += blocksize )
{ {
int bsz = std::min(total - j, blocksize); int bsz = std::min(total - j, blocksize);
func( ptrs[0], &ptrs[1], bsz, cn ); func( ptrs[0], &ptrs[1], bsz, cn );
if( j + blocksize < total ) if( j + blocksize < total )
{ {
ptrs[0] += bsz*esz; ptrs[0] += bsz*esz;
@ -252,45 +252,45 @@ void cv::split(const Mat& src, Mat* mv)
} }
} }
} }
void cv::split(const Mat& m, vector<Mat>& mv) void cv::split(const Mat& m, vector<Mat>& mv)
{ {
mv.resize(!m.empty() ? m.channels() : 0); mv.resize(!m.empty() ? m.channels() : 0);
if(!m.empty()) if(!m.empty())
split(m, &mv[0]); split(m, &mv[0]);
} }
void cv::merge(const Mat* mv, size_t n, OutputArray _dst) void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
{ {
CV_Assert( mv && n > 0 ); CV_Assert( mv && n > 0 );
int depth = mv[0].depth(); int depth = mv[0].depth();
bool allch1 = true; bool allch1 = true;
int k, cn = 0; int k, cn = 0;
size_t i; size_t i;
for( i = 0; i < n; i++ ) for( i = 0; i < n; i++ )
{ {
CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth); CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth);
allch1 = allch1 && mv[i].channels() == 1; allch1 = allch1 && mv[i].channels() == 1;
cn += mv[i].channels(); cn += mv[i].channels();
} }
CV_Assert( 0 < cn && cn <= CV_CN_MAX ); CV_Assert( 0 < cn && cn <= CV_CN_MAX );
_dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, cn)); _dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, cn));
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
if( n == 1 ) if( n == 1 )
{ {
mv[0].copyTo(dst); mv[0].copyTo(dst);
return; return;
} }
if( !allch1 ) if( !allch1 )
{ {
AutoBuffer<int> pairs(cn*2); AutoBuffer<int> pairs(cn*2);
int j, ni=0; int j, ni=0;
for( i = 0, j = 0; i < n; i++, j += ni ) for( i = 0, j = 0; i < n; i++, j += ni )
{ {
ni = mv[i].channels(); ni = mv[i].channels();
@ -303,33 +303,33 @@ void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
mixChannels( mv, n, &dst, 1, &pairs[0], cn ); mixChannels( mv, n, &dst, 1, &pairs[0], cn );
return; return;
} }
size_t esz = dst.elemSize(), esz1 = dst.elemSize1(); size_t esz = dst.elemSize(), esz1 = dst.elemSize1();
int blocksize0 = (int)((BLOCK_SIZE + esz-1)/esz); int blocksize0 = (int)((BLOCK_SIZE + esz-1)/esz);
AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16); AutoBuffer<uchar> _buf((cn+1)*(sizeof(Mat*) + sizeof(uchar*)) + 16);
const Mat** arrays = (const Mat**)(uchar*)_buf; const Mat** arrays = (const Mat**)(uchar*)_buf;
uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16); uchar** ptrs = (uchar**)alignPtr(arrays + cn + 1, 16);
arrays[0] = &dst; arrays[0] = &dst;
for( k = 0; k < cn; k++ ) for( k = 0; k < cn; k++ )
arrays[k+1] = &mv[k]; arrays[k+1] = &mv[k];
NAryMatIterator it(arrays, ptrs, cn+1); NAryMatIterator it(arrays, ptrs, cn+1);
int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0); int total = (int)it.size, blocksize = cn <= 4 ? total : std::min(total, blocksize0);
MergeFunc func = mergeTab[depth]; MergeFunc func = mergeTab[depth];
for( i = 0; i < it.nplanes; i++, ++it ) for( i = 0; i < it.nplanes; i++, ++it )
{ {
for( int j = 0; j < total; j += blocksize ) for( int j = 0; j < total; j += blocksize )
{ {
int bsz = std::min(total - j, blocksize); int bsz = std::min(total - j, blocksize);
func( (const uchar**)&ptrs[1], ptrs[0], bsz, cn ); func( (const uchar**)&ptrs[1], ptrs[0], bsz, cn );
if( j + blocksize < total ) if( j + blocksize < total )
{ {
ptrs[0] += bsz*esz; ptrs[0] += bsz*esz;
for( int k = 0; k < cn; k++ ) for( int t = 0; t < cn; t++ )
ptrs[k+1] += bsz*esz1; ptrs[t+1] += bsz*esz1;
} }
} }
} }
@ -338,7 +338,7 @@ void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
void cv::merge(const vector<Mat>& mv, OutputArray _dst) void cv::merge(const vector<Mat>& mv, OutputArray _dst)
{ {
merge(!mv.empty() ? &mv[0] : 0, mv.size(), _dst); merge(!mv.empty() ? &mv[0] : 0, mv.size(), _dst);
} }
/****************************************************************************************\ /****************************************************************************************\
* Generalized split/merge: mixing channels * * Generalized split/merge: mixing channels *
@ -378,7 +378,7 @@ mixChannels_( const T** src, const int* sdelta,
} }
} }
static void mixChannels8u( const uchar** src, const int* sdelta, static void mixChannels8u( const uchar** src, const int* sdelta,
uchar** dst, const int* ddelta, uchar** dst, const int* ddelta,
int len, int npairs ) int len, int npairs )
@ -399,14 +399,14 @@ static void mixChannels32s( const int** src, const int* sdelta,
{ {
mixChannels_(src, sdelta, dst, ddelta, len, npairs); mixChannels_(src, sdelta, dst, ddelta, len, npairs);
} }
static void mixChannels64s( const int64** src, const int* sdelta, static void mixChannels64s( const int64** src, const int* sdelta,
int64** dst, const int* ddelta, int64** dst, const int* ddelta,
int len, int npairs ) int len, int npairs )
{ {
mixChannels_(src, sdelta, dst, ddelta, len, npairs); mixChannels_(src, sdelta, dst, ddelta, len, npairs);
} }
typedef void (*MixChannelsFunc)( const uchar** src, const int* sdelta, typedef void (*MixChannelsFunc)( const uchar** src, const int* sdelta,
uchar** dst, const int* ddelta, int len, int npairs ); uchar** dst, const int* ddelta, int len, int npairs );
@ -414,17 +414,17 @@ static MixChannelsFunc mixchTab[] =
{ {
(MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels16u, (MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels8u, (MixChannelsFunc)mixChannels16u,
(MixChannelsFunc)mixChannels16u, (MixChannelsFunc)mixChannels32s, (MixChannelsFunc)mixChannels32s, (MixChannelsFunc)mixChannels16u, (MixChannelsFunc)mixChannels32s, (MixChannelsFunc)mixChannels32s,
(MixChannelsFunc)mixChannels64s, 0 (MixChannelsFunc)mixChannels64s, 0
}; };
} }
void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs ) void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs )
{ {
if( npairs == 0 ) if( npairs == 0 )
return; return;
CV_Assert( src && nsrcs > 0 && dst && ndsts > 0 && fromTo && npairs > 0 ); CV_Assert( src && nsrcs > 0 && dst && ndsts > 0 && fromTo && npairs > 0 );
size_t i, j, k, esz1 = dst[0].elemSize1(); size_t i, j, k, esz1 = dst[0].elemSize1();
int depth = dst[0].depth(); int depth = dst[0].depth();
@ -435,13 +435,13 @@ void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, cons
uchar** dsts = (uchar**)(srcs + npairs); uchar** dsts = (uchar**)(srcs + npairs);
int* tab = (int*)(dsts + npairs); int* tab = (int*)(dsts + npairs);
int *sdelta = (int*)(tab + npairs*4), *ddelta = sdelta + npairs; int *sdelta = (int*)(tab + npairs*4), *ddelta = sdelta + npairs;
for( i = 0; i < nsrcs; i++ ) for( i = 0; i < nsrcs; i++ )
arrays[i] = &src[i]; arrays[i] = &src[i];
for( i = 0; i < ndsts; i++ ) for( i = 0; i < ndsts; i++ )
arrays[i + nsrcs] = &dst[i]; arrays[i + nsrcs] = &dst[i];
ptrs[nsrcs + ndsts] = 0; ptrs[nsrcs + ndsts] = 0;
for( i = 0; i < npairs; i++ ) for( i = 0; i < npairs; i++ )
{ {
int i0 = fromTo[i*2], i1 = fromTo[i*2+1]; int i0 = fromTo[i*2], i1 = fromTo[i*2+1];
@ -459,7 +459,7 @@ void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, cons
tab[i*4] = (int)(nsrcs + ndsts); tab[i*4+1] = 0; tab[i*4] = (int)(nsrcs + ndsts); tab[i*4+1] = 0;
sdelta[i] = 0; sdelta[i] = 0;
} }
for( j = 0; j < ndsts; i1 -= dst[j].channels(), j++ ) for( j = 0; j < ndsts; i1 -= dst[j].channels(), j++ )
if( i1 < dst[j].channels() ) if( i1 < dst[j].channels() )
break; break;
@ -471,7 +471,7 @@ void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, cons
NAryMatIterator it(arrays, ptrs, (int)(nsrcs + ndsts)); NAryMatIterator it(arrays, ptrs, (int)(nsrcs + ndsts));
int total = (int)it.size, blocksize = std::min(total, (int)((BLOCK_SIZE + esz1-1)/esz1)); int total = (int)it.size, blocksize = std::min(total, (int)((BLOCK_SIZE + esz1-1)/esz1));
MixChannelsFunc func = mixchTab[depth]; MixChannelsFunc func = mixchTab[depth];
for( i = 0; i < it.nplanes; i++, ++it ) for( i = 0; i < it.nplanes; i++, ++it )
{ {
for( k = 0; k < npairs; k++ ) for( k = 0; k < npairs; k++ )
@ -479,13 +479,13 @@ void cv::mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, cons
srcs[k] = ptrs[tab[k*4]] + tab[k*4+1]; srcs[k] = ptrs[tab[k*4]] + tab[k*4+1];
dsts[k] = ptrs[tab[k*4+2]] + tab[k*4+3]; dsts[k] = ptrs[tab[k*4+2]] + tab[k*4+3];
} }
for( int j = 0; j < total; j += blocksize ) for( int t = 0; t < total; t += blocksize )
{ {
int bsz = std::min(total - j, blocksize); int bsz = std::min(total - t, blocksize);
func( srcs, sdelta, dsts, ddelta, bsz, (int)npairs ); func( srcs, sdelta, dsts, ddelta, bsz, (int)npairs );
if( j + blocksize < total ) if( t + blocksize < total )
for( k = 0; k < npairs; k++ ) for( k = 0; k < npairs; k++ )
{ {
srcs[k] += blocksize*sdelta[k]*esz1; srcs[k] += blocksize*sdelta[k]*esz1;
@ -515,7 +515,7 @@ void cv::mixChannels(InputArrayOfArrays src, InputArrayOfArrays dst,
int i; int i;
int nsrc = src_is_mat ? 1 : (int)src.total(); int nsrc = src_is_mat ? 1 : (int)src.total();
int ndst = dst_is_mat ? 1 : (int)dst.total(); int ndst = dst_is_mat ? 1 : (int)dst.total();
CV_Assert(fromTo.size()%2 == 0 && nsrc > 0 && ndst > 0); CV_Assert(fromTo.size()%2 == 0 && nsrc > 0 && ndst > 0);
cv::AutoBuffer<Mat> _buf(nsrc + ndst); cv::AutoBuffer<Mat> _buf(nsrc + ndst);
Mat* buf = _buf; Mat* buf = _buf;
@ -559,7 +559,7 @@ cvtScaleAbs_( const T* src, size_t sstep,
{ {
sstep /= sizeof(src[0]); sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]); dstep /= sizeof(dst[0]);
for( ; size.height--; src += sstep, dst += dstep ) for( ; size.height--; src += sstep, dst += dstep )
{ {
int x = 0; int x = 0;
@ -574,11 +574,11 @@ cvtScaleAbs_( const T* src, size_t sstep,
t1 = saturate_cast<DT>(std::abs(src[x+3]*scale + shift)); t1 = saturate_cast<DT>(std::abs(src[x+3]*scale + shift));
dst[x+2] = t0; dst[x+3] = t1; dst[x+2] = t0; dst[x+3] = t1;
} }
#endif #endif
for( ; x < size.width; x++ ) for( ; x < size.width; x++ )
dst[x] = saturate_cast<DT>(std::abs(src[x]*scale + shift)); dst[x] = saturate_cast<DT>(std::abs(src[x]*scale + shift));
} }
} }
template<typename T, typename DT, typename WT> static void template<typename T, typename DT, typename WT> static void
@ -588,7 +588,7 @@ cvtScale_( const T* src, size_t sstep,
{ {
sstep /= sizeof(src[0]); sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]); dstep /= sizeof(dst[0]);
for( ; size.height--; src += sstep, dst += dstep ) for( ; size.height--; src += sstep, dst += dstep )
{ {
int x = 0; int x = 0;
@ -614,7 +614,7 @@ cvtScale_( const T* src, size_t sstep,
template<> void template<> void
cvtScale_<short, short, float>( const short* src, size_t sstep, cvtScale_<short, short, float>( const short* src, size_t sstep,
short* dst, size_t dstep, Size size, short* dst, size_t dstep, Size size,
float scale, float shift ) float scale, float shift )
{ {
sstep /= sizeof(src[0]); sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]); dstep /= sizeof(dst[0]);
@ -639,13 +639,13 @@ cvtScale_<short, short, float>( const short* src, size_t sstep,
r1 = _mm_cvtps_epi32(rf1); r1 = _mm_cvtps_epi32(rf1);
r0 = _mm_packs_epi32(r0, r1); r0 = _mm_packs_epi32(r0, r1);
_mm_storeu_si128((__m128i*)(dst + x), r0); _mm_storeu_si128((__m128i*)(dst + x), r0);
} }
} }
#endif #endif
for(; x < size.width; x++ ) for(; x < size.width; x++ )
dst[x] = saturate_cast<short>(src[x]*scale + shift); dst[x] = saturate_cast<short>(src[x]*scale + shift);
} }
} }
@ -655,7 +655,7 @@ cvt_( const T* src, size_t sstep,
{ {
sstep /= sizeof(src[0]); sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]); dstep /= sizeof(dst[0]);
for( ; size.height--; src += sstep, dst += dstep ) for( ; size.height--; src += sstep, dst += dstep )
{ {
int x = 0; int x = 0;
@ -683,7 +683,7 @@ cvt_<float, short>( const float* src, size_t sstep,
{ {
sstep /= sizeof(src[0]); sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]); dstep /= sizeof(dst[0]);
for( ; size.height--; src += sstep, dst += dstep ) for( ; size.height--; src += sstep, dst += dstep )
{ {
int x = 0; int x = 0;
@ -693,10 +693,10 @@ cvt_<float, short>( const float* src, size_t sstep,
{ {
__m128 src128 = _mm_loadu_ps (src + x); __m128 src128 = _mm_loadu_ps (src + x);
__m128i src_int128 = _mm_cvtps_epi32 (src128); __m128i src_int128 = _mm_cvtps_epi32 (src128);
src128 = _mm_loadu_ps (src + x + 4); src128 = _mm_loadu_ps (src + x + 4);
__m128i src1_int128 = _mm_cvtps_epi32 (src128); __m128i src1_int128 = _mm_cvtps_epi32 (src128);
src1_int128 = _mm_packs_epi32(src_int128, src1_int128); src1_int128 = _mm_packs_epi32(src_int128, src1_int128);
_mm_storeu_si128((__m128i*)(dst + x),src1_int128); _mm_storeu_si128((__m128i*)(dst + x),src1_int128);
} }
@ -714,11 +714,11 @@ cpy_( const T* src, size_t sstep, T* dst, size_t dstep, Size size )
{ {
sstep /= sizeof(src[0]); sstep /= sizeof(src[0]);
dstep /= sizeof(dst[0]); dstep /= sizeof(dst[0]);
for( ; size.height--; src += sstep, dst += dstep ) for( ; size.height--; src += sstep, dst += dstep )
memcpy(dst, src, size.width*sizeof(src[0])); memcpy(dst, src, size.width*sizeof(src[0]));
} }
#define DEF_CVT_SCALE_ABS_FUNC(suffix, tfunc, stype, dtype, wtype) \ #define DEF_CVT_SCALE_ABS_FUNC(suffix, tfunc, stype, dtype, wtype) \
static void cvtScaleAbs##suffix( const stype* src, size_t sstep, const uchar*, size_t, \ static void cvtScaleAbs##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
dtype* dst, size_t dstep, Size size, double* scale) \ dtype* dst, size_t dstep, Size size, double* scale) \
@ -732,8 +732,8 @@ dtype* dst, size_t dstep, Size size, double* scale) \
{ \ { \
cvtScale_(src, sstep, dst, dstep, size, (wtype)scale[0], (wtype)scale[1]); \ cvtScale_(src, sstep, dst, dstep, size, (wtype)scale[0], (wtype)scale[1]); \
} }
#define DEF_CVT_FUNC(suffix, stype, dtype) \ #define DEF_CVT_FUNC(suffix, stype, dtype) \
static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \ static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
dtype* dst, size_t dstep, Size size, double*) \ dtype* dst, size_t dstep, Size size, double*) \
@ -747,15 +747,15 @@ stype* dst, size_t dstep, Size size, double*) \
{ \ { \
cpy_(src, sstep, dst, dstep, size); \ cpy_(src, sstep, dst, dstep, size); \
} }
DEF_CVT_SCALE_ABS_FUNC(8u, cvtScaleAbs_, uchar, uchar, float); DEF_CVT_SCALE_ABS_FUNC(8u, cvtScaleAbs_, uchar, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(8s8u, cvtScaleAbs_, schar, uchar, float); DEF_CVT_SCALE_ABS_FUNC(8s8u, cvtScaleAbs_, schar, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(16u8u, cvtScaleAbs_, ushort, uchar, float); DEF_CVT_SCALE_ABS_FUNC(16u8u, cvtScaleAbs_, ushort, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(16s8u, cvtScaleAbs_, short, uchar, float); DEF_CVT_SCALE_ABS_FUNC(16s8u, cvtScaleAbs_, short, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(32s8u, cvtScaleAbs_, int, uchar, float); DEF_CVT_SCALE_ABS_FUNC(32s8u, cvtScaleAbs_, int, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(32f8u, cvtScaleAbs_, float, uchar, float); DEF_CVT_SCALE_ABS_FUNC(32f8u, cvtScaleAbs_, float, uchar, float);
DEF_CVT_SCALE_ABS_FUNC(64f8u, cvtScaleAbs_, double, uchar, float); DEF_CVT_SCALE_ABS_FUNC(64f8u, cvtScaleAbs_, double, uchar, float);
DEF_CVT_SCALE_FUNC(8u, uchar, uchar, float); DEF_CVT_SCALE_FUNC(8u, uchar, uchar, float);
DEF_CVT_SCALE_FUNC(8s8u, schar, uchar, float); DEF_CVT_SCALE_FUNC(8s8u, schar, uchar, float);
@ -763,7 +763,7 @@ DEF_CVT_SCALE_FUNC(16u8u, ushort, uchar, float);
DEF_CVT_SCALE_FUNC(16s8u, short, uchar, float); DEF_CVT_SCALE_FUNC(16s8u, short, uchar, float);
DEF_CVT_SCALE_FUNC(32s8u, int, uchar, float); DEF_CVT_SCALE_FUNC(32s8u, int, uchar, float);
DEF_CVT_SCALE_FUNC(32f8u, float, uchar, float); DEF_CVT_SCALE_FUNC(32f8u, float, uchar, float);
DEF_CVT_SCALE_FUNC(64f8u, double, uchar, float); DEF_CVT_SCALE_FUNC(64f8u, double, uchar, float);
DEF_CVT_SCALE_FUNC(8u8s, uchar, schar, float); DEF_CVT_SCALE_FUNC(8u8s, uchar, schar, float);
DEF_CVT_SCALE_FUNC(8s, schar, schar, float); DEF_CVT_SCALE_FUNC(8s, schar, schar, float);
@ -771,7 +771,7 @@ DEF_CVT_SCALE_FUNC(16u8s, ushort, schar, float);
DEF_CVT_SCALE_FUNC(16s8s, short, schar, float); DEF_CVT_SCALE_FUNC(16s8s, short, schar, float);
DEF_CVT_SCALE_FUNC(32s8s, int, schar, float); DEF_CVT_SCALE_FUNC(32s8s, int, schar, float);
DEF_CVT_SCALE_FUNC(32f8s, float, schar, float); DEF_CVT_SCALE_FUNC(32f8s, float, schar, float);
DEF_CVT_SCALE_FUNC(64f8s, double, schar, float); DEF_CVT_SCALE_FUNC(64f8s, double, schar, float);
DEF_CVT_SCALE_FUNC(8u16u, uchar, ushort, float); DEF_CVT_SCALE_FUNC(8u16u, uchar, ushort, float);
DEF_CVT_SCALE_FUNC(8s16u, schar, ushort, float); DEF_CVT_SCALE_FUNC(8s16u, schar, ushort, float);
@ -779,7 +779,7 @@ DEF_CVT_SCALE_FUNC(16u, ushort, ushort, float);
DEF_CVT_SCALE_FUNC(16s16u, short, ushort, float); DEF_CVT_SCALE_FUNC(16s16u, short, ushort, float);
DEF_CVT_SCALE_FUNC(32s16u, int, ushort, float); DEF_CVT_SCALE_FUNC(32s16u, int, ushort, float);
DEF_CVT_SCALE_FUNC(32f16u, float, ushort, float); DEF_CVT_SCALE_FUNC(32f16u, float, ushort, float);
DEF_CVT_SCALE_FUNC(64f16u, double, ushort, float); DEF_CVT_SCALE_FUNC(64f16u, double, ushort, float);
DEF_CVT_SCALE_FUNC(8u16s, uchar, short, float); DEF_CVT_SCALE_FUNC(8u16s, uchar, short, float);
DEF_CVT_SCALE_FUNC(8s16s, schar, short, float); DEF_CVT_SCALE_FUNC(8s16s, schar, short, float);
@ -788,7 +788,7 @@ DEF_CVT_SCALE_FUNC(16s, short, short, float);
DEF_CVT_SCALE_FUNC(32s16s, int, short, float); DEF_CVT_SCALE_FUNC(32s16s, int, short, float);
DEF_CVT_SCALE_FUNC(32f16s, float, short, float); DEF_CVT_SCALE_FUNC(32f16s, float, short, float);
DEF_CVT_SCALE_FUNC(64f16s, double, short, float); DEF_CVT_SCALE_FUNC(64f16s, double, short, float);
DEF_CVT_SCALE_FUNC(8u32s, uchar, int, float); DEF_CVT_SCALE_FUNC(8u32s, uchar, int, float);
DEF_CVT_SCALE_FUNC(8s32s, schar, int, float); DEF_CVT_SCALE_FUNC(8s32s, schar, int, float);
DEF_CVT_SCALE_FUNC(16u32s, ushort, int, float); DEF_CVT_SCALE_FUNC(16u32s, ushort, int, float);
@ -865,7 +865,7 @@ DEF_CVT_FUNC(16s64f, short, double);
DEF_CVT_FUNC(32s64f, int, double); DEF_CVT_FUNC(32s64f, int, double);
DEF_CVT_FUNC(32f64f, float, double); DEF_CVT_FUNC(32f64f, float, double);
DEF_CPY_FUNC(64s, int64); DEF_CPY_FUNC(64s, int64);
static BinaryFunc cvtScaleAbsTab[] = static BinaryFunc cvtScaleAbsTab[] =
{ {
(BinaryFunc)cvtScaleAbs8u, (BinaryFunc)cvtScaleAbs8s8u, (BinaryFunc)cvtScaleAbs16u8u, (BinaryFunc)cvtScaleAbs8u, (BinaryFunc)cvtScaleAbs8s8u, (BinaryFunc)cvtScaleAbs16u8u,
@ -956,7 +956,7 @@ static BinaryFunc cvtTab[][8] =
0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0
} }
}; };
BinaryFunc getConvertFunc(int sdepth, int ddepth) BinaryFunc getConvertFunc(int sdepth, int ddepth)
{ {
return cvtTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)]; return cvtTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)];
@ -965,10 +965,10 @@ BinaryFunc getConvertFunc(int sdepth, int ddepth)
BinaryFunc getConvertScaleFunc(int sdepth, int ddepth) BinaryFunc getConvertScaleFunc(int sdepth, int ddepth)
{ {
return cvtScaleTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)]; return cvtScaleTab[CV_MAT_DEPTH(ddepth)][CV_MAT_DEPTH(sdepth)];
}
} }
}
void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, double beta ) void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, double beta )
{ {
Mat src = _src.getMat(); Mat src = _src.getMat();
@ -978,7 +978,7 @@ void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, doubl
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
BinaryFunc func = cvtScaleAbsTab[src.depth()]; BinaryFunc func = cvtScaleAbsTab[src.depth()];
CV_Assert( func != 0 ); CV_Assert( func != 0 );
if( src.dims <= 2 ) if( src.dims <= 2 )
{ {
Size sz = getContinuousSize(src, dst, cn); Size sz = getContinuousSize(src, dst, cn);
@ -990,7 +990,7 @@ void cv::convertScaleAbs( InputArray _src, OutputArray _dst, double alpha, doubl
uchar* ptrs[2]; uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs); NAryMatIterator it(arrays, ptrs);
Size sz((int)it.size*cn, 1); Size sz((int)it.size*cn, 1);
for( size_t i = 0; i < it.nplanes; i++, ++it ) for( size_t i = 0; i < it.nplanes; i++, ++it )
func( ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale ); func( ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale );
} }
@ -1013,12 +1013,12 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta)
} }
Mat src = *this; Mat src = *this;
BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth); BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth);
double scale[] = {alpha, beta}; double scale[] = {alpha, beta};
int cn = channels(); int cn = channels();
CV_Assert( func != 0 ); CV_Assert( func != 0 );
if( dims <= 2 ) if( dims <= 2 )
{ {
_dst.create( size(), _type ); _dst.create( size(), _type );
@ -1034,7 +1034,7 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta)
uchar* ptrs[2]; uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs); NAryMatIterator it(arrays, ptrs);
Size sz((int)(it.size*cn), 1); Size sz((int)(it.size*cn), 1);
for( size_t i = 0; i < it.nplanes; i++, ++it ) for( size_t i = 0; i < it.nplanes; i++, ++it )
func(ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale); func(ptrs[0], 0, 0, 0, ptrs[1], 0, sz, scale);
} }
@ -1096,10 +1096,10 @@ static void LUT8u_32f( const uchar* src, const float* lut, float* dst, int len,
static void LUT8u_64f( const uchar* src, const double* lut, double* dst, int len, int cn, int lutcn ) static void LUT8u_64f( const uchar* src, const double* lut, double* dst, int len, int cn, int lutcn )
{ {
LUT8u_( src, lut, dst, len, cn, lutcn ); LUT8u_( src, lut, dst, len, cn, lutcn );
} }
typedef void (*LUTFunc)( const uchar* src, const uchar* lut, uchar* dst, int len, int cn, int lutcn ); typedef void (*LUTFunc)( const uchar* src, const uchar* lut, uchar* dst, int len, int cn, int lutcn );
static LUTFunc lutTab[] = static LUTFunc lutTab[] =
{ {
(LUTFunc)LUT8u_8u, (LUTFunc)LUT8u_8s, (LUTFunc)LUT8u_16u, (LUTFunc)LUT8u_16s, (LUTFunc)LUT8u_8u, (LUTFunc)LUT8u_8s, (LUTFunc)LUT8u_16u, (LUTFunc)LUT8u_16s,
@ -1107,7 +1107,7 @@ static LUTFunc lutTab[] =
}; };
} }
void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst, int interpolation ) void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst, int interpolation )
{ {
Mat src = _src.getMat(), lut = _lut.getMat(); Mat src = _src.getMat(), lut = _lut.getMat();
@ -1123,12 +1123,12 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst, int interpolat
LUTFunc func = lutTab[lut.depth()]; LUTFunc func = lutTab[lut.depth()];
CV_Assert( func != 0 ); CV_Assert( func != 0 );
const Mat* arrays[] = {&src, &dst, 0}; const Mat* arrays[] = {&src, &dst, 0};
uchar* ptrs[2]; uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs); NAryMatIterator it(arrays, ptrs);
int len = (int)it.size; int len = (int)it.size;
for( size_t i = 0; i < it.nplanes; i++, ++it ) for( size_t i = 0; i < it.nplanes; i++, ++it )
func(ptrs[0], lut.data, ptrs[1], len, cn, lutcn); func(ptrs[0], lut.data, ptrs[1], len, cn, lutcn);
} }
@ -1138,7 +1138,7 @@ void cv::normalize( InputArray _src, OutputArray _dst, double a, double b,
int norm_type, int rtype, InputArray _mask ) int norm_type, int rtype, InputArray _mask )
{ {
Mat src = _src.getMat(), mask = _mask.getMat(); Mat src = _src.getMat(), mask = _mask.getMat();
double scale = 1, shift = 0; double scale = 1, shift = 0;
if( norm_type == CV_MINMAX ) if( norm_type == CV_MINMAX )
{ {
@ -1156,13 +1156,13 @@ void cv::normalize( InputArray _src, OutputArray _dst, double a, double b,
} }
else else
CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" ); CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" );
if( rtype < 0 ) if( rtype < 0 )
rtype = _dst.fixedType() ? _dst.depth() : src.depth(); rtype = _dst.fixedType() ? _dst.depth() : src.depth();
_dst.create(src.dims, src.size, CV_MAKETYPE(rtype, src.channels())); _dst.create(src.dims, src.size, CV_MAKETYPE(rtype, src.channels()));
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
if( !mask.data ) if( !mask.data )
src.convertTo( dst, rtype, scale, shift ); src.convertTo( dst, rtype, scale, shift );
else else
@ -1273,7 +1273,7 @@ cvConvertScale( const void* srcarr, void* dstarr,
double scale, double shift ) double scale, double shift )
{ {
cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr); cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
CV_Assert( src.size == dst.size && src.channels() == dst.channels() ); CV_Assert( src.size == dst.size && src.channels() == dst.channels() );
src.convertTo(dst, dst.type(), scale, shift); src.convertTo(dst, dst.type(), scale, shift);
} }

View File

@ -59,7 +59,7 @@ copyMask_(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, ucha
const T* src = (const T*)_src; const T* src = (const T*)_src;
T* dst = (T*)_dst; T* dst = (T*)_dst;
int x = 0; int x = 0;
#if CV_ENABLE_UNROLLED #if CV_ENABLE_UNROLLED
for( ; x <= size.width - 4; x += 4 ) for( ; x <= size.width - 4; x += 4 )
{ {
if( mask[x] ) if( mask[x] )
@ -96,16 +96,16 @@ copyMaskGeneric(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep
} }
} }
} }
#define DEF_COPY_MASK(suffix, type) \ #define DEF_COPY_MASK(suffix, type) \
static void copyMask##suffix(const uchar* src, size_t sstep, const uchar* mask, size_t mstep, \ static void copyMask##suffix(const uchar* src, size_t sstep, const uchar* mask, size_t mstep, \
uchar* dst, size_t dstep, Size size, void*) \ uchar* dst, size_t dstep, Size size, void*) \
{ \ { \
copyMask_<type>(src, sstep, mask, mstep, dst, dstep, size); \ copyMask_<type>(src, sstep, mask, mstep, dst, dstep, size); \
} }
DEF_COPY_MASK(8u, uchar); DEF_COPY_MASK(8u, uchar);
DEF_COPY_MASK(16u, ushort); DEF_COPY_MASK(16u, ushort);
DEF_COPY_MASK(8uC3, Vec3b); DEF_COPY_MASK(8uC3, Vec3b);
@ -116,7 +116,7 @@ DEF_COPY_MASK(32sC3, Vec3i);
DEF_COPY_MASK(32sC4, Vec4i); DEF_COPY_MASK(32sC4, Vec4i);
DEF_COPY_MASK(32sC6, Vec6i); DEF_COPY_MASK(32sC6, Vec6i);
DEF_COPY_MASK(32sC8, Vec8i); DEF_COPY_MASK(32sC8, Vec8i);
BinaryFunc copyMaskTab[] = BinaryFunc copyMaskTab[] =
{ {
0, 0,
@ -137,7 +137,7 @@ BinaryFunc copyMaskTab[] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
copyMask32sC8 copyMask32sC8
}; };
BinaryFunc getCopyMaskFunc(size_t esz) BinaryFunc getCopyMaskFunc(size_t esz)
{ {
return esz <= 32 && copyMaskTab[esz] ? copyMaskTab[esz] : copyMaskGeneric; return esz <= 32 && copyMaskTab[esz] ? copyMaskTab[esz] : copyMaskGeneric;
@ -152,51 +152,51 @@ void Mat::copyTo( OutputArray _dst ) const
convertTo( _dst, dtype ); convertTo( _dst, dtype );
return; return;
} }
if( empty() ) if( empty() )
{ {
_dst.release(); _dst.release();
return; return;
} }
if( dims <= 2 ) if( dims <= 2 )
{ {
_dst.create( rows, cols, type() ); _dst.create( rows, cols, type() );
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
if( data == dst.data ) if( data == dst.data )
return; return;
if( rows > 0 && cols > 0 ) if( rows > 0 && cols > 0 )
{ {
const uchar* sptr = data; const uchar* sptr = data;
uchar* dptr = dst.data; uchar* dptr = dst.data;
// to handle the copying 1xn matrix => nx1 std vector. // to handle the copying 1xn matrix => nx1 std vector.
Size sz = size() == dst.size() ? Size sz = size() == dst.size() ?
getContinuousSize(*this, dst) : getContinuousSize(*this, dst) :
getContinuousSize(*this); getContinuousSize(*this);
size_t len = sz.width*elemSize(); size_t len = sz.width*elemSize();
for( ; sz.height--; sptr += step, dptr += dst.step ) for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, len ); memcpy( dptr, sptr, len );
} }
return; return;
} }
_dst.create( dims, size, type() ); _dst.create( dims, size, type() );
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
if( data == dst.data ) if( data == dst.data )
return; return;
if( total() != 0 ) if( total() != 0 )
{ {
const Mat* arrays[] = { this, &dst }; const Mat* arrays[] = { this, &dst };
uchar* ptrs[2]; uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2); NAryMatIterator it(arrays, ptrs, 2);
size_t size = it.size*elemSize(); size_t sz = it.size*elemSize();
for( size_t i = 0; i < it.nplanes; i++, ++it ) for( size_t i = 0; i < it.nplanes; i++, ++it )
memcpy(ptrs[1], ptrs[0], size); memcpy(ptrs[1], ptrs[0], sz);
} }
} }
@ -208,33 +208,33 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
copyTo(_dst); copyTo(_dst);
return; return;
} }
int cn = channels(), mcn = mask.channels(); int cn = channels(), mcn = mask.channels();
CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) ); CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) );
bool colorMask = mcn > 1; bool colorMask = mcn > 1;
size_t esz = colorMask ? elemSize1() : elemSize(); size_t esz = colorMask ? elemSize1() : elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz); BinaryFunc copymask = getCopyMaskFunc(esz);
uchar* data0 = _dst.getMat().data; uchar* data0 = _dst.getMat().data;
_dst.create( dims, size, type() ); _dst.create( dims, size, type() );
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
if( dst.data != data0 ) // do not leave dst uninitialized if( dst.data != data0 ) // do not leave dst uninitialized
dst = Scalar(0); dst = Scalar(0);
if( dims <= 2 ) if( dims <= 2 )
{ {
Size sz = getContinuousSize(*this, dst, mask, mcn); Size sz = getContinuousSize(*this, dst, mask, mcn);
copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz); copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
return; return;
} }
const Mat* arrays[] = { this, &dst, &mask, 0 }; const Mat* arrays[] = { this, &dst, &mask, 0 };
uchar* ptrs[3]; uchar* ptrs[3];
NAryMatIterator it(arrays, ptrs); NAryMatIterator it(arrays, ptrs);
Size sz((int)(it.size*mcn), 1); Size sz((int)(it.size*mcn), 1);
for( size_t i = 0; i < it.nplanes; i++, ++it ) for( size_t i = 0; i < it.nplanes; i++, ++it )
copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz); copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz);
} }
@ -242,14 +242,14 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
Mat& Mat::operator = (const Scalar& s) Mat& Mat::operator = (const Scalar& s)
{ {
const Mat* arrays[] = { this }; const Mat* arrays[] = { this };
uchar* ptr; uchar* dptr;
NAryMatIterator it(arrays, &ptr, 1); NAryMatIterator it(arrays, &dptr, 1);
size_t size = it.size*elemSize(); size_t elsize = it.size*elemSize();
if( s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0 ) if( s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0 )
{ {
for( size_t i = 0; i < it.nplanes; i++, ++it ) for( size_t i = 0; i < it.nplanes; i++, ++it )
memset( ptr, 0, size ); memset( dptr, 0, elsize );
} }
else else
{ {
@ -258,50 +258,50 @@ Mat& Mat::operator = (const Scalar& s)
double scalar[12]; double scalar[12];
scalarToRawData(s, scalar, type(), 12); scalarToRawData(s, scalar, type(), 12);
size_t blockSize = 12*elemSize1(); size_t blockSize = 12*elemSize1();
for( size_t j = 0; j < size; j += blockSize ) for( size_t j = 0; j < elsize; j += blockSize )
{ {
size_t sz = MIN(blockSize, size - j); size_t sz = MIN(blockSize, elsize - j);
memcpy( ptr + j, scalar, sz ); memcpy( dptr + j, scalar, sz );
} }
} }
for( size_t i = 1; i < it.nplanes; i++ ) for( size_t i = 1; i < it.nplanes; i++ )
{ {
++it; ++it;
memcpy( ptr, data, size ); memcpy( dptr, data, elsize );
} }
} }
return *this; return *this;
} }
Mat& Mat::setTo(InputArray _value, InputArray _mask) Mat& Mat::setTo(InputArray _value, InputArray _mask)
{ {
if( !data ) if( !data )
return *this; return *this;
Mat value = _value.getMat(), mask = _mask.getMat(); Mat value = _value.getMat(), mask = _mask.getMat();
CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::MAT )); CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::MAT ));
CV_Assert( mask.empty() || mask.type() == CV_8U ); CV_Assert( mask.empty() || mask.type() == CV_8U );
size_t esz = elemSize(); size_t esz = elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz); BinaryFunc copymask = getCopyMaskFunc(esz);
const Mat* arrays[] = { this, !mask.empty() ? &mask : 0, 0 }; const Mat* arrays[] = { this, !mask.empty() ? &mask : 0, 0 };
uchar* ptrs[2]={0,0}; uchar* ptrs[2]={0,0};
NAryMatIterator it(arrays, ptrs); NAryMatIterator it(arrays, ptrs);
int total = (int)it.size, blockSize0 = std::min(total, (int)((BLOCK_SIZE + esz-1)/esz)); int totalsz = (int)it.size, blockSize0 = std::min(totalsz, (int)((BLOCK_SIZE + esz-1)/esz));
AutoBuffer<uchar> _scbuf(blockSize0*esz + 32); AutoBuffer<uchar> _scbuf(blockSize0*esz + 32);
uchar* scbuf = alignPtr((uchar*)_scbuf, (int)sizeof(double)); uchar* scbuf = alignPtr((uchar*)_scbuf, (int)sizeof(double));
convertAndUnrollScalar( value, type(), scbuf, blockSize0 ); convertAndUnrollScalar( value, type(), scbuf, blockSize0 );
for( size_t i = 0; i < it.nplanes; i++, ++it ) for( size_t i = 0; i < it.nplanes; i++, ++it )
{ {
for( int j = 0; j < total; j += blockSize0 ) for( int j = 0; j < totalsz; j += blockSize0 )
{ {
Size sz(std::min(blockSize0, total - j), 1); Size sz(std::min(blockSize0, totalsz - j), 1);
size_t blockSize = sz.width*esz; size_t blockSize = sz.width*esz;
if( ptrs[1] ) if( ptrs[1] )
{ {
@ -323,7 +323,7 @@ flipHoriz( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size size,
int i, j, limit = (int)(((size.width + 1)/2)*esz); int i, j, limit = (int)(((size.width + 1)/2)*esz);
AutoBuffer<int> _tab(size.width*esz); AutoBuffer<int> _tab(size.width*esz);
int* tab = _tab; int* tab = _tab;
for( i = 0; i < size.width; i++ ) for( i = 0; i < size.width; i++ )
for( size_t k = 0; k < esz; k++ ) for( size_t k = 0; k < esz; k++ )
tab[i*esz + k] = (int)((size.width - i - 1)*esz + k); tab[i*esz + k] = (int)((size.width - i - 1)*esz + k);
@ -403,7 +403,7 @@ flipVert( const uchar* src0, size_t sstep, uchar* dst0, size_t dstep, Size size,
void flip( InputArray _src, OutputArray _dst, int flip_mode ) void flip( InputArray _src, OutputArray _dst, int flip_mode )
{ {
Mat src = _src.getMat(); Mat src = _src.getMat();
CV_Assert( src.dims <= 2 ); CV_Assert( src.dims <= 2 );
_dst.create( src.size(), src.type() ); _dst.create( src.size(), src.type() );
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
@ -413,7 +413,7 @@ void flip( InputArray _src, OutputArray _dst, int flip_mode )
flipVert( src.data, src.step, dst.data, dst.step, src.size(), esz ); flipVert( src.data, src.step, dst.data, dst.step, src.size(), esz );
else else
flipHoriz( src.data, src.step, dst.data, dst.step, src.size(), esz ); flipHoriz( src.data, src.step, dst.data, dst.step, src.size(), esz );
if( flip_mode < 0 ) if( flip_mode < 0 )
flipHoriz( dst.data, dst.step, dst.data, dst.step, dst.size(), esz ); flipHoriz( dst.data, dst.step, dst.data, dst.step, dst.size(), esz );
} }
@ -423,7 +423,7 @@ void repeat(InputArray _src, int ny, int nx, OutputArray _dst)
{ {
Mat src = _src.getMat(); Mat src = _src.getMat();
CV_Assert( src.dims <= 2 ); CV_Assert( src.dims <= 2 );
_dst.create(src.rows*ny, src.cols*nx, src.type()); _dst.create(src.rows*ny, src.cols*nx, src.type());
Mat dst = _dst.getMat(); Mat dst = _dst.getMat();
Size ssize = src.size(), dsize = dst.size(); Size ssize = src.size(), dsize = dst.size();
@ -493,25 +493,25 @@ cvCopy( const void* srcarr, void* dstarr, const void* maskarr )
} }
cv::Mat src = cv::cvarrToMat(srcarr, false, true, 1), dst = cv::cvarrToMat(dstarr, false, true, 1); cv::Mat src = cv::cvarrToMat(srcarr, false, true, 1), dst = cv::cvarrToMat(dstarr, false, true, 1);
CV_Assert( src.depth() == dst.depth() && src.size == dst.size ); CV_Assert( src.depth() == dst.depth() && src.size == dst.size );
int coi1 = 0, coi2 = 0; int coi1 = 0, coi2 = 0;
if( CV_IS_IMAGE(srcarr) ) if( CV_IS_IMAGE(srcarr) )
coi1 = cvGetImageCOI((const IplImage*)srcarr); coi1 = cvGetImageCOI((const IplImage*)srcarr);
if( CV_IS_IMAGE(dstarr) ) if( CV_IS_IMAGE(dstarr) )
coi2 = cvGetImageCOI((const IplImage*)dstarr); coi2 = cvGetImageCOI((const IplImage*)dstarr);
if( coi1 || coi2 ) if( coi1 || coi2 )
{ {
CV_Assert( (coi1 != 0 || src.channels() == 1) && CV_Assert( (coi1 != 0 || src.channels() == 1) &&
(coi2 != 0 || dst.channels() == 1) ); (coi2 != 0 || dst.channels() == 1) );
int pair[] = { std::max(coi1-1, 0), std::max(coi2-1, 0) }; int pair[] = { std::max(coi1-1, 0), std::max(coi2-1, 0) };
cv::mixChannels( &src, 1, &dst, 1, pair, 1 ); cv::mixChannels( &src, 1, &dst, 1, pair, 1 );
return; return;
} }
else else
CV_Assert( src.channels() == dst.channels() ); CV_Assert( src.channels() == dst.channels() );
if( !maskarr ) if( !maskarr )
src.copyTo(dst); src.copyTo(dst);
else else
@ -548,12 +548,12 @@ cvFlip( const CvArr* srcarr, CvArr* dstarr, int flip_mode )
{ {
cv::Mat src = cv::cvarrToMat(srcarr); cv::Mat src = cv::cvarrToMat(srcarr);
cv::Mat dst; cv::Mat dst;
if (!dstarr) if (!dstarr)
dst = src; dst = src;
else else
dst = cv::cvarrToMat(dstarr); dst = cv::cvarrToMat(dstarr);
CV_Assert( src.type() == dst.type() && src.size() == dst.size() ); CV_Assert( src.type() == dst.type() && src.size() == dst.size() );
cv::flip( src, dst, flip_mode ); cv::flip( src, dst, flip_mode );
} }

View File

@ -3349,7 +3349,7 @@ cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage )
} }
} }
return allseq; return allseq;
} }
@ -3531,9 +3531,9 @@ namespace cv
// both cv (CvFeatureTree) and ml (kNN). // both cv (CvFeatureTree) and ml (kNN).
// The algorithm is taken from: // The algorithm is taken from:
// J.S. Beis and D.G. Lowe. Shape indexing using approximate nearest-neighbor search // J.S. Beis and D.G. Lowe. Shape indexing using approximate nearest-neighbor search
// in highdimensional spaces. In Proc. IEEE Conf. Comp. Vision Patt. Recog., // in highdimensional spaces. In Proc. IEEE Conf. Comp. Vision Patt. Recog.,
// pages 1000--1006, 1997. http://citeseer.ist.psu.edu/beis97shape.html // pages 1000--1006, 1997. http://citeseer.ist.psu.edu/beis97shape.html
const int MAX_TREE_DEPTH = 32; const int MAX_TREE_DEPTH = 32;
@ -3555,8 +3555,8 @@ KDTree::KDTree(InputArray _points, InputArray _labels, bool _copyData)
maxDepth = -1; maxDepth = -1;
normType = NORM_L2; normType = NORM_L2;
build(_points, _labels, _copyData); build(_points, _labels, _copyData);
} }
struct SubTree struct SubTree
{ {
SubTree() : first(0), last(0), nodeIdx(0), depth(0) {} SubTree() : first(0), last(0), nodeIdx(0), depth(0) {}
@ -3596,7 +3596,7 @@ medianPartition( size_t* ofs, int a, int b, const float* vals )
else else
a = i0; a = i0;
} }
float pivot = vals[ofs[middle]]; float pivot = vals[ofs[middle]];
int less = 0, more = 0; int less = 0, more = 0;
for( k = a0; k < middle; k++ ) for( k = a0; k < middle; k++ )
@ -3632,7 +3632,7 @@ computeSums( const Mat& points, const size_t* ofs, int a, int b, double* sums )
} }
} }
void KDTree::build(InputArray _points, bool _copyData) void KDTree::build(InputArray _points, bool _copyData)
{ {
build(_points, noArray(), _copyData); build(_points, noArray(), _copyData);
@ -3652,8 +3652,8 @@ void KDTree::build(InputArray __points, InputArray __labels, bool _copyData)
points.release(); points.release();
points.create(_points.size(), _points.type()); points.create(_points.size(), _points.type());
} }
int i, j, n = _points.rows, dims = _points.cols, top = 0; int i, j, n = _points.rows, ptdims = _points.cols, top = 0;
const float* data = _points.ptr<float>(0); const float* data = _points.ptr<float>(0);
float* dstdata = points.ptr<float>(0); float* dstdata = points.ptr<float>(0);
size_t step = _points.step1(); size_t step = _points.step1();
@ -3661,7 +3661,7 @@ void KDTree::build(InputArray __points, InputArray __labels, bool _copyData)
int ptpos = 0; int ptpos = 0;
labels.resize(n); labels.resize(n);
const int* _labels_data = 0; const int* _labels_data = 0;
if( !_labels.empty() ) if( !_labels.empty() )
{ {
int nlabels = _labels.checkVector(1, CV_32S, true); int nlabels = _labels.checkVector(1, CV_32S, true);
@ -3669,9 +3669,9 @@ void KDTree::build(InputArray __points, InputArray __labels, bool _copyData)
_labels_data = (const int*)_labels.data; _labels_data = (const int*)_labels.data;
} }
Mat sumstack(MAX_TREE_DEPTH*2, dims*2, CV_64F); Mat sumstack(MAX_TREE_DEPTH*2, ptdims*2, CV_64F);
SubTree stack[MAX_TREE_DEPTH*2]; SubTree stack[MAX_TREE_DEPTH*2];
vector<size_t> _ptofs(n); vector<size_t> _ptofs(n);
size_t* ptofs = &_ptofs[0]; size_t* ptofs = &_ptofs[0];
@ -3682,7 +3682,7 @@ void KDTree::build(InputArray __points, InputArray __labels, bool _copyData)
computeSums(points, ptofs, 0, n-1, sumstack.ptr<double>(top)); computeSums(points, ptofs, 0, n-1, sumstack.ptr<double>(top));
stack[top++] = SubTree(0, n-1, 0, 0); stack[top++] = SubTree(0, n-1, 0, 0);
int _maxDepth = 0; int _maxDepth = 0;
while( --top >= 0 ) while( --top >= 0 )
{ {
int first = stack[top].first, last = stack[top].last; int first = stack[top].first, last = stack[top].last;
@ -3700,16 +3700,16 @@ void KDTree::build(InputArray __points, InputArray __labels, bool _copyData)
{ {
const float* src = data + ptofs[first]; const float* src = data + ptofs[first];
float* dst = dstdata + idx*dstep; float* dst = dstdata + idx*dstep;
for( j = 0; j < dims; j++ ) for( j = 0; j < ptdims; j++ )
dst[j] = src[j]; dst[j] = src[j];
} }
labels[idx] = _labels_data ? _labels_data[idx0] : idx0; labels[idx] = _labels_data ? _labels_data[idx0] : idx0;
_maxDepth = std::max(_maxDepth, depth); _maxDepth = std::max(_maxDepth, depth);
continue; continue;
} }
// find the dimensionality with the biggest variance // find the dimensionality with the biggest variance
for( j = 0; j < dims; j++ ) for( j = 0; j < ptdims; j++ )
{ {
double m = sums[j*2]*invCount; double m = sums[j*2]*invCount;
double varj = sums[j*2+1]*invCount - m*m; double varj = sums[j*2+1]*invCount - m*m;
@ -3729,9 +3729,9 @@ void KDTree::build(InputArray __points, InputArray __labels, bool _copyData)
nodes[nidx].boundary = medianPartition(ptofs, first, last, data + dim); nodes[nidx].boundary = medianPartition(ptofs, first, last, data + dim);
int middle = (first + last)/2; int middle = (first + last)/2;
double *lsums = (double*)sums, *rsums = lsums + dims*2; double *lsums = (double*)sums, *rsums = lsums + ptdims*2;
computeSums(points, ptofs, middle+1, last, rsums); computeSums(points, ptofs, middle+1, last, rsums);
for( j = 0; j < dims*2; j++ ) for( j = 0; j < ptdims*2; j++ )
lsums[j] = sums[j] - rsums[j]; lsums[j] = sums[j] - rsums[j];
stack[top++] = SubTree(first, middle, left, depth+1); stack[top++] = SubTree(first, middle, left, depth+1);
stack[top++] = SubTree(middle+1, last, right, depth+1); stack[top++] = SubTree(middle+1, last, right, depth+1);
@ -3752,13 +3752,13 @@ struct PQueueElem
int KDTree::findNearest(InputArray _vec, int K, int emax, int KDTree::findNearest(InputArray _vec, int K, int emax,
OutputArray _neighborsIdx, OutputArray _neighbors, OutputArray _neighborsIdx, OutputArray _neighbors,
OutputArray _dist, OutputArray _labels) const OutputArray _dist, OutputArray _labels) const
{ {
Mat vecmat = _vec.getMat(); Mat vecmat = _vec.getMat();
CV_Assert( vecmat.isContinuous() && vecmat.type() == CV_32F && vecmat.total() == (size_t)points.cols ); CV_Assert( vecmat.isContinuous() && vecmat.type() == CV_32F && vecmat.total() == (size_t)points.cols );
const float* vec = vecmat.ptr<float>(); const float* vec = vecmat.ptr<float>();
K = std::min(K, points.rows); K = std::min(K, points.rows);
int dims = points.cols; int ptdims = points.cols;
CV_Assert(K > 0 && (normType == NORM_L2 || normType == NORM_L1)); CV_Assert(K > 0 && (normType == NORM_L2 || normType == NORM_L1));
@ -3776,7 +3776,7 @@ int KDTree::findNearest(InputArray _vec, int K, int emax,
{ {
float d, alt_d = 0.f; float d, alt_d = 0.f;
int nidx; int nidx;
if( e == 0 ) if( e == 0 )
nidx = 0; nidx = 0;
else else
@ -3803,7 +3803,7 @@ int KDTree::findNearest(InputArray _vec, int K, int emax,
i = left; i = left;
} }
} }
if( ncount == K && alt_d > dist[ncount-1] ) if( ncount == K && alt_d > dist[ncount-1] )
continue; continue;
} }
@ -3813,21 +3813,21 @@ int KDTree::findNearest(InputArray _vec, int K, int emax,
if( nidx < 0 ) if( nidx < 0 )
break; break;
const Node& n = nodes[nidx]; const Node& n = nodes[nidx];
if( n.idx < 0 ) if( n.idx < 0 )
{ {
i = ~n.idx; i = ~n.idx;
const float* row = points.ptr<float>(i); const float* row = points.ptr<float>(i);
if( normType == NORM_L2 ) if( normType == NORM_L2 )
for( j = 0, d = 0.f; j < dims; j++ ) for( j = 0, d = 0.f; j < ptdims; j++ )
{ {
float t = vec[j] - row[j]; float t = vec[j] - row[j];
d += t*t; d += t*t;
} }
else else
for( j = 0, d = 0.f; j < dims; j++ ) for( j = 0, d = 0.f; j < ptdims; j++ )
d += std::abs(vec[j] - row[j]); d += std::abs(vec[j] - row[j]);
dist[ncount] = d; dist[ncount] = d;
idx[ncount] = i; idx[ncount] = i;
for( i = ncount-1; i >= 0; i-- ) for( i = ncount-1; i >= 0; i-- )
@ -3839,9 +3839,9 @@ int KDTree::findNearest(InputArray _vec, int K, int emax,
} }
ncount += ncount < K; ncount += ncount < K;
e++; e++;
break; break;
} }
int alt; int alt;
if( vec[n.idx] <= n.boundary ) if( vec[n.idx] <= n.boundary )
{ {
@ -3853,7 +3853,7 @@ int KDTree::findNearest(InputArray _vec, int K, int emax,
nidx = n.right; nidx = n.right;
alt = n.left; alt = n.left;
} }
d = vec[n.idx] - n.boundary; d = vec[n.idx] - n.boundary;
if( normType == NORM_L2 ) if( normType == NORM_L2 )
d = d*d + alt_d; d = d*d + alt_d;
@ -3898,22 +3898,22 @@ void KDTree::findOrthoRange(InputArray _lowerBound,
OutputArray _neighbors, OutputArray _neighbors,
OutputArray _labels ) const OutputArray _labels ) const
{ {
int dims = points.cols; int ptdims = points.cols;
Mat lowerBound = _lowerBound.getMat(), upperBound = _upperBound.getMat(); Mat lowerBound = _lowerBound.getMat(), upperBound = _upperBound.getMat();
CV_Assert( lowerBound.size == upperBound.size && CV_Assert( lowerBound.size == upperBound.size &&
lowerBound.isContinuous() && lowerBound.isContinuous() &&
upperBound.isContinuous() && upperBound.isContinuous() &&
lowerBound.type() == upperBound.type() && lowerBound.type() == upperBound.type() &&
lowerBound.type() == CV_32F && lowerBound.type() == CV_32F &&
lowerBound.total() == (size_t)dims ); lowerBound.total() == (size_t)ptdims );
const float* L = lowerBound.ptr<float>(); const float* L = lowerBound.ptr<float>();
const float* R = upperBound.ptr<float>(); const float* R = upperBound.ptr<float>();
vector<int> idx; vector<int> idx;
AutoBuffer<int> _stack(MAX_TREE_DEPTH*2 + 1); AutoBuffer<int> _stack(MAX_TREE_DEPTH*2 + 1);
int* stack = _stack; int* stack = _stack;
int top = 0; int top = 0;
stack[top++] = 0; stack[top++] = 0;
while( --top >= 0 ) while( --top >= 0 )
@ -3926,10 +3926,10 @@ void KDTree::findOrthoRange(InputArray _lowerBound,
{ {
int j, i = ~n.idx; int j, i = ~n.idx;
const float* row = points.ptr<float>(i); const float* row = points.ptr<float>(i);
for( j = 0; j < dims; j++ ) for( j = 0; j < ptdims; j++ )
if( row[j] < L[j] || row[j] >= R[j] ) if( row[j] < L[j] || row[j] >= R[j] )
break; break;
if( j == dims ) if( j == ptdims )
idx.push_back(i); idx.push_back(i);
continue; continue;
} }
@ -3948,7 +3948,7 @@ void KDTree::findOrthoRange(InputArray _lowerBound,
getPoints( idx, _neighbors, _labels ); getPoints( idx, _neighbors, _labels );
} }
void KDTree::getPoints(InputArray _idx, OutputArray _pts, OutputArray _labels) const void KDTree::getPoints(InputArray _idx, OutputArray _pts, OutputArray _labels) const
{ {
Mat idxmat = _idx.getMat(), pts, labelsmat; Mat idxmat = _idx.getMat(), pts, labelsmat;
@ -3956,8 +3956,8 @@ void KDTree::getPoints(InputArray _idx, OutputArray _pts, OutputArray _labels) c
(idxmat.cols == 1 || idxmat.rows == 1) ); (idxmat.cols == 1 || idxmat.rows == 1) );
const int* idx = idxmat.ptr<int>(); const int* idx = idxmat.ptr<int>();
int* dstlabels = 0; int* dstlabels = 0;
int dims = points.cols; int ptdims = points.cols;
int i, nidx = (int)idxmat.total(); int i, nidx = (int)idxmat.total();
if( nidx == 0 ) if( nidx == 0 )
{ {
@ -3965,13 +3965,13 @@ void KDTree::getPoints(InputArray _idx, OutputArray _pts, OutputArray _labels) c
_labels.release(); _labels.release();
return; return;
} }
if( _pts.needed() ) if( _pts.needed() )
{ {
_pts.create( nidx, dims, points.type()); _pts.create( nidx, ptdims, points.type());
pts = _pts.getMat(); pts = _pts.getMat();
} }
if(_labels.needed()) if(_labels.needed())
{ {
_labels.create(nidx, 1, CV_32S, -1, true); _labels.create(nidx, 1, CV_32S, -1, true);
@ -3980,14 +3980,14 @@ void KDTree::getPoints(InputArray _idx, OutputArray _pts, OutputArray _labels) c
dstlabels = labelsmat.ptr<int>(); dstlabels = labelsmat.ptr<int>();
} }
const int* srclabels = !labels.empty() ? &labels[0] : 0; const int* srclabels = !labels.empty() ? &labels[0] : 0;
for( i = 0; i < nidx; i++ ) for( i = 0; i < nidx; i++ )
{ {
int k = idx[i]; int k = idx[i];
CV_Assert( (unsigned)k < (unsigned)points.rows ); CV_Assert( (unsigned)k < (unsigned)points.rows );
const float* src = points.ptr<float>(k); const float* src = points.ptr<float>(k);
if( pts.data ) if( pts.data )
std::copy(src, src + dims, pts.ptr<float>(i)); std::copy(src, src + ptdims, pts.ptr<float>(i));
if( dstlabels ) if( dstlabels )
dstlabels[i] = srclabels ? srclabels[k] : k; dstlabels[i] = srclabels ? srclabels[k] : k;
} }
@ -4007,9 +4007,9 @@ int KDTree::dims() const
{ {
return !points.empty() ? points.cols : 0; return !points.empty() ? points.cols : 0;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
schar* seqPush( CvSeq* seq, const void* element ) schar* seqPush( CvSeq* seq, const void* element )
{ {
return cvSeqPush(seq, element); return cvSeqPush(seq, element);

View File

@ -169,7 +169,7 @@ LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
} }
int bt_pix0 = (int)img.elemSize(), bt_pix = bt_pix0; int bt_pix0 = (int)img.elemSize(), bt_pix = bt_pix0;
size_t step = img.step; size_t istep = img.step;
int dx = pt2.x - pt1.x; int dx = pt2.x - pt1.x;
int dy = pt2.y - pt1.y; int dy = pt2.y - pt1.y;
@ -188,11 +188,11 @@ LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
bt_pix = (bt_pix ^ s) - s; bt_pix = (bt_pix ^ s) - s;
} }
ptr = (uchar*)(img.data + pt1.y * step + pt1.x * bt_pix0); ptr = (uchar*)(img.data + pt1.y * istep + pt1.x * bt_pix0);
s = dy < 0 ? -1 : 0; s = dy < 0 ? -1 : 0;
dy = (dy ^ s) - s; dy = (dy ^ s) - s;
step = (step ^ s) - s; istep = (istep ^ s) - s;
s = dy > dx ? -1 : 0; s = dy > dx ? -1 : 0;
@ -201,9 +201,9 @@ LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
dy ^= dx & s; dy ^= dx & s;
dx ^= dy & s; dx ^= dy & s;
bt_pix ^= step & s; bt_pix ^= istep & s;
step ^= bt_pix & s; istep ^= bt_pix & s;
bt_pix ^= step & s; bt_pix ^= istep & s;
if( connectivity == 8 ) if( connectivity == 8 )
{ {
@ -212,7 +212,7 @@ LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
err = dx - (dy + dy); err = dx - (dy + dy);
plusDelta = dx + dx; plusDelta = dx + dx;
minusDelta = -(dy + dy); minusDelta = -(dy + dy);
plusStep = (int)step; plusStep = (int)istep;
minusStep = bt_pix; minusStep = bt_pix;
count = dx + 1; count = dx + 1;
} }
@ -223,7 +223,7 @@ LineIterator::LineIterator(const Mat& img, Point pt1, Point pt2,
err = 0; err = 0;
plusDelta = (dx + dx) + (dy + dy); plusDelta = (dx + dx) + (dy + dy);
minusDelta = -(dy + dy); minusDelta = -(dy + dy);
plusStep = (int)step - bt_pix; plusStep = (int)istep - bt_pix;
minusStep = bt_pix; minusStep = bt_pix;
count = dx + dy + 1; count = dx + dy + 1;
} }

View File

@ -46,8 +46,8 @@ namespace cv
// On Win64 optimized versions of DFT and DCT fail the tests (fixed in VS2010) // On Win64 optimized versions of DFT and DCT fail the tests (fixed in VS2010)
#if defined _MSC_VER && !defined CV_ICC && defined _M_X64 && _MSC_VER < 1600 #if defined _MSC_VER && !defined CV_ICC && defined _M_X64 && _MSC_VER < 1600
#pragma optimize("", off) # pragma optimize("", off)
#pragma warning( disable : 4748 ) # pragma warning(disable: 4748)
#endif #endif
/****************************************************************************************\ /****************************************************************************************\

View File

@ -524,30 +524,30 @@ cv::gpu::GpuMat::GpuMat(Size size_, int type_, void* data_, size_t step_) :
dataend += step * (rows - 1) + minstep; dataend += step * (rows - 1) + minstep;
} }
cv::gpu::GpuMat::GpuMat(const GpuMat& m, Range rowRange, Range colRange) cv::gpu::GpuMat::GpuMat(const GpuMat& m, Range _rowRange, Range _colRange)
{ {
flags = m.flags; flags = m.flags;
step = m.step; refcount = m.refcount; step = m.step; refcount = m.refcount;
data = m.data; datastart = m.datastart; dataend = m.dataend; data = m.data; datastart = m.datastart; dataend = m.dataend;
if (rowRange == Range::all()) if (_rowRange == Range::all())
rows = m.rows; rows = m.rows;
else else
{ {
CV_Assert(0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows); CV_Assert(0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows);
rows = rowRange.size(); rows = _rowRange.size();
data += step*rowRange.start; data += step*_rowRange.start;
} }
if (colRange == Range::all()) if (_colRange == Range::all())
cols = m.cols; cols = m.cols;
else else
{ {
CV_Assert(0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols); CV_Assert(0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols);
cols = colRange.size(); cols = _colRange.size();
data += colRange.start*elemSize(); data += _colRange.start*elemSize();
flags &= cols < m.cols ? ~Mat::CONTINUOUS_FLAG : -1; flags &= cols < m.cols ? ~Mat::CONTINUOUS_FLAG : -1;
} }

File diff suppressed because it is too large Load Diff

View File

@ -63,7 +63,7 @@ GEMM_CopyBlock( const uchar* src, size_t src_step,
for( ; size.height--; src += src_step, dst += dst_step ) for( ; size.height--; src += src_step, dst += dst_step )
{ {
j=0; j=0;
#if CV_ENABLE_UNROLLED #if CV_ENABLE_UNROLLED
for( ; j <= size.width - 4; j += 4 ) for( ; j <= size.width - 4; j += 4 )
{ {
@ -345,7 +345,7 @@ GEMMSingleMul( const T* a_data, size_t a_step,
for( k = 0; k < n; k++, b_data += b_step ) for( k = 0; k < n; k++, b_data += b_step )
{ {
WT al(a_data[k]); WT al(a_data[k]);
j=0; j=0;
#if CV_ENABLE_UNROLLED #if CV_ENABLE_UNROLLED
for(; j <= m - 4; j += 4 ) for(; j <= m - 4; j += 4 )
{ {
@ -513,8 +513,8 @@ GEMMStore( const T* c_data, size_t c_step,
if( _c_data ) if( _c_data )
{ {
c_data = _c_data; c_data = _c_data;
j=0; j=0;
#if CV_ENABLE_UNROLLED #if CV_ENABLE_UNROLLED
for(; j <= d_size.width - 4; j += 4, c_data += 4*c_step1 ) for(; j <= d_size.width - 4; j += 4, c_data += 4*c_step1 )
{ {
WT t0 = alpha*d_buf[j]; WT t0 = alpha*d_buf[j];
@ -539,8 +539,8 @@ GEMMStore( const T* c_data, size_t c_step,
} }
else else
{ {
j = 0; j = 0;
#if CV_ENABLE_UNROLLED #if CV_ENABLE_UNROLLED
for( ; j <= d_size.width - 4; j += 4 ) for( ; j <= d_size.width - 4; j += 4 )
{ {
WT t0 = alpha*d_buf[j]; WT t0 = alpha*d_buf[j];
@ -552,7 +552,7 @@ GEMMStore( const T* c_data, size_t c_step,
d_data[j+2] = T(t0); d_data[j+2] = T(t0);
d_data[j+3] = T(t1); d_data[j+3] = T(t1);
} }
#endif #endif
for( ; j < d_size.width; j++ ) for( ; j < d_size.width; j++ )
d_data[j] = T(alpha*d_buf[j]); d_data[j] = T(alpha*d_buf[j]);
} }
@ -597,7 +597,7 @@ static void GEMMSingleMul_64f( const double* a_data, size_t a_step,
alpha, beta, flags); alpha, beta, flags);
} }
static void GEMMSingleMul_32fc( const Complexf* a_data, size_t a_step, static void GEMMSingleMul_32fc( const Complexf* a_data, size_t a_step,
const Complexf* b_data, size_t b_step, const Complexf* b_data, size_t b_step,
const Complexf* c_data, size_t c_step, const Complexf* c_data, size_t c_step,
@ -620,7 +620,7 @@ static void GEMMSingleMul_64fc( const Complexd* a_data, size_t a_step,
GEMMSingleMul<Complexd,Complexd>(a_data, a_step, b_data, b_step, c_data, GEMMSingleMul<Complexd,Complexd>(a_data, a_step, b_data, b_step, c_data,
c_step, d_data, d_step, a_size, d_size, c_step, d_data, d_step, a_size, d_size,
alpha, beta, flags); alpha, beta, flags);
} }
static void GEMMBlockMul_32f( const float* a_data, size_t a_step, static void GEMMBlockMul_32f( const float* a_data, size_t a_step,
const float* b_data, size_t b_step, const float* b_data, size_t b_step,
@ -696,7 +696,7 @@ static void GEMMStore_64fc( const Complexd* c_data, size_t c_step,
} }
void cv::gemm( InputArray matA, InputArray matB, double alpha, void cv::gemm( InputArray matA, InputArray matB, double alpha,
InputArray matC, double beta, OutputArray matD, int flags ) InputArray matC, double beta, OutputArray _matD, int flags )
{ {
const int block_lin_size = 128; const int block_lin_size = 128;
const int block_size = block_lin_size * block_lin_size; const int block_size = block_lin_size * block_lin_size;
@ -741,8 +741,8 @@ void cv::gemm( InputArray matA, InputArray matB, double alpha,
((flags&GEMM_3_T) != 0 && C.rows == d_size.width && C.cols == d_size.height))); ((flags&GEMM_3_T) != 0 && C.rows == d_size.width && C.cols == d_size.height)));
} }
matD.create( d_size.height, d_size.width, type ); _matD.create( d_size.height, d_size.width, type );
Mat D = matD.getMat(); Mat D = _matD.getMat();
if( (flags & GEMM_3_T) != 0 && C.data == D.data ) if( (flags & GEMM_3_T) != 0 && C.data == D.data )
{ {
transpose( C, C ); transpose( C, C );
@ -2008,7 +2008,7 @@ static void scaleAdd_32f(const float* src1, const float* src2, float* dst,
t1 = src1[i+3]*alpha + src2[i+3]; t1 = src1[i+3]*alpha + src2[i+3];
dst[i+2] = t0; dst[i+3] = t1; dst[i+2] = t0; dst[i+3] = t1;
} }
for(; i < len; i++ ) for(; i < len; i++ )
dst[i] = src1[i]*alpha + src2[i]; dst[i] = src1[i]*alpha + src2[i];
} }
@ -2035,7 +2035,7 @@ static void scaleAdd_64f(const double* src1, const double* src2, double* dst,
} }
else else
#endif #endif
//vz why do we need unroll here? //vz why do we need unroll here?
for( ; i <= len - 4; i += 4 ) for( ; i <= len - 4; i += 4 )
{ {
double t0, t1; double t0, t1;
@ -2046,7 +2046,7 @@ static void scaleAdd_64f(const double* src1, const double* src2, double* dst,
t1 = src1[i+3]*alpha + src2[i+3]; t1 = src1[i+3]*alpha + src2[i+3];
dst[i+2] = t0; dst[i+3] = t1; dst[i+2] = t0; dst[i+3] = t1;
} }
for(; i < len; i++ ) for(; i < len; i++ )
dst[i] = src1[i]*alpha + src2[i]; dst[i] = src1[i]*alpha + src2[i];
} }
@ -2072,7 +2072,7 @@ void cv::scaleAdd( InputArray _src1, double alpha, InputArray _src2, OutputArray
float falpha = (float)alpha; float falpha = (float)alpha;
void* palpha = depth == CV_32F ? (void*)&falpha : (void*)&alpha; void* palpha = depth == CV_32F ? (void*)&falpha : (void*)&alpha;
ScaleAddFunc func = depth == CV_32F ? (ScaleAddFunc)scaleAdd_32f : (ScaleAddFunc)scaleAdd_64f; ScaleAddFunc func = depth == CV_32F ? (ScaleAddFunc)scaleAdd_32f : (ScaleAddFunc)scaleAdd_64f;
if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() ) if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() )
{ {
@ -2134,12 +2134,12 @@ void cv::calcCovarMatrix( const Mat* data, int nsamples, Mat& covar, Mat& _mean,
_mean = mean.reshape(1, size.height); _mean = mean.reshape(1, size.height);
} }
void cv::calcCovarMatrix( InputArray _data, OutputArray _covar, InputOutputArray _mean, int flags, int ctype ) void cv::calcCovarMatrix( InputArray _src, OutputArray _covar, InputOutputArray _mean, int flags, int ctype )
{ {
if(_data.kind() == _InputArray::STD_VECTOR_MAT) if(_src.kind() == _InputArray::STD_VECTOR_MAT)
{ {
std::vector<cv::Mat> src; std::vector<cv::Mat> src;
_data.getMatVector(src); _src.getMatVector(src);
CV_Assert( src.size() > 0 ); CV_Assert( src.size() > 0 );
@ -2185,7 +2185,7 @@ void cv::calcCovarMatrix( InputArray _data, OutputArray _covar, InputOutputArray
return; return;
} }
Mat data = _data.getMat(), mean; Mat data = _src.getMat(), mean;
CV_Assert( ((flags & CV_COVAR_ROWS) != 0) ^ ((flags & CV_COVAR_COLS) != 0) ); CV_Assert( ((flags & CV_COVAR_ROWS) != 0) ^ ((flags & CV_COVAR_COLS) != 0) );
bool takeRows = (flags & CV_COVAR_ROWS) != 0; bool takeRows = (flags & CV_COVAR_ROWS) != 0;
int type = data.type(); int type = data.type();
@ -2209,7 +2209,7 @@ void cv::calcCovarMatrix( InputArray _data, OutputArray _covar, InputOutputArray
else else
{ {
ctype = std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), CV_32F); ctype = std::max(CV_MAT_DEPTH(ctype >= 0 ? ctype : type), CV_32F);
reduce( _data, _mean, takeRows ? 0 : 1, CV_REDUCE_AVG, ctype ); reduce( _src, _mean, takeRows ? 0 : 1, CV_REDUCE_AVG, ctype );
mean = _mean.getMat(); mean = _mean.getMat();
} }
@ -2223,7 +2223,7 @@ void cv::calcCovarMatrix( InputArray _data, OutputArray _covar, InputOutputArray
double cv::Mahalanobis( InputArray _v1, InputArray _v2, InputArray _icovar ) double cv::Mahalanobis( InputArray _v1, InputArray _v2, InputArray _icovar )
{ {
Mat v1 = _v1.getMat(), v2 = _v2.getMat(), icovar = _icovar.getMat(); Mat v1 = _v1.getMat(), v2 = _v2.getMat(), icovar = _icovar.getMat();
int type = v1.type(), depth = v1.depth(); int type = v1.type(), depth = v1.depth();
Size sz = v1.size(); Size sz = v1.size();
int i, j, len = sz.width*sz.height*v1.channels(); int i, j, len = sz.width*sz.height*v1.channels();
@ -2261,7 +2261,7 @@ double cv::Mahalanobis( InputArray _v1, InputArray _v2, InputArray _icovar )
{ {
double row_sum = 0; double row_sum = 0;
j = 0; j = 0;
#if CV_ENABLE_UNROLLED #if CV_ENABLE_UNROLLED
for(; j <= len - 4; j += 4 ) for(; j <= len - 4; j += 4 )
row_sum += diff[j]*mat[j] + diff[j+1]*mat[j+1] + row_sum += diff[j]*mat[j] + diff[j+1]*mat[j+1] +
diff[j+2]*mat[j+2] + diff[j+3]*mat[j+3]; diff[j+2]*mat[j+2] + diff[j+3]*mat[j+3];
@ -2292,7 +2292,7 @@ double cv::Mahalanobis( InputArray _v1, InputArray _v2, InputArray _icovar )
{ {
double row_sum = 0; double row_sum = 0;
j = 0; j = 0;
#if CV_ENABLE_UNROLLED #if CV_ENABLE_UNROLLED
for(; j <= len - 4; j += 4 ) for(; j <= len - 4; j += 4 )
row_sum += diff[j]*mat[j] + diff[j+1]*mat[j+1] + row_sum += diff[j]*mat[j] + diff[j+1]*mat[j+1] +
diff[j+2]*mat[j+2] + diff[j+3]*mat[j+3]; diff[j+2]*mat[j+2] + diff[j+3]*mat[j+3];
@ -2642,7 +2642,7 @@ dotProd_(const T* src1, const T* src2, int len)
{ {
int i = 0; int i = 0;
double result = 0; double result = 0;
#if CV_ENABLE_UNROLLED #if CV_ENABLE_UNROLLED
for( ; i <= len - 4; i += 4 ) for( ; i <= len - 4; i += 4 )
result += (double)src1[i]*src2[i] + (double)src1[i+1]*src2[i+1] + result += (double)src1[i]*src2[i] + (double)src1[i+1]*src2[i+1] +
(double)src1[i+2]*src2[i+2] + (double)src1[i+3]*src2[i+3]; (double)src1[i+2]*src2[i+2] + (double)src1[i+3]*src2[i+3];
@ -2674,7 +2674,7 @@ static double dotProd_8u(const uchar* src1, const uchar* src2, int len)
{ {
blockSize = std::min(len0 - i, blockSize0); blockSize = std::min(len0 - i, blockSize0);
__m128i s = _mm_setzero_si128(); __m128i s = _mm_setzero_si128();
j = 0; j = 0;
for( ; j <= blockSize - 16; j += 16 ) for( ; j <= blockSize - 16; j += 16 )
{ {
__m128i b0 = _mm_loadu_si128((const __m128i*)(src1 + j)); __m128i b0 = _mm_loadu_si128((const __m128i*)(src1 + j));
@ -2806,9 +2806,9 @@ double Mat::dot(InputArray _mat) const
PCA::PCA() {} PCA::PCA() {}
PCA::PCA(InputArray data, InputArray mean, int flags, int maxComponents) PCA::PCA(InputArray data, InputArray _mean, int flags, int maxComponents)
{ {
operator()(data, mean, flags, maxComponents); operator()(data, _mean, flags, maxComponents);
} }
PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComponents) PCA& PCA::operator()(InputArray _data, InputArray __mean, int flags, int maxComponents)
@ -2964,7 +2964,7 @@ void cv::PCACompute(InputArray data, InputOutputArray mean,
pca.mean.copyTo(mean); pca.mean.copyTo(mean);
pca.eigenvectors.copyTo(eigenvectors); pca.eigenvectors.copyTo(eigenvectors);
} }
void cv::PCAProject(InputArray data, InputArray mean, void cv::PCAProject(InputArray data, InputArray mean,
InputArray eigenvectors, OutputArray result) InputArray eigenvectors, OutputArray result)
{ {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -163,11 +163,11 @@ void icvSetOpenGlFuncTab(const CvOpenGlFuncTab* tab)
void cv::gpu::setGlDevice(int device) void cv::gpu::setGlDevice(int device)
{ {
#ifndef HAVE_CUDA #ifndef HAVE_CUDA
(void)device; (void)device;
throw_nocuda; throw_nocuda;
#else #else
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)device; (void)device;
throw_nogl; throw_nogl;
#else #else
if (!glFuncTab()->isGlContextInitialized()) if (!glFuncTab()->isGlContextInitialized())
@ -287,7 +287,7 @@ class cv::GlBuffer::Impl
{ {
public: public:
static const Ptr<Impl>& empty(); static const Ptr<Impl>& empty();
Impl(int rows, int cols, int type, unsigned int target); Impl(int rows, int cols, int type, unsigned int target);
Impl(const Mat& m, unsigned int target); Impl(const Mat& m, unsigned int target);
~Impl(); ~Impl();
@ -311,7 +311,7 @@ public:
private: private:
Impl(); Impl();
unsigned int buffer_; unsigned int buffer_;
#ifdef HAVE_CUDA #ifdef HAVE_CUDA
@ -484,57 +484,57 @@ inline void cv::GlBuffer::Impl::unmapDevice(cudaStream_t stream)
#endif // HAVE_OPENGL #endif // HAVE_OPENGL
cv::GlBuffer::GlBuffer(Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage) cv::GlBuffer::GlBuffer(Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)usage; (void)_usage;
throw_nogl; throw_nogl;
#else #else
impl_ = Impl::empty(); impl_ = Impl::empty();
#endif #endif
} }
cv::GlBuffer::GlBuffer(int rows, int cols, int type, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage) cv::GlBuffer::GlBuffer(int _rows, int _cols, int _type, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)rows; (void)_rows;
(void)cols; (void)_cols;
(void)type; (void)_type;
(void)usage; (void)_usage;
throw_nogl; throw_nogl;
#else #else
impl_ = new Impl(rows, cols, type, usage); impl_ = new Impl(_rows, _cols, _type, _usage);
rows_ = rows; rows_ = _rows;
cols_ = cols; cols_ = _cols;
type_ = type; type_ = _type;
#endif #endif
} }
cv::GlBuffer::GlBuffer(Size size, int type, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage) cv::GlBuffer::GlBuffer(Size _size, int _type, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)size; (void)_size;
(void)type; (void)_type;
(void)usage; (void)_usage;
throw_nogl; throw_nogl;
#else #else
impl_ = new Impl(size.height, size.width, type, usage); impl_ = new Impl(_size.height, _size.width, _type, _usage);
rows_ = size.height; rows_ = _size.height;
cols_ = size.width; cols_ = _size.width;
type_ = type; type_ = _type;
#endif #endif
} }
cv::GlBuffer::GlBuffer(InputArray mat_, Usage usage) : rows_(0), cols_(0), type_(0), usage_(usage) cv::GlBuffer::GlBuffer(InputArray mat_, Usage _usage) : rows_(0), cols_(0), type_(0), usage_(_usage)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)mat_; (void)mat_;
(void)usage; (void)_usage;
throw_nogl; throw_nogl;
#else #else
int kind = mat_.kind(); int kind = mat_.kind();
Size size = mat_.size(); Size _size = mat_.size();
int type = mat_.type(); int _type = mat_.type();
if (kind == _InputArray::GPU_MAT) if (kind == _InputArray::GPU_MAT)
{ {
@ -542,38 +542,38 @@ cv::GlBuffer::GlBuffer(InputArray mat_, Usage usage) : rows_(0), cols_(0), type_
throw_nocuda; throw_nocuda;
#else #else
GpuMat d_mat = mat_.getGpuMat(); GpuMat d_mat = mat_.getGpuMat();
impl_ = new Impl(d_mat.rows, d_mat.cols, d_mat.type(), usage); impl_ = new Impl(d_mat.rows, d_mat.cols, d_mat.type(), _usage);
impl_->copyFrom(d_mat); impl_->copyFrom(d_mat);
#endif #endif
} }
else else
{ {
Mat mat = mat_.getMat(); Mat mat = mat_.getMat();
impl_ = new Impl(mat, usage); impl_ = new Impl(mat, _usage);
} }
rows_ = size.height; rows_ = _size.height;
cols_ = size.width; cols_ = _size.width;
type_ = type; type_ = _type;
#endif #endif
} }
void cv::GlBuffer::create(int rows, int cols, int type, Usage usage) void cv::GlBuffer::create(int _rows, int _cols, int _type, Usage _usage)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)rows; (void)_rows;
(void)cols; (void)_cols;
(void)type; (void)_type;
(void)usage; (void)_usage;
throw_nogl; throw_nogl;
#else #else
if (rows_ != rows || cols_ != cols || type_ != type || usage_ != usage) if (rows_ != _rows || cols_ != _cols || type_ != _type || usage_ != _usage)
{ {
impl_ = new Impl(rows, cols, type, usage); impl_ = new Impl(_rows, _cols, _type, _usage);
rows_ = rows; rows_ = _rows;
cols_ = cols; cols_ = _cols;
type_ = type; type_ = _type;
usage_ = usage; usage_ = _usage;
} }
#endif #endif
} }
@ -590,14 +590,14 @@ void cv::GlBuffer::release()
void cv::GlBuffer::copyFrom(InputArray mat_) void cv::GlBuffer::copyFrom(InputArray mat_)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)mat_; (void)mat_;
throw_nogl; throw_nogl;
#else #else
int kind = mat_.kind(); int kind = mat_.kind();
Size size = mat_.size(); Size _size = mat_.size();
int type = mat_.type(); int _type = mat_.type();
create(size, type); create(_size, _type);
switch (kind) switch (kind)
{ {
@ -728,7 +728,7 @@ public:
private: private:
Impl(); Impl();
GLuint tex_; GLuint tex_;
}; };
@ -926,45 +926,45 @@ cv::GlTexture::GlTexture() : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTUR
#endif #endif
} }
cv::GlTexture::GlTexture(int rows, int cols, int type) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER) cv::GlTexture::GlTexture(int _rows, int _cols, int _type) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)rows; (void)_rows;
(void)cols; (void)_cols;
(void)type; (void)_type;
throw_nogl; throw_nogl;
#else #else
impl_ = new Impl(rows, cols, type); impl_ = new Impl(_rows, _cols, _type);
rows_ = rows; rows_ = _rows;
cols_ = cols; cols_ = _cols;
type_ = type; type_ = _type;
#endif #endif
} }
cv::GlTexture::GlTexture(Size size, int type) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER) cv::GlTexture::GlTexture(Size _size, int _type) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)size; (void)_size;
(void)type; (void)_type;
throw_nogl; throw_nogl;
#else #else
impl_ = new Impl(size.height, size.width, type); impl_ = new Impl(_size.height, _size.width, _type);
rows_ = size.height; rows_ = _size.height;
cols_ = size.width; cols_ = _size.width;
type_ = type; type_ = _type;
#endif #endif
} }
cv::GlTexture::GlTexture(InputArray mat_, bool bgra) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER) cv::GlTexture::GlTexture(InputArray mat_, bool bgra) : rows_(0), cols_(0), type_(0), buf_(GlBuffer::TEXTURE_BUFFER)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)mat_; (void)mat_;
(void)bgra; (void)bgra;
throw_nogl; throw_nogl;
#else #else
int kind = mat_.kind(); int kind = mat_.kind();
Size size = mat_.size(); Size _size = mat_.size();
int type = mat_.type(); int _type = mat_.type();
switch (kind) switch (kind)
{ {
@ -994,26 +994,26 @@ cv::GlTexture::GlTexture(InputArray mat_, bool bgra) : rows_(0), cols_(0), type_
} }
} }
rows_ = size.height; rows_ = _size.height;
cols_ = size.width; cols_ = _size.width;
type_ = type; type_ = _type;
#endif #endif
} }
void cv::GlTexture::create(int rows, int cols, int type) void cv::GlTexture::create(int _rows, int _cols, int _type)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)rows; (void)_rows;
(void)cols; (void)_cols;
(void)type; (void)_type;
throw_nogl; throw_nogl;
#else #else
if (rows_ != rows || cols_ != cols || type_ != type) if (rows_ != _rows || cols_ != _cols || type_ != _type)
{ {
impl_ = new Impl(rows, cols, type); impl_ = new Impl(_rows, _cols, _type);
rows_ = rows; rows_ = _rows;
cols_ = cols; cols_ = _cols;
type_ = type; type_ = _type;
} }
#endif #endif
} }
@ -1030,15 +1030,15 @@ void cv::GlTexture::release()
void cv::GlTexture::copyFrom(InputArray mat_, bool bgra) void cv::GlTexture::copyFrom(InputArray mat_, bool bgra)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)mat_; (void)mat_;
(void)bgra; (void)bgra;
throw_nogl; throw_nogl;
#else #else
int kind = mat_.kind(); int kind = mat_.kind();
Size size = mat_.size(); Size _size = mat_.size();
int type = mat_.type(); int _type = mat_.type();
create(size, type); create(_size, _type);
switch(kind) switch(kind)
{ {
@ -1244,8 +1244,8 @@ void cv::GlArrays::unbind() const
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// GlFont // GlFont
cv::GlFont::GlFont(const string& family, int height, Weight weight, Style style) cv::GlFont::GlFont(const string& _family, int _height, Weight _weight, Style _style)
: family_(family), height_(height), weight_(weight), style_(style), base_(0) : family_(_family), height_(_height), weight_(_weight), style_(_style), base_(0)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
throw_nogl; throw_nogl;
@ -1253,7 +1253,7 @@ cv::GlFont::GlFont(const string& family, int height, Weight weight, Style style)
base_ = glGenLists(256); base_ = glGenLists(256);
CV_CheckGlError(); CV_CheckGlError();
glFuncTab()->generateBitmapFont(family, height, weight, (style & STYLE_ITALIC) != 0, (style & STYLE_UNDERLINE) != 0, 0, 256, base_); glFuncTab()->generateBitmapFont(family_, height_, weight_, (style_ & STYLE_ITALIC) != 0, (style_ & STYLE_UNDERLINE) != 0, 0, 256, base_);
#endif #endif
} }
@ -1283,7 +1283,7 @@ namespace
class FontCompare : public unary_function<Ptr<GlFont>, bool> class FontCompare : public unary_function<Ptr<GlFont>, bool>
{ {
public: public:
inline FontCompare(const string& family, int height, GlFont::Weight weight, GlFont::Style style) inline FontCompare(const string& family, int height, GlFont::Weight weight, GlFont::Style style)
: family_(family), height_(height), weight_(weight), style_(style) : family_(family), height_(height), weight_(weight), style_(style)
{ {
} }
@ -1304,10 +1304,10 @@ namespace
Ptr<GlFont> cv::GlFont::get(const std::string& family, int height, Weight weight, Style style) Ptr<GlFont> cv::GlFont::get(const std::string& family, int height, Weight weight, Style style)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)family; (void)family;
(void)height; (void)height;
(void)weight; (void)weight;
(void)style; (void)style;
throw_nogl; throw_nogl;
return Ptr<GlFont>(); return Ptr<GlFont>();
#else #else
@ -1333,9 +1333,9 @@ Ptr<GlFont> cv::GlFont::get(const std::string& family, int height, Weight weight
void cv::render(const GlTexture& tex, Rect_<double> wndRect, Rect_<double> texRect) void cv::render(const GlTexture& tex, Rect_<double> wndRect, Rect_<double> texRect)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)tex; (void)tex;
(void)wndRect; (void)wndRect;
(void)texRect; (void)texRect;
throw_nogl; throw_nogl;
#else #else
if (!tex.empty()) if (!tex.empty())
@ -1368,9 +1368,9 @@ void cv::render(const GlTexture& tex, Rect_<double> wndRect, Rect_<double> texRe
void cv::render(const GlArrays& arr, int mode, Scalar color) void cv::render(const GlArrays& arr, int mode, Scalar color)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)arr; (void)arr;
(void)mode; (void)mode;
(void)color; (void)color;
throw_nogl; throw_nogl;
#else #else
glColor3d(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0); glColor3d(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0);
@ -1386,10 +1386,10 @@ void cv::render(const GlArrays& arr, int mode, Scalar color)
void cv::render(const string& str, const Ptr<GlFont>& font, Scalar color, Point2d pos) void cv::render(const string& str, const Ptr<GlFont>& font, Scalar color, Point2d pos)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)str; (void)str;
(void)font; (void)font;
(void)color; (void)color;
(void)pos; (void)pos;
throw_nogl; throw_nogl;
#else #else
glPushAttrib(GL_DEPTH_BUFFER_BIT); glPushAttrib(GL_DEPTH_BUFFER_BIT);
@ -1544,9 +1544,9 @@ void cv::GlCamera::setupModelViewMatrix() const
bool icvCheckGlError(const char* file, const int line, const char* func) bool icvCheckGlError(const char* file, const int line, const char* func)
{ {
#ifndef HAVE_OPENGL #ifndef HAVE_OPENGL
(void)file; (void)file;
(void)line; (void)line;
(void)func; (void)func;
return true; return true;
#else #else
GLenum err = glGetError(); GLenum err = glGetError();

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