mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Global CMake reorganization:
[~] Automatically tracked dependencies between modules [+] Support for optional module dependencies [+] Options to choose modules to build [~] Removed hardcoded modules lists from OpenCVConfig.cmake, opencv.pc and OpenCV.mk [+] Added COMPONENTS support for FIND_PACKAGE(OpenCV) [~] haartraining and traincascade are moved outside of modules folder since they aren't the modules
This commit is contained in:
@@ -1,10 +1,5 @@
|
||||
file(GLOB ocvmodules RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*")
|
||||
if(ocvmodules)
|
||||
list(SORT ocvmodules)
|
||||
if(NOT OPENCV_MODULES_PATH)
|
||||
set(OPENCV_MODULES_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
foreach(mod ${ocvmodules})
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${mod}/CMakeLists.txt")
|
||||
add_subdirectory("${mod}")
|
||||
endif()
|
||||
endforeach()
|
||||
ocv_glob_modules(${OPENCV_MODULES_PATH})
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
IF(NOT ANDROID OR NOT WITH_ANDROID_CAMERA)
|
||||
return()
|
||||
IF(NOT ANDROID OR ANDROID_NATIVE_API_LEVEL LESS 8)
|
||||
ocv_module_disable(androidcamera)
|
||||
ENDIF()
|
||||
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/camera_wrapper")
|
||||
set(OPENCV_ANDROIDCAMERA_MODULE_TYPE STATIC)
|
||||
define_opencv_moduleEx(androidcamera INTERNAL log dl)
|
||||
set(the_description "Auxiliary module for Android native camera support")
|
||||
set(OPENCV_MODULE_TYPE STATIC)
|
||||
|
||||
ocv_define_module(androidcamera INTERNAL log dl)
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/camera_wrapper")
|
||||
|
||||
# Android source tree for native camera
|
||||
SET (ANDROID_SOURCE_TREE "ANDROID_SOURCE_TREE-NOTFOUND" CACHE PATH
|
||||
"Path to Android source tree. Set this variable to path to your Android sources to compile libnative_camera_rx.x.x.so for your Android")
|
||||
SET(BUILD_ANDROID_CAMERA_WRAPPER OFF)
|
||||
if(ANDROID_SOURCE_TREE)
|
||||
FILE(STRINGS "${ANDROID_SOURCE_TREE}/development/sdk/platform_source.properties" ANDROID_VERSION REGEX "Platform\\.Version=[0-9]+\\.[0-9]+(\\.[0-9]+)?" )
|
||||
string(REGEX REPLACE "Platform\\.Version=([0-9]+\\.[0-9]+(\\.[0-9]+)?)" "\\1" ANDROID_VERSION "${ANDROID_VERSION}")
|
||||
if(ANDROID_VERSION MATCHES "^[0-9]+\\.[0-9]+$")
|
||||
SET(ANDROID_VERSION "${ANDROID_VERSION}.0")
|
||||
endif()
|
||||
if(NOT "${ANDROID_VERSION}" STREQUAL "")
|
||||
SET(BUILD_ANDROID_CAMERA_WRAPPER ON)
|
||||
endif()
|
||||
endif()
|
||||
MARK_AS_ADVANCED(ANDROID_SOURCE_TREE)
|
||||
|
||||
# process wrapper libs
|
||||
if (BUILD_ANDROID_CAMERA_WRAPPER)
|
||||
add_subdirectory(camera_wrapper)
|
||||
else()
|
||||
@@ -13,13 +32,12 @@ else()
|
||||
|
||||
foreach(wrapper ${camera_wrappers})
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${the_target}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${LIBRARY_OUTPUT_PATH}"
|
||||
)
|
||||
TARGET ${the_module} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${LIBRARY_OUTPUT_PATH}"
|
||||
)
|
||||
get_filename_component(wrapper_name "${wrapper}" NAME)
|
||||
install(FILES "${LIBRARY_OUTPUT_PATH}/${wrapper_name}"
|
||||
DESTINATION ${OPENCV_LIB_INSTALL_PATH}
|
||||
COMPONENT main)
|
||||
DESTINATION ${OPENCV_LIB_INSTALL_PATH}
|
||||
COMPONENT main)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
define_opencv_module(calib3d opencv_core opencv_imgproc opencv_features2d opencv_flann)
|
||||
set(the_description "Camera Calibration and 3D Reconstruction")
|
||||
ocv_define_module(calib3d opencv_imgproc opencv_features2d)
|
||||
|
||||
@@ -1 +1 @@
|
||||
define_opencv_module(contrib opencv_core opencv_imgproc opencv_calib3d opencv_features2d opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_flann)
|
||||
ocv_define_module(contrib opencv_imgproc opencv_calib3d opencv_features2d opencv_highgui opencv_ml opencv_video opencv_objdetect)
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include "precomp.hpp"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <highgui.h>
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
#include "opencv2/contrib/hybridtracker.hpp"
|
||||
|
||||
|
||||
@@ -1,7 +1,43 @@
|
||||
if(ZLIB_FOUND)
|
||||
include_directories(${ZLIB_INCLUDE_DIR})
|
||||
set(the_description "The Core Functionality")
|
||||
ocv_add_module(core ${ZLIB_LIBRARY})
|
||||
|
||||
if(HAVE_CUDA)
|
||||
file(GLOB lib_cuda "src/cuda/*.cu")
|
||||
source_group("Cuda" FILES "${lib_cuda}")
|
||||
|
||||
include_directories(${CUDA_INCLUDE_DIRS} "${OpenCV_SOURCE_DIR}/modules/gpu/src" "${OpenCV_SOURCE_DIR}/modules/gpu/src/cuda")
|
||||
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -gencode arch=compute_10,code=sm_10
|
||||
-gencode arch=compute_11,code=sm_11
|
||||
-gencode arch=compute_12,code=sm_12
|
||||
-gencode arch=compute_13,code=sm_13
|
||||
-gencode arch=compute_20,code=sm_20
|
||||
-gencode arch=compute_20,code=sm_21)
|
||||
|
||||
OCV_CUDA_COMPILE(cuda_objs ${lib_cuda})
|
||||
|
||||
unset(CUDA_npp_LIBRARY CACHE)
|
||||
find_cuda_helper_libs(npp)
|
||||
set(cuda_link_libs ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
else()
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/zlib")
|
||||
set(lib_cuda "")
|
||||
set(cuda_objs "")
|
||||
set(cuda_link_libs "")
|
||||
endif()
|
||||
|
||||
define_opencv_module(core ${ZLIB_LIBRARY})
|
||||
ocv_glob_module_sources(SOURCES ${lib_cuda} ${cuda_objs})
|
||||
|
||||
if(NOT ZLIB_FOUND)
|
||||
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/zlib")
|
||||
endif()
|
||||
ocv_module_include_directories(${ZLIB_INCLUDE_DIR})
|
||||
|
||||
ocv_create_module(${cuda_link_libs})
|
||||
ocv_add_precompiled_headers(${the_module})
|
||||
|
||||
ocv_add_accuracy_tests()
|
||||
ocv_add_perf_tests()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
#define CV_MAJOR_VERSION 2
|
||||
#define CV_MINOR_VERSION 3
|
||||
#define CV_SUBMINOR_VERSION 2
|
||||
#define CV_SUBMINOR_VERSION 3
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
define_opencv_module(features2d opencv_core opencv_imgproc opencv_highgui opencv_flann)
|
||||
set(the_description "2D Features Framework")
|
||||
ocv_define_module(features2d opencv_imgproc opencv_highgui opencv_flann)
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
define_opencv_module(flann opencv_core)
|
||||
set(the_description "Clustering and Search in Multi-Dimensional Spaces")
|
||||
ocv_define_module(flann opencv_core)
|
||||
|
||||
|
||||
+76
-156
@@ -1,181 +1,101 @@
|
||||
if(ANDROID OR IOS)
|
||||
return()
|
||||
ocv_module_disable(gpu)
|
||||
endif()
|
||||
|
||||
option(OCVMODULE_GPU "Include gpu module into the OpenCV build" ON)
|
||||
if(NOT OCVMODULE_GPU)
|
||||
return()
|
||||
endif()
|
||||
set(the_description "GPU-accelerated Computer Vision")
|
||||
ocv_add_module(gpu opencv_imgproc opencv_calib3d opencv_objdetect)
|
||||
|
||||
set(name "gpu")
|
||||
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/cuda")
|
||||
|
||||
set(the_target "opencv_${name}")
|
||||
project(${the_target})
|
||||
file(GLOB lib_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
|
||||
file(GLOB lib_int_hdrs "src/*.hpp" "src/*.h")
|
||||
file(GLOB lib_cuda_hdrs "src/cuda/*.hpp" "src/cuda/*.h")
|
||||
file(GLOB lib_device_hdrs "src/opencv2/gpu/device/*.hpp" "src/opencv2/gpu/device/*.h")
|
||||
file(GLOB lib_device_hdrs_detail "src/opencv2/gpu/device/detail/*.hpp" "src/opencv2/gpu/device/detail/*.h")
|
||||
file(GLOB lib_srcs "src/*.cpp")
|
||||
file(GLOB lib_cuda "src/cuda/*.cu*")
|
||||
|
||||
set(DEPS "opencv_core" "opencv_imgproc" "opencv_calib3d" "opencv_objdetect")
|
||||
set(DEPS_HEADER ${DEPS} "opencv_features2d" "opencv_flann")
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} opencv_gpu)
|
||||
|
||||
opencv_module_includes(${DEPS_HEADER})
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/cuda")
|
||||
|
||||
file(GLOB lib_srcs "src/*.cpp")
|
||||
file(GLOB lib_int_hdrs "src/*.h*")
|
||||
file(GLOB lib_cuda "src/cuda/*.cu*")
|
||||
file(GLOB lib_cuda_hdrs "src/cuda/*.h*")
|
||||
source_group("Include" FILES ${lib_hdrs})
|
||||
source_group("Src\\Host" FILES ${lib_srcs} ${lib_int_hdrs})
|
||||
source_group("Src\\Cuda" FILES ${lib_cuda} ${lib_cuda_hdrs})
|
||||
|
||||
file(GLOB lib_hdrs "include/opencv2/${name}/*.h*")
|
||||
source_group("Include" FILES ${lib_hdrs})
|
||||
|
||||
#file(GLOB lib_device_hdrs "include/opencv2/${name}/device/*.h*")
|
||||
file(GLOB lib_device_hdrs "src/opencv2/gpu/device/*.h*")
|
||||
file(GLOB lib_device_hdrs_detail "src/opencv2/gpu/device/detail/*.h*")
|
||||
source_group("Device" FILES ${lib_device_hdrs})
|
||||
source_group("Device\\Detail" FILES ${lib_device_hdrs_detail})
|
||||
|
||||
if (HAVE_CUDA)
|
||||
file(GLOB_RECURSE ncv_srcs "src/nvidia/*.cpp")
|
||||
file(GLOB_RECURSE ncv_cuda "src/nvidia/*.cu")
|
||||
file(GLOB_RECURSE ncv_hdrs "src/nvidia/*.hpp" "src/nvidia/*.h")
|
||||
file(GLOB_RECURSE ncv_srcs "src/nvidia/*.cpp")
|
||||
file(GLOB_RECURSE ncv_cuda "src/nvidia/*.cu")
|
||||
file(GLOB_RECURSE ncv_hdrs "src/nvidia/*.hpp" "src/nvidia/*.h")
|
||||
set(ncv_files ${ncv_srcs} ${ncv_hdrs} ${ncv_cuda})
|
||||
|
||||
source_group("Src\\NVidia" FILES ${ncv_files})
|
||||
include_directories("src/nvidia/core" "src/nvidia/NPP_staging" ${CUDA_INCLUDE_DIRS})
|
||||
|
||||
#set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-keep")
|
||||
#set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;/EHsc-;")
|
||||
|
||||
source_group("Src\\NVidia" FILES ${ncv_srcs} ${ncv_hdrs} ${ncv_cuda})
|
||||
include_directories("src/nvidia/core" "src/nvidia/NPP_staging")
|
||||
foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
|
||||
string(REPLACE "/W4" "/W3" ${var} "${${var}}")
|
||||
endforeach()
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4211 /wd4201 /wd4100 /wd4505 /wd4408 /wd4251")
|
||||
|
||||
foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
|
||||
string(REPLACE "/EHsc-" "/EHs" ${var} "${${var}}")
|
||||
endforeach()
|
||||
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler /wd4251)
|
||||
endif()
|
||||
|
||||
OCV_CUDA_COMPILE(cuda_objs ${lib_cuda} ${ncv_cuda})
|
||||
#CUDA_BUILD_CLEAN_TARGET()
|
||||
|
||||
unset(CUDA_npp_LIBRARY CACHE)
|
||||
find_cuda_helper_libs(npp)
|
||||
set(cuda_link_libs ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
else()
|
||||
set(lib_cuda "")
|
||||
set(cuda_objs "")
|
||||
set(cuda_link_libs "")
|
||||
set(ncv_files "")
|
||||
endif()
|
||||
|
||||
if (HAVE_CUDA)
|
||||
include_directories(${CUDA_INCLUDE_DIRS})
|
||||
ocv_set_module_sources(
|
||||
HEADERS ${lib_hdrs}
|
||||
SOURCES ${lib_int_hdrs} ${lib_cuda_hdrs} ${lib_device_hdrs} ${lib_device_hdrs_detail} ${lib_srcs} ${lib_cuda} ${ncv_files} ${cuda_objs}
|
||||
)
|
||||
|
||||
ocv_create_module(${cuda_link_libs})
|
||||
|
||||
if(HAVE_CUDA)
|
||||
if(HAVE_CUFFT)
|
||||
CUDA_ADD_CUFFT_TO_TARGET(${the_module})
|
||||
endif()
|
||||
|
||||
if (UNIX OR APPLE)
|
||||
set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;-fPIC;")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" "-fPIC")
|
||||
endif()
|
||||
|
||||
#set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-keep")
|
||||
#set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;/EHsc-;")
|
||||
|
||||
if (APPLE)
|
||||
set (CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;-fno-finite-math-only;")
|
||||
endif()
|
||||
|
||||
string(REPLACE "/W4" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REPLACE "/W4" "/W3" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
string(REPLACE "/W4" "/W3" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
|
||||
if(MSVC)
|
||||
#string(REPLACE "/W4" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
#string(REPLACE "/W4" "/W3" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
#string(REPLACE "/W4" "/W3" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4211 /wd4201 /wd4100 /wd4505 /wd4408 /wd4251")
|
||||
|
||||
string(REPLACE "/EHsc-" "/EHs" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string(REPLACE "/EHsc-" "/EHs" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
string(REPLACE "/EHsc-" "/EHs" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
|
||||
string(REPLACE "/EHsc-" "/EHs" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REPLACE "/EHsc-" "/EHs" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
string(REPLACE "/EHsc-" "/EHs" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;-DCVAPI_EXPORTS")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xcompiler;/wd4251")
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
# we remove -ggdb3 flag as it leads to preprocessor errors when compiling CUDA files (CUDA 4.1)
|
||||
set(tmp ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
string(REPLACE "-ggdb3" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
CUDA_COMPILE(cuda_objs ${lib_cuda} ${ncv_cuda})
|
||||
set(CMAKE_CXX_DEBUG_FLAGS ${tmp})
|
||||
|
||||
#CUDA_BUILD_CLEAN_TARGET()
|
||||
endif()
|
||||
|
||||
add_library(${the_target} ${lib_srcs} ${lib_hdrs} ${lib_int_hdrs} ${lib_cuda} ${lib_cuda_hdrs} ${lib_device_hdrs} ${lib_device_hdrs_detail} ${ncv_srcs} ${ncv_hdrs} ${ncv_cuda} ${cuda_objs})
|
||||
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${DEPS} )
|
||||
opencv_module_register(${the_target})
|
||||
|
||||
if (HAVE_CUDA)
|
||||
target_link_libraries(${the_target} ${CUDA_LIBRARIES})
|
||||
|
||||
unset(CUDA_npp_LIBRARY CACHE)
|
||||
find_cuda_helper_libs(npp)
|
||||
target_link_libraries(${the_target} ${CUDA_npp_LIBRARY})
|
||||
|
||||
if(HAVE_CUFFT)
|
||||
CUDA_ADD_CUFFT_TO_TARGET(${the_target})
|
||||
endif()
|
||||
|
||||
if(HAVE_CUBLAS)
|
||||
CUDA_ADD_CUBLAS_TO_TARGET(${the_target})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
opencv_module_setup(${name})
|
||||
|
||||
install(FILES src/nvidia/NPP_staging/NPP_staging.hpp src/nvidia/core/NCV.hpp
|
||||
if(HAVE_CUBLAS)
|
||||
CUDA_ADD_CUBLAS_TO_TARGET(${the_module})
|
||||
endif()
|
||||
|
||||
install(FILES src/nvidia/NPP_staging/NPP_staging.hpp src/nvidia/core/NCV.hpp
|
||||
DESTINATION ${OPENCV_INCLUDE_PREFIX}/opencv2/${name}
|
||||
COMPONENT main)
|
||||
endif()
|
||||
|
||||
#install(FILES ${lib_device_hdrs}
|
||||
# DESTINATION ${OPENCV_INCLUDE_PREFIX}/opencv2/${name}/device
|
||||
# COMPONENT main)
|
||||
|
||||
ocv_add_precompiled_headers(${the_module})
|
||||
|
||||
################################################################################################################
|
||||
################################ GPU Module Tests #####################################################
|
||||
################################################################################################################
|
||||
|
||||
# Test files processing is in the separated directory to avoid 'Src' source
|
||||
# filter creation in Visual Studio
|
||||
if(BUILD_TESTS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/test)
|
||||
set(the_test_target "opencv_test_${name}")
|
||||
set(test_deps opencv_${name} opencv_ts opencv_highgui opencv_calib3d ${DEPS})
|
||||
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/test")
|
||||
opencv_module_includes(${test_deps})
|
||||
|
||||
file(GLOB test_srcs "test/*.cpp")
|
||||
file(GLOB test_hdrs "test/*.h*")
|
||||
|
||||
source_group("Src" FILES ${test_hdrs} ${test_srcs})
|
||||
if(HAVE_CUDA)
|
||||
include_directories(${CUDA_INCLUDE_DIRS} ${OpenCV_SOURCE_DIR}/modules/gpu/src/nvidia ${OpenCV_SOURCE_DIR}/modules/gpu/src/nvidia/core ${OpenCV_SOURCE_DIR}/modules/gpu/src/nvidia/NPP_staging)
|
||||
|
||||
file(GLOB nvidia "test/nvidia/*.cpp" "test/nvidia/*.h*")
|
||||
source_group("Src\\NVidia" FILES ${nvidia})
|
||||
endif()
|
||||
|
||||
add_executable(${the_test_target} ${test_srcs} ${test_hdrs} ${nvidia})
|
||||
|
||||
# Additional target properties
|
||||
set_target_properties(${the_test_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}"
|
||||
)
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_test_target} PROPERTIES FOLDER "tests")
|
||||
endif()
|
||||
|
||||
# Add the required libraries for linking:
|
||||
target_link_libraries(${the_test_target} ${OPENCV_LINKER_LIBS} ${test_deps})
|
||||
|
||||
enable_testing()
|
||||
get_target_property(LOC ${the_test_target} LOCATION)
|
||||
add_test(${the_test_target} "${LOC}")
|
||||
|
||||
#if(WIN32)
|
||||
# install(TARGETS ${the_test_target} RUNTIME DESTINATION bin COMPONENT main)
|
||||
#endif()
|
||||
|
||||
add_opencv_precompiled_headers(${the_test_target})
|
||||
file(GLOB test_srcs "test/*.cpp")
|
||||
file(GLOB test_hdrs "test/*.hpp" "test/*.h")
|
||||
if(HAVE_CUDA)
|
||||
file(GLOB nvidia "test/nvidia/*.cpp" "test/nvidia/*.hpp" "test/nvidia/*.h")
|
||||
set(nvidia FILES "Src\\\\\\\\NVidia" ${nvidia}) # 8 ugly backslashes :'(
|
||||
else()
|
||||
set(nvidia "")
|
||||
endif()
|
||||
|
||||
|
||||
define_opencv_perf_test(${name})
|
||||
ocv_add_accuracy_tests(FILES "Include" ${test_hdrs}
|
||||
FILES "Src" ${test_srcs}
|
||||
${nvidia})
|
||||
ocv_add_perf_tests()
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
if(IOS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(haartraining)
|
||||
|
||||
include_directories(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/modules/core/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/imgproc/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/objdetect/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/ml/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/highgui/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/video/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/features2d/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/flann/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/calib3d/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/legacy/include"
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
link_directories(${OpenCV_SOURCE_DIR}/lib ${OpenCV_SOURCE_DIR}/bin ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
set(haartraining_libs opencv_core opencv_imgproc opencv_highgui opencv_objdetect opencv_calib3d opencv_haartraining_engine)
|
||||
|
||||
link_libraries(${haartraining_libs})
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# Library
|
||||
# -----------------------------------------------------------
|
||||
set(cvhaartraining_lib_src
|
||||
_cvcommon.h
|
||||
cvclassifier.h
|
||||
_cvhaartraining.h
|
||||
cvhaartraining.h
|
||||
cvboost.cpp
|
||||
cvcommon.cpp
|
||||
cvhaarclassifier.cpp
|
||||
cvhaartraining.cpp
|
||||
cvsamples.cpp
|
||||
)
|
||||
|
||||
add_library(opencv_haartraining_engine STATIC ${cvhaartraining_lib_src})
|
||||
set_target_properties(opencv_haartraining_engine PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
INSTALL_NAME_DIR lib
|
||||
)
|
||||
|
||||
if(NOT ANDROID)
|
||||
# -----------------------------------------------------------
|
||||
# haartraining
|
||||
# -----------------------------------------------------------
|
||||
|
||||
add_executable(opencv_haartraining cvhaartraining.h haartraining.cpp)
|
||||
add_dependencies(opencv_haartraining ${haartraining_libs})
|
||||
set_target_properties(opencv_haartraining PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
OUTPUT_NAME "opencv_haartraining")
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# createsamples
|
||||
# -----------------------------------------------------------
|
||||
|
||||
add_executable(opencv_createsamples cvhaartraining.h createsamples.cpp)
|
||||
add_dependencies(opencv_createsamples ${haartraining_libs})
|
||||
set_target_properties(opencv_createsamples PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
OUTPUT_NAME "opencv_createsamples")
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# performance
|
||||
# -----------------------------------------------------------
|
||||
add_executable(opencv_performance performance.cpp)
|
||||
add_dependencies(opencv_performance ${haartraining_libs})
|
||||
set_target_properties(opencv_performance PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
OUTPUT_NAME "opencv_performance")
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# Install part
|
||||
# -----------------------------------------------------------
|
||||
|
||||
install(TARGETS opencv_haartraining RUNTIME DESTINATION bin COMPONENT main)
|
||||
install(TARGETS opencv_createsamples RUNTIME DESTINATION bin COMPONENT main)
|
||||
install(TARGETS opencv_performance RUNTIME DESTINATION bin COMPONENT main)
|
||||
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(opencv_performance PROPERTIES FOLDER "applications")
|
||||
set_target_properties(opencv_createsamples PROPERTIES FOLDER "applications")
|
||||
set_target_properties(opencv_haartraining PROPERTIES FOLDER "applications")
|
||||
set_target_properties(opencv_haartraining_engine PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
@@ -1,100 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __CVCOMMON_H_
|
||||
#define __CVCOMMON_H_
|
||||
|
||||
#include "cxcore.h"
|
||||
#include "cv.h"
|
||||
#include "cxmisc.h"
|
||||
|
||||
#define __BEGIN__ __CV_BEGIN__
|
||||
#define __END__ __CV_END__
|
||||
#define EXIT __CV_EXIT__
|
||||
|
||||
#define CV_DECLARE_QSORT( func_name, T, less_than ) \
|
||||
void func_name( T* array, size_t length, int aux );
|
||||
|
||||
#define less_than( a, b ) ((a) < (b))
|
||||
|
||||
CV_DECLARE_QSORT( icvSort_32f, float, less_than )
|
||||
|
||||
CV_DECLARE_QSORT( icvSort_32s, int, less_than )
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 512
|
||||
#endif /* PATH_MAX */
|
||||
|
||||
int icvMkDir( const char* filename );
|
||||
|
||||
/* returns index at specified position from index matrix of any type.
|
||||
if matrix is NULL, then specified position is returned */
|
||||
CV_INLINE
|
||||
int icvGetIdxAt( CvMat* idx, int pos );
|
||||
|
||||
CV_INLINE
|
||||
int icvGetIdxAt( CvMat* idx, int pos )
|
||||
{
|
||||
if( idx == NULL )
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
CvScalar sc;
|
||||
int type;
|
||||
|
||||
type = CV_MAT_TYPE( idx->type );
|
||||
cvRawDataToScalar( idx->data.ptr + pos *
|
||||
( (idx->rows == 1) ? CV_ELEM_SIZE( type ) : idx->step ), type, &sc );
|
||||
|
||||
return (int) sc.val[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* debug functions */
|
||||
|
||||
#define CV_DEBUG_SAVE( ptr ) icvSave( ptr, __FILE__, __LINE__ );
|
||||
|
||||
void icvSave( const CvArr* ptr, const char* filename, int line );
|
||||
|
||||
#endif /* __CVCOMMON_H_ */
|
||||
|
||||
@@ -1,414 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* _cvhaartraining.h
|
||||
*
|
||||
* training of cascade of boosted classifiers based on haar features
|
||||
*/
|
||||
|
||||
#ifndef __CVHAARTRAINING_H_
|
||||
#define __CVHAARTRAINING_H_
|
||||
|
||||
#include "_cvcommon.h"
|
||||
#include "cvclassifier.h"
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
/* parameters for tree cascade classifier training */
|
||||
|
||||
/* max number of clusters */
|
||||
#define CV_MAX_CLUSTERS 3
|
||||
|
||||
/* term criteria for K-Means */
|
||||
#define CV_TERM_CRITERIA() cvTermCriteria( CV_TERMCRIT_EPS, 1000, 1E-5 )
|
||||
|
||||
/* print statistic info */
|
||||
#define CV_VERBOSE 1
|
||||
|
||||
#define CV_STAGE_CART_FILE_NAME "AdaBoostCARTHaarClassifier.txt"
|
||||
|
||||
#define CV_HAAR_FEATURE_MAX 3
|
||||
#define CV_HAAR_FEATURE_DESC_MAX 20
|
||||
|
||||
typedef int sum_type;
|
||||
typedef double sqsum_type;
|
||||
typedef short idx_type;
|
||||
|
||||
#define CV_SUM_MAT_TYPE CV_32SC1
|
||||
#define CV_SQSUM_MAT_TYPE CV_64FC1
|
||||
#define CV_IDX_MAT_TYPE CV_16SC1
|
||||
|
||||
#define CV_STUMP_TRAIN_PORTION 100
|
||||
|
||||
#define CV_THRESHOLD_EPS (0.00001F)
|
||||
|
||||
typedef struct CvTHaarFeature
|
||||
{
|
||||
char desc[CV_HAAR_FEATURE_DESC_MAX];
|
||||
int tilted;
|
||||
struct
|
||||
{
|
||||
CvRect r;
|
||||
float weight;
|
||||
} rect[CV_HAAR_FEATURE_MAX];
|
||||
} CvTHaarFeature;
|
||||
|
||||
typedef struct CvFastHaarFeature
|
||||
{
|
||||
int tilted;
|
||||
struct
|
||||
{
|
||||
int p0, p1, p2, p3;
|
||||
float weight;
|
||||
} rect[CV_HAAR_FEATURE_MAX];
|
||||
} CvFastHaarFeature;
|
||||
|
||||
typedef struct CvIntHaarFeatures
|
||||
{
|
||||
CvSize winsize;
|
||||
int count;
|
||||
CvTHaarFeature* feature;
|
||||
CvFastHaarFeature* fastfeature;
|
||||
} CvIntHaarFeatures;
|
||||
|
||||
CV_INLINE CvTHaarFeature cvHaarFeature( const char* desc,
|
||||
int x0, int y0, int w0, int h0, float wt0,
|
||||
int x1, int y1, int w1, int h1, float wt1,
|
||||
int x2 CV_DEFAULT( 0 ), int y2 CV_DEFAULT( 0 ),
|
||||
int w2 CV_DEFAULT( 0 ), int h2 CV_DEFAULT( 0 ),
|
||||
float wt2 CV_DEFAULT( 0.0F ) );
|
||||
|
||||
CV_INLINE CvTHaarFeature cvHaarFeature( const char* desc,
|
||||
int x0, int y0, int w0, int h0, float wt0,
|
||||
int x1, int y1, int w1, int h1, float wt1,
|
||||
int x2, int y2, int w2, int h2, float wt2 )
|
||||
{
|
||||
CvTHaarFeature hf;
|
||||
|
||||
assert( CV_HAAR_FEATURE_MAX >= 3 );
|
||||
assert( strlen( desc ) < CV_HAAR_FEATURE_DESC_MAX );
|
||||
|
||||
strcpy( &(hf.desc[0]), desc );
|
||||
hf.tilted = ( hf.desc[0] == 't' );
|
||||
|
||||
hf.rect[0].r.x = x0;
|
||||
hf.rect[0].r.y = y0;
|
||||
hf.rect[0].r.width = w0;
|
||||
hf.rect[0].r.height = h0;
|
||||
hf.rect[0].weight = wt0;
|
||||
|
||||
hf.rect[1].r.x = x1;
|
||||
hf.rect[1].r.y = y1;
|
||||
hf.rect[1].r.width = w1;
|
||||
hf.rect[1].r.height = h1;
|
||||
hf.rect[1].weight = wt1;
|
||||
|
||||
hf.rect[2].r.x = x2;
|
||||
hf.rect[2].r.y = y2;
|
||||
hf.rect[2].r.width = w2;
|
||||
hf.rect[2].r.height = h2;
|
||||
hf.rect[2].weight = wt2;
|
||||
|
||||
return hf;
|
||||
}
|
||||
|
||||
/* Prepared for training samples */
|
||||
typedef struct CvHaarTrainingData
|
||||
{
|
||||
CvSize winsize; /* training image size */
|
||||
int maxnum; /* maximum number of samples */
|
||||
CvMat sum; /* sum images (each row represents image) */
|
||||
CvMat tilted; /* tilted sum images (each row represents image) */
|
||||
CvMat normfactor; /* normalization factor */
|
||||
CvMat cls; /* classes. 1.0 - object, 0.0 - background */
|
||||
CvMat weights; /* weights */
|
||||
|
||||
CvMat* valcache; /* precalculated feature values (CV_32FC1) */
|
||||
CvMat* idxcache; /* presorted indices (CV_IDX_MAT_TYPE) */
|
||||
} CvHaarTrainigData;
|
||||
|
||||
|
||||
/* Passed to callback functions */
|
||||
typedef struct CvUserdata
|
||||
{
|
||||
CvHaarTrainingData* trainingData;
|
||||
CvIntHaarFeatures* haarFeatures;
|
||||
} CvUserdata;
|
||||
|
||||
CV_INLINE
|
||||
CvUserdata cvUserdata( CvHaarTrainingData* trainingData,
|
||||
CvIntHaarFeatures* haarFeatures );
|
||||
|
||||
CV_INLINE
|
||||
CvUserdata cvUserdata( CvHaarTrainingData* trainingData,
|
||||
CvIntHaarFeatures* haarFeatures )
|
||||
{
|
||||
CvUserdata userdata;
|
||||
|
||||
userdata.trainingData = trainingData;
|
||||
userdata.haarFeatures = haarFeatures;
|
||||
|
||||
return userdata;
|
||||
}
|
||||
|
||||
|
||||
#define CV_INT_HAAR_CLASSIFIER_FIELDS() \
|
||||
float (*eval)( CvIntHaarClassifier*, sum_type*, sum_type*, float ); \
|
||||
void (*save)( CvIntHaarClassifier*, FILE* file ); \
|
||||
void (*release)( CvIntHaarClassifier** );
|
||||
|
||||
/* internal weak classifier*/
|
||||
typedef struct CvIntHaarClassifier
|
||||
{
|
||||
CV_INT_HAAR_CLASSIFIER_FIELDS()
|
||||
} CvIntHaarClassifier;
|
||||
|
||||
/*
|
||||
* CART classifier
|
||||
*/
|
||||
typedef struct CvCARTHaarClassifier
|
||||
{
|
||||
CV_INT_HAAR_CLASSIFIER_FIELDS()
|
||||
|
||||
int count;
|
||||
int* compidx;
|
||||
CvTHaarFeature* feature;
|
||||
CvFastHaarFeature* fastfeature;
|
||||
float* threshold;
|
||||
int* left;
|
||||
int* right;
|
||||
float* val;
|
||||
} CvCARTHaarClassifier;
|
||||
|
||||
/* internal stage classifier */
|
||||
typedef struct CvStageHaarClassifier
|
||||
{
|
||||
CV_INT_HAAR_CLASSIFIER_FIELDS()
|
||||
|
||||
int count;
|
||||
float threshold;
|
||||
CvIntHaarClassifier** classifier;
|
||||
} CvStageHaarClassifier;
|
||||
|
||||
/* internal cascade classifier */
|
||||
typedef struct CvCascadeHaarClassifier
|
||||
{
|
||||
CV_INT_HAAR_CLASSIFIER_FIELDS()
|
||||
|
||||
int count;
|
||||
CvIntHaarClassifier** classifier;
|
||||
} CvCascadeHaarClassifier;
|
||||
|
||||
|
||||
/* internal tree cascade classifier node */
|
||||
typedef struct CvTreeCascadeNode
|
||||
{
|
||||
CvStageHaarClassifier* stage;
|
||||
|
||||
struct CvTreeCascadeNode* next;
|
||||
struct CvTreeCascadeNode* child;
|
||||
struct CvTreeCascadeNode* parent;
|
||||
|
||||
struct CvTreeCascadeNode* next_same_level;
|
||||
struct CvTreeCascadeNode* child_eval;
|
||||
int idx;
|
||||
int leaf;
|
||||
} CvTreeCascadeNode;
|
||||
|
||||
/* internal tree cascade classifier */
|
||||
typedef struct CvTreeCascadeClassifier
|
||||
{
|
||||
CV_INT_HAAR_CLASSIFIER_FIELDS()
|
||||
|
||||
CvTreeCascadeNode* root; /* root of the tree */
|
||||
CvTreeCascadeNode* root_eval; /* root node for the filtering */
|
||||
|
||||
int next_idx;
|
||||
} CvTreeCascadeClassifier;
|
||||
|
||||
|
||||
CV_INLINE float cvEvalFastHaarFeature( const CvFastHaarFeature* feature,
|
||||
const sum_type* sum, const sum_type* tilted )
|
||||
{
|
||||
const sum_type* img = feature->tilted ? tilted : sum;
|
||||
float ret = feature->rect[0].weight*
|
||||
(img[feature->rect[0].p0] - img[feature->rect[0].p1] -
|
||||
img[feature->rect[0].p2] + img[feature->rect[0].p3]) +
|
||||
feature->rect[1].weight*
|
||||
(img[feature->rect[1].p0] - img[feature->rect[1].p1] -
|
||||
img[feature->rect[1].p2] + img[feature->rect[1].p3]);
|
||||
|
||||
if( feature->rect[2].weight != 0.0f )
|
||||
ret += feature->rect[2].weight *
|
||||
( img[feature->rect[2].p0] - img[feature->rect[2].p1] -
|
||||
img[feature->rect[2].p2] + img[feature->rect[2].p3] );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
typedef struct CvSampleDistortionData
|
||||
{
|
||||
IplImage* src;
|
||||
IplImage* erode;
|
||||
IplImage* dilate;
|
||||
IplImage* mask;
|
||||
IplImage* img;
|
||||
IplImage* maskimg;
|
||||
int dx;
|
||||
int dy;
|
||||
int bgcolor;
|
||||
} CvSampleDistortionData;
|
||||
|
||||
/*
|
||||
* icvConvertToFastHaarFeature
|
||||
*
|
||||
* Convert to fast representation of haar features
|
||||
*
|
||||
* haarFeature - input array
|
||||
* fastHaarFeature - output array
|
||||
* size - size of arrays
|
||||
* step - row step for the integral image
|
||||
*/
|
||||
void icvConvertToFastHaarFeature( CvTHaarFeature* haarFeature,
|
||||
CvFastHaarFeature* fastHaarFeature,
|
||||
int size, int step );
|
||||
|
||||
|
||||
void icvWriteVecHeader( FILE* file, int count, int width, int height );
|
||||
void icvWriteVecSample( FILE* file, CvArr* sample );
|
||||
void icvPlaceDistortedSample( CvArr* background,
|
||||
int inverse, int maxintensitydev,
|
||||
double maxxangle, double maxyangle, double maxzangle,
|
||||
int inscribe, double maxshiftf, double maxscalef,
|
||||
CvSampleDistortionData* data );
|
||||
void icvEndSampleDistortion( CvSampleDistortionData* data );
|
||||
|
||||
int icvStartSampleDistortion( const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
CvSampleDistortionData* data );
|
||||
|
||||
typedef int (*CvGetHaarTrainingDataCallback)( CvMat* img, void* userdata );
|
||||
|
||||
typedef struct CvVecFile
|
||||
{
|
||||
FILE* input;
|
||||
int count;
|
||||
int vecsize;
|
||||
int last;
|
||||
short* vector;
|
||||
} CvVecFile;
|
||||
|
||||
int icvGetHaarTraininDataFromVecCallback( CvMat* img, void* userdata );
|
||||
|
||||
/*
|
||||
* icvGetHaarTrainingDataFromVec
|
||||
*
|
||||
* Fill <data> with samples from .vec file, passed <cascade>
|
||||
int icvGetHaarTrainingDataFromVec( CvHaarTrainingData* data, int first, int count,
|
||||
CvIntHaarClassifier* cascade,
|
||||
const char* filename,
|
||||
int* consumed );
|
||||
*/
|
||||
|
||||
CvIntHaarClassifier* icvCreateCARTHaarClassifier( int count );
|
||||
|
||||
void icvReleaseHaarClassifier( CvIntHaarClassifier** classifier );
|
||||
|
||||
void icvInitCARTHaarClassifier( CvCARTHaarClassifier* carthaar, CvCARTClassifier* cart,
|
||||
CvIntHaarFeatures* intHaarFeatures );
|
||||
|
||||
float icvEvalCARTHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor );
|
||||
|
||||
CvIntHaarClassifier* icvCreateStageHaarClassifier( int count, float threshold );
|
||||
|
||||
void icvReleaseStageHaarClassifier( CvIntHaarClassifier** classifier );
|
||||
|
||||
float icvEvalStageHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor );
|
||||
|
||||
CvIntHaarClassifier* icvCreateCascadeHaarClassifier( int count );
|
||||
|
||||
void icvReleaseCascadeHaarClassifier( CvIntHaarClassifier** classifier );
|
||||
|
||||
float icvEvalCascadeHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor );
|
||||
|
||||
void icvSaveHaarFeature( CvTHaarFeature* feature, FILE* file );
|
||||
|
||||
void icvLoadHaarFeature( CvTHaarFeature* feature, FILE* file );
|
||||
|
||||
void icvSaveCARTHaarClassifier( CvIntHaarClassifier* classifier, FILE* file );
|
||||
|
||||
CvIntHaarClassifier* icvLoadCARTHaarClassifier( FILE* file, int step );
|
||||
|
||||
void icvSaveStageHaarClassifier( CvIntHaarClassifier* classifier, FILE* file );
|
||||
|
||||
CvIntHaarClassifier* icvLoadCARTStageHaarClassifier( const char* filename, int step );
|
||||
|
||||
|
||||
/* tree cascade classifier */
|
||||
|
||||
float icvEvalTreeCascadeClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor );
|
||||
|
||||
void icvSetLeafNode( CvTreeCascadeClassifier* tree, CvTreeCascadeNode* leaf );
|
||||
|
||||
float icvEvalTreeCascadeClassifierFilter( CvIntHaarClassifier* classifier, sum_type* sum,
|
||||
sum_type* tilted, float normfactor );
|
||||
|
||||
CvTreeCascadeNode* icvCreateTreeCascadeNode();
|
||||
|
||||
void icvReleaseTreeCascadeNodes( CvTreeCascadeNode** node );
|
||||
|
||||
void icvReleaseTreeCascadeClassifier( CvIntHaarClassifier** classifier );
|
||||
|
||||
/* Prints out current tree structure to <stdout> */
|
||||
void icvPrintTreeCascade( CvTreeCascadeNode* root );
|
||||
|
||||
/* Loads tree cascade classifier */
|
||||
CvIntHaarClassifier* icvLoadTreeCascadeClassifier( const char* filename, int step,
|
||||
int* splits );
|
||||
|
||||
/* Finds leaves belonging to maximal level and connects them via leaf->next_same_level */
|
||||
CvTreeCascadeNode* icvFindDeepestLeaves( CvTreeCascadeClassifier* tree );
|
||||
|
||||
#endif /* __CVHAARTRAINING_H_ */
|
||||
@@ -1,245 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* createsamples.cpp
|
||||
*
|
||||
* Create test/training samples
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "cvhaartraining.h"
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int i = 0;
|
||||
char* nullname = (char*)"(NULL)";
|
||||
char* vecname = NULL; /* .vec file name */
|
||||
char* infoname = NULL; /* file name with marked up image descriptions */
|
||||
char* imagename = NULL; /* single sample image */
|
||||
char* bgfilename = NULL; /* background */
|
||||
int num = 1000;
|
||||
int bgcolor = 0;
|
||||
int bgthreshold = 80;
|
||||
int invert = 0;
|
||||
int maxintensitydev = 40;
|
||||
double maxxangle = 1.1;
|
||||
double maxyangle = 1.1;
|
||||
double maxzangle = 0.5;
|
||||
int showsamples = 0;
|
||||
/* the samples are adjusted to this scale in the sample preview window */
|
||||
double scale = 4.0;
|
||||
int width = 24;
|
||||
int height = 24;
|
||||
|
||||
srand((unsigned int)time(0));
|
||||
|
||||
if( argc == 1 )
|
||||
{
|
||||
printf( "Usage: %s\n [-info <collection_file_name>]\n"
|
||||
" [-img <image_file_name>]\n"
|
||||
" [-vec <vec_file_name>]\n"
|
||||
" [-bg <background_file_name>]\n [-num <number_of_samples = %d>]\n"
|
||||
" [-bgcolor <background_color = %d>]\n"
|
||||
" [-inv] [-randinv] [-bgthresh <background_color_threshold = %d>]\n"
|
||||
" [-maxidev <max_intensity_deviation = %d>]\n"
|
||||
" [-maxxangle <max_x_rotation_angle = %f>]\n"
|
||||
" [-maxyangle <max_y_rotation_angle = %f>]\n"
|
||||
" [-maxzangle <max_z_rotation_angle = %f>]\n"
|
||||
" [-show [<scale = %f>]]\n"
|
||||
" [-w <sample_width = %d>]\n [-h <sample_height = %d>]\n",
|
||||
argv[0], num, bgcolor, bgthreshold, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle, scale, width, height );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 1; i < argc; ++i )
|
||||
{
|
||||
if( !strcmp( argv[i], "-info" ) )
|
||||
{
|
||||
infoname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-img" ) )
|
||||
{
|
||||
imagename = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-vec" ) )
|
||||
{
|
||||
vecname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg" ) )
|
||||
{
|
||||
bgfilename = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-num" ) )
|
||||
{
|
||||
num = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bgcolor" ) )
|
||||
{
|
||||
bgcolor = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bgthresh" ) )
|
||||
{
|
||||
bgthreshold = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-inv" ) )
|
||||
{
|
||||
invert = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-randinv" ) )
|
||||
{
|
||||
invert = CV_RANDOM_INVERT;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxidev" ) )
|
||||
{
|
||||
maxintensitydev = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxxangle" ) )
|
||||
{
|
||||
maxxangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxyangle" ) )
|
||||
{
|
||||
maxyangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxzangle" ) )
|
||||
{
|
||||
maxzangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-show" ) )
|
||||
{
|
||||
showsamples = 1;
|
||||
if( i+1 < argc && strlen( argv[i+1] ) > 0 && argv[i+1][0] != '-' )
|
||||
{
|
||||
double d;
|
||||
d = strtod( argv[i+1], 0 );
|
||||
if( d != -HUGE_VAL && d != HUGE_VAL && d > 0 ) scale = d;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-w" ) )
|
||||
{
|
||||
width = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-h" ) )
|
||||
{
|
||||
height = atoi( argv[++i] );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Info file name: %s\n", ((infoname == NULL) ? nullname : infoname ) );
|
||||
printf( "Img file name: %s\n", ((imagename == NULL) ? nullname : imagename ) );
|
||||
printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) );
|
||||
printf( "BG file name: %s\n", ((bgfilename == NULL) ? nullname : bgfilename ) );
|
||||
printf( "Num: %d\n", num );
|
||||
printf( "BG color: %d\n", bgcolor );
|
||||
printf( "BG threshold: %d\n", bgthreshold );
|
||||
printf( "Invert: %s\n", (invert == CV_RANDOM_INVERT) ? "RANDOM"
|
||||
: ( (invert) ? "TRUE" : "FALSE" ) );
|
||||
printf( "Max intensity deviation: %d\n", maxintensitydev );
|
||||
printf( "Max x angle: %g\n", maxxangle );
|
||||
printf( "Max y angle: %g\n", maxyangle );
|
||||
printf( "Max z angle: %g\n", maxzangle );
|
||||
printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" );
|
||||
if( showsamples )
|
||||
{
|
||||
printf( "Scale: %g\n", scale );
|
||||
}
|
||||
printf( "Width: %d\n", width );
|
||||
printf( "Height: %d\n", height );
|
||||
|
||||
/* determine action */
|
||||
if( imagename && vecname )
|
||||
{
|
||||
printf( "Create training samples from single image applying distortions...\n" );
|
||||
|
||||
cvCreateTrainingSamples( vecname, imagename, bgcolor, bgthreshold, bgfilename,
|
||||
num, invert, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle,
|
||||
showsamples, width, height );
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else if( imagename && bgfilename && infoname )
|
||||
{
|
||||
printf( "Create test samples from single image applying distortions...\n" );
|
||||
|
||||
cvCreateTestSamples( infoname, imagename, bgcolor, bgthreshold, bgfilename, num,
|
||||
invert, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle, showsamples, width, height );
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else if( infoname && vecname )
|
||||
{
|
||||
int total;
|
||||
|
||||
printf( "Create training samples from images collection...\n" );
|
||||
|
||||
total = cvCreateTrainingSamplesFromInfo( infoname, vecname, num, showsamples,
|
||||
width, height );
|
||||
|
||||
printf( "Done. Created %d samples\n", total );
|
||||
}
|
||||
else if( vecname )
|
||||
{
|
||||
printf( "View samples from vec file (press ESC to exit)...\n" );
|
||||
|
||||
cvShowVecSamples( vecname, width, height, scale );
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Nothing to do\n" );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,727 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* File cvclassifier.h
|
||||
*
|
||||
* Classifier types
|
||||
*/
|
||||
|
||||
#ifndef _CVCLASSIFIER_H_
|
||||
#define _CVCLASSIFIER_H_
|
||||
|
||||
#include <cmath>
|
||||
#include "cxcore.h"
|
||||
|
||||
#define CV_BOOST_API
|
||||
|
||||
/* Convert matrix to vector */
|
||||
#define CV_MAT2VEC( mat, vdata, vstep, num ) \
|
||||
assert( (mat).rows == 1 || (mat).cols == 1 ); \
|
||||
(vdata) = ((mat).data.ptr); \
|
||||
if( (mat).rows == 1 ) \
|
||||
{ \
|
||||
(vstep) = CV_ELEM_SIZE( (mat).type ); \
|
||||
(num) = (mat).cols; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(vstep) = (mat).step; \
|
||||
(num) = (mat).rows; \
|
||||
}
|
||||
|
||||
/* Set up <sample> matrix header to be <num> sample of <trainData> samples matrix */
|
||||
#define CV_GET_SAMPLE( trainData, tdflags, num, sample ) \
|
||||
if( CV_IS_ROW_SAMPLE( tdflags ) ) \
|
||||
{ \
|
||||
cvInitMatHeader( &(sample), 1, (trainData).cols, \
|
||||
CV_MAT_TYPE( (trainData).type ), \
|
||||
((trainData).data.ptr + (num) * (trainData).step), \
|
||||
(trainData).step ); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
cvInitMatHeader( &(sample), (trainData).rows, 1, \
|
||||
CV_MAT_TYPE( (trainData).type ), \
|
||||
((trainData).data.ptr + (num) * CV_ELEM_SIZE( (trainData).type )), \
|
||||
(trainData).step ); \
|
||||
}
|
||||
|
||||
#define CV_GET_SAMPLE_STEP( trainData, tdflags, sstep ) \
|
||||
(sstep) = ( ( CV_IS_ROW_SAMPLE( tdflags ) ) \
|
||||
? (trainData).step : CV_ELEM_SIZE( (trainData).type ) );
|
||||
|
||||
|
||||
#define CV_LOGRATIO_THRESHOLD 0.00001F
|
||||
|
||||
/* log( val / (1 - val ) ) */
|
||||
CV_INLINE float cvLogRatio( float val );
|
||||
|
||||
CV_INLINE float cvLogRatio( float val )
|
||||
{
|
||||
float tval;
|
||||
|
||||
tval = MAX(CV_LOGRATIO_THRESHOLD, MIN( 1.0F - CV_LOGRATIO_THRESHOLD, (val) ));
|
||||
return logf( tval / (1.0F - tval) );
|
||||
}
|
||||
|
||||
|
||||
/* flags values for classifier consturctor flags parameter */
|
||||
|
||||
/* each trainData matrix column is a sample */
|
||||
#define CV_COL_SAMPLE 0
|
||||
|
||||
/* each trainData matrix row is a sample */
|
||||
#define CV_ROW_SAMPLE 1
|
||||
|
||||
#define CV_IS_ROW_SAMPLE( flags ) ( ( flags ) & CV_ROW_SAMPLE )
|
||||
|
||||
/* Classifier supports tune function */
|
||||
#define CV_TUNABLE (1 << 1)
|
||||
|
||||
#define CV_IS_TUNABLE( flags ) ( (flags) & CV_TUNABLE )
|
||||
|
||||
|
||||
/* classifier fields common to all classifiers */
|
||||
#define CV_CLASSIFIER_FIELDS() \
|
||||
int flags; \
|
||||
float(*eval)( struct CvClassifier*, CvMat* ); \
|
||||
void (*tune)( struct CvClassifier*, CvMat*, int flags, CvMat*, CvMat*, CvMat*, \
|
||||
CvMat*, CvMat* ); \
|
||||
int (*save)( struct CvClassifier*, const char* file_name ); \
|
||||
void (*release)( struct CvClassifier** );
|
||||
|
||||
typedef struct CvClassifier
|
||||
{
|
||||
CV_CLASSIFIER_FIELDS()
|
||||
} CvClassifier;
|
||||
|
||||
#define CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
typedef struct CvClassifierTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
} CvClassifierTrainParams;
|
||||
|
||||
|
||||
/*
|
||||
Common classifier constructor:
|
||||
CvClassifier* cvCreateMyClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask CV_DEFAULT(0),
|
||||
CvCompIdx* compIdx CV_DEFAULT(0),
|
||||
CvMat* sampleIdx CV_DEFAULT(0),
|
||||
CvMat* weights CV_DEFAULT(0),
|
||||
CvClassifierTrainParams* trainParams CV_DEFAULT(0)
|
||||
)
|
||||
|
||||
*/
|
||||
|
||||
typedef CvClassifier* (*CvClassifierConstructor)( CvMat*, int, CvMat*, CvMat*, CvMat*,
|
||||
CvMat*, CvMat*, CvMat*,
|
||||
CvClassifierTrainParams* );
|
||||
|
||||
typedef enum CvStumpType
|
||||
{
|
||||
CV_CLASSIFICATION = 0,
|
||||
CV_CLASSIFICATION_CLASS = 1,
|
||||
CV_REGRESSION = 2
|
||||
} CvStumpType;
|
||||
|
||||
typedef enum CvStumpError
|
||||
{
|
||||
CV_MISCLASSIFICATION = 0,
|
||||
CV_GINI = 1,
|
||||
CV_ENTROPY = 2,
|
||||
CV_SQUARE = 3
|
||||
} CvStumpError;
|
||||
|
||||
|
||||
typedef struct CvStumpTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
CvStumpType type;
|
||||
CvStumpError error;
|
||||
} CvStumpTrainParams;
|
||||
|
||||
typedef struct CvMTStumpTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
CvStumpType type;
|
||||
CvStumpError error;
|
||||
int portion; /* number of components calculated in each thread */
|
||||
int numcomp; /* total number of components */
|
||||
|
||||
/* callback which fills <mat> with components [first, first+num[ */
|
||||
void (*getTrainData)( CvMat* mat, CvMat* sampleIdx, CvMat* compIdx,
|
||||
int first, int num, void* userdata );
|
||||
CvMat* sortedIdx; /* presorted samples indices */
|
||||
void* userdata; /* passed to callback */
|
||||
} CvMTStumpTrainParams;
|
||||
|
||||
typedef struct CvStumpClassifier
|
||||
{
|
||||
CV_CLASSIFIER_FIELDS()
|
||||
int compidx;
|
||||
|
||||
float lerror; /* impurity of the right node */
|
||||
float rerror; /* impurity of the left node */
|
||||
|
||||
float threshold;
|
||||
float left;
|
||||
float right;
|
||||
} CvStumpClassifier;
|
||||
|
||||
typedef struct CvCARTTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
/* desired number of internal nodes */
|
||||
int count;
|
||||
CvClassifierTrainParams* stumpTrainParams;
|
||||
CvClassifierConstructor stumpConstructor;
|
||||
|
||||
/*
|
||||
* Split sample indices <idx>
|
||||
* on the "left" indices <left> and "right" indices <right>
|
||||
* according to samples components <compidx> values and <threshold>.
|
||||
*
|
||||
* NOTE: Matrices <left> and <right> must be allocated using cvCreateMat function
|
||||
* since they are freed using cvReleaseMat function
|
||||
*
|
||||
* If it is NULL then the default implementation which evaluates training
|
||||
* samples from <trainData> passed to classifier constructor is used
|
||||
*/
|
||||
void (*splitIdx)( int compidx, float threshold,
|
||||
CvMat* idx, CvMat** left, CvMat** right,
|
||||
void* userdata );
|
||||
void* userdata;
|
||||
} CvCARTTrainParams;
|
||||
|
||||
typedef struct CvCARTClassifier
|
||||
{
|
||||
CV_CLASSIFIER_FIELDS()
|
||||
/* number of internal nodes */
|
||||
int count;
|
||||
|
||||
/* internal nodes (each array of <count> elements) */
|
||||
int* compidx;
|
||||
float* threshold;
|
||||
int* left;
|
||||
int* right;
|
||||
|
||||
/* leaves (array of <count>+1 elements) */
|
||||
float* val;
|
||||
} CvCARTClassifier;
|
||||
|
||||
CV_BOOST_API
|
||||
void cvGetSortedIndices( CvMat* val, CvMat* idx, int sortcols CV_DEFAULT( 0 ) );
|
||||
|
||||
CV_BOOST_API
|
||||
void cvReleaseStumpClassifier( CvClassifier** classifier );
|
||||
|
||||
CV_BOOST_API
|
||||
float cvEvalStumpClassifier( CvClassifier* classifier, CvMat* sample );
|
||||
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateStumpClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask CV_DEFAULT(0),
|
||||
CvMat* compIdx CV_DEFAULT(0),
|
||||
CvMat* sampleIdx CV_DEFAULT(0),
|
||||
CvMat* weights CV_DEFAULT(0),
|
||||
CvClassifierTrainParams* trainParams CV_DEFAULT(0) );
|
||||
|
||||
/*
|
||||
* cvCreateMTStumpClassifier
|
||||
*
|
||||
* Multithreaded stump classifier constructor
|
||||
* Includes huge train data support through callback function
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateMTStumpClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask,
|
||||
CvMat* compIdx,
|
||||
CvMat* sampleIdx,
|
||||
CvMat* weights,
|
||||
CvClassifierTrainParams* trainParams );
|
||||
|
||||
/*
|
||||
* cvCreateCARTClassifier
|
||||
*
|
||||
* CART classifier constructor
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateCARTClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask,
|
||||
CvMat* compIdx,
|
||||
CvMat* sampleIdx,
|
||||
CvMat* weights,
|
||||
CvClassifierTrainParams* trainParams );
|
||||
|
||||
CV_BOOST_API
|
||||
void cvReleaseCARTClassifier( CvClassifier** classifier );
|
||||
|
||||
CV_BOOST_API
|
||||
float cvEvalCARTClassifier( CvClassifier* classifier, CvMat* sample );
|
||||
|
||||
/****************************************************************************************\
|
||||
* Boosting *
|
||||
\****************************************************************************************/
|
||||
|
||||
/*
|
||||
* CvBoostType
|
||||
*
|
||||
* The CvBoostType enumeration specifies the boosting type.
|
||||
*
|
||||
* Remarks
|
||||
* Four different boosting variants for 2 class classification problems are supported:
|
||||
* Discrete AdaBoost, Real AdaBoost, LogitBoost and Gentle AdaBoost.
|
||||
* The L2 (2 class classification problems) and LK (K class classification problems)
|
||||
* algorithms are close to LogitBoost but more numerically stable than last one.
|
||||
* For regression three different loss functions are supported:
|
||||
* Least square, least absolute deviation and huber loss.
|
||||
*/
|
||||
typedef enum CvBoostType
|
||||
{
|
||||
CV_DABCLASS = 0, /* 2 class Discrete AdaBoost */
|
||||
CV_RABCLASS = 1, /* 2 class Real AdaBoost */
|
||||
CV_LBCLASS = 2, /* 2 class LogitBoost */
|
||||
CV_GABCLASS = 3, /* 2 class Gentle AdaBoost */
|
||||
CV_L2CLASS = 4, /* classification (2 class problem) */
|
||||
CV_LKCLASS = 5, /* classification (K class problem) */
|
||||
CV_LSREG = 6, /* least squares regression */
|
||||
CV_LADREG = 7, /* least absolute deviation regression */
|
||||
CV_MREG = 8, /* M-regression (Huber loss) */
|
||||
} CvBoostType;
|
||||
|
||||
/****************************************************************************************\
|
||||
* Iterative training functions *
|
||||
\****************************************************************************************/
|
||||
|
||||
/*
|
||||
* CvBoostTrainer
|
||||
*
|
||||
* The CvBoostTrainer structure represents internal boosting trainer.
|
||||
*/
|
||||
typedef struct CvBoostTrainer CvBoostTrainer;
|
||||
|
||||
/*
|
||||
* cvBoostStartTraining
|
||||
*
|
||||
* The cvBoostStartTraining function starts training process and calculates
|
||||
* response values and weights for the first weak classifier training.
|
||||
*
|
||||
* Parameters
|
||||
* trainClasses
|
||||
* Vector of classes of training samples classes. Each element must be 0 or 1 and
|
||||
* of type CV_32FC1.
|
||||
* weakTrainVals
|
||||
* Vector of response values for the first trained weak classifier.
|
||||
* Must be of type CV_32FC1.
|
||||
* weights
|
||||
* Weight vector of training samples for the first trained weak classifier.
|
||||
* Must be of type CV_32FC1.
|
||||
* type
|
||||
* Boosting type. CV_DABCLASS, CV_RABCLASS, CV_LBCLASS, CV_GABCLASS
|
||||
* types are supported.
|
||||
*
|
||||
* Return Values
|
||||
* The return value is a pointer to internal trainer structure which is used
|
||||
* to perform next training iterations.
|
||||
*
|
||||
* Remarks
|
||||
* weakTrainVals and weights must be allocated before calling the function
|
||||
* and of the same size as trainingClasses. Usually weights should be initialized
|
||||
* with 1.0 value.
|
||||
* The function calculates response values and weights for the first weak
|
||||
* classifier training and stores them into weakTrainVals and weights
|
||||
* respectively.
|
||||
* Note, the training of the weak classifier using weakTrainVals, weight,
|
||||
* trainingData is outside of this function.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvBoostTrainer* cvBoostStartTraining( CvMat* trainClasses,
|
||||
CvMat* weakTrainVals,
|
||||
CvMat* weights,
|
||||
CvMat* sampleIdx,
|
||||
CvBoostType type );
|
||||
/*
|
||||
* cvBoostNextWeakClassifier
|
||||
*
|
||||
* The cvBoostNextWeakClassifier function performs next training
|
||||
* iteration and caluclates response values and weights for the next weak
|
||||
* classifier training.
|
||||
*
|
||||
* Parameters
|
||||
* weakEvalVals
|
||||
* Vector of values obtained by evaluation of each sample with
|
||||
* the last trained weak classifier (iteration i). Must be of CV_32FC1 type.
|
||||
* trainClasses
|
||||
* Vector of classes of training samples. Each element must be 0 or 1,
|
||||
* and of type CV_32FC1.
|
||||
* weakTrainVals
|
||||
* Vector of response values for the next weak classifier training
|
||||
* (iteration i+1). Must be of type CV_32FC1.
|
||||
* weights
|
||||
* Weight vector of training samples for the next weak classifier training
|
||||
* (iteration i+1). Must be of type CV_32FC1.
|
||||
* trainer
|
||||
* A pointer to internal trainer returned by the cvBoostStartTraining
|
||||
* function call.
|
||||
*
|
||||
* Return Values
|
||||
* The return value is the coefficient for the last trained weak classifier.
|
||||
*
|
||||
* Remarks
|
||||
* weakTrainVals and weights must be exactly the same vectors as used in
|
||||
* the cvBoostStartTraining function call and should not be modified.
|
||||
* The function calculates response values and weights for the next weak
|
||||
* classifier training and stores them into weakTrainVals and weights
|
||||
* respectively.
|
||||
* Note, the training of the weak classifier of iteration i+1 using
|
||||
* weakTrainVals, weight, trainingData is outside of this function.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
float cvBoostNextWeakClassifier( CvMat* weakEvalVals,
|
||||
CvMat* trainClasses,
|
||||
CvMat* weakTrainVals,
|
||||
CvMat* weights,
|
||||
CvBoostTrainer* trainer );
|
||||
|
||||
/*
|
||||
* cvBoostEndTraining
|
||||
*
|
||||
* The cvBoostEndTraining function finishes training process and releases
|
||||
* internally allocated memory.
|
||||
*
|
||||
* Parameters
|
||||
* trainer
|
||||
* A pointer to a pointer to internal trainer returned by the cvBoostStartTraining
|
||||
* function call.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
void cvBoostEndTraining( CvBoostTrainer** trainer );
|
||||
|
||||
/****************************************************************************************\
|
||||
* Boosted tree models *
|
||||
\****************************************************************************************/
|
||||
|
||||
/*
|
||||
* CvBtClassifier
|
||||
*
|
||||
* The CvBtClassifier structure represents boosted tree model.
|
||||
*
|
||||
* Members
|
||||
* flags
|
||||
* Flags. If CV_IS_TUNABLE( flags ) != 0 then the model supports tuning.
|
||||
* eval
|
||||
* Evaluation function. Returns sample predicted class (0, 1, etc.)
|
||||
* for classification or predicted value for regression.
|
||||
* tune
|
||||
* Tune function. If the model supports tuning then tune call performs
|
||||
* one more boosting iteration if passed to the function flags parameter
|
||||
* is CV_TUNABLE otherwise releases internally allocated for tuning memory
|
||||
* and makes the model untunable.
|
||||
* NOTE: Since tuning uses the pointers to parameters,
|
||||
* passed to the cvCreateBtClassifier function, they should not be modified
|
||||
* or released between tune calls.
|
||||
* save
|
||||
* This function stores the model into given file.
|
||||
* release
|
||||
* This function releases the model.
|
||||
* type
|
||||
* Boosted tree model type.
|
||||
* numclasses
|
||||
* Number of classes for CV_LKCLASS type or 1 for all other types.
|
||||
* numiter
|
||||
* Number of iterations. Number of weak classifiers is equal to number
|
||||
* of iterations for all types except CV_LKCLASS. For CV_LKCLASS type
|
||||
* number of weak classifiers is (numiter * numclasses).
|
||||
* numfeatures
|
||||
* Number of features in sample.
|
||||
* trees
|
||||
* Stores weak classifiers when the model does not support tuning.
|
||||
* seq
|
||||
* Stores weak classifiers when the model supports tuning.
|
||||
* trainer
|
||||
* Pointer to internal tuning parameters if the model supports tuning.
|
||||
*/
|
||||
typedef struct CvBtClassifier
|
||||
{
|
||||
CV_CLASSIFIER_FIELDS()
|
||||
|
||||
CvBoostType type;
|
||||
int numclasses;
|
||||
int numiter;
|
||||
int numfeatures;
|
||||
union
|
||||
{
|
||||
CvCARTClassifier** trees;
|
||||
CvSeq* seq;
|
||||
};
|
||||
void* trainer;
|
||||
} CvBtClassifier;
|
||||
|
||||
/*
|
||||
* CvBtClassifierTrainParams
|
||||
*
|
||||
* The CvBtClassifierTrainParams structure stores training parameters for
|
||||
* boosted tree model.
|
||||
*
|
||||
* Members
|
||||
* type
|
||||
* Boosted tree model type.
|
||||
* numiter
|
||||
* Desired number of iterations.
|
||||
* param
|
||||
* Parameter Model Type Parameter Meaning
|
||||
* param[0] Any Shrinkage factor
|
||||
* param[1] CV_MREG alpha. (1-alpha) determines "break-down" point of
|
||||
* the training procedure, i.e. the fraction of samples
|
||||
* that can be arbitrary modified without serious
|
||||
* degrading the quality of the result.
|
||||
* CV_DABCLASS, Weight trimming factor.
|
||||
* CV_RABCLASS,
|
||||
* CV_LBCLASS,
|
||||
* CV_GABCLASS,
|
||||
* CV_L2CLASS,
|
||||
* CV_LKCLASS
|
||||
* numsplits
|
||||
* Desired number of splits in each tree.
|
||||
*/
|
||||
typedef struct CvBtClassifierTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
|
||||
CvBoostType type;
|
||||
int numiter;
|
||||
float param[2];
|
||||
int numsplits;
|
||||
} CvBtClassifierTrainParams;
|
||||
|
||||
/*
|
||||
* cvCreateBtClassifier
|
||||
*
|
||||
* The cvCreateBtClassifier function creates boosted tree model.
|
||||
*
|
||||
* Parameters
|
||||
* trainData
|
||||
* Matrix of feature values. Must have CV_32FC1 type.
|
||||
* flags
|
||||
* Determines how samples are stored in trainData.
|
||||
* One of CV_ROW_SAMPLE or CV_COL_SAMPLE.
|
||||
* Optionally may be combined with CV_TUNABLE to make tunable model.
|
||||
* trainClasses
|
||||
* Vector of responses for regression or classes (0, 1, 2, etc.) for classification.
|
||||
* typeMask,
|
||||
* missedMeasurementsMask,
|
||||
* compIdx
|
||||
* Not supported. Must be NULL.
|
||||
* sampleIdx
|
||||
* Indices of samples used in training. If NULL then all samples are used.
|
||||
* For CV_DABCLASS, CV_RABCLASS, CV_LBCLASS and CV_GABCLASS must be NULL.
|
||||
* weights
|
||||
* Not supported. Must be NULL.
|
||||
* trainParams
|
||||
* A pointer to CvBtClassifierTrainParams structure. Training parameters.
|
||||
* See CvBtClassifierTrainParams description for details.
|
||||
*
|
||||
* Return Values
|
||||
* The return value is a pointer to created boosted tree model of type CvBtClassifier.
|
||||
*
|
||||
* Remarks
|
||||
* The function performs trainParams->numiter training iterations.
|
||||
* If CV_TUNABLE flag is specified then created model supports tuning.
|
||||
* In this case additional training iterations may be performed by
|
||||
* tune function call.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateBtClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask,
|
||||
CvMat* compIdx,
|
||||
CvMat* sampleIdx,
|
||||
CvMat* weights,
|
||||
CvClassifierTrainParams* trainParams );
|
||||
|
||||
/*
|
||||
* cvCreateBtClassifierFromFile
|
||||
*
|
||||
* The cvCreateBtClassifierFromFile function restores previously saved
|
||||
* boosted tree model from file.
|
||||
*
|
||||
* Parameters
|
||||
* filename
|
||||
* The name of the file with boosted tree model.
|
||||
*
|
||||
* Remarks
|
||||
* The restored model does not support tuning.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateBtClassifierFromFile( const char* filename );
|
||||
|
||||
/****************************************************************************************\
|
||||
* Utility functions *
|
||||
\****************************************************************************************/
|
||||
|
||||
/*
|
||||
* cvTrimWeights
|
||||
*
|
||||
* The cvTrimWeights function performs weight trimming.
|
||||
*
|
||||
* Parameters
|
||||
* weights
|
||||
* Weights vector.
|
||||
* idx
|
||||
* Indices vector of weights that should be considered.
|
||||
* If it is NULL then all weights are used.
|
||||
* factor
|
||||
* Weight trimming factor. Must be in [0, 1] range.
|
||||
*
|
||||
* Return Values
|
||||
* The return value is a vector of indices. If all samples should be used then
|
||||
* it is equal to idx. In other case the cvReleaseMat function should be called
|
||||
* to release it.
|
||||
*
|
||||
* Remarks
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvMat* cvTrimWeights( CvMat* weights, CvMat* idx, float factor );
|
||||
|
||||
/*
|
||||
* cvReadTrainData
|
||||
*
|
||||
* The cvReadTrainData function reads feature values and responses from file.
|
||||
*
|
||||
* Parameters
|
||||
* filename
|
||||
* The name of the file to be read.
|
||||
* flags
|
||||
* One of CV_ROW_SAMPLE or CV_COL_SAMPLE. Determines how feature values
|
||||
* will be stored.
|
||||
* trainData
|
||||
* A pointer to a pointer to created matrix with feature values.
|
||||
* cvReleaseMat function should be used to destroy created matrix.
|
||||
* trainClasses
|
||||
* A pointer to a pointer to created matrix with response values.
|
||||
* cvReleaseMat function should be used to destroy created matrix.
|
||||
*
|
||||
* Remarks
|
||||
* File format:
|
||||
* ============================================
|
||||
* m n
|
||||
* value_1_1 value_1_2 ... value_1_n response_1
|
||||
* value_2_1 value_2_2 ... value_2_n response_2
|
||||
* ...
|
||||
* value_m_1 value_m_2 ... value_m_n response_m
|
||||
* ============================================
|
||||
* m
|
||||
* Number of samples
|
||||
* n
|
||||
* Number of features in each sample
|
||||
* value_i_j
|
||||
* Value of j-th feature of i-th sample
|
||||
* response_i
|
||||
* Response value of i-th sample
|
||||
* For classification problems responses represent classes (0, 1, etc.)
|
||||
* All values and classes are integer or real numbers.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
void cvReadTrainData( const char* filename,
|
||||
int flags,
|
||||
CvMat** trainData,
|
||||
CvMat** trainClasses );
|
||||
|
||||
|
||||
/*
|
||||
* cvWriteTrainData
|
||||
*
|
||||
* The cvWriteTrainData function stores feature values and responses into file.
|
||||
*
|
||||
* Parameters
|
||||
* filename
|
||||
* The name of the file.
|
||||
* flags
|
||||
* One of CV_ROW_SAMPLE or CV_COL_SAMPLE. Determines how feature values
|
||||
* are stored.
|
||||
* trainData
|
||||
* Feature values matrix.
|
||||
* trainClasses
|
||||
* Response values vector.
|
||||
* sampleIdx
|
||||
* Vector of idicies of the samples that should be stored. If it is NULL
|
||||
* then all samples will be stored.
|
||||
*
|
||||
* Remarks
|
||||
* See the cvReadTrainData function for file format description.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
void cvWriteTrainData( const char* filename,
|
||||
int flags,
|
||||
CvMat* trainData,
|
||||
CvMat* trainClasses,
|
||||
CvMat* sampleIdx );
|
||||
|
||||
/*
|
||||
* cvRandShuffle
|
||||
*
|
||||
* The cvRandShuffle function perfroms random shuffling of given vector.
|
||||
*
|
||||
* Parameters
|
||||
* vector
|
||||
* Vector that should be shuffled.
|
||||
* Must have CV_8UC1, CV_16SC1, CV_32SC1 or CV_32FC1 type.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
void cvRandShuffleVec( CvMat* vector );
|
||||
|
||||
#endif /* _CVCLASSIFIER_H_ */
|
||||
@@ -1,130 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "_cvcommon.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
CV_IMPLEMENT_QSORT( icvSort_32f, float, less_than )
|
||||
|
||||
CV_IMPLEMENT_QSORT( icvSort_32s, int, less_than )
|
||||
|
||||
int icvMkDir( const char* filename )
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char* p;
|
||||
int pos;
|
||||
|
||||
#ifdef _WIN32
|
||||
struct _stat st;
|
||||
#else /* _WIN32 */
|
||||
struct stat st;
|
||||
mode_t mode;
|
||||
|
||||
mode = 0755;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
strcpy( path, filename );
|
||||
|
||||
p = path;
|
||||
for( ; ; )
|
||||
{
|
||||
pos = (int)strcspn( p, "/\\" );
|
||||
|
||||
if( pos == (int) strlen( p ) ) break;
|
||||
if( pos != 0 )
|
||||
{
|
||||
p[pos] = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
if( p[pos-1] != ':' )
|
||||
{
|
||||
if( _stat( path, &st ) != 0 )
|
||||
{
|
||||
if( _mkdir( path ) != 0 ) return 0;
|
||||
}
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
if( stat( path, &st ) != 0 )
|
||||
{
|
||||
if( mkdir( path, mode ) != 0 ) return 0;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
p[pos] = '/';
|
||||
|
||||
p += pos + 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* debug functions */
|
||||
void icvSave( const CvArr* ptr, const char* filename, int line )
|
||||
{
|
||||
CvFileStorage* fs;
|
||||
char buf[PATH_MAX];
|
||||
const char* name;
|
||||
|
||||
name = strrchr( filename, '\\' );
|
||||
if( !name ) name = strrchr( filename, '/' );
|
||||
if( !name ) name = filename;
|
||||
else name++; /* skip '/' or '\\' */
|
||||
|
||||
sprintf( buf, "%s-%d-%d", name, line, time( NULL ) );
|
||||
fs = cvOpenFileStorage( buf, NULL, CV_STORAGE_WRITE_TEXT );
|
||||
if( !fs ) return;
|
||||
cvWrite( fs, "debug", ptr );
|
||||
cvReleaseFileStorage( &fs );
|
||||
}
|
||||
#endif // #if 0
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,826 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* cvhaarclassifier.cpp
|
||||
*
|
||||
* haar classifiers (stump, CART, stage, cascade)
|
||||
*/
|
||||
|
||||
#include "_cvhaartraining.h"
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvCreateCARTHaarClassifier( int count )
|
||||
{
|
||||
CvCARTHaarClassifier* cart;
|
||||
size_t datasize;
|
||||
|
||||
datasize = sizeof( *cart ) +
|
||||
( sizeof( int ) +
|
||||
sizeof( CvTHaarFeature ) + sizeof( CvFastHaarFeature ) +
|
||||
sizeof( float ) + sizeof( int ) + sizeof( int ) ) * count +
|
||||
sizeof( float ) * (count + 1);
|
||||
|
||||
cart = (CvCARTHaarClassifier*) cvAlloc( datasize );
|
||||
memset( cart, 0, datasize );
|
||||
|
||||
cart->feature = (CvTHaarFeature*) (cart + 1);
|
||||
cart->fastfeature = (CvFastHaarFeature*) (cart->feature + count);
|
||||
cart->threshold = (float*) (cart->fastfeature + count);
|
||||
cart->left = (int*) (cart->threshold + count);
|
||||
cart->right = (int*) (cart->left + count);
|
||||
cart->val = (float*) (cart->right + count);
|
||||
cart->compidx = (int*) (cart->val + count + 1 );
|
||||
cart->count = count;
|
||||
cart->eval = icvEvalCARTHaarClassifier;
|
||||
cart->save = icvSaveCARTHaarClassifier;
|
||||
cart->release = icvReleaseHaarClassifier;
|
||||
|
||||
return (CvIntHaarClassifier*) cart;
|
||||
}
|
||||
|
||||
|
||||
void icvReleaseHaarClassifier( CvIntHaarClassifier** classifier )
|
||||
{
|
||||
cvFree( classifier );
|
||||
*classifier = NULL;
|
||||
}
|
||||
|
||||
|
||||
void icvInitCARTHaarClassifier( CvCARTHaarClassifier* carthaar, CvCARTClassifier* cart,
|
||||
CvIntHaarFeatures* intHaarFeatures )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < cart->count; i++ )
|
||||
{
|
||||
carthaar->feature[i] = intHaarFeatures->feature[cart->compidx[i]];
|
||||
carthaar->fastfeature[i] = intHaarFeatures->fastfeature[cart->compidx[i]];
|
||||
carthaar->threshold[i] = cart->threshold[i];
|
||||
carthaar->left[i] = cart->left[i];
|
||||
carthaar->right[i] = cart->right[i];
|
||||
carthaar->val[i] = cart->val[i];
|
||||
carthaar->compidx[i] = cart->compidx[i];
|
||||
}
|
||||
carthaar->count = cart->count;
|
||||
carthaar->val[cart->count] = cart->val[cart->count];
|
||||
}
|
||||
|
||||
|
||||
float icvEvalCARTHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor )
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if( cvEvalFastHaarFeature(
|
||||
((CvCARTHaarClassifier*) classifier)->fastfeature + idx, sum, tilted )
|
||||
< (((CvCARTHaarClassifier*) classifier)->threshold[idx] * normfactor) )
|
||||
{
|
||||
idx = ((CvCARTHaarClassifier*) classifier)->left[idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
idx = ((CvCARTHaarClassifier*) classifier)->right[idx];
|
||||
}
|
||||
} while( idx > 0 );
|
||||
|
||||
return ((CvCARTHaarClassifier*) classifier)->val[-idx];
|
||||
}
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvCreateStageHaarClassifier( int count, float threshold )
|
||||
{
|
||||
CvStageHaarClassifier* stage;
|
||||
size_t datasize;
|
||||
|
||||
datasize = sizeof( *stage ) + sizeof( CvIntHaarClassifier* ) * count;
|
||||
stage = (CvStageHaarClassifier*) cvAlloc( datasize );
|
||||
memset( stage, 0, datasize );
|
||||
|
||||
stage->count = count;
|
||||
stage->threshold = threshold;
|
||||
stage->classifier = (CvIntHaarClassifier**) (stage + 1);
|
||||
|
||||
stage->eval = icvEvalStageHaarClassifier;
|
||||
stage->save = icvSaveStageHaarClassifier;
|
||||
stage->release = icvReleaseStageHaarClassifier;
|
||||
|
||||
return (CvIntHaarClassifier*) stage;
|
||||
}
|
||||
|
||||
|
||||
void icvReleaseStageHaarClassifier( CvIntHaarClassifier** classifier )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ((CvStageHaarClassifier*) *classifier)->count; i++ )
|
||||
{
|
||||
if( ((CvStageHaarClassifier*) *classifier)->classifier[i] != NULL )
|
||||
{
|
||||
((CvStageHaarClassifier*) *classifier)->classifier[i]->release(
|
||||
&(((CvStageHaarClassifier*) *classifier)->classifier[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
cvFree( classifier );
|
||||
*classifier = NULL;
|
||||
}
|
||||
|
||||
|
||||
float icvEvalStageHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor )
|
||||
{
|
||||
int i;
|
||||
float stage_sum;
|
||||
|
||||
stage_sum = 0.0F;
|
||||
for( i = 0; i < ((CvStageHaarClassifier*) classifier)->count; i++ )
|
||||
{
|
||||
stage_sum +=
|
||||
((CvStageHaarClassifier*) classifier)->classifier[i]->eval(
|
||||
((CvStageHaarClassifier*) classifier)->classifier[i],
|
||||
sum, tilted, normfactor );
|
||||
}
|
||||
|
||||
return stage_sum;
|
||||
}
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvCreateCascadeHaarClassifier( int count )
|
||||
{
|
||||
CvCascadeHaarClassifier* ptr;
|
||||
size_t datasize;
|
||||
|
||||
datasize = sizeof( *ptr ) + sizeof( CvIntHaarClassifier* ) * count;
|
||||
ptr = (CvCascadeHaarClassifier*) cvAlloc( datasize );
|
||||
memset( ptr, 0, datasize );
|
||||
|
||||
ptr->count = count;
|
||||
ptr->classifier = (CvIntHaarClassifier**) (ptr + 1);
|
||||
|
||||
ptr->eval = icvEvalCascadeHaarClassifier;
|
||||
ptr->save = NULL;
|
||||
ptr->release = icvReleaseCascadeHaarClassifier;
|
||||
|
||||
return (CvIntHaarClassifier*) ptr;
|
||||
}
|
||||
|
||||
|
||||
void icvReleaseCascadeHaarClassifier( CvIntHaarClassifier** classifier )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ((CvCascadeHaarClassifier*) *classifier)->count; i++ )
|
||||
{
|
||||
if( ((CvCascadeHaarClassifier*) *classifier)->classifier[i] != NULL )
|
||||
{
|
||||
((CvCascadeHaarClassifier*) *classifier)->classifier[i]->release(
|
||||
&(((CvCascadeHaarClassifier*) *classifier)->classifier[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
cvFree( classifier );
|
||||
*classifier = NULL;
|
||||
}
|
||||
|
||||
|
||||
float icvEvalCascadeHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ((CvCascadeHaarClassifier*) classifier)->count; i++ )
|
||||
{
|
||||
if( ((CvCascadeHaarClassifier*) classifier)->classifier[i]->eval(
|
||||
((CvCascadeHaarClassifier*) classifier)->classifier[i],
|
||||
sum, tilted, normfactor )
|
||||
< ( ((CvStageHaarClassifier*)
|
||||
((CvCascadeHaarClassifier*) classifier)->classifier[i])->threshold
|
||||
- CV_THRESHOLD_EPS) )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
|
||||
void icvSaveHaarFeature( CvTHaarFeature* feature, FILE* file )
|
||||
{
|
||||
fprintf( file, "%d\n", ( ( feature->rect[2].weight == 0.0F ) ? 2 : 3) );
|
||||
fprintf( file, "%d %d %d %d %d %d\n",
|
||||
feature->rect[0].r.x,
|
||||
feature->rect[0].r.y,
|
||||
feature->rect[0].r.width,
|
||||
feature->rect[0].r.height,
|
||||
0,
|
||||
(int) (feature->rect[0].weight) );
|
||||
fprintf( file, "%d %d %d %d %d %d\n",
|
||||
feature->rect[1].r.x,
|
||||
feature->rect[1].r.y,
|
||||
feature->rect[1].r.width,
|
||||
feature->rect[1].r.height,
|
||||
0,
|
||||
(int) (feature->rect[1].weight) );
|
||||
if( feature->rect[2].weight != 0.0F )
|
||||
{
|
||||
fprintf( file, "%d %d %d %d %d %d\n",
|
||||
feature->rect[2].r.x,
|
||||
feature->rect[2].r.y,
|
||||
feature->rect[2].r.width,
|
||||
feature->rect[2].r.height,
|
||||
0,
|
||||
(int) (feature->rect[2].weight) );
|
||||
}
|
||||
fprintf( file, "%s\n", &(feature->desc[0]) );
|
||||
}
|
||||
|
||||
|
||||
void icvLoadHaarFeature( CvTHaarFeature* feature, FILE* file )
|
||||
{
|
||||
int nrect;
|
||||
int j;
|
||||
int tmp;
|
||||
int weight;
|
||||
|
||||
nrect = 0;
|
||||
fscanf( file, "%d", &nrect );
|
||||
|
||||
assert( nrect <= CV_HAAR_FEATURE_MAX );
|
||||
|
||||
for( j = 0; j < nrect; j++ )
|
||||
{
|
||||
fscanf( file, "%d %d %d %d %d %d",
|
||||
&(feature->rect[j].r.x),
|
||||
&(feature->rect[j].r.y),
|
||||
&(feature->rect[j].r.width),
|
||||
&(feature->rect[j].r.height),
|
||||
&tmp, &weight );
|
||||
feature->rect[j].weight = (float) weight;
|
||||
}
|
||||
for( j = nrect; j < CV_HAAR_FEATURE_MAX; j++ )
|
||||
{
|
||||
feature->rect[j].r.x = 0;
|
||||
feature->rect[j].r.y = 0;
|
||||
feature->rect[j].r.width = 0;
|
||||
feature->rect[j].r.height = 0;
|
||||
feature->rect[j].weight = 0.0f;
|
||||
}
|
||||
fscanf( file, "%s", &(feature->desc[0]) );
|
||||
feature->tilted = ( feature->desc[0] == 't' );
|
||||
}
|
||||
|
||||
|
||||
void icvSaveCARTHaarClassifier( CvIntHaarClassifier* classifier, FILE* file )
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
count = ((CvCARTHaarClassifier*) classifier)->count;
|
||||
fprintf( file, "%d\n", count );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
icvSaveHaarFeature( &(((CvCARTHaarClassifier*) classifier)->feature[i]), file );
|
||||
fprintf( file, "%e %d %d\n",
|
||||
((CvCARTHaarClassifier*) classifier)->threshold[i],
|
||||
((CvCARTHaarClassifier*) classifier)->left[i],
|
||||
((CvCARTHaarClassifier*) classifier)->right[i] );
|
||||
}
|
||||
for( i = 0; i <= count; i++ )
|
||||
{
|
||||
fprintf( file, "%e ", ((CvCARTHaarClassifier*) classifier)->val[i] );
|
||||
}
|
||||
fprintf( file, "\n" );
|
||||
}
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvLoadCARTHaarClassifier( FILE* file, int step )
|
||||
{
|
||||
CvCARTHaarClassifier* ptr;
|
||||
int i;
|
||||
int count;
|
||||
|
||||
ptr = NULL;
|
||||
fscanf( file, "%d", &count );
|
||||
if( count > 0 )
|
||||
{
|
||||
ptr = (CvCARTHaarClassifier*) icvCreateCARTHaarClassifier( count );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
icvLoadHaarFeature( &(ptr->feature[i]), file );
|
||||
fscanf( file, "%f %d %d", &(ptr->threshold[i]), &(ptr->left[i]),
|
||||
&(ptr->right[i]) );
|
||||
}
|
||||
for( i = 0; i <= count; i++ )
|
||||
{
|
||||
fscanf( file, "%f", &(ptr->val[i]) );
|
||||
}
|
||||
icvConvertToFastHaarFeature( ptr->feature, ptr->fastfeature, ptr->count, step );
|
||||
}
|
||||
|
||||
return (CvIntHaarClassifier*) ptr;
|
||||
}
|
||||
|
||||
|
||||
void icvSaveStageHaarClassifier( CvIntHaarClassifier* classifier, FILE* file )
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
float threshold;
|
||||
|
||||
count = ((CvStageHaarClassifier*) classifier)->count;
|
||||
fprintf( file, "%d\n", count );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
((CvStageHaarClassifier*) classifier)->classifier[i]->save(
|
||||
((CvStageHaarClassifier*) classifier)->classifier[i], file );
|
||||
}
|
||||
|
||||
threshold = ((CvStageHaarClassifier*) classifier)->threshold;
|
||||
|
||||
/* to be compatible with the previous implementation */
|
||||
/* threshold = 2.0F * ((CvStageHaarClassifier*) classifier)->threshold - count; */
|
||||
|
||||
fprintf( file, "%e\n", threshold );
|
||||
}
|
||||
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvLoadCARTStageHaarClassifierF( FILE* file, int step )
|
||||
{
|
||||
CvStageHaarClassifier* ptr = NULL;
|
||||
|
||||
//CV_FUNCNAME( "icvLoadCARTStageHaarClassifierF" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
if( file != NULL )
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
float threshold;
|
||||
|
||||
count = 0;
|
||||
fscanf( file, "%d", &count );
|
||||
if( count > 0 )
|
||||
{
|
||||
ptr = (CvStageHaarClassifier*) icvCreateStageHaarClassifier( count, 0.0F );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
ptr->classifier[i] = icvLoadCARTHaarClassifier( file, step );
|
||||
}
|
||||
|
||||
fscanf( file, "%f", &threshold );
|
||||
|
||||
ptr->threshold = threshold;
|
||||
/* to be compatible with the previous implementation */
|
||||
/* ptr->threshold = 0.5F * (threshold + count); */
|
||||
}
|
||||
if( feof( file ) )
|
||||
{
|
||||
ptr->release( (CvIntHaarClassifier**) &ptr );
|
||||
ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
__END__;
|
||||
|
||||
return (CvIntHaarClassifier*) ptr;
|
||||
}
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvLoadCARTStageHaarClassifier( const char* filename, int step )
|
||||
{
|
||||
CvIntHaarClassifier* ptr = NULL;
|
||||
|
||||
CV_FUNCNAME( "icvLoadCARTStageHaarClassifier" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
FILE* file;
|
||||
|
||||
file = fopen( filename, "r" );
|
||||
if( file )
|
||||
{
|
||||
CV_CALL( ptr = icvLoadCARTStageHaarClassifierF( file, step ) );
|
||||
fclose( file );
|
||||
}
|
||||
|
||||
__END__;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* tree cascade classifier */
|
||||
|
||||
/* evaluates a tree cascade classifier */
|
||||
|
||||
float icvEvalTreeCascadeClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor )
|
||||
{
|
||||
CvTreeCascadeNode* ptr;
|
||||
|
||||
ptr = ((CvTreeCascadeClassifier*) classifier)->root;
|
||||
|
||||
while( ptr )
|
||||
{
|
||||
if( ptr->stage->eval( (CvIntHaarClassifier*) ptr->stage,
|
||||
sum, tilted, normfactor )
|
||||
>= ptr->stage->threshold - CV_THRESHOLD_EPS )
|
||||
{
|
||||
ptr = ptr->child;
|
||||
}
|
||||
else
|
||||
{
|
||||
while( ptr && ptr->next == NULL ) ptr = ptr->parent;
|
||||
if( ptr == NULL ) return 0.0F;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
/* sets path int the tree form the root to the leaf node */
|
||||
|
||||
void icvSetLeafNode( CvTreeCascadeClassifier* tcc, CvTreeCascadeNode* leaf )
|
||||
{
|
||||
CV_FUNCNAME( "icvSetLeafNode" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
CvTreeCascadeNode* ptr;
|
||||
|
||||
ptr = NULL;
|
||||
while( leaf )
|
||||
{
|
||||
leaf->child_eval = ptr;
|
||||
ptr = leaf;
|
||||
leaf = leaf->parent;
|
||||
}
|
||||
|
||||
leaf = tcc->root;
|
||||
while( leaf && leaf != ptr ) leaf = leaf->next;
|
||||
if( leaf != ptr )
|
||||
CV_ERROR( CV_StsError, "Invalid tcc or leaf node." );
|
||||
|
||||
tcc->root_eval = ptr;
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
/* evaluates a tree cascade classifier. used in filtering */
|
||||
|
||||
float icvEvalTreeCascadeClassifierFilter( CvIntHaarClassifier* classifier, sum_type* sum,
|
||||
sum_type* tilted, float normfactor )
|
||||
{
|
||||
CvTreeCascadeNode* ptr;
|
||||
CvTreeCascadeClassifier* tree;
|
||||
|
||||
tree = (CvTreeCascadeClassifier*) classifier;
|
||||
|
||||
|
||||
|
||||
ptr = ((CvTreeCascadeClassifier*) classifier)->root_eval;
|
||||
while( ptr )
|
||||
{
|
||||
if( ptr->stage->eval( (CvIntHaarClassifier*) ptr->stage,
|
||||
sum, tilted, normfactor )
|
||||
< ptr->stage->threshold - CV_THRESHOLD_EPS )
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
ptr = ptr->child_eval;
|
||||
}
|
||||
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
/* creates tree cascade node */
|
||||
|
||||
CvTreeCascadeNode* icvCreateTreeCascadeNode()
|
||||
{
|
||||
CvTreeCascadeNode* ptr = NULL;
|
||||
|
||||
CV_FUNCNAME( "icvCreateTreeCascadeNode" );
|
||||
|
||||
__BEGIN__;
|
||||
size_t data_size;
|
||||
|
||||
data_size = sizeof( *ptr );
|
||||
CV_CALL( ptr = (CvTreeCascadeNode*) cvAlloc( data_size ) );
|
||||
memset( ptr, 0, data_size );
|
||||
|
||||
__END__;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* releases all tree cascade nodes accessible via links */
|
||||
|
||||
void icvReleaseTreeCascadeNodes( CvTreeCascadeNode** node )
|
||||
{
|
||||
//CV_FUNCNAME( "icvReleaseTreeCascadeNodes" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
if( node && *node )
|
||||
{
|
||||
CvTreeCascadeNode* ptr;
|
||||
CvTreeCascadeNode* ptr_;
|
||||
|
||||
ptr = *node;
|
||||
|
||||
while( ptr )
|
||||
{
|
||||
while( ptr->child ) ptr = ptr->child;
|
||||
|
||||
if( ptr->stage ) ptr->stage->release( (CvIntHaarClassifier**) &ptr->stage );
|
||||
ptr_ = ptr;
|
||||
|
||||
while( ptr && ptr->next == NULL ) ptr = ptr->parent;
|
||||
if( ptr ) ptr = ptr->next;
|
||||
|
||||
cvFree( &ptr_ );
|
||||
}
|
||||
}
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
|
||||
/* releases tree cascade classifier */
|
||||
|
||||
void icvReleaseTreeCascadeClassifier( CvIntHaarClassifier** classifier )
|
||||
{
|
||||
if( classifier && *classifier )
|
||||
{
|
||||
icvReleaseTreeCascadeNodes( &((CvTreeCascadeClassifier*) *classifier)->root );
|
||||
cvFree( classifier );
|
||||
*classifier = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvPrintTreeCascade( CvTreeCascadeNode* root )
|
||||
{
|
||||
//CV_FUNCNAME( "icvPrintTreeCascade" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
CvTreeCascadeNode* node;
|
||||
CvTreeCascadeNode* n;
|
||||
char buf0[256];
|
||||
char buf[256];
|
||||
int level;
|
||||
int i;
|
||||
int max_level;
|
||||
|
||||
node = root;
|
||||
level = max_level = 0;
|
||||
while( node )
|
||||
{
|
||||
while( node->child ) { node = node->child; level++; }
|
||||
if( level > max_level ) { max_level = level; }
|
||||
while( node && !node->next ) { node = node->parent; level--; }
|
||||
if( node ) node = node->next;
|
||||
}
|
||||
|
||||
printf( "\nTree Classifier\n" );
|
||||
printf( "Stage\n" );
|
||||
for( i = 0; i <= max_level; i++ ) printf( "+---" );
|
||||
printf( "+\n" );
|
||||
for( i = 0; i <= max_level; i++ ) printf( "|%3d", i );
|
||||
printf( "|\n" );
|
||||
for( i = 0; i <= max_level; i++ ) printf( "+---" );
|
||||
printf( "+\n\n" );
|
||||
|
||||
node = root;
|
||||
|
||||
buf[0] = 0;
|
||||
while( node )
|
||||
{
|
||||
sprintf( buf + strlen( buf ), "%3d", node->idx );
|
||||
while( node->child )
|
||||
{
|
||||
node = node->child;
|
||||
sprintf( buf + strlen( buf ),
|
||||
((node->idx < 10) ? "---%d" : ((node->idx < 100) ? "--%d" : "-%d")),
|
||||
node->idx );
|
||||
}
|
||||
printf( " %s\n", buf );
|
||||
|
||||
while( node && !node->next ) { node = node->parent; }
|
||||
if( node )
|
||||
{
|
||||
node = node->next;
|
||||
|
||||
n = node->parent;
|
||||
buf[0] = 0;
|
||||
while( n )
|
||||
{
|
||||
if( n->next )
|
||||
sprintf( buf0, " | %s", buf );
|
||||
else
|
||||
sprintf( buf0, " %s", buf );
|
||||
strcpy( buf, buf0 );
|
||||
n = n->parent;
|
||||
}
|
||||
printf( " %s |\n", buf );
|
||||
}
|
||||
}
|
||||
printf( "\n" );
|
||||
fflush( stdout );
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvLoadTreeCascadeClassifier( const char* filename, int step,
|
||||
int* splits )
|
||||
{
|
||||
CvTreeCascadeClassifier* ptr = NULL;
|
||||
CvTreeCascadeNode** nodes = NULL;
|
||||
|
||||
CV_FUNCNAME( "icvLoadTreeCascadeClassifier" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
size_t data_size;
|
||||
CvStageHaarClassifier* stage;
|
||||
char stage_name[PATH_MAX];
|
||||
char* suffix;
|
||||
int i, num;
|
||||
FILE* f;
|
||||
int result, parent=0, next=0;
|
||||
int stub;
|
||||
|
||||
if( !splits ) splits = &stub;
|
||||
|
||||
*splits = 0;
|
||||
|
||||
data_size = sizeof( *ptr );
|
||||
|
||||
CV_CALL( ptr = (CvTreeCascadeClassifier*) cvAlloc( data_size ) );
|
||||
memset( ptr, 0, data_size );
|
||||
|
||||
ptr->eval = icvEvalTreeCascadeClassifier;
|
||||
ptr->release = icvReleaseTreeCascadeClassifier;
|
||||
|
||||
sprintf( stage_name, "%s/", filename );
|
||||
suffix = stage_name + strlen( stage_name );
|
||||
|
||||
for( i = 0; ; i++ )
|
||||
{
|
||||
sprintf( suffix, "%d/%s", i, CV_STAGE_CART_FILE_NAME );
|
||||
f = fopen( stage_name, "r" );
|
||||
if( !f ) break;
|
||||
fclose( f );
|
||||
}
|
||||
num = i;
|
||||
|
||||
if( num < 1 ) EXIT;
|
||||
|
||||
data_size = sizeof( *nodes ) * num;
|
||||
CV_CALL( nodes = (CvTreeCascadeNode**) cvAlloc( data_size ) );
|
||||
|
||||
for( i = 0; i < num; i++ )
|
||||
{
|
||||
sprintf( suffix, "%d/%s", i, CV_STAGE_CART_FILE_NAME );
|
||||
f = fopen( stage_name, "r" );
|
||||
CV_CALL( stage = (CvStageHaarClassifier*)
|
||||
icvLoadCARTStageHaarClassifierF( f, step ) );
|
||||
|
||||
result = ( f && stage ) ? fscanf( f, "%d%d", &parent, &next ) : 0;
|
||||
if( f ) fclose( f );
|
||||
|
||||
if( result != 2 )
|
||||
{
|
||||
num = i;
|
||||
break;
|
||||
}
|
||||
|
||||
printf( "Stage %d loaded\n", i );
|
||||
|
||||
if( parent >= i || (next != -1 && next != i + 1) )
|
||||
CV_ERROR( CV_StsError, "Invalid tree links" );
|
||||
|
||||
CV_CALL( nodes[i] = icvCreateTreeCascadeNode() );
|
||||
nodes[i]->stage = stage;
|
||||
nodes[i]->idx = i;
|
||||
nodes[i]->parent = (parent != -1 ) ? nodes[parent] : NULL;
|
||||
nodes[i]->next = ( next != -1 ) ? nodes[i] : NULL;
|
||||
nodes[i]->child = NULL;
|
||||
}
|
||||
for( i = 0; i < num; i++ )
|
||||
{
|
||||
if( nodes[i]->next )
|
||||
{
|
||||
(*splits)++;
|
||||
nodes[i]->next = nodes[i+1];
|
||||
}
|
||||
if( nodes[i]->parent && nodes[i]->parent->child == NULL )
|
||||
{
|
||||
nodes[i]->parent->child = nodes[i];
|
||||
}
|
||||
}
|
||||
ptr->root = nodes[0];
|
||||
ptr->next_idx = num;
|
||||
|
||||
__END__;
|
||||
|
||||
cvFree( &nodes );
|
||||
|
||||
return (CvIntHaarClassifier*) ptr;
|
||||
}
|
||||
|
||||
|
||||
CvTreeCascadeNode* icvFindDeepestLeaves( CvTreeCascadeClassifier* tcc )
|
||||
{
|
||||
CvTreeCascadeNode* leaves;
|
||||
|
||||
//CV_FUNCNAME( "icvFindDeepestLeaves" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
int level, cur_level;
|
||||
CvTreeCascadeNode* ptr;
|
||||
CvTreeCascadeNode* last;
|
||||
|
||||
leaves = last = NULL;
|
||||
|
||||
ptr = tcc->root;
|
||||
level = -1;
|
||||
cur_level = 0;
|
||||
|
||||
/* find leaves with maximal level */
|
||||
while( ptr )
|
||||
{
|
||||
if( ptr->child ) { ptr = ptr->child; cur_level++; }
|
||||
else
|
||||
{
|
||||
if( cur_level == level )
|
||||
{
|
||||
last->next_same_level = ptr;
|
||||
ptr->next_same_level = NULL;
|
||||
last = ptr;
|
||||
}
|
||||
if( cur_level > level )
|
||||
{
|
||||
level = cur_level;
|
||||
leaves = last = ptr;
|
||||
ptr->next_same_level = NULL;
|
||||
}
|
||||
while( ptr && ptr->next == NULL ) { ptr = ptr->parent; cur_level--; }
|
||||
if( ptr ) ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
__END__;
|
||||
|
||||
return leaves;
|
||||
}
|
||||
|
||||
/* End of file. */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,192 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* cvhaartraining.h
|
||||
*
|
||||
* haar training functions
|
||||
*/
|
||||
|
||||
#ifndef _CVHAARTRAINING_H_
|
||||
#define _CVHAARTRAINING_H_
|
||||
|
||||
/*
|
||||
* cvCreateTrainingSamples
|
||||
*
|
||||
* Create training samples applying random distortions to sample image and
|
||||
* store them in .vec file
|
||||
*
|
||||
* filename - .vec file name
|
||||
* imgfilename - sample image file name
|
||||
* bgcolor - background color for sample image
|
||||
* bgthreshold - background color threshold. Pixels those colors are in range
|
||||
* [bgcolor-bgthreshold, bgcolor+bgthreshold] are considered as transparent
|
||||
* bgfilename - background description file name. If not NULL samples
|
||||
* will be put on arbitrary background
|
||||
* count - desired number of samples
|
||||
* invert - if not 0 sample foreground pixels will be inverted
|
||||
* if invert == CV_RANDOM_INVERT then samples will be inverted randomly
|
||||
* maxintensitydev - desired max intensity deviation of foreground samples pixels
|
||||
* maxxangle - max rotation angles
|
||||
* maxyangle
|
||||
* maxzangle
|
||||
* showsamples - if not 0 samples will be shown
|
||||
* winwidth - desired samples width
|
||||
* winheight - desired samples height
|
||||
*/
|
||||
#define CV_RANDOM_INVERT 0x7FFFFFFF
|
||||
|
||||
void cvCreateTrainingSamples( const char* filename,
|
||||
const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
const char* bgfilename, int count,
|
||||
int invert = 0, int maxintensitydev = 40,
|
||||
double maxxangle = 1.1,
|
||||
double maxyangle = 1.1,
|
||||
double maxzangle = 0.5,
|
||||
int showsamples = 0,
|
||||
int winwidth = 24, int winheight = 24 );
|
||||
|
||||
void cvCreateTestSamples( const char* infoname,
|
||||
const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
const char* bgfilename, int count,
|
||||
int invert, int maxintensitydev,
|
||||
double maxxangle, double maxyangle, double maxzangle,
|
||||
int showsamples,
|
||||
int winwidth, int winheight );
|
||||
|
||||
/*
|
||||
* cvCreateTrainingSamplesFromInfo
|
||||
*
|
||||
* Create training samples from a set of marked up images and store them into .vec file
|
||||
* infoname - file in which marked up image descriptions are stored
|
||||
* num - desired number of samples
|
||||
* showsamples - if not 0 samples will be shown
|
||||
* winwidth - sample width
|
||||
* winheight - sample height
|
||||
*
|
||||
* Return number of successfully created samples
|
||||
*/
|
||||
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
|
||||
int num,
|
||||
int showsamples,
|
||||
int winwidth, int winheight );
|
||||
|
||||
/*
|
||||
* cvShowVecSamples
|
||||
*
|
||||
* Shows samples stored in .vec file
|
||||
*
|
||||
* filename
|
||||
* .vec file name
|
||||
* winwidth
|
||||
* sample width
|
||||
* winheight
|
||||
* sample height
|
||||
* scale
|
||||
* the scale each sample is adjusted to
|
||||
*/
|
||||
void cvShowVecSamples( const char* filename, int winwidth, int winheight, double scale );
|
||||
|
||||
|
||||
/*
|
||||
* cvCreateCascadeClassifier
|
||||
*
|
||||
* Create cascade classifier
|
||||
* dirname - directory name in which cascade classifier will be created.
|
||||
* It must exist and contain subdirectories 0, 1, 2, ... (nstages-1).
|
||||
* vecfilename - name of .vec file with object's images
|
||||
* bgfilename - name of background description file
|
||||
* bg_vecfile - true if bgfilename represents a vec file with discrete negatives
|
||||
* npos - number of positive samples used in training of each stage
|
||||
* nneg - number of negative samples used in training of each stage
|
||||
* nstages - number of stages
|
||||
* numprecalculated - number of features being precalculated. Each precalculated feature
|
||||
* requires (number_of_samples*(sizeof( float ) + sizeof( short ))) bytes of memory
|
||||
* numsplits - number of binary splits in each weak classifier
|
||||
* 1 - stumps, 2 and more - trees.
|
||||
* minhitrate - desired min hit rate of each stage
|
||||
* maxfalsealarm - desired max false alarm of each stage
|
||||
* weightfraction - weight trimming parameter
|
||||
* mode - 0 - BASIC = Viola
|
||||
* 1 - CORE = All upright
|
||||
* 2 - ALL = All features
|
||||
* symmetric - if not 0 vertical symmetry is assumed
|
||||
* equalweights - if not 0 initial weights of all samples will be equal
|
||||
* winwidth - sample width
|
||||
* winheight - sample height
|
||||
* boosttype - type of applied boosting algorithm
|
||||
* 0 - Discrete AdaBoost
|
||||
* 1 - Real AdaBoost
|
||||
* 2 - LogitBoost
|
||||
* 3 - Gentle AdaBoost
|
||||
* stumperror - type of used error if Discrete AdaBoost algorithm is applied
|
||||
* 0 - misclassification error
|
||||
* 1 - gini error
|
||||
* 2 - entropy error
|
||||
*/
|
||||
void cvCreateCascadeClassifier( const char* dirname,
|
||||
const char* vecfilename,
|
||||
const char* bgfilename,
|
||||
int npos, int nneg, int nstages,
|
||||
int numprecalculated,
|
||||
int numsplits,
|
||||
float minhitrate = 0.995F, float maxfalsealarm = 0.5F,
|
||||
float weightfraction = 0.95F,
|
||||
int mode = 0, int symmetric = 1,
|
||||
int equalweights = 1,
|
||||
int winwidth = 24, int winheight = 24,
|
||||
int boosttype = 3, int stumperror = 0 );
|
||||
|
||||
void cvCreateTreeCascadeClassifier( const char* dirname,
|
||||
const char* vecfilename,
|
||||
const char* bgfilename,
|
||||
int npos, int nneg, int nstages,
|
||||
int numprecalculated,
|
||||
int numsplits,
|
||||
float minhitrate, float maxfalsealarm,
|
||||
float weightfraction,
|
||||
int mode, int symmetric,
|
||||
int equalweights,
|
||||
int winwidth, int winheight,
|
||||
int boosttype, int stumperror,
|
||||
int maxtreesplits, int minpos, bool bg_vecfile = false );
|
||||
|
||||
#endif /* _CVHAARTRAINING_H_ */
|
||||
@@ -1,955 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* cvsamples.cpp
|
||||
*
|
||||
* support functions for training and test samples creation.
|
||||
*/
|
||||
|
||||
#include "cvhaartraining.h"
|
||||
#include "_cvhaartraining.h"
|
||||
|
||||
/* if ipl.h file is included then iplWarpPerspectiveQ function
|
||||
is used for image transformation during samples creation;
|
||||
otherwise internal cvWarpPerspective function is used */
|
||||
|
||||
//#include <ipl.h>
|
||||
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
/* Calculates coefficients of perspective transformation
|
||||
* which maps <quad> into rectangle ((0,0), (w,0), (w,h), (h,0)):
|
||||
*
|
||||
* c00*xi + c01*yi + c02
|
||||
* ui = ---------------------
|
||||
* c20*xi + c21*yi + c22
|
||||
*
|
||||
* c10*xi + c11*yi + c12
|
||||
* vi = ---------------------
|
||||
* c20*xi + c21*yi + c22
|
||||
*
|
||||
* Coefficients are calculated by solving linear system:
|
||||
* / x0 y0 1 0 0 0 -x0*u0 -y0*u0 \ /c00\ /u0\
|
||||
* | x1 y1 1 0 0 0 -x1*u1 -y1*u1 | |c01| |u1|
|
||||
* | x2 y2 1 0 0 0 -x2*u2 -y2*u2 | |c02| |u2|
|
||||
* | x3 y3 1 0 0 0 -x3*u3 -y3*u3 |.|c10|=|u3|,
|
||||
* | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 | |c11| |v0|
|
||||
* | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 | |c12| |v1|
|
||||
* | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 | |c20| |v2|
|
||||
* \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 / \c21/ \v3/
|
||||
*
|
||||
* where:
|
||||
* (xi, yi) = (quad[i][0], quad[i][1])
|
||||
* cij - coeffs[i][j], coeffs[2][2] = 1
|
||||
* (ui, vi) - rectangle vertices
|
||||
*/
|
||||
void cvGetPerspectiveTransform( CvSize src_size, double quad[4][2],
|
||||
double coeffs[3][3] )
|
||||
{
|
||||
//CV_FUNCNAME( "cvWarpPerspective" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
double a[8][8];
|
||||
double b[8];
|
||||
|
||||
CvMat A = cvMat( 8, 8, CV_64FC1, a );
|
||||
CvMat B = cvMat( 8, 1, CV_64FC1, b );
|
||||
CvMat X = cvMat( 8, 1, CV_64FC1, coeffs );
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 4; ++i )
|
||||
{
|
||||
a[i][0] = quad[i][0]; a[i][1] = quad[i][1]; a[i][2] = 1;
|
||||
a[i][3] = a[i][4] = a[i][5] = a[i][6] = a[i][7] = 0;
|
||||
b[i] = 0;
|
||||
}
|
||||
for( i = 4; i < 8; ++i )
|
||||
{
|
||||
a[i][3] = quad[i-4][0]; a[i][4] = quad[i-4][1]; a[i][5] = 1;
|
||||
a[i][0] = a[i][1] = a[i][2] = a[i][6] = a[i][7] = 0;
|
||||
b[i] = 0;
|
||||
}
|
||||
|
||||
int u = src_size.width - 1;
|
||||
int v = src_size.height - 1;
|
||||
|
||||
a[1][6] = -quad[1][0] * u; a[1][7] = -quad[1][1] * u;
|
||||
a[2][6] = -quad[2][0] * u; a[2][7] = -quad[2][1] * u;
|
||||
b[1] = b[2] = u;
|
||||
|
||||
a[6][6] = -quad[2][0] * v; a[6][7] = -quad[2][1] * v;
|
||||
a[7][6] = -quad[3][0] * v; a[7][7] = -quad[3][1] * v;
|
||||
b[6] = b[7] = v;
|
||||
|
||||
cvSolve( &A, &B, &X );
|
||||
|
||||
coeffs[2][2] = 1;
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
/* Warps source into destination by a perspective transform */
|
||||
void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] )
|
||||
{
|
||||
CV_FUNCNAME( "cvWarpPerspective" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
#ifdef __IPL_H__
|
||||
IplImage src_stub, dst_stub;
|
||||
IplImage* src_img;
|
||||
IplImage* dst_img;
|
||||
CV_CALL( src_img = cvGetImage( src, &src_stub ) );
|
||||
CV_CALL( dst_img = cvGetImage( dst, &dst_stub ) );
|
||||
iplWarpPerspectiveQ( src_img, dst_img, quad, IPL_WARP_R_TO_Q,
|
||||
IPL_INTER_CUBIC | IPL_SMOOTH_EDGE );
|
||||
#else
|
||||
|
||||
int fill_value = 0;
|
||||
|
||||
double c[3][3]; /* transformation coefficients */
|
||||
double q[4][2]; /* rearranged quad */
|
||||
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int next_right = 0;
|
||||
int next_left = 0;
|
||||
double y_min = 0;
|
||||
double y_max = 0;
|
||||
double k_left, b_left, k_right, b_right;
|
||||
|
||||
uchar* src_data;
|
||||
int src_step;
|
||||
CvSize src_size;
|
||||
|
||||
uchar* dst_data;
|
||||
int dst_step;
|
||||
CvSize dst_size;
|
||||
|
||||
double d = 0;
|
||||
int direction = 0;
|
||||
int i;
|
||||
|
||||
if( !src || (!CV_IS_IMAGE( src ) && !CV_IS_MAT( src )) ||
|
||||
cvGetElemType( src ) != CV_8UC1 ||
|
||||
cvGetDims( src ) != 2 )
|
||||
{
|
||||
CV_ERROR( CV_StsBadArg,
|
||||
"Source must be two-dimensional array of CV_8UC1 type." );
|
||||
}
|
||||
if( !dst || (!CV_IS_IMAGE( dst ) && !CV_IS_MAT( dst )) ||
|
||||
cvGetElemType( dst ) != CV_8UC1 ||
|
||||
cvGetDims( dst ) != 2 )
|
||||
{
|
||||
CV_ERROR( CV_StsBadArg,
|
||||
"Destination must be two-dimensional array of CV_8UC1 type." );
|
||||
}
|
||||
|
||||
CV_CALL( cvGetRawData( src, &src_data, &src_step, &src_size ) );
|
||||
CV_CALL( cvGetRawData( dst, &dst_data, &dst_step, &dst_size ) );
|
||||
|
||||
CV_CALL( cvGetPerspectiveTransform( src_size, quad, c ) );
|
||||
|
||||
/* if direction > 0 then vertices in quad follow in a CW direction,
|
||||
otherwise they follow in a CCW direction */
|
||||
direction = 0;
|
||||
for( i = 0; i < 4; ++i )
|
||||
{
|
||||
int ni = i + 1; if( ni == 4 ) ni = 0;
|
||||
int pi = i - 1; if( pi == -1 ) pi = 3;
|
||||
|
||||
d = (quad[i][0] - quad[pi][0])*(quad[ni][1] - quad[i][1]) -
|
||||
(quad[i][1] - quad[pi][1])*(quad[ni][0] - quad[i][0]);
|
||||
int cur_direction = CV_SIGN(d);
|
||||
if( direction == 0 )
|
||||
{
|
||||
direction = cur_direction;
|
||||
}
|
||||
else if( direction * cur_direction < 0 )
|
||||
{
|
||||
direction = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( direction == 0 )
|
||||
{
|
||||
CV_ERROR( CV_StsBadArg, "Quadrangle is nonconvex or degenerated." );
|
||||
}
|
||||
|
||||
/* <left> is the index of the topmost quad vertice
|
||||
if there are two such vertices <left> is the leftmost one */
|
||||
left = 0;
|
||||
for( i = 1; i < 4; ++i )
|
||||
{
|
||||
if( (quad[i][1] < quad[left][1]) ||
|
||||
((quad[i][1] == quad[left][1]) && (quad[i][0] < quad[left][0])) )
|
||||
{
|
||||
left = i;
|
||||
}
|
||||
}
|
||||
/* rearrange <quad> vertices in such way that they follow in a CW
|
||||
direction and the first vertice is the topmost one and put them
|
||||
into <q> */
|
||||
if( direction > 0 )
|
||||
{
|
||||
for( i = left; i < 4; ++i )
|
||||
{
|
||||
q[i-left][0] = quad[i][0];
|
||||
q[i-left][1] = quad[i][1];
|
||||
}
|
||||
for( i = 0; i < left; ++i )
|
||||
{
|
||||
q[4-left+i][0] = quad[i][0];
|
||||
q[4-left+i][1] = quad[i][1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = left; i >= 0; --i )
|
||||
{
|
||||
q[left-i][0] = quad[i][0];
|
||||
q[left-i][1] = quad[i][1];
|
||||
}
|
||||
for( i = 3; i > left; --i )
|
||||
{
|
||||
q[4+left-i][0] = quad[i][0];
|
||||
q[4+left-i][1] = quad[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
left = right = 0;
|
||||
/* if there are two topmost points, <right> is the index of the rightmost one
|
||||
otherwise <right> */
|
||||
if( q[left][1] == q[left+1][1] )
|
||||
{
|
||||
right = 1;
|
||||
}
|
||||
|
||||
/* <next_left> follows <left> in a CCW direction */
|
||||
next_left = 3;
|
||||
/* <next_right> follows <right> in a CW direction */
|
||||
next_right = right + 1;
|
||||
|
||||
/* subtraction of 1 prevents skipping of the first row */
|
||||
y_min = q[left][1] - 1;
|
||||
|
||||
/* left edge equation: y = k_left * x + b_left */
|
||||
k_left = (q[left][0] - q[next_left][0]) /
|
||||
(q[left][1] - q[next_left][1]);
|
||||
b_left = (q[left][1] * q[next_left][0] -
|
||||
q[left][0] * q[next_left][1]) /
|
||||
(q[left][1] - q[next_left][1]);
|
||||
|
||||
/* right edge equation: y = k_right * x + b_right */
|
||||
k_right = (q[right][0] - q[next_right][0]) /
|
||||
(q[right][1] - q[next_right][1]);
|
||||
b_right = (q[right][1] * q[next_right][0] -
|
||||
q[right][0] * q[next_right][1]) /
|
||||
(q[right][1] - q[next_right][1]);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
y_max = MIN( q[next_left][1], q[next_right][1] );
|
||||
|
||||
int iy_min = MAX( cvRound(y_min), 0 ) + 1;
|
||||
int iy_max = MIN( cvRound(y_max), dst_size.height - 1 );
|
||||
|
||||
double x_min = k_left * iy_min + b_left;
|
||||
double x_max = k_right * iy_min + b_right;
|
||||
|
||||
/* walk through the destination quadrangle row by row */
|
||||
for( y = iy_min; y <= iy_max; ++y )
|
||||
{
|
||||
int ix_min = MAX( cvRound( x_min ), 0 );
|
||||
int ix_max = MIN( cvRound( x_max ), dst_size.width - 1 );
|
||||
|
||||
for( x = ix_min; x <= ix_max; ++x )
|
||||
{
|
||||
/* calculate coordinates of the corresponding source array point */
|
||||
double div = (c[2][0] * x + c[2][1] * y + c[2][2]);
|
||||
double src_x = (c[0][0] * x + c[0][1] * y + c[0][2]) / div;
|
||||
double src_y = (c[1][0] * x + c[1][1] * y + c[1][2]) / div;
|
||||
|
||||
int isrc_x = cvFloor( src_x );
|
||||
int isrc_y = cvFloor( src_y );
|
||||
double delta_x = src_x - isrc_x;
|
||||
double delta_y = src_y - isrc_y;
|
||||
|
||||
uchar* s = src_data + isrc_y * src_step + isrc_x;
|
||||
|
||||
int i00, i10, i01, i11;
|
||||
i00 = i10 = i01 = i11 = (int) fill_value;
|
||||
|
||||
double i = fill_value;
|
||||
|
||||
/* linear interpolation using 2x2 neighborhood */
|
||||
if( isrc_x >= 0 && isrc_x <= src_size.width &&
|
||||
isrc_y >= 0 && isrc_y <= src_size.height )
|
||||
{
|
||||
i00 = s[0];
|
||||
}
|
||||
if( isrc_x >= -1 && isrc_x < src_size.width &&
|
||||
isrc_y >= 0 && isrc_y <= src_size.height )
|
||||
{
|
||||
i10 = s[1];
|
||||
}
|
||||
if( isrc_x >= 0 && isrc_x <= src_size.width &&
|
||||
isrc_y >= -1 && isrc_y < src_size.height )
|
||||
{
|
||||
i01 = s[src_step];
|
||||
}
|
||||
if( isrc_x >= -1 && isrc_x < src_size.width &&
|
||||
isrc_y >= -1 && isrc_y < src_size.height )
|
||||
{
|
||||
i11 = s[src_step+1];
|
||||
}
|
||||
|
||||
double i0 = i00 + (i10 - i00)*delta_x;
|
||||
double i1 = i01 + (i11 - i01)*delta_x;
|
||||
i = i0 + (i1 - i0)*delta_y;
|
||||
|
||||
((uchar*)(dst_data + y * dst_step))[x] = (uchar) i;
|
||||
}
|
||||
x_min += k_left;
|
||||
x_max += k_right;
|
||||
}
|
||||
|
||||
if( (next_left == next_right) ||
|
||||
(next_left+1 == next_right && q[next_left][1] == q[next_right][1]) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( y_max == q[next_left][1] )
|
||||
{
|
||||
left = next_left;
|
||||
next_left = left - 1;
|
||||
|
||||
k_left = (q[left][0] - q[next_left][0]) /
|
||||
(q[left][1] - q[next_left][1]);
|
||||
b_left = (q[left][1] * q[next_left][0] -
|
||||
q[left][0] * q[next_left][1]) /
|
||||
(q[left][1] - q[next_left][1]);
|
||||
}
|
||||
if( y_max == q[next_right][1] )
|
||||
{
|
||||
right = next_right;
|
||||
next_right = right + 1;
|
||||
|
||||
k_right = (q[right][0] - q[next_right][0]) /
|
||||
(q[right][1] - q[next_right][1]);
|
||||
b_right = (q[right][1] * q[next_right][0] -
|
||||
q[right][0] * q[next_right][1]) /
|
||||
(q[right][1] - q[next_right][1]);
|
||||
}
|
||||
y_min = y_max;
|
||||
}
|
||||
#endif /* #ifndef __IPL_H__ */
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
static
|
||||
void icvRandomQuad( int width, int height, double quad[4][2],
|
||||
double maxxangle,
|
||||
double maxyangle,
|
||||
double maxzangle )
|
||||
{
|
||||
double distfactor = 3.0;
|
||||
double distfactor2 = 1.0;
|
||||
|
||||
double halfw, halfh;
|
||||
int i;
|
||||
|
||||
double rotVectData[3];
|
||||
double vectData[3];
|
||||
double rotMatData[9];
|
||||
|
||||
CvMat rotVect;
|
||||
CvMat rotMat;
|
||||
CvMat vect;
|
||||
|
||||
double d;
|
||||
|
||||
rotVect = cvMat( 3, 1, CV_64FC1, &rotVectData[0] );
|
||||
rotMat = cvMat( 3, 3, CV_64FC1, &rotMatData[0] );
|
||||
vect = cvMat( 3, 1, CV_64FC1, &vectData[0] );
|
||||
|
||||
rotVectData[0] = maxxangle * (2.0 * rand() / RAND_MAX - 1.0);
|
||||
rotVectData[1] = ( maxyangle - fabs( rotVectData[0] ) )
|
||||
* (2.0 * rand() / RAND_MAX - 1.0);
|
||||
rotVectData[2] = maxzangle * (2.0 * rand() / RAND_MAX - 1.0);
|
||||
d = (distfactor + distfactor2 * (2.0 * rand() / RAND_MAX - 1.0)) * width;
|
||||
|
||||
/*
|
||||
rotVectData[0] = maxxangle;
|
||||
rotVectData[1] = maxyangle;
|
||||
rotVectData[2] = maxzangle;
|
||||
|
||||
d = distfactor * width;
|
||||
*/
|
||||
|
||||
cvRodrigues2( &rotVect, &rotMat );
|
||||
|
||||
halfw = 0.5 * width;
|
||||
halfh = 0.5 * height;
|
||||
|
||||
quad[0][0] = -halfw;
|
||||
quad[0][1] = -halfh;
|
||||
quad[1][0] = halfw;
|
||||
quad[1][1] = -halfh;
|
||||
quad[2][0] = halfw;
|
||||
quad[2][1] = halfh;
|
||||
quad[3][0] = -halfw;
|
||||
quad[3][1] = halfh;
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
rotVectData[0] = quad[i][0];
|
||||
rotVectData[1] = quad[i][1];
|
||||
rotVectData[2] = 0.0;
|
||||
cvMatMulAdd( &rotMat, &rotVect, 0, &vect );
|
||||
quad[i][0] = vectData[0] * d / (d + vectData[2]) + halfw;
|
||||
quad[i][1] = vectData[1] * d / (d + vectData[2]) + halfh;
|
||||
|
||||
/*
|
||||
quad[i][0] += halfw;
|
||||
quad[i][1] += halfh;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int icvStartSampleDistortion( const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
CvSampleDistortionData* data )
|
||||
{
|
||||
memset( data, 0, sizeof( *data ) );
|
||||
data->src = cvLoadImage( imgfilename, 0 );
|
||||
if( data->src != NULL && data->src->nChannels == 1
|
||||
&& data->src->depth == IPL_DEPTH_8U )
|
||||
{
|
||||
int r, c;
|
||||
uchar* pmask;
|
||||
uchar* psrc;
|
||||
uchar* perode;
|
||||
uchar* pdilate;
|
||||
uchar dd, de;
|
||||
|
||||
data->dx = data->src->width / 2;
|
||||
data->dy = data->src->height / 2;
|
||||
data->bgcolor = bgcolor;
|
||||
|
||||
data->mask = cvCloneImage( data->src );
|
||||
data->erode = cvCloneImage( data->src );
|
||||
data->dilate = cvCloneImage( data->src );
|
||||
|
||||
/* make mask image */
|
||||
for( r = 0; r < data->mask->height; r++ )
|
||||
{
|
||||
for( c = 0; c < data->mask->width; c++ )
|
||||
{
|
||||
pmask = ( (uchar*) (data->mask->imageData + r * data->mask->widthStep)
|
||||
+ c );
|
||||
if( bgcolor - bgthreshold <= (int) (*pmask) &&
|
||||
(int) (*pmask) <= bgcolor + bgthreshold )
|
||||
{
|
||||
*pmask = (uchar) 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pmask = (uchar) 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* extend borders of source image */
|
||||
cvErode( data->src, data->erode, 0, 1 );
|
||||
cvDilate( data->src, data->dilate, 0, 1 );
|
||||
for( r = 0; r < data->mask->height; r++ )
|
||||
{
|
||||
for( c = 0; c < data->mask->width; c++ )
|
||||
{
|
||||
pmask = ( (uchar*) (data->mask->imageData + r * data->mask->widthStep)
|
||||
+ c );
|
||||
if( (*pmask) == 0 )
|
||||
{
|
||||
psrc = ( (uchar*) (data->src->imageData + r * data->src->widthStep)
|
||||
+ c );
|
||||
perode =
|
||||
( (uchar*) (data->erode->imageData + r * data->erode->widthStep)
|
||||
+ c );
|
||||
pdilate =
|
||||
( (uchar*)(data->dilate->imageData + r * data->dilate->widthStep)
|
||||
+ c );
|
||||
de = (uchar)(bgcolor - (*perode));
|
||||
dd = (uchar)((*pdilate) - bgcolor);
|
||||
if( de >= dd && de > bgthreshold )
|
||||
{
|
||||
(*psrc) = (*perode);
|
||||
}
|
||||
if( dd > de && dd > bgthreshold )
|
||||
{
|
||||
(*psrc) = (*pdilate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data->img = cvCreateImage( cvSize( data->src->width + 2 * data->dx,
|
||||
data->src->height + 2 * data->dy ),
|
||||
IPL_DEPTH_8U, 1 );
|
||||
data->maskimg = cvCloneImage( data->img );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void icvPlaceDistortedSample( CvArr* background,
|
||||
int inverse, int maxintensitydev,
|
||||
double maxxangle, double maxyangle, double maxzangle,
|
||||
int inscribe, double maxshiftf, double maxscalef,
|
||||
CvSampleDistortionData* data )
|
||||
{
|
||||
double quad[4][2];
|
||||
int r, c;
|
||||
uchar* pimg;
|
||||
uchar* pbg;
|
||||
uchar* palpha;
|
||||
uchar chartmp;
|
||||
int forecolordev;
|
||||
float scale;
|
||||
IplImage* img;
|
||||
IplImage* maskimg;
|
||||
CvMat stub;
|
||||
CvMat* bgimg;
|
||||
|
||||
CvRect cr;
|
||||
CvRect roi;
|
||||
|
||||
double xshift, yshift, randscale;
|
||||
|
||||
icvRandomQuad( data->src->width, data->src->height, quad,
|
||||
maxxangle, maxyangle, maxzangle );
|
||||
quad[0][0] += (double) data->dx;
|
||||
quad[0][1] += (double) data->dy;
|
||||
quad[1][0] += (double) data->dx;
|
||||
quad[1][1] += (double) data->dy;
|
||||
quad[2][0] += (double) data->dx;
|
||||
quad[2][1] += (double) data->dy;
|
||||
quad[3][0] += (double) data->dx;
|
||||
quad[3][1] += (double) data->dy;
|
||||
|
||||
cvSet( data->img, cvScalar( data->bgcolor ) );
|
||||
cvSet( data->maskimg, cvScalar( 0.0 ) );
|
||||
|
||||
cvWarpPerspective( data->src, data->img, quad );
|
||||
cvWarpPerspective( data->mask, data->maskimg, quad );
|
||||
|
||||
cvSmooth( data->maskimg, data->maskimg, CV_GAUSSIAN, 3, 3 );
|
||||
|
||||
bgimg = cvGetMat( background, &stub );
|
||||
|
||||
cr.x = data->dx;
|
||||
cr.y = data->dy;
|
||||
cr.width = data->src->width;
|
||||
cr.height = data->src->height;
|
||||
|
||||
if( inscribe )
|
||||
{
|
||||
/* quad's circumscribing rectangle */
|
||||
cr.x = (int) MIN( quad[0][0], quad[3][0] );
|
||||
cr.y = (int) MIN( quad[0][1], quad[1][1] );
|
||||
cr.width = (int) (MAX( quad[1][0], quad[2][0] ) + 0.5F ) - cr.x;
|
||||
cr.height = (int) (MAX( quad[2][1], quad[3][1] ) + 0.5F ) - cr.y;
|
||||
}
|
||||
|
||||
xshift = maxshiftf * rand() / RAND_MAX;
|
||||
yshift = maxshiftf * rand() / RAND_MAX;
|
||||
|
||||
cr.x -= (int) ( xshift * cr.width );
|
||||
cr.y -= (int) ( yshift * cr.height );
|
||||
cr.width = (int) ((1.0 + maxshiftf) * cr.width );
|
||||
cr.height = (int) ((1.0 + maxshiftf) * cr.height);
|
||||
|
||||
randscale = maxscalef * rand() / RAND_MAX;
|
||||
cr.x -= (int) ( 0.5 * randscale * cr.width );
|
||||
cr.y -= (int) ( 0.5 * randscale * cr.height );
|
||||
cr.width = (int) ((1.0 + randscale) * cr.width );
|
||||
cr.height = (int) ((1.0 + randscale) * cr.height);
|
||||
|
||||
scale = MAX( ((float) cr.width) / bgimg->cols, ((float) cr.height) / bgimg->rows );
|
||||
|
||||
roi.x = (int) (-0.5F * (scale * bgimg->cols - cr.width) + cr.x);
|
||||
roi.y = (int) (-0.5F * (scale * bgimg->rows - cr.height) + cr.y);
|
||||
roi.width = (int) (scale * bgimg->cols);
|
||||
roi.height = (int) (scale * bgimg->rows);
|
||||
|
||||
img = cvCreateImage( cvSize( bgimg->cols, bgimg->rows ), IPL_DEPTH_8U, 1 );
|
||||
maskimg = cvCreateImage( cvSize( bgimg->cols, bgimg->rows ), IPL_DEPTH_8U, 1 );
|
||||
|
||||
cvSetImageROI( data->img, roi );
|
||||
cvResize( data->img, img );
|
||||
cvResetImageROI( data->img );
|
||||
cvSetImageROI( data->maskimg, roi );
|
||||
cvResize( data->maskimg, maskimg );
|
||||
cvResetImageROI( data->maskimg );
|
||||
|
||||
forecolordev = (int) (maxintensitydev * (2.0 * rand() / RAND_MAX - 1.0));
|
||||
|
||||
for( r = 0; r < img->height; r++ )
|
||||
{
|
||||
for( c = 0; c < img->width; c++ )
|
||||
{
|
||||
pimg = (uchar*) img->imageData + r * img->widthStep + c;
|
||||
pbg = (uchar*) bgimg->data.ptr + r * bgimg->step + c;
|
||||
palpha = (uchar*) maskimg->imageData + r * maskimg->widthStep + c;
|
||||
chartmp = (uchar) MAX( 0, MIN( 255, forecolordev + (*pimg) ) );
|
||||
if( inverse )
|
||||
{
|
||||
chartmp ^= 0xFF;
|
||||
}
|
||||
*pbg = (uchar) (( chartmp*(*palpha )+(255 - (*palpha) )*(*pbg) ) / 255);
|
||||
}
|
||||
}
|
||||
|
||||
cvReleaseImage( &img );
|
||||
cvReleaseImage( &maskimg );
|
||||
}
|
||||
|
||||
void icvEndSampleDistortion( CvSampleDistortionData* data )
|
||||
{
|
||||
if( data->src )
|
||||
{
|
||||
cvReleaseImage( &data->src );
|
||||
}
|
||||
if( data->mask )
|
||||
{
|
||||
cvReleaseImage( &data->mask );
|
||||
}
|
||||
if( data->erode )
|
||||
{
|
||||
cvReleaseImage( &data->erode );
|
||||
}
|
||||
if( data->dilate )
|
||||
{
|
||||
cvReleaseImage( &data->dilate );
|
||||
}
|
||||
if( data->img )
|
||||
{
|
||||
cvReleaseImage( &data->img );
|
||||
}
|
||||
if( data->maskimg )
|
||||
{
|
||||
cvReleaseImage( &data->maskimg );
|
||||
}
|
||||
}
|
||||
|
||||
void icvWriteVecHeader( FILE* file, int count, int width, int height )
|
||||
{
|
||||
int vecsize;
|
||||
short tmp;
|
||||
|
||||
/* number of samples */
|
||||
fwrite( &count, sizeof( count ), 1, file );
|
||||
/* vector size */
|
||||
vecsize = width * height;
|
||||
fwrite( &vecsize, sizeof( vecsize ), 1, file );
|
||||
/* min/max values */
|
||||
tmp = 0;
|
||||
fwrite( &tmp, sizeof( tmp ), 1, file );
|
||||
fwrite( &tmp, sizeof( tmp ), 1, file );
|
||||
}
|
||||
|
||||
void icvWriteVecSample( FILE* file, CvArr* sample )
|
||||
{
|
||||
CvMat* mat, stub;
|
||||
int r, c;
|
||||
short tmp;
|
||||
uchar chartmp;
|
||||
|
||||
mat = cvGetMat( sample, &stub );
|
||||
chartmp = 0;
|
||||
fwrite( &chartmp, sizeof( chartmp ), 1, file );
|
||||
for( r = 0; r < mat->rows; r++ )
|
||||
{
|
||||
for( c = 0; c < mat->cols; c++ )
|
||||
{
|
||||
tmp = (short) (CV_MAT_ELEM( *mat, uchar, r, c ));
|
||||
fwrite( &tmp, sizeof( tmp ), 1, file );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
|
||||
int num,
|
||||
int showsamples,
|
||||
int winwidth, int winheight )
|
||||
{
|
||||
char fullname[PATH_MAX];
|
||||
char* filename;
|
||||
|
||||
FILE* info;
|
||||
FILE* vec;
|
||||
IplImage* src=0;
|
||||
IplImage* sample;
|
||||
int line;
|
||||
int error;
|
||||
int i;
|
||||
int x, y, width, height;
|
||||
int total;
|
||||
|
||||
assert( infoname != NULL );
|
||||
assert( vecfilename != NULL );
|
||||
|
||||
total = 0;
|
||||
if( !icvMkDir( vecfilename ) )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "Unable to create directory hierarchy: %s\n", vecfilename );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
info = fopen( infoname, "r" );
|
||||
if( info == NULL )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "Unable to open file: %s\n", infoname );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
vec = fopen( vecfilename, "wb" );
|
||||
if( vec == NULL )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "Unable to open file: %s\n", vecfilename );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
fclose( info );
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
sample = cvCreateImage( cvSize( winwidth, winheight ), IPL_DEPTH_8U, 1 );
|
||||
|
||||
icvWriteVecHeader( vec, num, sample->width, sample->height );
|
||||
|
||||
if( showsamples )
|
||||
{
|
||||
cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
|
||||
}
|
||||
|
||||
strcpy( fullname, infoname );
|
||||
filename = strrchr( fullname, '\\' );
|
||||
if( filename == NULL )
|
||||
{
|
||||
filename = strrchr( fullname, '/' );
|
||||
}
|
||||
if( filename == NULL )
|
||||
{
|
||||
filename = fullname;
|
||||
}
|
||||
else
|
||||
{
|
||||
filename++;
|
||||
}
|
||||
|
||||
for( line = 1, error = 0, total = 0; total < num ;line++ )
|
||||
{
|
||||
int count;
|
||||
|
||||
error = ( fscanf( info, "%s %d", filename, &count ) != 2 );
|
||||
if( !error )
|
||||
{
|
||||
src = cvLoadImage( fullname, 0 );
|
||||
error = ( src == NULL );
|
||||
if( error )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "Unable to open image: %s\n", fullname );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
}
|
||||
}
|
||||
for( i = 0; (i < count) && (total < num); i++, total++ )
|
||||
{
|
||||
error = ( fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4 );
|
||||
if( error ) break;
|
||||
cvSetImageROI( src, cvRect( x, y, width, height ) );
|
||||
cvResize( src, sample, width >= sample->width &&
|
||||
height >= sample->height ? CV_INTER_AREA : CV_INTER_LINEAR );
|
||||
|
||||
if( showsamples )
|
||||
{
|
||||
cvShowImage( "Sample", sample );
|
||||
if( cvWaitKey( 0 ) == 27 )
|
||||
{
|
||||
showsamples = 0;
|
||||
}
|
||||
}
|
||||
icvWriteVecSample( vec, sample );
|
||||
}
|
||||
|
||||
if( src )
|
||||
{
|
||||
cvReleaseImage( &src );
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "%s(%d) : parse error", infoname, line );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( sample )
|
||||
{
|
||||
cvReleaseImage( &sample );
|
||||
}
|
||||
|
||||
fclose( vec );
|
||||
fclose( info );
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
void cvShowVecSamples( const char* filename, int winwidth, int winheight,
|
||||
double scale )
|
||||
{
|
||||
CvVecFile file;
|
||||
short tmp;
|
||||
int i;
|
||||
CvMat* sample;
|
||||
|
||||
tmp = 0;
|
||||
file.input = fopen( filename, "rb" );
|
||||
|
||||
if( file.input != NULL )
|
||||
{
|
||||
fread( &file.count, sizeof( file.count ), 1, file.input );
|
||||
fread( &file.vecsize, sizeof( file.vecsize ), 1, file.input );
|
||||
fread( &tmp, sizeof( tmp ), 1, file.input );
|
||||
fread( &tmp, sizeof( tmp ), 1, file.input );
|
||||
|
||||
if( file.vecsize != winwidth * winheight )
|
||||
{
|
||||
int guessed_w = 0;
|
||||
int guessed_h = 0;
|
||||
|
||||
fprintf( stderr, "Warning: specified sample width=%d and height=%d "
|
||||
"does not correspond to .vec file vector size=%d.\n",
|
||||
winwidth, winheight, file.vecsize );
|
||||
if( file.vecsize > 0 )
|
||||
{
|
||||
guessed_w = cvFloor( sqrt( (float) file.vecsize ) );
|
||||
if( guessed_w > 0 )
|
||||
{
|
||||
guessed_h = file.vecsize / guessed_w;
|
||||
}
|
||||
}
|
||||
|
||||
if( guessed_w <= 0 || guessed_h <= 0 || guessed_w * guessed_h != file.vecsize)
|
||||
{
|
||||
fprintf( stderr, "Error: failed to guess sample width and height\n" );
|
||||
fclose( file.input );
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
winwidth = guessed_w;
|
||||
winheight = guessed_h;
|
||||
fprintf( stderr, "Guessed width=%d, guessed height=%d\n",
|
||||
winwidth, winheight );
|
||||
}
|
||||
}
|
||||
|
||||
if( !feof( file.input ) && scale > 0 )
|
||||
{
|
||||
CvMat* scaled_sample = 0;
|
||||
|
||||
file.last = 0;
|
||||
file.vector = (short*) cvAlloc( sizeof( *file.vector ) * file.vecsize );
|
||||
sample = scaled_sample = cvCreateMat( winheight, winwidth, CV_8UC1 );
|
||||
if( scale != 1.0 )
|
||||
{
|
||||
scaled_sample = cvCreateMat( MAX( 1, cvCeil( scale * winheight ) ),
|
||||
MAX( 1, cvCeil( scale * winwidth ) ),
|
||||
CV_8UC1 );
|
||||
}
|
||||
cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
|
||||
for( i = 0; i < file.count; i++ )
|
||||
{
|
||||
icvGetHaarTraininDataFromVecCallback( sample, &file );
|
||||
if( scale != 1.0 ) cvResize( sample, scaled_sample, CV_INTER_LINEAR);
|
||||
cvShowImage( "Sample", scaled_sample );
|
||||
if( cvWaitKey( 0 ) == 27 ) break;
|
||||
}
|
||||
if( scaled_sample && scaled_sample != sample ) cvReleaseMat( &scaled_sample );
|
||||
cvReleaseMat( &sample );
|
||||
cvFree( &file.vector );
|
||||
}
|
||||
fclose( file.input );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,284 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* haartraining.cpp
|
||||
*
|
||||
* Train cascade classifier
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "cvhaartraining.h"
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int i = 0;
|
||||
char* nullname = (char*)"(NULL)";
|
||||
|
||||
char* vecname = NULL;
|
||||
char* dirname = NULL;
|
||||
char* bgname = NULL;
|
||||
|
||||
bool bg_vecfile = false;
|
||||
int npos = 2000;
|
||||
int nneg = 2000;
|
||||
int nstages = 14;
|
||||
int mem = 200;
|
||||
int nsplits = 1;
|
||||
float minhitrate = 0.995F;
|
||||
float maxfalsealarm = 0.5F;
|
||||
float weightfraction = 0.95F;
|
||||
int mode = 0;
|
||||
int symmetric = 1;
|
||||
int equalweights = 0;
|
||||
int width = 24;
|
||||
int height = 24;
|
||||
const char* boosttypes[] = { "DAB", "RAB", "LB", "GAB" };
|
||||
int boosttype = 3;
|
||||
const char* stumperrors[] = { "misclass", "gini", "entropy" };
|
||||
int stumperror = 0;
|
||||
int maxtreesplits = 0;
|
||||
int minpos = 500;
|
||||
|
||||
if( argc == 1 )
|
||||
{
|
||||
printf( "Usage: %s\n -data <dir_name>\n"
|
||||
" -vec <vec_file_name>\n"
|
||||
" -bg <background_file_name>\n"
|
||||
" [-bg-vecfile]\n"
|
||||
" [-npos <number_of_positive_samples = %d>]\n"
|
||||
" [-nneg <number_of_negative_samples = %d>]\n"
|
||||
" [-nstages <number_of_stages = %d>]\n"
|
||||
" [-nsplits <number_of_splits = %d>]\n"
|
||||
" [-mem <memory_in_MB = %d>]\n"
|
||||
" [-sym (default)] [-nonsym]\n"
|
||||
" [-minhitrate <min_hit_rate = %f>]\n"
|
||||
" [-maxfalsealarm <max_false_alarm_rate = %f>]\n"
|
||||
" [-weighttrimming <weight_trimming = %f>]\n"
|
||||
" [-eqw]\n"
|
||||
" [-mode <BASIC (default) | CORE | ALL>]\n"
|
||||
" [-w <sample_width = %d>]\n"
|
||||
" [-h <sample_height = %d>]\n"
|
||||
" [-bt <DAB | RAB | LB | GAB (default)>]\n"
|
||||
" [-err <misclass (default) | gini | entropy>]\n"
|
||||
" [-maxtreesplits <max_number_of_splits_in_tree_cascade = %d>]\n"
|
||||
" [-minpos <min_number_of_positive_samples_per_cluster = %d>]\n",
|
||||
argv[0], npos, nneg, nstages, nsplits, mem,
|
||||
minhitrate, maxfalsealarm, weightfraction, width, height,
|
||||
maxtreesplits, minpos );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
if( !strcmp( argv[i], "-data" ) )
|
||||
{
|
||||
dirname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-vec" ) )
|
||||
{
|
||||
vecname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg" ) )
|
||||
{
|
||||
bgname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg-vecfile" ) )
|
||||
{
|
||||
bg_vecfile = true;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-npos" ) )
|
||||
{
|
||||
npos = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nneg" ) )
|
||||
{
|
||||
nneg = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nstages" ) )
|
||||
{
|
||||
nstages = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nsplits" ) )
|
||||
{
|
||||
nsplits = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-mem" ) )
|
||||
{
|
||||
mem = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-sym" ) )
|
||||
{
|
||||
symmetric = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nonsym" ) )
|
||||
{
|
||||
symmetric = 0;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-minhitrate" ) )
|
||||
{
|
||||
minhitrate = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxfalsealarm" ) )
|
||||
{
|
||||
maxfalsealarm = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-weighttrimming" ) )
|
||||
{
|
||||
weightfraction = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-eqw" ) )
|
||||
{
|
||||
equalweights = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-mode" ) )
|
||||
{
|
||||
char* tmp = argv[++i];
|
||||
|
||||
if( !strcmp( tmp, "CORE" ) )
|
||||
{
|
||||
mode = 1;
|
||||
}
|
||||
else if( !strcmp( tmp, "ALL" ) )
|
||||
{
|
||||
mode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = 0;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-w" ) )
|
||||
{
|
||||
width = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-h" ) )
|
||||
{
|
||||
height = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bt" ) )
|
||||
{
|
||||
i++;
|
||||
if( !strcmp( argv[i], boosttypes[0] ) )
|
||||
{
|
||||
boosttype = 0;
|
||||
}
|
||||
else if( !strcmp( argv[i], boosttypes[1] ) )
|
||||
{
|
||||
boosttype = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], boosttypes[2] ) )
|
||||
{
|
||||
boosttype = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
boosttype = 3;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-err" ) )
|
||||
{
|
||||
i++;
|
||||
if( !strcmp( argv[i], stumperrors[0] ) )
|
||||
{
|
||||
stumperror = 0;
|
||||
}
|
||||
else if( !strcmp( argv[i], stumperrors[1] ) )
|
||||
{
|
||||
stumperror = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
stumperror = 2;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxtreesplits" ) )
|
||||
{
|
||||
maxtreesplits = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-minpos" ) )
|
||||
{
|
||||
minpos = atoi( argv[++i] );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Data dir name: %s\n", ((dirname == NULL) ? nullname : dirname ) );
|
||||
printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) );
|
||||
printf( "BG file name: %s, is a vecfile: %s\n", ((bgname == NULL) ? nullname : bgname ), bg_vecfile ? "yes" : "no" );
|
||||
printf( "Num pos: %d\n", npos );
|
||||
printf( "Num neg: %d\n", nneg );
|
||||
printf( "Num stages: %d\n", nstages );
|
||||
printf( "Num splits: %d (%s as weak classifier)\n", nsplits,
|
||||
(nsplits == 1) ? "stump" : "tree" );
|
||||
printf( "Mem: %d MB\n", mem );
|
||||
printf( "Symmetric: %s\n", (symmetric) ? "TRUE" : "FALSE" );
|
||||
printf( "Min hit rate: %f\n", minhitrate );
|
||||
printf( "Max false alarm rate: %f\n", maxfalsealarm );
|
||||
printf( "Weight trimming: %f\n", weightfraction );
|
||||
printf( "Equal weights: %s\n", (equalweights) ? "TRUE" : "FALSE" );
|
||||
printf( "Mode: %s\n", ( (mode == 0) ? "BASIC" : ( (mode == 1) ? "CORE" : "ALL") ) );
|
||||
printf( "Width: %d\n", width );
|
||||
printf( "Height: %d\n", height );
|
||||
//printf( "Max num of precalculated features: %d\n", numprecalculated );
|
||||
printf( "Applied boosting algorithm: %s\n", boosttypes[boosttype] );
|
||||
printf( "Error (valid only for Discrete and Real AdaBoost): %s\n",
|
||||
stumperrors[stumperror] );
|
||||
|
||||
printf( "Max number of splits in tree cascade: %d\n", maxtreesplits );
|
||||
printf( "Min number of positive samples per cluster: %d\n", minpos );
|
||||
|
||||
cvCreateTreeCascadeClassifier( dirname, vecname, bgname,
|
||||
npos, nneg, nstages, mem,
|
||||
nsplits,
|
||||
minhitrate, maxfalsealarm, weightfraction,
|
||||
mode, symmetric,
|
||||
equalweights, width, height,
|
||||
boosttype, stumperror,
|
||||
maxtreesplits, minpos, bg_vecfile );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,375 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* performance.cpp
|
||||
*
|
||||
* Measure performance of classifier
|
||||
*/
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
#ifdef _WIN32
|
||||
/* use clock() function insted of time() */
|
||||
#define time( arg ) (((double) clock()) / CLOCKS_PER_SEC)
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 512
|
||||
#endif /* PATH_MAX */
|
||||
|
||||
typedef struct HidCascade
|
||||
{
|
||||
int size;
|
||||
int count;
|
||||
} HidCascade;
|
||||
|
||||
typedef struct ObjectPos
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
int found; /* for reference */
|
||||
int neghbors;
|
||||
} ObjectPos;
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int i, j;
|
||||
char* classifierdir = NULL;
|
||||
//char* samplesdir = NULL;
|
||||
|
||||
int saveDetected = 1;
|
||||
double scale_factor = 1.2;
|
||||
float maxSizeDiff = 1.5F;
|
||||
float maxPosDiff = 0.3F;
|
||||
|
||||
/* number of stages. if <=0 all stages are used */
|
||||
int nos = -1, nos0;
|
||||
|
||||
int width = 24;
|
||||
int height = 24;
|
||||
|
||||
int rocsize;
|
||||
|
||||
FILE* info;
|
||||
char* infoname;
|
||||
char fullname[PATH_MAX];
|
||||
char detfilename[PATH_MAX];
|
||||
char* filename;
|
||||
char detname[] = "det-";
|
||||
|
||||
CvHaarClassifierCascade* cascade;
|
||||
CvMemStorage* storage;
|
||||
CvSeq* objects;
|
||||
|
||||
double totaltime;
|
||||
|
||||
infoname = (char*)"";
|
||||
rocsize = 40;
|
||||
if( argc == 1 )
|
||||
{
|
||||
printf( "Usage: %s\n -data <classifier_directory_name>\n"
|
||||
" -info <collection_file_name>\n"
|
||||
" [-maxSizeDiff <max_size_difference = %f>]\n"
|
||||
" [-maxPosDiff <max_position_difference = %f>]\n"
|
||||
" [-sf <scale_factor = %f>]\n"
|
||||
" [-ni]\n"
|
||||
" [-nos <number_of_stages = %d>]\n"
|
||||
" [-rs <roc_size = %d>]\n"
|
||||
" [-w <sample_width = %d>]\n"
|
||||
" [-h <sample_height = %d>]\n",
|
||||
argv[0], maxSizeDiff, maxPosDiff, scale_factor, nos, rocsize,
|
||||
width, height );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
if( !strcmp( argv[i], "-data" ) )
|
||||
{
|
||||
classifierdir = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-info" ) )
|
||||
{
|
||||
infoname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxSizeDiff" ) )
|
||||
{
|
||||
maxSizeDiff = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxPosDiff" ) )
|
||||
{
|
||||
maxPosDiff = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-sf" ) )
|
||||
{
|
||||
scale_factor = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-ni" ) )
|
||||
{
|
||||
saveDetected = 0;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nos" ) )
|
||||
{
|
||||
nos = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-rs" ) )
|
||||
{
|
||||
rocsize = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-w" ) )
|
||||
{
|
||||
width = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-h" ) )
|
||||
{
|
||||
height = atoi( argv[++i] );
|
||||
}
|
||||
}
|
||||
|
||||
cascade = cvLoadHaarClassifierCascade( classifierdir, cvSize( width, height ) );
|
||||
if( cascade == NULL )
|
||||
{
|
||||
printf( "Unable to load classifier from %s\n", classifierdir );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int* numclassifiers = new int[cascade->count];
|
||||
numclassifiers[0] = cascade->stage_classifier[0].count;
|
||||
for( i = 1; i < cascade->count; i++ )
|
||||
{
|
||||
numclassifiers[i] = numclassifiers[i-1] + cascade->stage_classifier[i].count;
|
||||
}
|
||||
|
||||
storage = cvCreateMemStorage();
|
||||
|
||||
nos0 = cascade->count;
|
||||
if( nos <= 0 )
|
||||
nos = nos0;
|
||||
|
||||
strcpy( fullname, infoname );
|
||||
filename = strrchr( fullname, '\\' );
|
||||
if( filename == NULL )
|
||||
{
|
||||
filename = strrchr( fullname, '/' );
|
||||
}
|
||||
if( filename == NULL )
|
||||
{
|
||||
filename = fullname;
|
||||
}
|
||||
else
|
||||
{
|
||||
filename++;
|
||||
}
|
||||
|
||||
info = fopen( infoname, "r" );
|
||||
totaltime = 0.0;
|
||||
if( info != NULL )
|
||||
{
|
||||
int x, y, width, height;
|
||||
IplImage* img;
|
||||
int hits, missed, falseAlarms;
|
||||
int totalHits, totalMissed, totalFalseAlarms;
|
||||
int found;
|
||||
float distance;
|
||||
|
||||
int refcount;
|
||||
ObjectPos* ref;
|
||||
int detcount;
|
||||
ObjectPos* det;
|
||||
int error=0;
|
||||
|
||||
int* pos;
|
||||
int* neg;
|
||||
|
||||
pos = (int*) cvAlloc( rocsize * sizeof( *pos ) );
|
||||
neg = (int*) cvAlloc( rocsize * sizeof( *neg ) );
|
||||
for( i = 0; i < rocsize; i++ ) { pos[i] = neg[i] = 0; }
|
||||
|
||||
printf( "+================================+======+======+======+\n" );
|
||||
printf( "| File Name | Hits |Missed| False|\n" );
|
||||
printf( "+================================+======+======+======+\n" );
|
||||
|
||||
totalHits = totalMissed = totalFalseAlarms = 0;
|
||||
while( !feof( info ) )
|
||||
{
|
||||
if( fscanf( info, "%s %d", filename, &refcount ) != 2 || refcount <= 0 ) break;
|
||||
|
||||
img = cvLoadImage( fullname );
|
||||
if( !img ) continue;
|
||||
|
||||
ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) );
|
||||
for( i = 0; i < refcount; i++ )
|
||||
{
|
||||
error = (fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4);
|
||||
if( error ) break;
|
||||
ref[i].x = 0.5F * width + x;
|
||||
ref[i].y = 0.5F * height + y;
|
||||
ref[i].width = sqrtf( 0.5F * (width * width + height * height) );
|
||||
ref[i].found = 0;
|
||||
ref[i].neghbors = 0;
|
||||
}
|
||||
if( !error )
|
||||
{
|
||||
cvClearMemStorage( storage );
|
||||
|
||||
cascade->count = nos;
|
||||
totaltime -= time( 0 );
|
||||
objects = cvHaarDetectObjects( img, cascade, storage, scale_factor, 1 );
|
||||
totaltime += time( 0 );
|
||||
cascade->count = nos0;
|
||||
|
||||
detcount = ( objects ? objects->total : 0);
|
||||
det = (detcount > 0) ?
|
||||
( (ObjectPos*)cvAlloc( detcount * sizeof( *det )) ) : NULL;
|
||||
hits = missed = falseAlarms = 0;
|
||||
for( i = 0; i < detcount; i++ )
|
||||
{
|
||||
CvAvgComp r = *((CvAvgComp*) cvGetSeqElem( objects, i ));
|
||||
det[i].x = 0.5F * r.rect.width + r.rect.x;
|
||||
det[i].y = 0.5F * r.rect.height + r.rect.y;
|
||||
det[i].width = sqrtf( 0.5F * (r.rect.width * r.rect.width +
|
||||
r.rect.height * r.rect.height) );
|
||||
det[i].neghbors = r.neighbors;
|
||||
|
||||
if( saveDetected )
|
||||
{
|
||||
cvRectangle( img, cvPoint( r.rect.x, r.rect.y ),
|
||||
cvPoint( r.rect.x + r.rect.width, r.rect.y + r.rect.height ),
|
||||
CV_RGB( 255, 0, 0 ), 3 );
|
||||
}
|
||||
|
||||
found = 0;
|
||||
for( j = 0; j < refcount; j++ )
|
||||
{
|
||||
distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
|
||||
(det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
|
||||
if( (distance < ref[j].width * maxPosDiff) &&
|
||||
(det[i].width > ref[j].width / maxSizeDiff) &&
|
||||
(det[i].width < ref[j].width * maxSizeDiff) )
|
||||
{
|
||||
ref[j].found = 1;
|
||||
ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if( !found )
|
||||
{
|
||||
falseAlarms++;
|
||||
neg[MIN(det[i].neghbors, rocsize - 1)]++;
|
||||
}
|
||||
}
|
||||
for( j = 0; j < refcount; j++ )
|
||||
{
|
||||
if( ref[j].found )
|
||||
{
|
||||
hits++;
|
||||
pos[MIN(ref[j].neghbors, rocsize - 1)]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
missed++;
|
||||
}
|
||||
}
|
||||
|
||||
totalHits += hits;
|
||||
totalMissed += missed;
|
||||
totalFalseAlarms += falseAlarms;
|
||||
printf( "|%32.32s|%6d|%6d|%6d|\n", filename, hits, missed, falseAlarms );
|
||||
printf( "+--------------------------------+------+------+------+\n" );
|
||||
fflush( stdout );
|
||||
|
||||
if( saveDetected )
|
||||
{
|
||||
strcpy( detfilename, detname );
|
||||
strcat( detfilename, filename );
|
||||
strcpy( filename, detfilename );
|
||||
cvvSaveImage( fullname, img );
|
||||
}
|
||||
|
||||
if( det ) { cvFree( &det ); det = NULL; }
|
||||
} /* if( !error ) */
|
||||
|
||||
cvReleaseImage( &img );
|
||||
cvFree( &ref );
|
||||
}
|
||||
fclose( info );
|
||||
|
||||
printf( "|%32.32s|%6d|%6d|%6d|\n", "Total",
|
||||
totalHits, totalMissed, totalFalseAlarms );
|
||||
printf( "+================================+======+======+======+\n" );
|
||||
printf( "Number of stages: %d\n", nos );
|
||||
printf( "Number of weak classifiers: %d\n", numclassifiers[nos - 1] );
|
||||
printf( "Total time: %f\n", totaltime );
|
||||
|
||||
/* print ROC to stdout */
|
||||
for( i = rocsize - 1; i > 0; i-- )
|
||||
{
|
||||
pos[i-1] += pos[i];
|
||||
neg[i-1] += neg[i];
|
||||
}
|
||||
fprintf( stderr, "%d\n", nos );
|
||||
for( i = 0; i < rocsize; i++ )
|
||||
{
|
||||
fprintf( stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
|
||||
((float)pos[i]) / (totalHits + totalMissed),
|
||||
((float)neg[i]) / (totalHits + totalMissed) );
|
||||
}
|
||||
|
||||
cvFree( &pos );
|
||||
cvFree( &neg );
|
||||
}
|
||||
|
||||
delete[] numclassifiers;
|
||||
|
||||
cvReleaseHaarClassifierCascade( &cascade );
|
||||
cvReleaseMemStorage( &storage );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
set(the_description "High-level GUI and Media I/O")
|
||||
ocv_add_module(highgui opencv_imgproc OPTIONAL opencv_androidcamera)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# CMake file for highgui. See root CMakeLists.txt
|
||||
# Some parts taken from version of Hartmut Seichter, HIT Lab NZ.
|
||||
# Jose Luis Blanco, 2008
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
option(OCVMODULE_HIGHGUI "Include highgui module into the OpenCV build" ON)
|
||||
if(NOT OCVMODULE_HIGHGUI)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(the_target "opencv_highgui")
|
||||
project(${the_target})
|
||||
|
||||
#so that the headers get installed.
|
||||
file(GLOB lib_hdrs "include/opencv2/highgui/*.h*")
|
||||
|
||||
set(GRFMT_LIBS)
|
||||
set(GRFMT_LIBS "")
|
||||
|
||||
if(WITH_PNG OR WITH_TIFF OR WITH_OPENEXR)
|
||||
if(ZLIB_FOUND)
|
||||
@@ -85,6 +77,7 @@ set(grfmt_srcs src/bitstrm.cpp ${grfmt_srcs})
|
||||
|
||||
source_group("Src\\grfmts" FILES ${grfmt_hdrs} ${grfmt_srcs})
|
||||
|
||||
set(highgui_hdrs src/precomp.hpp src/utils.hpp)
|
||||
set(highgui_srcs
|
||||
src/cap.cpp
|
||||
src/cap_images.cpp
|
||||
@@ -94,15 +87,7 @@ set(highgui_srcs
|
||||
src/utils.cpp
|
||||
src/window.cpp
|
||||
)
|
||||
|
||||
set(highgui_hdrs src/precomp.hpp src/utils.hpp)
|
||||
|
||||
#YV
|
||||
set(lib_hdr_names highgui_c.h highgui.hpp)
|
||||
set(highgui_ext_hdrs)
|
||||
foreach(h ${lib_hdr_names})
|
||||
list(APPEND highgui_ext_hdrs "${CMAKE_CURRENT_SOURCE_DIR}/include/opencv2/highgui/${h}")
|
||||
endforeach()
|
||||
file(GLOB highgui_ext_hdrs "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
|
||||
|
||||
#YV
|
||||
if (HAVE_QT)
|
||||
@@ -225,11 +210,9 @@ if(APPLE)
|
||||
endif()
|
||||
endif(APPLE)
|
||||
|
||||
if(WITH_ANDROID_CAMERA)
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../androidcamera/include")
|
||||
if(WITH_ANDROID_CAMERA AND OPENCV_MODULE_ANDROIDCAMERA)
|
||||
set(highgui_srcs ${highgui_srcs} src/cap_android.cpp)
|
||||
add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA)
|
||||
set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} opencv_androidcamera)
|
||||
add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA)#TODO: remove this line
|
||||
endif()
|
||||
|
||||
if(HAVE_XIMEA AND XIMEA_FOUND)
|
||||
@@ -265,32 +248,16 @@ if(OPENCV_BUILD_3RDPARTY_LIBS AND WIN32)
|
||||
link_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/lib")
|
||||
endif()
|
||||
|
||||
if(COMMAND get_module_external_sources)
|
||||
set( lib_srcs "${highgui_srcs}" )
|
||||
set( lib_int_hdrs "${highgui_hdrs}" )
|
||||
get_module_external_sources(highgui)
|
||||
set( highgui_srcs "${lib_srcs}" )
|
||||
set( highgui_hdrs "${lib_int_hdrs}" )
|
||||
endif()
|
||||
|
||||
source_group("Src" FILES ${highgui_srcs} ${highgui_hdrs})
|
||||
source_group("Include" FILES ${highgui_ext_hdrs})
|
||||
ocv_set_module_sources(HEADERS ${highgui_ext_hdrs} SOURCES ${highgui_srcs} ${highgui_hdrs} ${grfmt_srcs} ${grfmt_hdrs})
|
||||
|
||||
#message(STATUS "GRFMT: ${GRFMT_LIBS}")
|
||||
#message(STATUS "OPENCV_LIBS: ${OPENCV_LINKER_LIBS}")
|
||||
#message(STATUS "HIGHGUI_LIBS: ${HIGHGUI_LIBRARIES}")
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
# Define the library target:
|
||||
# ----------------------------------------------------------------------------------
|
||||
opencv_module_includes(opencv_core opencv_imgproc)
|
||||
ocv_module_include_directories()
|
||||
if(WIN32)
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/include")
|
||||
endif()
|
||||
|
||||
add_library(${the_target} ${highgui_srcs} ${grfmt_srcs} ${highgui_hdrs} ${grfmt_hdrs} ${highgui_ext_hdrs})
|
||||
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} opencv_core opencv_imgproc ${GRFMT_LIBS} ${HIGHGUI_LIBRARIES})
|
||||
opencv_module_register(${the_target})
|
||||
ocv_create_module(${GRFMT_LIBS} ${HIGHGUI_LIBRARIES})
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
add_definitions(-DHIGHGUI_EXPORTS)
|
||||
@@ -300,6 +267,7 @@ if(MSVC)
|
||||
set_target_properties(${the_target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /NODEFAULTLIB:libcmt.lib /DEBUG")
|
||||
endif()
|
||||
|
||||
opencv_module_setup(highgui)
|
||||
define_opencv_test(highgui)
|
||||
define_opencv_perf_test(highgui)
|
||||
ocv_add_precompiled_headers(${the_module})
|
||||
|
||||
ocv_add_accuracy_tests()
|
||||
ocv_add_perf_tests()
|
||||
|
||||
@@ -221,7 +221,6 @@ make & enjoy!
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "highgui.h"
|
||||
#include "precomp.hpp"
|
||||
|
||||
#if !defined WIN32 && defined HAVE_LIBV4L
|
||||
@@ -393,6 +392,7 @@ static void icvInitCapture_V4L() {
|
||||
|
||||
|
||||
static int try_init_v4l(CvCaptureCAM_V4L* capture, char *deviceName)
|
||||
|
||||
{
|
||||
|
||||
// if detect = -1 then unable to open device
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
define_opencv_module(imgproc opencv_core)
|
||||
set(the_description "Image Processing")
|
||||
ocv_define_module(imgproc opencv_core)
|
||||
|
||||
+16
-24
@@ -1,22 +1,18 @@
|
||||
if(NOT BUILD_JAVA_SUPPORT OR NOT PYTHON_EXECUTABLE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# CMake file for java support
|
||||
# ----------------------------------------------------------------------------
|
||||
project(opencv_java)
|
||||
set(target opencv_java)
|
||||
if(NOT BUILD_JAVA_SUPPORT OR NOT PYTHON_EXECUTABLE)
|
||||
ocv_module_disable(java)
|
||||
endif()
|
||||
|
||||
set(the_description "The java bindings")
|
||||
ocv_add_module(java BINDINGS opencv_objdetect opencv_features2d opencv_imgproc opencv_video opencv_highgui opencv_ml opencv_core opencv_calib3d)
|
||||
|
||||
string(REPLACE "opencv_" "" OPENCV_JAVA_MODULES "${OPENCV_MODULE_${the_module}_REQ_DEPS}")
|
||||
|
||||
set(target ${the_module})
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp")
|
||||
|
||||
|
||||
SET(OPENCV_JAVA_MODULES objdetect features2d imgproc video highgui ml core calib3d)
|
||||
SET(OPENCV_EXTRA_JAVA_MODULES contrib legacy flann)
|
||||
IF(WITH_ANDROID_CAMERA AND NOT BUILD_SHARED_LIBS)
|
||||
LIST(APPEND OPENCV_EXTRA_JAVA_MODULES androidcamera)
|
||||
ENDIF()
|
||||
|
||||
|
||||
SET(GEN_JAVA "${CMAKE_CURRENT_SOURCE_DIR}/gen_java.py")
|
||||
SET(HDR_PARSER "${CMAKE_CURRENT_SOURCE_DIR}/../python/src2/hdr_parser.py")
|
||||
SET(GEN_JAVADOC "${CMAKE_CURRENT_SOURCE_DIR}/gen_javadoc.py")
|
||||
@@ -81,25 +77,21 @@ foreach(module ${OPENCV_JAVA_MODULES})
|
||||
endforeach()
|
||||
|
||||
FILE(GLOB handwrittren_cpp_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/*.cpp")
|
||||
FILE(GLOB handwrittren_h_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/*.h*")
|
||||
FILE(GLOB handwrittren_h_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/*.h??")
|
||||
FILE(GLOB handwrittren_java_sources "${CMAKE_CURRENT_SOURCE_DIR}/src/java/*.java")
|
||||
SET (generated_cpp_sources)
|
||||
SET (generated_java_sources)
|
||||
SET (documented_java_files)
|
||||
SET (undocumented_java_files)
|
||||
SET (dependent_libs)
|
||||
SET (dependent_extra_libs)
|
||||
|
||||
foreach(module ${OPENCV_JAVA_MODULES})
|
||||
LIST(APPEND generated_cpp_sources "${CMAKE_CURRENT_BINARY_DIR}/${module}.cpp")
|
||||
LIST(APPEND generated_java_sources ${${module}_generated_java_sources})
|
||||
LIST(APPEND dependent_libs opencv_${module})
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include")
|
||||
endforeach()
|
||||
|
||||
# extra includes and dependencies
|
||||
foreach(module ${OPENCV_EXTRA_JAVA_MODULES})
|
||||
LIST(APPEND dependent_extra_libs opencv_${module})
|
||||
# all needed includes
|
||||
foreach(module ${OPENCV_MODULE_${the_module}_DEPS})
|
||||
string(REPLACE "opencv_" "" module "${module}")
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../${module}/include")
|
||||
endforeach()
|
||||
|
||||
@@ -154,8 +146,8 @@ ADD_CUSTOM_TARGET(${api_target} DEPENDS ${java_files})
|
||||
|
||||
# add opencv_java library
|
||||
add_library(${target} SHARED ${handwrittren_h_sources} ${handwrittren_cpp_sources} ${generated_cpp_sources})
|
||||
target_link_libraries(${target} ${dependent_libs} ${dependent_extra_libs} ${OPENCV_LINKER_LIBS})
|
||||
add_dependencies(${target} ${dependent_extra_libs} ${dependent_libs} ${api_target})
|
||||
target_link_libraries(${target} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS})
|
||||
add_dependencies(${target} ${api_target})
|
||||
|
||||
# Additional target properties
|
||||
set_target_properties(${target} PROPERTIES
|
||||
|
||||
@@ -1 +1 @@
|
||||
define_opencv_module(legacy opencv_core opencv_imgproc opencv_calib3d opencv_features2d opencv_highgui opencv_video opencv_flann)
|
||||
ocv_define_module(legacy opencv_calib3d opencv_highgui opencv_video)
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
define_opencv_module(ml opencv_core)
|
||||
set(the_description "Machine Learning")
|
||||
ocv_define_module(ml opencv_core)
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
define_opencv_module(objdetect opencv_core opencv_imgproc opencv_highgui opencv_features2d opencv_calib3d opencv_flann)
|
||||
set(the_description "Object Detection")
|
||||
ocv_define_module(objdetect opencv_highgui opencv_calib3d)
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
return()
|
||||
endif()
|
||||
if(NOT PYTHONLIBS_FOUND OR NOT BUILD_NEW_PYTHON_SUPPORT OR NOT PYTHON_USE_NUMPY)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# CMake file for python support
|
||||
# ----------------------------------------------------------------------------
|
||||
project(opencv_python)
|
||||
|
||||
if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
ocv_module_disable(python)
|
||||
endif()
|
||||
if(NOT PYTHONLIBS_FOUND OR NOT BUILD_NEW_PYTHON_SUPPORT OR NOT PYTHON_USE_NUMPY)
|
||||
ocv_module_disable(python)
|
||||
endif()
|
||||
|
||||
set(the_description "The python bindings")
|
||||
ocv_add_module(python BINDINGS opencv_core opencv_flann opencv_imgproc opencv_video opencv_ml opencv_features2d opencv_highgui opencv_calib3d opencv_objdetect opencv_legacy opencv_contrib)
|
||||
|
||||
include_directories(${PYTHON_INCLUDE_PATH})
|
||||
include_directories(
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
if(IOS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(DEPS opencv_core opencv_imgproc opencv_features2d opencv_calib3d opencv_flann opencv_objdetect)
|
||||
if(NOT ANDROID)
|
||||
set(DEPS ${DEPS} opencv_gpu)
|
||||
endif()
|
||||
|
||||
define_opencv_module(stitching ${DEPS})
|
||||
set(the_description "Images stitching")
|
||||
ocv_define_module(stitching opencv_imgproc opencv_features2d opencv_calib3d opencv_objdetect OPTIONAL opencv_gpu)
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
|
||||
#ifndef ANDROID
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
#include "opencv2/gpu/gpu.hpp"
|
||||
#endif
|
||||
|
||||
@@ -102,7 +103,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
class CV_EXPORTS SurfFeaturesFinderGpu : public FeaturesFinder
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#define __OPENCV_STITCHING_SEAM_FINDERS_HPP__
|
||||
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace detail {
|
||||
@@ -114,7 +115,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#ifndef ANDROID
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
# include "opencv2/gpu/gpu.hpp"
|
||||
#endif
|
||||
|
||||
@@ -184,7 +185,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
class PlaneWarperGpu: public WarperCreator
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -189,7 +189,7 @@ Rect FeatherBlender::createWeightMaps(const vector<Mat> &masks, const vector<Poi
|
||||
MultiBandBlender::MultiBandBlender(int try_gpu, int num_bands)
|
||||
{
|
||||
setNumBands(num_bands);
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
can_use_gpu_ = try_gpu && gpu::getCudaEnabledDeviceCount();
|
||||
#else
|
||||
can_use_gpu_ = false;
|
||||
@@ -383,7 +383,7 @@ void createLaplacePyr(const Mat &img, int num_levels, vector<Mat> &pyr)
|
||||
|
||||
void createLaplacePyrGpu(const Mat &img, int num_levels, vector<Mat> &pyr)
|
||||
{
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
pyr.resize(num_levels + 1);
|
||||
|
||||
vector<gpu::GpuMat> gpu_pyr(num_levels + 1);
|
||||
@@ -419,7 +419,7 @@ void restoreImageFromLaplacePyr(vector<Mat> &pyr)
|
||||
|
||||
void restoreImageFromLaplacePyrGpu(vector<Mat> &pyr)
|
||||
{
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
if (pyr.empty())
|
||||
return;
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@
|
||||
#include "precomp.hpp"
|
||||
|
||||
using namespace std;
|
||||
#ifndef ANDROID
|
||||
using namespace cv::gpu;
|
||||
#endif
|
||||
|
||||
namespace cv {
|
||||
namespace detail {
|
||||
|
||||
@@ -46,7 +46,7 @@ using namespace std;
|
||||
using namespace cv;
|
||||
using namespace cv::detail;
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
using namespace cv::gpu;
|
||||
#endif
|
||||
|
||||
@@ -127,7 +127,7 @@ private:
|
||||
float match_conf_;
|
||||
};
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
class GpuMatcher : public FeaturesMatcher
|
||||
{
|
||||
public:
|
||||
@@ -202,7 +202,7 @@ void CpuMatcher::match(const ImageFeatures &features1, const ImageFeatures &feat
|
||||
LOG("1->2 & 2->1 matches: " << matches_info.matches.size() << endl);
|
||||
}
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
void GpuMatcher::match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo& matches_info)
|
||||
{
|
||||
matches_info.matches.clear();
|
||||
@@ -398,7 +398,7 @@ void OrbFeaturesFinder::find(const Mat &image, ImageFeatures &features)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
SurfFeaturesFinderGpu::SurfFeaturesFinderGpu(double hess_thresh, int num_octaves, int num_layers,
|
||||
int num_octaves_descr, int num_layers_descr)
|
||||
{
|
||||
@@ -499,7 +499,7 @@ void FeaturesMatcher::operator ()(const vector<ImageFeatures> &features, vector<
|
||||
|
||||
BestOf2NearestMatcher::BestOf2NearestMatcher(bool try_use_gpu, float match_conf, int num_matches_thresh1, int num_matches_thresh2)
|
||||
{
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
if (try_use_gpu && getCudaEnabledDeviceCount() > 0)
|
||||
impl_ = new GpuMatcher(match_conf);
|
||||
else
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#ifdef HAVE_CVCONFIG_H
|
||||
#include "cvconfig.h"
|
||||
#endif
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
@@ -69,11 +70,11 @@
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/calib3d/calib3d.hpp"
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
# include "opencv2/gpu/gpu.hpp"
|
||||
#endif
|
||||
|
||||
#include "modules/imgproc/src/gcgraph.hpp"
|
||||
#include "../../imgproc/src/gcgraph.hpp"
|
||||
|
||||
#ifdef HAVE_TEGRA_OPTIMIZATION
|
||||
# include "opencv2/stitching/stitching_tegra.hpp"
|
||||
|
||||
@@ -417,7 +417,7 @@ void GraphCutSeamFinder::find(const vector<Mat> &src, const vector<Point> &corne
|
||||
}
|
||||
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
void GraphCutSeamFinderGpu::find(const vector<Mat> &src, const vector<Point> &corners,
|
||||
vector<Mat> &masks)
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ Stitcher Stitcher::createDefault(bool try_use_gpu)
|
||||
stitcher.setFeaturesMatcher(new detail::BestOf2NearestMatcher(try_use_gpu));
|
||||
stitcher.setBundleAdjuster(new detail::BundleAdjusterRay());
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
if (try_use_gpu && gpu::getCudaEnabledDeviceCount() > 0)
|
||||
{
|
||||
stitcher.setFeaturesFinder(new detail::SurfFeaturesFinderGpu());
|
||||
|
||||
@@ -212,7 +212,7 @@ void SphericalWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_b
|
||||
}
|
||||
|
||||
|
||||
#ifndef ANDROID
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
Rect PlaneWarperGpu::buildMaps(Size src_size, const Mat &K, const Mat &R, gpu::GpuMat &xmap, gpu::GpuMat &ymap)
|
||||
{
|
||||
return buildMaps(src_size, K, R, Mat::zeros(3, 1, CV_32F), xmap, ymap);
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
if(IOS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(traincascade)
|
||||
|
||||
include_directories(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/modules/core/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/imgproc/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/objdetect/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/ml/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/highgui/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/video/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/features2d/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/flann/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/calib3d/include"
|
||||
"${OpenCV_SOURCE_DIR}/modules/legacy/include"
|
||||
)
|
||||
|
||||
set(traincascade_libs opencv_core opencv_ml opencv_imgproc
|
||||
opencv_objdetect opencv_highgui opencv_haartraining_engine)
|
||||
|
||||
set(traincascade_files traincascade.cpp
|
||||
cascadeclassifier.cpp cascadeclassifier.h
|
||||
boost.cpp boost.h features.cpp traincascade_features.h
|
||||
haarfeatures.cpp haarfeatures.h
|
||||
lbpfeatures.cpp lbpfeatures.h
|
||||
HOGfeatures.cpp HOGfeatures.h
|
||||
imagestorage.cpp imagestorage.h)
|
||||
|
||||
set(the_target opencv_traincascade)
|
||||
add_executable(${the_target} ${traincascade_files})
|
||||
|
||||
add_dependencies(${the_target} ${traincascade_libs})
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
INSTALL_NAME_DIR lib
|
||||
OUTPUT_NAME "opencv_traincascade")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
target_link_libraries(${the_target} ${traincascade_libs})
|
||||
|
||||
if(NOT ANDROID)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION bin COMPONENT main)
|
||||
endif()
|
||||
@@ -1,245 +0,0 @@
|
||||
#include "HOGfeatures.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
|
||||
CvHOGFeatureParams::CvHOGFeatureParams()
|
||||
{
|
||||
maxCatCount = 0;
|
||||
name = HOGF_NAME;
|
||||
featSize = N_BINS * N_CELLS;
|
||||
}
|
||||
|
||||
void CvHOGEvaluator::init(const CvFeatureParams *_featureParams, int _maxSampleCount, Size _winSize)
|
||||
{
|
||||
CV_Assert( _maxSampleCount > 0);
|
||||
int cols = (_winSize.width + 1) * (_winSize.height + 1);
|
||||
for (int bin = 0; bin < N_BINS; bin++)
|
||||
{
|
||||
hist.push_back(Mat(_maxSampleCount, cols, CV_32FC1));
|
||||
}
|
||||
normSum.create( (int)_maxSampleCount, cols, CV_32FC1 );
|
||||
CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
|
||||
}
|
||||
|
||||
void CvHOGEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
|
||||
{
|
||||
CV_DbgAssert( !hist.empty());
|
||||
CvFeatureEvaluator::setImage( img, clsLabel, idx );
|
||||
vector<Mat> integralHist;
|
||||
for (int bin = 0; bin < N_BINS; bin++)
|
||||
{
|
||||
integralHist.push_back( Mat(winSize.height + 1, winSize.width + 1, hist[bin].type(), hist[bin].ptr<float>((int)idx)) );
|
||||
}
|
||||
Mat integralNorm(winSize.height + 1, winSize.width + 1, normSum.type(), normSum.ptr<float>((int)idx));
|
||||
integralHistogram(img, integralHist, integralNorm, (int)N_BINS);
|
||||
}
|
||||
|
||||
//void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
//{
|
||||
// _writeFeatures( features, fs, featureMap );
|
||||
//}
|
||||
|
||||
void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
int featIdx;
|
||||
int componentIdx;
|
||||
const Mat_<int>& featureMap_ = (const Mat_<int>&)featureMap;
|
||||
fs << FEATURES << "[";
|
||||
for ( int fi = 0; fi < featureMap.cols; fi++ )
|
||||
if ( featureMap_(0, fi) >= 0 )
|
||||
{
|
||||
fs << "{";
|
||||
featIdx = fi / getFeatureSize();
|
||||
componentIdx = fi % getFeatureSize();
|
||||
features[featIdx].write( fs, componentIdx );
|
||||
fs << "}";
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
|
||||
void CvHOGEvaluator::generateFeatures()
|
||||
{
|
||||
int offset = winSize.width + 1;
|
||||
Size blockStep;
|
||||
int x, y, t, w, h;
|
||||
|
||||
for (t = 8; t <= winSize.width/2; t+=8) //t = size of a cell. blocksize = 4*cellSize
|
||||
{
|
||||
blockStep = Size(4,4);
|
||||
w = 2*t; //width of a block
|
||||
h = 2*t; //height of a block
|
||||
for (x = 0; x <= winSize.width - w; x += blockStep.width)
|
||||
{
|
||||
for (y = 0; y <= winSize.height - h; y += blockStep.height)
|
||||
{
|
||||
features.push_back(Feature(offset, x, y, t, t));
|
||||
}
|
||||
}
|
||||
w = 2*t;
|
||||
h = 4*t;
|
||||
for (x = 0; x <= winSize.width - w; x += blockStep.width)
|
||||
{
|
||||
for (y = 0; y <= winSize.height - h; y += blockStep.height)
|
||||
{
|
||||
features.push_back(Feature(offset, x, y, t, 2*t));
|
||||
}
|
||||
}
|
||||
w = 4*t;
|
||||
h = 2*t;
|
||||
for (x = 0; x <= winSize.width - w; x += blockStep.width)
|
||||
{
|
||||
for (y = 0; y <= winSize.height - h; y += blockStep.height)
|
||||
{
|
||||
features.push_back(Feature(offset, x, y, 2*t, t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
numFeatures = (int)features.size();
|
||||
}
|
||||
|
||||
CvHOGEvaluator::Feature::Feature()
|
||||
{
|
||||
for (int i = 0; i < N_CELLS; i++)
|
||||
{
|
||||
rect[i] = Rect(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
CvHOGEvaluator::Feature::Feature( int offset, int x, int y, int cellW, int cellH )
|
||||
{
|
||||
rect[0] = Rect(x, y, cellW, cellH); //cell0
|
||||
rect[1] = Rect(x+cellW, y, cellW, cellH); //cell1
|
||||
rect[2] = Rect(x, y+cellH, cellW, cellH); //cell2
|
||||
rect[3] = Rect(x+cellW, y+cellH, cellW, cellH); //cell3
|
||||
|
||||
for (int i = 0; i < N_CELLS; i++)
|
||||
{
|
||||
CV_SUM_OFFSETS(fastRect[i].p0, fastRect[i].p1, fastRect[i].p2, fastRect[i].p3, rect[i], offset);
|
||||
}
|
||||
}
|
||||
|
||||
void CvHOGEvaluator::Feature::write(FileStorage &fs) const
|
||||
{
|
||||
fs << CC_RECTS << "[";
|
||||
for( int i = 0; i < N_CELLS; i++ )
|
||||
{
|
||||
fs << "[:" << rect[i].x << rect[i].y << rect[i].width << rect[i].height << "]";
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
|
||||
//cell and bin idx writing
|
||||
//void CvHOGEvaluator::Feature::write(FileStorage &fs, int varIdx) const
|
||||
//{
|
||||
// int featComponent = varIdx % (N_CELLS * N_BINS);
|
||||
// int cellIdx = featComponent / N_BINS;
|
||||
// int binIdx = featComponent % N_BINS;
|
||||
//
|
||||
// fs << CC_RECTS << "[:" << rect[cellIdx].x << rect[cellIdx].y <<
|
||||
// rect[cellIdx].width << rect[cellIdx].height << binIdx << "]";
|
||||
//}
|
||||
|
||||
//cell[0] and featComponent idx writing. By cell[0] it's possible to recover all block
|
||||
//All block is nessesary for block normalization
|
||||
void CvHOGEvaluator::Feature::write(FileStorage &fs, int featComponentIdx) const
|
||||
{
|
||||
fs << CC_RECT << "[:" << rect[0].x << rect[0].y <<
|
||||
rect[0].width << rect[0].height << featComponentIdx << "]";
|
||||
}
|
||||
|
||||
|
||||
void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, Mat &norm, int nbins) const
|
||||
{
|
||||
CV_Assert( img.type() == CV_8U || img.type() == CV_8UC3 );
|
||||
int x, y, binIdx;
|
||||
|
||||
Size gradSize(img.size());
|
||||
Size histSize(histogram[0].size());
|
||||
Mat grad(gradSize, CV_32F);
|
||||
Mat qangle(gradSize, CV_8U);
|
||||
|
||||
AutoBuffer<int> mapbuf(gradSize.width + gradSize.height + 4);
|
||||
int* xmap = (int*)mapbuf + 1;
|
||||
int* ymap = xmap + gradSize.width + 2;
|
||||
|
||||
const int borderType = (int)BORDER_REPLICATE;
|
||||
|
||||
for( x = -1; x < gradSize.width + 1; x++ )
|
||||
xmap[x] = borderInterpolate(x, gradSize.width, borderType);
|
||||
for( y = -1; y < gradSize.height + 1; y++ )
|
||||
ymap[y] = borderInterpolate(y, gradSize.height, borderType);
|
||||
|
||||
int width = gradSize.width;
|
||||
AutoBuffer<float> _dbuf(width*4);
|
||||
float* dbuf = _dbuf;
|
||||
Mat Dx(1, width, CV_32F, dbuf);
|
||||
Mat Dy(1, width, CV_32F, dbuf + width);
|
||||
Mat Mag(1, width, CV_32F, dbuf + width*2);
|
||||
Mat Angle(1, width, CV_32F, dbuf + width*3);
|
||||
|
||||
float angleScale = (float)(nbins/CV_PI);
|
||||
|
||||
for( y = 0; y < gradSize.height; y++ )
|
||||
{
|
||||
const uchar* currPtr = img.data + img.step*ymap[y];
|
||||
const uchar* prevPtr = img.data + img.step*ymap[y-1];
|
||||
const uchar* nextPtr = img.data + img.step*ymap[y+1];
|
||||
float* gradPtr = (float*)grad.ptr(y);
|
||||
uchar* qanglePtr = (uchar*)qangle.ptr(y);
|
||||
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
dbuf[x] = (float)(currPtr[xmap[x+1]] - currPtr[xmap[x-1]]);
|
||||
dbuf[width + x] = (float)(nextPtr[xmap[x]] - prevPtr[xmap[x]]);
|
||||
}
|
||||
cartToPolar( Dx, Dy, Mag, Angle, false );
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
float mag = dbuf[x+width*2];
|
||||
float angle = dbuf[x+width*3];
|
||||
angle = angle*angleScale - 0.5f;
|
||||
int bidx = cvFloor(angle);
|
||||
angle -= bidx;
|
||||
if( bidx < 0 )
|
||||
bidx += nbins;
|
||||
else if( bidx >= nbins )
|
||||
bidx -= nbins;
|
||||
|
||||
qanglePtr[x] = (uchar)bidx;
|
||||
gradPtr[x] = mag;
|
||||
}
|
||||
}
|
||||
integral(grad, norm, grad.depth());
|
||||
|
||||
float* histBuf;
|
||||
const float* magBuf;
|
||||
const uchar* binsBuf;
|
||||
|
||||
int binsStep = (int)( qangle.step / sizeof(uchar) );
|
||||
int histStep = (int)( histogram[0].step / sizeof(float) );
|
||||
int magStep = (int)( grad.step / sizeof(float) );
|
||||
for( binIdx = 0; binIdx < nbins; binIdx++ )
|
||||
{
|
||||
histBuf = (float*)histogram[binIdx].data;
|
||||
magBuf = (const float*)grad.data;
|
||||
binsBuf = (const uchar*)qangle.data;
|
||||
|
||||
memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) );
|
||||
histBuf += histStep + 1;
|
||||
for( y = 0; y < qangle.rows; y++ )
|
||||
{
|
||||
histBuf[-1] = 0.f;
|
||||
float strSum = 0.f;
|
||||
for( x = 0; x < qangle.cols; x++ )
|
||||
{
|
||||
if( binsBuf[x] == binIdx )
|
||||
strSum += magBuf[x];
|
||||
histBuf[x] = histBuf[-histStep + x] + strSum;
|
||||
}
|
||||
histBuf += histStep;
|
||||
binsBuf += binsStep;
|
||||
magBuf += magStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
#ifndef _OPENCV_HOGFEATURES_H_
|
||||
#define _OPENCV_HOGFEATURES_H_
|
||||
|
||||
#include "traincascade_features.h"
|
||||
|
||||
//#define TEST_INTHIST_BUILD
|
||||
//#define TEST_FEAT_CALC
|
||||
|
||||
#define N_BINS 9
|
||||
#define N_CELLS 4
|
||||
|
||||
#define HOGF_NAME "HOGFeatureParams"
|
||||
struct CvHOGFeatureParams : public CvFeatureParams
|
||||
{
|
||||
CvHOGFeatureParams();
|
||||
};
|
||||
|
||||
class CvHOGEvaluator : public CvFeatureEvaluator
|
||||
{
|
||||
public:
|
||||
virtual ~CvHOGEvaluator() {}
|
||||
virtual void init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, Size _winSize );
|
||||
virtual void setImage(const Mat& img, uchar clsLabel, int idx);
|
||||
virtual float operator()(int varIdx, int sampleIdx) const;
|
||||
virtual void writeFeatures( FileStorage &fs, const Mat& featureMap ) const;
|
||||
protected:
|
||||
virtual void generateFeatures();
|
||||
virtual void integralHistogram(const Mat &img, vector<Mat> &histogram, Mat &norm, int nbins) const;
|
||||
class Feature
|
||||
{
|
||||
public:
|
||||
Feature();
|
||||
Feature( int offset, int x, int y, int cellW, int cellH );
|
||||
float calc( const vector<Mat> &_hists, const Mat &_normSum, size_t y, int featComponent ) const;
|
||||
void write( FileStorage &fs ) const;
|
||||
void write( FileStorage &fs, int varIdx ) const;
|
||||
|
||||
Rect rect[N_CELLS]; //cells
|
||||
|
||||
struct
|
||||
{
|
||||
int p0, p1, p2, p3;
|
||||
} fastRect[N_CELLS];
|
||||
};
|
||||
vector<Feature> features;
|
||||
|
||||
Mat normSum; //for nomalization calculation (L1 or L2)
|
||||
vector<Mat> hist;
|
||||
};
|
||||
|
||||
inline float CvHOGEvaluator::operator()(int varIdx, int sampleIdx) const
|
||||
{
|
||||
int featureIdx = varIdx / (N_BINS * N_CELLS);
|
||||
int componentIdx = varIdx % (N_BINS * N_CELLS);
|
||||
//return features[featureIdx].calc( hist, sampleIdx, componentIdx);
|
||||
return features[featureIdx].calc( hist, normSum, sampleIdx, componentIdx);
|
||||
}
|
||||
|
||||
inline float CvHOGEvaluator::Feature::calc( const vector<Mat>& _hists, const Mat& _normSum, size_t y, int featComponent ) const
|
||||
{
|
||||
float normFactor;
|
||||
float res;
|
||||
|
||||
int binIdx = featComponent % N_BINS;
|
||||
int cellIdx = featComponent / N_BINS;
|
||||
|
||||
const float *hist = _hists[binIdx].ptr<float>(y);
|
||||
res = hist[fastRect[cellIdx].p0] - hist[fastRect[cellIdx].p1] - hist[fastRect[cellIdx].p2] + hist[fastRect[cellIdx].p3];
|
||||
|
||||
const float *normSum = _normSum.ptr<float>(y);
|
||||
normFactor = (float)(normSum[fastRect[0].p0] - normSum[fastRect[1].p1] - normSum[fastRect[2].p2] + normSum[fastRect[3].p3]);
|
||||
res = (res > 0.001f) ? ( res / (normFactor + 0.001f) ) : 0.f; //for cutting negative values, which apper due to floating precision
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif // _OPENCV_HOGFEATURES_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,86 +0,0 @@
|
||||
#ifndef _OPENCV_BOOST_H_
|
||||
#define _OPENCV_BOOST_H_
|
||||
|
||||
#include "traincascade_features.h"
|
||||
#include "ml.h"
|
||||
|
||||
struct CvCascadeBoostParams : CvBoostParams
|
||||
{
|
||||
float minHitRate;
|
||||
float maxFalseAlarm;
|
||||
|
||||
CvCascadeBoostParams();
|
||||
CvCascadeBoostParams( int _boostType, float _minHitRate, float _maxFalseAlarm,
|
||||
double _weightTrimRate, int _maxDepth, int _maxWeakCount );
|
||||
virtual ~CvCascadeBoostParams() {}
|
||||
void write( FileStorage &fs ) const;
|
||||
bool read( const FileNode &node );
|
||||
virtual void printDefaults() const;
|
||||
virtual void printAttrs() const;
|
||||
virtual bool scanAttr( const String prmName, const String val);
|
||||
};
|
||||
|
||||
struct CvCascadeBoostTrainData : CvDTreeTrainData
|
||||
{
|
||||
CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator,
|
||||
const CvDTreeParams& _params );
|
||||
CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator,
|
||||
int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
const CvDTreeParams& _params = CvDTreeParams() );
|
||||
virtual void setData( const CvFeatureEvaluator* _featureEvaluator,
|
||||
int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
const CvDTreeParams& _params=CvDTreeParams() );
|
||||
void precalculate();
|
||||
|
||||
virtual CvDTreeNode* subsample_data( const CvMat* _subsample_idx );
|
||||
|
||||
virtual const int* get_class_labels( CvDTreeNode* n, int* labelsBuf );
|
||||
virtual const int* get_cv_labels( CvDTreeNode* n, int* labelsBuf);
|
||||
virtual const int* get_sample_indices( CvDTreeNode* n, int* indicesBuf );
|
||||
|
||||
virtual void get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf,
|
||||
const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf );
|
||||
virtual const int* get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf );
|
||||
virtual float getVarValue( int vi, int si );
|
||||
virtual void free_train_data();
|
||||
|
||||
const CvFeatureEvaluator* featureEvaluator;
|
||||
Mat valCache; // precalculated feature values (CV_32FC1)
|
||||
CvMat _resp; // for casting
|
||||
int numPrecalcVal, numPrecalcIdx;
|
||||
};
|
||||
|
||||
class CvCascadeBoostTree : public CvBoostTree
|
||||
{
|
||||
public:
|
||||
virtual CvDTreeNode* predict( int sampleIdx ) const;
|
||||
void write( FileStorage &fs, const Mat& featureMap );
|
||||
void read( const FileNode &node, CvBoost* _ensemble, CvDTreeTrainData* _data );
|
||||
void markFeaturesInMap( Mat& featureMap );
|
||||
protected:
|
||||
virtual void split_node_data( CvDTreeNode* n );
|
||||
};
|
||||
|
||||
class CvCascadeBoost : public CvBoost
|
||||
{
|
||||
public:
|
||||
virtual bool train( const CvFeatureEvaluator* _featureEvaluator,
|
||||
int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
const CvCascadeBoostParams& _params=CvCascadeBoostParams() );
|
||||
virtual float predict( int sampleIdx, bool returnSum = false ) const;
|
||||
|
||||
float getThreshold() const { return threshold; }
|
||||
void write( FileStorage &fs, const Mat& featureMap ) const;
|
||||
bool read( const FileNode &node, const CvFeatureEvaluator* _featureEvaluator,
|
||||
const CvCascadeBoostParams& _params );
|
||||
void markUsedFeaturesInMap( Mat& featureMap );
|
||||
protected:
|
||||
virtual bool set_params( const CvBoostParams& _params );
|
||||
virtual void update_weights( CvBoostTree* tree );
|
||||
virtual bool isErrDesired();
|
||||
|
||||
float threshold;
|
||||
float minHitRate, maxFalseAlarm;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,527 +0,0 @@
|
||||
#include "cascadeclassifier.h"
|
||||
#include <queue>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char* stageTypes[] = { CC_BOOST };
|
||||
static const char* featureTypes[] = { CC_HAAR, CC_LBP, CC_HOG };
|
||||
|
||||
CvCascadeParams::CvCascadeParams() : stageType( defaultStageType ),
|
||||
featureType( defaultFeatureType ), winSize( cvSize(24, 24) )
|
||||
{
|
||||
name = CC_CASCADE_PARAMS;
|
||||
}
|
||||
CvCascadeParams::CvCascadeParams( int _stageType, int _featureType ) : stageType( _stageType ),
|
||||
featureType( _featureType ), winSize( cvSize(24, 24) )
|
||||
{
|
||||
name = CC_CASCADE_PARAMS;
|
||||
}
|
||||
|
||||
//---------------------------- CascadeParams --------------------------------------
|
||||
|
||||
void CvCascadeParams::write( FileStorage &fs ) const
|
||||
{
|
||||
String stageTypeStr = stageType == BOOST ? CC_BOOST : String();
|
||||
CV_Assert( !stageTypeStr.empty() );
|
||||
fs << CC_STAGE_TYPE << stageTypeStr;
|
||||
String featureTypeStr = featureType == CvFeatureParams::HAAR ? CC_HAAR :
|
||||
featureType == CvFeatureParams::LBP ? CC_LBP :
|
||||
featureType == CvFeatureParams::HOG ? CC_HOG :
|
||||
0;
|
||||
CV_Assert( !stageTypeStr.empty() );
|
||||
fs << CC_FEATURE_TYPE << featureTypeStr;
|
||||
fs << CC_HEIGHT << winSize.height;
|
||||
fs << CC_WIDTH << winSize.width;
|
||||
}
|
||||
|
||||
bool CvCascadeParams::read( const FileNode &node )
|
||||
{
|
||||
if ( node.empty() )
|
||||
return false;
|
||||
String stageTypeStr, featureTypeStr;
|
||||
FileNode rnode = node[CC_STAGE_TYPE];
|
||||
if ( !rnode.isString() )
|
||||
return false;
|
||||
rnode >> stageTypeStr;
|
||||
stageType = !stageTypeStr.compare( CC_BOOST ) ? BOOST : -1;
|
||||
if (stageType == -1)
|
||||
return false;
|
||||
rnode = node[CC_FEATURE_TYPE];
|
||||
if ( !rnode.isString() )
|
||||
return false;
|
||||
rnode >> featureTypeStr;
|
||||
featureType = !featureTypeStr.compare( CC_HAAR ) ? CvFeatureParams::HAAR :
|
||||
!featureTypeStr.compare( CC_LBP ) ? CvFeatureParams::LBP :
|
||||
!featureTypeStr.compare( CC_HOG ) ? CvFeatureParams::HOG :
|
||||
-1;
|
||||
if (featureType == -1)
|
||||
return false;
|
||||
node[CC_HEIGHT] >> winSize.height;
|
||||
node[CC_WIDTH] >> winSize.width;
|
||||
return winSize.height > 0 && winSize.width > 0;
|
||||
}
|
||||
|
||||
void CvCascadeParams::printDefaults() const
|
||||
{
|
||||
CvParams::printDefaults();
|
||||
cout << " [-stageType <";
|
||||
for( int i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ )
|
||||
{
|
||||
cout << (i ? " | " : "") << stageTypes[i];
|
||||
if ( i == defaultStageType )
|
||||
cout << "(default)";
|
||||
}
|
||||
cout << ">]" << endl;
|
||||
|
||||
cout << " [-featureType <{";
|
||||
for( int i = 0; i < (int)(sizeof(featureTypes)/sizeof(featureTypes[0])); i++ )
|
||||
{
|
||||
cout << (i ? ", " : "") << featureTypes[i];
|
||||
if ( i == defaultStageType )
|
||||
cout << "(default)";
|
||||
}
|
||||
cout << "}>]" << endl;
|
||||
cout << " [-w <sampleWidth = " << winSize.width << ">]" << endl;
|
||||
cout << " [-h <sampleHeight = " << winSize.height << ">]" << endl;
|
||||
}
|
||||
|
||||
void CvCascadeParams::printAttrs() const
|
||||
{
|
||||
cout << "stageType: " << stageTypes[stageType] << endl;
|
||||
cout << "featureType: " << featureTypes[featureType] << endl;
|
||||
cout << "sampleWidth: " << winSize.width << endl;
|
||||
cout << "sampleHeight: " << winSize.height << endl;
|
||||
}
|
||||
|
||||
bool CvCascadeParams::scanAttr( const String prmName, const String val )
|
||||
{
|
||||
bool res = true;
|
||||
if( !prmName.compare( "-stageType" ) )
|
||||
{
|
||||
for( int i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ )
|
||||
if( !val.compare( stageTypes[i] ) )
|
||||
stageType = i;
|
||||
}
|
||||
else if( !prmName.compare( "-featureType" ) )
|
||||
{
|
||||
for( int i = 0; i < (int)(sizeof(featureTypes)/sizeof(featureTypes[0])); i++ )
|
||||
if( !val.compare( featureTypes[i] ) )
|
||||
featureType = i;
|
||||
}
|
||||
else if( !prmName.compare( "-w" ) )
|
||||
{
|
||||
winSize.width = atoi( val.c_str() );
|
||||
}
|
||||
else if( !prmName.compare( "-h" ) )
|
||||
{
|
||||
winSize.height = atoi( val.c_str() );
|
||||
}
|
||||
else
|
||||
res = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
//---------------------------- CascadeClassifier --------------------------------------
|
||||
|
||||
bool CvCascadeClassifier::train( const String _cascadeDirName,
|
||||
const String _posFilename,
|
||||
const String _negFilename,
|
||||
int _numPos, int _numNeg,
|
||||
int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
int _numStages,
|
||||
const CvCascadeParams& _cascadeParams,
|
||||
const CvFeatureParams& _featureParams,
|
||||
const CvCascadeBoostParams& _stageParams,
|
||||
bool baseFormatSave )
|
||||
{
|
||||
if( _cascadeDirName.empty() || _posFilename.empty() || _negFilename.empty() )
|
||||
CV_Error( CV_StsBadArg, "_cascadeDirName or _bgfileName or _vecFileName is NULL" );
|
||||
|
||||
string dirName;
|
||||
if ( _cascadeDirName.find('/') != string::npos )
|
||||
dirName = _cascadeDirName + '/';
|
||||
else
|
||||
dirName = _cascadeDirName + '\\';
|
||||
|
||||
numPos = _numPos;
|
||||
numNeg = _numNeg;
|
||||
numStages = _numStages;
|
||||
if ( !imgReader.create( _posFilename, _negFilename, _cascadeParams.winSize ) )
|
||||
{
|
||||
cout << "Image reader can not be created from -vec " << _posFilename
|
||||
<< " and -bg " << _negFilename << "." << endl;
|
||||
return false;
|
||||
}
|
||||
if ( !load( dirName ) )
|
||||
{
|
||||
cascadeParams = _cascadeParams;
|
||||
featureParams = CvFeatureParams::create(cascadeParams.featureType);
|
||||
featureParams->init(_featureParams);
|
||||
stageParams = new CvCascadeBoostParams;
|
||||
*stageParams = _stageParams;
|
||||
featureEvaluator = CvFeatureEvaluator::create(cascadeParams.featureType);
|
||||
featureEvaluator->init( (CvFeatureParams*)featureParams, numPos + numNeg, cascadeParams.winSize );
|
||||
stageClassifiers.reserve( numStages );
|
||||
}
|
||||
cout << "PARAMETERS:" << endl;
|
||||
cout << "cascadeDirName: " << _cascadeDirName << endl;
|
||||
cout << "vecFileName: " << _posFilename << endl;
|
||||
cout << "bgFileName: " << _negFilename << endl;
|
||||
cout << "numPos: " << _numPos << endl;
|
||||
cout << "numNeg: " << _numNeg << endl;
|
||||
cout << "numStages: " << numStages << endl;
|
||||
cout << "precalcValBufSize[Mb] : " << _precalcValBufSize << endl;
|
||||
cout << "precalcIdxBufSize[Mb] : " << _precalcIdxBufSize << endl;
|
||||
cascadeParams.printAttrs();
|
||||
stageParams->printAttrs();
|
||||
featureParams->printAttrs();
|
||||
|
||||
int startNumStages = (int)stageClassifiers.size();
|
||||
if ( startNumStages > 1 )
|
||||
cout << endl << "Stages 0-" << startNumStages-1 << " are loaded" << endl;
|
||||
else if ( startNumStages == 1)
|
||||
cout << endl << "Stage 0 is loaded" << endl;
|
||||
|
||||
double requiredLeafFARate = pow( (double) stageParams->maxFalseAlarm, (double) numStages ) /
|
||||
(double)stageParams->max_depth;
|
||||
double tempLeafFARate;
|
||||
|
||||
for( int i = startNumStages; i < numStages; i++ )
|
||||
{
|
||||
cout << endl << "===== TRAINING " << i << "-stage =====" << endl;
|
||||
cout << "<BEGIN" << endl;
|
||||
|
||||
if ( !updateTrainingSet( tempLeafFARate ) )
|
||||
{
|
||||
cout << "Train dataset for temp stage can not be filled. "
|
||||
"Branch training terminated." << endl;
|
||||
break;
|
||||
}
|
||||
if( tempLeafFARate <= requiredLeafFARate )
|
||||
{
|
||||
cout << "Required leaf false alarm rate achieved. "
|
||||
"Branch training terminated." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
CvCascadeBoost* tempStage = new CvCascadeBoost;
|
||||
tempStage->train( (CvFeatureEvaluator*)featureEvaluator,
|
||||
curNumSamples, _precalcValBufSize, _precalcIdxBufSize,
|
||||
*((CvCascadeBoostParams*)stageParams) );
|
||||
stageClassifiers.push_back( tempStage );
|
||||
|
||||
cout << "END>" << endl;
|
||||
|
||||
// save params
|
||||
String filename;
|
||||
if ( i == 0)
|
||||
{
|
||||
filename = dirName + CC_PARAMS_FILENAME;
|
||||
FileStorage fs( filename, FileStorage::WRITE);
|
||||
if ( !fs.isOpened() )
|
||||
{
|
||||
cout << "Parameters can not be written, because file " << filename
|
||||
<< " can not be opened." << endl;
|
||||
return false;
|
||||
}
|
||||
fs << FileStorage::getDefaultObjectName(filename) << "{";
|
||||
writeParams( fs );
|
||||
fs << "}";
|
||||
}
|
||||
// save current stage
|
||||
char buf[10];
|
||||
sprintf(buf, "%s%d", "stage", i );
|
||||
filename = dirName + buf + ".xml";
|
||||
FileStorage fs( filename, FileStorage::WRITE );
|
||||
if ( !fs.isOpened() )
|
||||
{
|
||||
cout << "Current stage can not be written, because file " << filename
|
||||
<< " can not be opened." << endl;
|
||||
return false;
|
||||
}
|
||||
fs << FileStorage::getDefaultObjectName(filename) << "{";
|
||||
tempStage->write( fs, Mat() );
|
||||
fs << "}";
|
||||
}
|
||||
save( dirName + CC_CASCADE_FILENAME, baseFormatSave );
|
||||
return true;
|
||||
}
|
||||
|
||||
int CvCascadeClassifier::predict( int sampleIdx )
|
||||
{
|
||||
CV_DbgAssert( sampleIdx < numPos + numNeg );
|
||||
for (vector< Ptr<CvCascadeBoost> >::iterator it = stageClassifiers.begin();
|
||||
it != stageClassifiers.end(); it++ )
|
||||
{
|
||||
if ( (*it)->predict( sampleIdx ) == 0.f )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CvCascadeClassifier::updateTrainingSet( double& acceptanceRatio)
|
||||
{
|
||||
int64 posConsumed = 0, negConsumed = 0;
|
||||
imgReader.restart();
|
||||
int posCount = fillPassedSamples( 0, numPos, true, posConsumed );
|
||||
if( !posCount )
|
||||
return false;
|
||||
cout << "POS count : consumed " << posCount << " : " << (int)posConsumed << endl;
|
||||
|
||||
int proNumNeg = cvRound( ( ((double)numNeg) * ((double)posCount) ) / numPos ); // apply only a fraction of negative samples. double is required since overflow is possible
|
||||
int negCount = fillPassedSamples( posCount, proNumNeg, false, negConsumed );
|
||||
if ( !negCount )
|
||||
return false;
|
||||
|
||||
curNumSamples = posCount + negCount;
|
||||
acceptanceRatio = negConsumed == 0 ? 0 : ( (double)negCount/(double)(int64)negConsumed );
|
||||
cout << "NEG count : acceptanceRatio " << negCount << " : " << acceptanceRatio << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
int CvCascadeClassifier::fillPassedSamples( int first, int count, bool isPositive, int64& consumed )
|
||||
{
|
||||
int getcount = 0;
|
||||
Mat img(cascadeParams.winSize, CV_8UC1);
|
||||
for( int i = first; i < first + count; i++ )
|
||||
{
|
||||
for( ; ; )
|
||||
{
|
||||
bool isGetImg = isPositive ? imgReader.getPos( img ) :
|
||||
imgReader.getNeg( img );
|
||||
if( !isGetImg )
|
||||
return getcount;
|
||||
consumed++;
|
||||
|
||||
featureEvaluator->setImage( img, isPositive ? 1 : 0, i );
|
||||
if( predict( i ) == 1.0F )
|
||||
{
|
||||
getcount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return getcount;
|
||||
}
|
||||
|
||||
void CvCascadeClassifier::writeParams( FileStorage &fs ) const
|
||||
{
|
||||
cascadeParams.write( fs );
|
||||
fs << CC_STAGE_PARAMS << "{"; stageParams->write( fs ); fs << "}";
|
||||
fs << CC_FEATURE_PARAMS << "{"; featureParams->write( fs ); fs << "}";
|
||||
}
|
||||
|
||||
void CvCascadeClassifier::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
((CvFeatureEvaluator*)((Ptr<CvFeatureEvaluator>)featureEvaluator))->writeFeatures( fs, featureMap );
|
||||
}
|
||||
|
||||
void CvCascadeClassifier::writeStages( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
char cmnt[30];
|
||||
int i = 0;
|
||||
fs << CC_STAGES << "[";
|
||||
for( vector< Ptr<CvCascadeBoost> >::const_iterator it = stageClassifiers.begin();
|
||||
it != stageClassifiers.end(); it++, i++ )
|
||||
{
|
||||
sprintf( cmnt, "stage %d", i );
|
||||
cvWriteComment( fs.fs, cmnt, 0 );
|
||||
fs << "{";
|
||||
((CvCascadeBoost*)((Ptr<CvCascadeBoost>)*it))->write( fs, featureMap );
|
||||
fs << "}";
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
|
||||
bool CvCascadeClassifier::readParams( const FileNode &node )
|
||||
{
|
||||
if ( !node.isMap() || !cascadeParams.read( node ) )
|
||||
return false;
|
||||
|
||||
stageParams = new CvCascadeBoostParams;
|
||||
FileNode rnode = node[CC_STAGE_PARAMS];
|
||||
if ( !stageParams->read( rnode ) )
|
||||
return false;
|
||||
|
||||
featureParams = CvFeatureParams::create(cascadeParams.featureType);
|
||||
rnode = node[CC_FEATURE_PARAMS];
|
||||
if ( !featureParams->read( rnode ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCascadeClassifier::readStages( const FileNode &node)
|
||||
{
|
||||
FileNode rnode = node[CC_STAGES];
|
||||
if (!rnode.empty() || !rnode.isSeq())
|
||||
return false;
|
||||
stageClassifiers.reserve(numStages);
|
||||
FileNodeIterator it = rnode.begin();
|
||||
for( int i = 0; i < min( (int)rnode.size(), numStages ); i++, it++ )
|
||||
{
|
||||
CvCascadeBoost* tempStage = new CvCascadeBoost;
|
||||
if ( !tempStage->read( *it, (CvFeatureEvaluator *)featureEvaluator, *((CvCascadeBoostParams*)stageParams) ) )
|
||||
{
|
||||
delete tempStage;
|
||||
return false;
|
||||
}
|
||||
stageClassifiers.push_back(tempStage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// For old Haar Classifier file saving
|
||||
#define ICV_HAAR_SIZE_NAME "size"
|
||||
#define ICV_HAAR_STAGES_NAME "stages"
|
||||
#define ICV_HAAR_TREES_NAME "trees"
|
||||
#define ICV_HAAR_FEATURE_NAME "feature"
|
||||
#define ICV_HAAR_RECTS_NAME "rects"
|
||||
#define ICV_HAAR_TILTED_NAME "tilted"
|
||||
#define ICV_HAAR_THRESHOLD_NAME "threshold"
|
||||
#define ICV_HAAR_LEFT_NODE_NAME "left_node"
|
||||
#define ICV_HAAR_LEFT_VAL_NAME "left_val"
|
||||
#define ICV_HAAR_RIGHT_NODE_NAME "right_node"
|
||||
#define ICV_HAAR_RIGHT_VAL_NAME "right_val"
|
||||
#define ICV_HAAR_STAGE_THRESHOLD_NAME "stage_threshold"
|
||||
#define ICV_HAAR_PARENT_NAME "parent"
|
||||
#define ICV_HAAR_NEXT_NAME "next"
|
||||
|
||||
void CvCascadeClassifier::save( const String filename, bool baseFormat )
|
||||
{
|
||||
FileStorage fs( filename, FileStorage::WRITE );
|
||||
|
||||
if ( !fs.isOpened() )
|
||||
return;
|
||||
|
||||
fs << FileStorage::getDefaultObjectName(filename) << "{";
|
||||
if ( !baseFormat )
|
||||
{
|
||||
Mat featureMap;
|
||||
getUsedFeaturesIdxMap( featureMap );
|
||||
writeParams( fs );
|
||||
fs << CC_STAGE_NUM << (int)stageClassifiers.size();
|
||||
writeStages( fs, featureMap );
|
||||
writeFeatures( fs, featureMap );
|
||||
}
|
||||
else
|
||||
{
|
||||
//char buf[256];
|
||||
CvSeq* weak;
|
||||
if ( cascadeParams.featureType != CvFeatureParams::HAAR )
|
||||
CV_Error( CV_StsBadFunc, "old file format is used for Haar-like features only");
|
||||
fs << ICV_HAAR_SIZE_NAME << "[:" << cascadeParams.winSize.width <<
|
||||
cascadeParams.winSize.height << "]";
|
||||
fs << ICV_HAAR_STAGES_NAME << "[";
|
||||
for( size_t si = 0; si < stageClassifiers.size(); si++ )
|
||||
{
|
||||
fs << "{"; //stage
|
||||
/*sprintf( buf, "stage %d", si );
|
||||
CV_CALL( cvWriteComment( fs, buf, 1 ) );*/
|
||||
weak = stageClassifiers[si]->get_weak_predictors();
|
||||
fs << ICV_HAAR_TREES_NAME << "[";
|
||||
for( int wi = 0; wi < weak->total; wi++ )
|
||||
{
|
||||
int inner_node_idx = -1, total_inner_node_idx = -1;
|
||||
queue<const CvDTreeNode*> inner_nodes_queue;
|
||||
CvCascadeBoostTree* tree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi ));
|
||||
|
||||
fs << "[";
|
||||
/*sprintf( buf, "tree %d", wi );
|
||||
CV_CALL( cvWriteComment( fs, buf, 1 ) );*/
|
||||
|
||||
const CvDTreeNode* tempNode;
|
||||
|
||||
inner_nodes_queue.push( tree->get_root() );
|
||||
total_inner_node_idx++;
|
||||
|
||||
while (!inner_nodes_queue.empty())
|
||||
{
|
||||
tempNode = inner_nodes_queue.front();
|
||||
inner_node_idx++;
|
||||
|
||||
fs << "{";
|
||||
fs << ICV_HAAR_FEATURE_NAME << "{";
|
||||
((CvHaarEvaluator*)((CvFeatureEvaluator*)featureEvaluator))->writeFeature( fs, tempNode->split->var_idx );
|
||||
fs << "}";
|
||||
|
||||
fs << ICV_HAAR_THRESHOLD_NAME << tempNode->split->ord.c;
|
||||
|
||||
if( tempNode->left->left || tempNode->left->right )
|
||||
{
|
||||
inner_nodes_queue.push( tempNode->left );
|
||||
total_inner_node_idx++;
|
||||
fs << ICV_HAAR_LEFT_NODE_NAME << total_inner_node_idx;
|
||||
}
|
||||
else
|
||||
fs << ICV_HAAR_LEFT_VAL_NAME << tempNode->left->value;
|
||||
|
||||
if( tempNode->right->left || tempNode->right->right )
|
||||
{
|
||||
inner_nodes_queue.push( tempNode->right );
|
||||
total_inner_node_idx++;
|
||||
fs << ICV_HAAR_RIGHT_NODE_NAME << total_inner_node_idx;
|
||||
}
|
||||
else
|
||||
fs << ICV_HAAR_RIGHT_VAL_NAME << tempNode->right->value;
|
||||
fs << "}"; // ICV_HAAR_FEATURE_NAME
|
||||
inner_nodes_queue.pop();
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
fs << "]"; //ICV_HAAR_TREES_NAME
|
||||
fs << ICV_HAAR_STAGE_THRESHOLD_NAME << stageClassifiers[si]->getThreshold();
|
||||
fs << ICV_HAAR_PARENT_NAME << (int)si-1 << ICV_HAAR_NEXT_NAME << -1;
|
||||
fs << "}"; //stage
|
||||
} /* for each stage */
|
||||
fs << "]"; //ICV_HAAR_STAGES_NAME
|
||||
}
|
||||
fs << "}";
|
||||
}
|
||||
|
||||
bool CvCascadeClassifier::load( const String cascadeDirName )
|
||||
{
|
||||
FileStorage fs( cascadeDirName + CC_PARAMS_FILENAME, FileStorage::READ );
|
||||
if ( !fs.isOpened() )
|
||||
return false;
|
||||
FileNode node = fs.getFirstTopLevelNode();
|
||||
if ( !readParams( node ) )
|
||||
return false;
|
||||
featureEvaluator = CvFeatureEvaluator::create(cascadeParams.featureType);
|
||||
featureEvaluator->init( ((CvFeatureParams*)featureParams), numPos + numNeg, cascadeParams.winSize );
|
||||
fs.release();
|
||||
|
||||
char buf[10];
|
||||
for ( int si = 0; si < numStages; si++ )
|
||||
{
|
||||
sprintf( buf, "%s%d", "stage", si);
|
||||
fs.open( cascadeDirName + buf + ".xml", FileStorage::READ );
|
||||
node = fs.getFirstTopLevelNode();
|
||||
if ( !fs.isOpened() )
|
||||
break;
|
||||
CvCascadeBoost *tempStage = new CvCascadeBoost;
|
||||
|
||||
if ( !tempStage->read( node, (CvFeatureEvaluator*)featureEvaluator, *((CvCascadeBoostParams*)stageParams )) )
|
||||
{
|
||||
delete tempStage;
|
||||
fs.release();
|
||||
break;
|
||||
}
|
||||
stageClassifiers.push_back(tempStage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CvCascadeClassifier::getUsedFeaturesIdxMap( Mat& featureMap )
|
||||
{
|
||||
int varCount = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize();
|
||||
featureMap.create( 1, varCount, CV_32SC1 );
|
||||
featureMap.setTo(Scalar(-1));
|
||||
|
||||
for( vector< Ptr<CvCascadeBoost> >::const_iterator it = stageClassifiers.begin();
|
||||
it != stageClassifiers.end(); it++ )
|
||||
((CvCascadeBoost*)((Ptr<CvCascadeBoost>)(*it)))->markUsedFeaturesInMap( featureMap );
|
||||
|
||||
for( int fi = 0, idx = 0; fi < varCount; fi++ )
|
||||
if ( featureMap.at<int>(0, fi) >= 0 )
|
||||
featureMap.ptr<int>(0)[fi] = idx++;
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
#ifndef _OPENCV_CASCADECLASSIFIER_H_
|
||||
#define _OPENCV_CASCADECLASSIFIER_H_
|
||||
|
||||
#include <ctime>
|
||||
#include "traincascade_features.h"
|
||||
#include "haarfeatures.h"
|
||||
#include "lbpfeatures.h"
|
||||
#include "HOGfeatures.h" //new
|
||||
#include "boost.h"
|
||||
#include "cv.h"
|
||||
#include "cxcore.h"
|
||||
|
||||
#define CC_CASCADE_FILENAME "cascade.xml"
|
||||
#define CC_PARAMS_FILENAME "params.xml"
|
||||
|
||||
#define CC_CASCADE_PARAMS "cascadeParams"
|
||||
#define CC_STAGE_TYPE "stageType"
|
||||
#define CC_FEATURE_TYPE "featureType"
|
||||
#define CC_HEIGHT "height"
|
||||
#define CC_WIDTH "width"
|
||||
|
||||
#define CC_STAGE_NUM "stageNum"
|
||||
#define CC_STAGES "stages"
|
||||
#define CC_STAGE_PARAMS "stageParams"
|
||||
|
||||
#define CC_BOOST "BOOST"
|
||||
#define CC_BOOST_TYPE "boostType"
|
||||
#define CC_DISCRETE_BOOST "DAB"
|
||||
#define CC_REAL_BOOST "RAB"
|
||||
#define CC_LOGIT_BOOST "LB"
|
||||
#define CC_GENTLE_BOOST "GAB"
|
||||
#define CC_MINHITRATE "minHitRate"
|
||||
#define CC_MAXFALSEALARM "maxFalseAlarm"
|
||||
#define CC_TRIM_RATE "weightTrimRate"
|
||||
#define CC_MAX_DEPTH "maxDepth"
|
||||
#define CC_WEAK_COUNT "maxWeakCount"
|
||||
#define CC_STAGE_THRESHOLD "stageThreshold"
|
||||
#define CC_WEAK_CLASSIFIERS "weakClassifiers"
|
||||
#define CC_INTERNAL_NODES "internalNodes"
|
||||
#define CC_LEAF_VALUES "leafValues"
|
||||
|
||||
#define CC_FEATURES FEATURES
|
||||
#define CC_FEATURE_PARAMS "featureParams"
|
||||
#define CC_MAX_CAT_COUNT "maxCatCount"
|
||||
#define CC_FEATURE_SIZE "featSize"
|
||||
|
||||
#define CC_HAAR "HAAR"
|
||||
#define CC_MODE "mode"
|
||||
#define CC_MODE_BASIC "BASIC"
|
||||
#define CC_MODE_CORE "CORE"
|
||||
#define CC_MODE_ALL "ALL"
|
||||
#define CC_RECTS "rects"
|
||||
#define CC_TILTED "tilted"
|
||||
|
||||
#define CC_LBP "LBP"
|
||||
#define CC_RECT "rect"
|
||||
|
||||
#define CC_HOG "HOG"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC)
|
||||
#else
|
||||
#define TIME( arg ) (time( arg ))
|
||||
#endif
|
||||
|
||||
class CvCascadeParams : public CvParams
|
||||
{
|
||||
public:
|
||||
enum { BOOST = 0 };
|
||||
static const int defaultStageType = BOOST;
|
||||
static const int defaultFeatureType = CvFeatureParams::HAAR;
|
||||
|
||||
CvCascadeParams();
|
||||
CvCascadeParams( int _stageType, int _featureType );
|
||||
void write( FileStorage &fs ) const;
|
||||
bool read( const FileNode &node );
|
||||
|
||||
void printDefaults() const;
|
||||
void printAttrs() const;
|
||||
bool scanAttr( const String prmName, const String val );
|
||||
|
||||
int stageType;
|
||||
int featureType;
|
||||
Size winSize;
|
||||
};
|
||||
|
||||
class CvCascadeClassifier
|
||||
{
|
||||
public:
|
||||
bool train( const String _cascadeDirName,
|
||||
const String _posFilename,
|
||||
const String _negFilename,
|
||||
int _numPos, int _numNeg,
|
||||
int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
int _numStages,
|
||||
const CvCascadeParams& _cascadeParams,
|
||||
const CvFeatureParams& _featureParams,
|
||||
const CvCascadeBoostParams& _stageParams,
|
||||
bool baseFormatSave = false );
|
||||
private:
|
||||
int predict( int sampleIdx );
|
||||
void save( const String cascadeDirName, bool baseFormat = false );
|
||||
bool load( const String cascadeDirName );
|
||||
bool updateTrainingSet( double& acceptanceRatio );
|
||||
int fillPassedSamples( int first, int count, bool isPositive, int64& consumed );
|
||||
|
||||
void writeParams( FileStorage &fs ) const;
|
||||
void writeStages( FileStorage &fs, const Mat& featureMap ) const;
|
||||
void writeFeatures( FileStorage &fs, const Mat& featureMap ) const;
|
||||
bool readParams( const FileNode &node );
|
||||
bool readStages( const FileNode &node );
|
||||
|
||||
void getUsedFeaturesIdxMap( Mat& featureMap );
|
||||
|
||||
CvCascadeParams cascadeParams;
|
||||
Ptr<CvFeatureParams> featureParams;
|
||||
Ptr<CvCascadeBoostParams> stageParams;
|
||||
|
||||
Ptr<CvFeatureEvaluator> featureEvaluator;
|
||||
vector< Ptr<CvCascadeBoost> > stageClassifiers;
|
||||
CvCascadeImageReader imgReader;
|
||||
int numStages, curNumSamples;
|
||||
int numPos, numNeg;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,90 +0,0 @@
|
||||
#include "traincascade_features.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
float calcNormFactor( const Mat& sum, const Mat& sqSum )
|
||||
{
|
||||
CV_DbgAssert( sum.cols > 3 && sqSum.rows > 3 );
|
||||
Rect normrect( 1, 1, sum.cols - 3, sum.rows - 3 );
|
||||
size_t p0, p1, p2, p3;
|
||||
CV_SUM_OFFSETS( p0, p1, p2, p3, normrect, sum.step1() )
|
||||
double area = normrect.width * normrect.height;
|
||||
const int *sp = (const int*)sum.data;
|
||||
int valSum = sp[p0] - sp[p1] - sp[p2] + sp[p3];
|
||||
const double *sqp = (const double *)sqSum.data;
|
||||
double valSqSum = sqp[p0] - sqp[p1] - sqp[p2] + sqp[p3];
|
||||
return (float) sqrt( (double) (area * valSqSum - (double)valSum * valSum) );
|
||||
}
|
||||
|
||||
CvParams::CvParams() : name( "params" ) {}
|
||||
void CvParams::printDefaults() const
|
||||
{ cout << "--" << name << "--" << endl; }
|
||||
void CvParams::printAttrs() const {}
|
||||
bool CvParams::scanAttr( const String prmName, const String val ) { return false; }
|
||||
|
||||
|
||||
//---------------------------- FeatureParams --------------------------------------
|
||||
|
||||
CvFeatureParams::CvFeatureParams() : maxCatCount( 0 ), featSize( 1 )
|
||||
{
|
||||
name = CC_FEATURE_PARAMS;
|
||||
}
|
||||
|
||||
void CvFeatureParams::init( const CvFeatureParams& fp )
|
||||
{
|
||||
maxCatCount = fp.maxCatCount;
|
||||
featSize = fp.featSize;
|
||||
}
|
||||
|
||||
void CvFeatureParams::write( FileStorage &fs ) const
|
||||
{
|
||||
fs << CC_MAX_CAT_COUNT << maxCatCount;
|
||||
fs << CC_FEATURE_SIZE << featSize;
|
||||
}
|
||||
|
||||
bool CvFeatureParams::read( const FileNode &node )
|
||||
{
|
||||
if ( node.empty() )
|
||||
return false;
|
||||
maxCatCount = node[CC_MAX_CAT_COUNT];
|
||||
featSize = node[CC_FEATURE_SIZE];
|
||||
return ( maxCatCount >= 0 && featSize >= 1 );
|
||||
}
|
||||
|
||||
Ptr<CvFeatureParams> CvFeatureParams::create( int featureType )
|
||||
{
|
||||
return featureType == HAAR ? Ptr<CvFeatureParams>(new CvHaarFeatureParams) :
|
||||
featureType == LBP ? Ptr<CvFeatureParams>(new CvLBPFeatureParams) :
|
||||
featureType == HOG ? Ptr<CvFeatureParams>(new CvHOGFeatureParams) :
|
||||
Ptr<CvFeatureParams>();
|
||||
}
|
||||
|
||||
//------------------------------------- FeatureEvaluator ---------------------------------------
|
||||
|
||||
void CvFeatureEvaluator::init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, Size _winSize )
|
||||
{
|
||||
CV_Assert(_maxSampleCount > 0);
|
||||
featureParams = (CvFeatureParams *)_featureParams;
|
||||
winSize = _winSize;
|
||||
numFeatures = 0;
|
||||
cls.create( (int)_maxSampleCount, 1, CV_32FC1 );
|
||||
generateFeatures();
|
||||
}
|
||||
|
||||
void CvFeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
|
||||
{
|
||||
CV_Assert(img.cols == winSize.width);
|
||||
CV_Assert(img.rows == winSize.height);
|
||||
CV_Assert(idx < cls.rows);
|
||||
cls.ptr<float>(idx)[0] = clsLabel;
|
||||
}
|
||||
|
||||
Ptr<CvFeatureEvaluator> CvFeatureEvaluator::create(int type)
|
||||
{
|
||||
return type == CvFeatureParams::HAAR ? Ptr<CvFeatureEvaluator>(new CvHaarEvaluator) :
|
||||
type == CvFeatureParams::LBP ? Ptr<CvFeatureEvaluator>(new CvLBPEvaluator) :
|
||||
type == CvFeatureParams::HOG ? Ptr<CvFeatureEvaluator>(new CvHOGEvaluator) :
|
||||
Ptr<CvFeatureEvaluator>();
|
||||
}
|
||||
@@ -1,303 +0,0 @@
|
||||
#include "haarfeatures.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC)
|
||||
{
|
||||
name = HFP_NAME;
|
||||
}
|
||||
|
||||
CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode )
|
||||
{
|
||||
name = HFP_NAME;
|
||||
}
|
||||
|
||||
void CvHaarFeatureParams::init( const CvFeatureParams& fp )
|
||||
{
|
||||
CvFeatureParams::init( fp );
|
||||
mode = ((const CvHaarFeatureParams&)fp).mode;
|
||||
}
|
||||
|
||||
void CvHaarFeatureParams::write( FileStorage &fs ) const
|
||||
{
|
||||
CvFeatureParams::write( fs );
|
||||
String modeStr = mode == BASIC ? CC_MODE_BASIC :
|
||||
mode == CORE ? CC_MODE_CORE :
|
||||
mode == ALL ? CC_MODE_ALL : String();
|
||||
CV_Assert( !modeStr.empty() );
|
||||
fs << CC_MODE << modeStr;
|
||||
}
|
||||
|
||||
bool CvHaarFeatureParams::read( const FileNode &node )
|
||||
{
|
||||
if( !CvFeatureParams::read( node ) )
|
||||
return false;
|
||||
|
||||
FileNode rnode = node[CC_MODE];
|
||||
if( !rnode.isString() )
|
||||
return false;
|
||||
String modeStr;
|
||||
rnode >> modeStr;
|
||||
mode = !modeStr.compare( CC_MODE_BASIC ) ? BASIC :
|
||||
!modeStr.compare( CC_MODE_CORE ) ? CORE :
|
||||
!modeStr.compare( CC_MODE_ALL ) ? ALL : -1;
|
||||
return (mode >= 0);
|
||||
}
|
||||
|
||||
void CvHaarFeatureParams::printDefaults() const
|
||||
{
|
||||
CvFeatureParams::printDefaults();
|
||||
cout << " [-mode <" CC_MODE_BASIC << "(default) | "
|
||||
<< CC_MODE_CORE <<" | " << CC_MODE_ALL << endl;
|
||||
}
|
||||
|
||||
void CvHaarFeatureParams::printAttrs() const
|
||||
{
|
||||
CvFeatureParams::printAttrs();
|
||||
String mode_str = mode == BASIC ? CC_MODE_BASIC :
|
||||
mode == CORE ? CC_MODE_CORE :
|
||||
mode == ALL ? CC_MODE_ALL : 0;
|
||||
cout << "mode: " << mode_str << endl;
|
||||
}
|
||||
|
||||
bool CvHaarFeatureParams::scanAttr( const String prmName, const String val)
|
||||
{
|
||||
if ( !CvFeatureParams::scanAttr( prmName, val ) )
|
||||
{
|
||||
if( !prmName.compare("-mode") )
|
||||
{
|
||||
mode = !val.compare( CC_MODE_CORE ) ? CORE :
|
||||
!val.compare( CC_MODE_ALL ) ? ALL :
|
||||
!val.compare( CC_MODE_BASIC ) ? BASIC : -1;
|
||||
if (mode == -1)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------- HaarFeatureEvaluator ----------------
|
||||
|
||||
void CvHaarEvaluator::init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, Size _winSize )
|
||||
{
|
||||
CV_Assert(_maxSampleCount > 0);
|
||||
int cols = (_winSize.width + 1) * (_winSize.height + 1);
|
||||
sum.create((int)_maxSampleCount, cols, CV_32SC1);
|
||||
tilted.create((int)_maxSampleCount, cols, CV_32SC1);
|
||||
normfactor.create(1, (int)_maxSampleCount, CV_32FC1);
|
||||
CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::setImage(const Mat& img, uchar clsLabel, int idx)
|
||||
{
|
||||
CV_DbgAssert( !sum.empty() && !tilted.empty() && !normfactor.empty() );
|
||||
CvFeatureEvaluator::setImage( img, clsLabel, idx);
|
||||
Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr<int>((int)idx));
|
||||
Mat innTilted(winSize.height + 1, winSize.width + 1, tilted.type(), tilted.ptr<int>((int)idx));
|
||||
Mat innSqSum;
|
||||
integral(img, innSum, innSqSum, innTilted);
|
||||
normfactor.ptr<float>(0)[idx] = calcNormFactor( innSum, innSqSum );
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
_writeFeatures( features, fs, featureMap );
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::writeFeature(FileStorage &fs, int fi) const
|
||||
{
|
||||
CV_DbgAssert( fi < (int)features.size() );
|
||||
features[fi].write(fs);
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::generateFeatures()
|
||||
{
|
||||
int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;
|
||||
int offset = winSize.width + 1;
|
||||
for( int x = 0; x < winSize.width; x++ )
|
||||
{
|
||||
for( int y = 0; y < winSize.height; y++ )
|
||||
{
|
||||
for( int dx = 1; dx <= winSize.width; dx++ )
|
||||
{
|
||||
for( int dy = 1; dy <= winSize.height; dy++ )
|
||||
{
|
||||
// haar_x2
|
||||
if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx*2, dy, -1,
|
||||
x+dx, y, dx , dy, +2 ) );
|
||||
}
|
||||
// haar_y2
|
||||
if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx, dy*2, -1,
|
||||
x, y+dy, dx, dy, +2 ) );
|
||||
}
|
||||
// haar_x3
|
||||
if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx*3, dy, -1,
|
||||
x+dx, y, dx , dy, +3 ) );
|
||||
}
|
||||
// haar_y3
|
||||
if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx, dy*3, -1,
|
||||
x, y+dy, dx, dy, +3 ) );
|
||||
}
|
||||
if( mode != CvHaarFeatureParams::BASIC )
|
||||
{
|
||||
// haar_x4
|
||||
if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx*4, dy, -1,
|
||||
x+dx, y, dx*2, dy, +2 ) );
|
||||
}
|
||||
// haar_y4
|
||||
if ( (x+dx <= winSize.width ) && (y+dy*4 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx, dy*4, -1,
|
||||
x, y+dy, dx, dy*2, +2 ) );
|
||||
}
|
||||
}
|
||||
// x2_y2
|
||||
if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx*2, dy*2, -1,
|
||||
x, y, dx, dy, +2,
|
||||
x+dx, y+dy, dx, dy, +2 ) );
|
||||
}
|
||||
if (mode != CvHaarFeatureParams::BASIC)
|
||||
{
|
||||
if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x , y , dx*3, dy*3, -1,
|
||||
x+dx, y+dy, dx , dy , +9) );
|
||||
}
|
||||
}
|
||||
if (mode == CvHaarFeatureParams::ALL)
|
||||
{
|
||||
// tilted haar_x2
|
||||
if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx*2, dy, -1,
|
||||
x, y, dx, dy, +2 ) );
|
||||
}
|
||||
// tilted haar_y2
|
||||
if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx, 2*dy, -1,
|
||||
x, y, dx, dy, +2 ) );
|
||||
}
|
||||
// tilted haar_x3
|
||||
if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx*3, dy, -1,
|
||||
x+dx, y+dx, dx, dy, +3 ) );
|
||||
}
|
||||
// tilted haar_y3
|
||||
if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx, 3*dy, -1,
|
||||
x-dy, y+dy, dx, dy, +3 ) );
|
||||
}
|
||||
// tilted haar_x4
|
||||
if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx*4, dy, -1,
|
||||
x+dx, y+dx, dx*2, dy, +2 ) );
|
||||
}
|
||||
// tilted haar_y4
|
||||
if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx, 4*dy, -1,
|
||||
x-dy, y+dy, dx, 2*dy, +2 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
numFeatures = (int)features.size();
|
||||
}
|
||||
|
||||
CvHaarEvaluator::Feature::Feature()
|
||||
{
|
||||
tilted = false;
|
||||
rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0);
|
||||
rect[0].weight = rect[1].weight = rect[2].weight = 0;
|
||||
}
|
||||
|
||||
CvHaarEvaluator::Feature::Feature( int offset, bool _tilted,
|
||||
int x0, int y0, int w0, int h0, float wt0,
|
||||
int x1, int y1, int w1, int h1, float wt1,
|
||||
int x2, int y2, int w2, int h2, float wt2 )
|
||||
{
|
||||
tilted = _tilted;
|
||||
|
||||
rect[0].r.x = x0;
|
||||
rect[0].r.y = y0;
|
||||
rect[0].r.width = w0;
|
||||
rect[0].r.height = h0;
|
||||
rect[0].weight = wt0;
|
||||
|
||||
rect[1].r.x = x1;
|
||||
rect[1].r.y = y1;
|
||||
rect[1].r.width = w1;
|
||||
rect[1].r.height = h1;
|
||||
rect[1].weight = wt1;
|
||||
|
||||
rect[2].r.x = x2;
|
||||
rect[2].r.y = y2;
|
||||
rect[2].r.width = w2;
|
||||
rect[2].r.height = h2;
|
||||
rect[2].weight = wt2;
|
||||
|
||||
if( !tilted )
|
||||
{
|
||||
for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
|
||||
{
|
||||
if( rect[j].weight == 0.0F )
|
||||
break;
|
||||
CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
|
||||
{
|
||||
if( rect[j].weight == 0.0F )
|
||||
break;
|
||||
CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::Feature::write( FileStorage &fs ) const
|
||||
{
|
||||
fs << CC_RECTS << "[";
|
||||
for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri )
|
||||
{
|
||||
fs << "[:" << rect[ri].r.x << rect[ri].r.y <<
|
||||
rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]";
|
||||
}
|
||||
fs << "]" << CC_TILTED << tilted;
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
#ifndef _OPENCV_HAARFEATURES_H_
|
||||
#define _OPENCV_HAARFEATURES_H_
|
||||
|
||||
#include "traincascade_features.h"
|
||||
|
||||
#define CV_HAAR_FEATURE_MAX 3
|
||||
|
||||
#define HFP_NAME "haarFeatureParams"
|
||||
class CvHaarFeatureParams : public CvFeatureParams
|
||||
{
|
||||
public:
|
||||
enum { BASIC = 0, CORE = 1, ALL = 2 };
|
||||
/* 0 - BASIC = Viola
|
||||
* 1 - CORE = All upright
|
||||
* 2 - ALL = All features */
|
||||
|
||||
CvHaarFeatureParams();
|
||||
CvHaarFeatureParams( int _mode );
|
||||
|
||||
virtual void init( const CvFeatureParams& fp );
|
||||
virtual void write( FileStorage &fs ) const;
|
||||
virtual bool read( const FileNode &node );
|
||||
|
||||
virtual void printDefaults() const;
|
||||
virtual void printAttrs() const;
|
||||
virtual bool scanAttr( const String prm, const String val);
|
||||
|
||||
int mode;
|
||||
};
|
||||
|
||||
class CvHaarEvaluator : public CvFeatureEvaluator
|
||||
{
|
||||
public:
|
||||
virtual void init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, Size _winSize );
|
||||
virtual void setImage(const Mat& img, uchar clsLabel, int idx);
|
||||
virtual float operator()(int featureIdx, int sampleIdx) const;
|
||||
virtual void writeFeatures( FileStorage &fs, const Mat& featureMap ) const;
|
||||
void writeFeature( FileStorage &fs, int fi ) const; // for old file fornat
|
||||
protected:
|
||||
virtual void generateFeatures();
|
||||
|
||||
class Feature
|
||||
{
|
||||
public:
|
||||
Feature();
|
||||
Feature( int offset, bool _tilted,
|
||||
int x0, int y0, int w0, int h0, float wt0,
|
||||
int x1, int y1, int w1, int h1, float wt1,
|
||||
int x2 = 0, int y2 = 0, int w2 = 0, int h2 = 0, float wt2 = 0.0F );
|
||||
float calc( const Mat &sum, const Mat &tilted, size_t y) const;
|
||||
void write( FileStorage &fs ) const;
|
||||
|
||||
bool tilted;
|
||||
struct
|
||||
{
|
||||
Rect r;
|
||||
float weight;
|
||||
} rect[CV_HAAR_FEATURE_MAX];
|
||||
|
||||
struct
|
||||
{
|
||||
int p0, p1, p2, p3;
|
||||
} fastRect[CV_HAAR_FEATURE_MAX];
|
||||
};
|
||||
|
||||
vector<Feature> features;
|
||||
Mat sum; /* sum images (each row represents image) */
|
||||
Mat tilted; /* tilted sum images (each row represents image) */
|
||||
Mat normfactor; /* normalization factor */
|
||||
};
|
||||
|
||||
inline float CvHaarEvaluator::operator()(int featureIdx, int sampleIdx) const
|
||||
{
|
||||
float nf = normfactor.at<float>(0, sampleIdx);
|
||||
return !nf ? 0.0f : (features[featureIdx].calc( sum, tilted, sampleIdx)/nf);
|
||||
}
|
||||
|
||||
inline float CvHaarEvaluator::Feature::calc( const Mat &_sum, const Mat &_tilted, size_t y) const
|
||||
{
|
||||
const int* img = tilted ? _tilted.ptr<int>((int)y) : _sum.ptr<int>((int)y);
|
||||
float ret = rect[0].weight * (img[fastRect[0].p0] - img[fastRect[0].p1] - img[fastRect[0].p2] + img[fastRect[0].p3] ) +
|
||||
rect[1].weight * (img[fastRect[1].p0] - img[fastRect[1].p1] - img[fastRect[1].p2] + img[fastRect[1].p3] );
|
||||
if( rect[2].weight != 0.0f )
|
||||
ret += rect[2].weight * (img[fastRect[2].p0] - img[fastRect[2].p1] - img[fastRect[2].p2] + img[fastRect[2].p3] );
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,179 +0,0 @@
|
||||
#include "cv.h"
|
||||
#include "imagestorage.h"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
bool CvCascadeImageReader::create( const String _posFilename, const String _negFilename, Size _winSize )
|
||||
{
|
||||
return posReader.create(_posFilename) && negReader.create(_negFilename, _winSize);
|
||||
}
|
||||
|
||||
CvCascadeImageReader::NegReader::NegReader()
|
||||
{
|
||||
src.create( 0, 0 , CV_8UC1 );
|
||||
img.create( 0, 0, CV_8UC1 );
|
||||
point = offset = Point( 0, 0 );
|
||||
scale = 1.0F;
|
||||
scaleFactor = 1.4142135623730950488016887242097F;
|
||||
stepFactor = 0.5F;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::NegReader::create( const String _filename, Size _winSize )
|
||||
{
|
||||
String dirname, str;
|
||||
std::ifstream file(_filename.c_str());
|
||||
if ( !file.is_open() )
|
||||
return false;
|
||||
|
||||
size_t pos = _filename.rfind('\\');
|
||||
char dlmrt = '\\';
|
||||
if (pos == String::npos)
|
||||
{
|
||||
pos = _filename.rfind('/');
|
||||
dlmrt = '/';
|
||||
}
|
||||
dirname = pos == String::npos ? "" : _filename.substr(0, pos) + dlmrt;
|
||||
while( !file.eof() )
|
||||
{
|
||||
std::getline(file, str);
|
||||
if (str.empty()) break;
|
||||
if (str.at(0) == '#' ) continue; /* comment */
|
||||
imgFilenames.push_back(dirname + str);
|
||||
}
|
||||
file.close();
|
||||
|
||||
winSize = _winSize;
|
||||
last = round = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::NegReader::nextImg()
|
||||
{
|
||||
Point _offset = Point(0,0);
|
||||
size_t count = imgFilenames.size();
|
||||
for( size_t i = 0; i < count; i++ )
|
||||
{
|
||||
src = imread( imgFilenames[last++], 0 );
|
||||
if( src.empty() )
|
||||
continue;
|
||||
round += last / count;
|
||||
round = round % (winSize.width * winSize.height);
|
||||
last %= count;
|
||||
|
||||
_offset.x = min( (int)round % winSize.width, src.cols - winSize.width );
|
||||
_offset.y = min( (int)round / winSize.width, src.rows - winSize.height );
|
||||
if( !src.empty() && src.type() == CV_8UC1
|
||||
&& offset.x >= 0 && offset.y >= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if( src.empty() )
|
||||
return false; // no appropriate image
|
||||
point = offset = _offset;
|
||||
scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
|
||||
((float)winSize.height + point.y) / ((float)src.rows) );
|
||||
|
||||
Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
|
||||
resize( src, img, sz );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::NegReader::get( Mat& _img )
|
||||
{
|
||||
CV_Assert( !_img.empty() );
|
||||
CV_Assert( _img.type() == CV_8UC1 );
|
||||
CV_Assert( _img.cols == winSize.width );
|
||||
CV_Assert( _img.rows == winSize.height );
|
||||
|
||||
if( img.empty() )
|
||||
if ( !nextImg() )
|
||||
return false;
|
||||
|
||||
Mat mat( winSize.height, winSize.width, CV_8UC1,
|
||||
(void*)(img.data + point.y * img.step + point.x * img.elemSize()), img.step );
|
||||
mat.copyTo(_img);
|
||||
|
||||
if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
|
||||
point.x += (int)(stepFactor * winSize.width);
|
||||
else
|
||||
{
|
||||
point.x = offset.x;
|
||||
if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )
|
||||
point.y += (int)(stepFactor * winSize.height);
|
||||
else
|
||||
{
|
||||
point.y = offset.y;
|
||||
scale *= scaleFactor;
|
||||
if( scale <= 1.0F )
|
||||
resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ) );
|
||||
else
|
||||
{
|
||||
if ( !nextImg() )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CvCascadeImageReader::PosReader::PosReader()
|
||||
{
|
||||
file = 0;
|
||||
vec = 0;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::PosReader::create( const String _filename )
|
||||
{
|
||||
if ( file )
|
||||
fclose( file );
|
||||
file = fopen( _filename.c_str(), "rb" );
|
||||
|
||||
if( !file )
|
||||
return false;
|
||||
short tmp = 0;
|
||||
if( fread( &count, sizeof( count ), 1, file ) != 1 ||
|
||||
fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||
|
||||
fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||
|
||||
fread( &tmp, sizeof( tmp ), 1, file ) != 1 )
|
||||
CV_Error_( CV_StsParseError, ("wrong file format for %s\n", _filename.c_str()) );
|
||||
base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp );
|
||||
if( feof( file ) )
|
||||
return false;
|
||||
last = 0;
|
||||
vec = (short*) cvAlloc( sizeof( *vec ) * vecSize );
|
||||
CV_Assert( vec );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::PosReader::get( Mat &_img )
|
||||
{
|
||||
CV_Assert( _img.rows * _img.cols == vecSize );
|
||||
uchar tmp = 0;
|
||||
fread( &tmp, sizeof( tmp ), 1, file );
|
||||
fread( vec, sizeof( vec[0] ), vecSize, file );
|
||||
|
||||
if( feof( file ) || last++ >= count )
|
||||
return false;
|
||||
|
||||
for( int r = 0; r < _img.rows; r++ )
|
||||
{
|
||||
for( int c = 0; c < _img.cols; c++ )
|
||||
_img.ptr(r)[c] = (uchar)vec[r * _img.cols + c];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CvCascadeImageReader::PosReader::restart()
|
||||
{
|
||||
CV_Assert( file );
|
||||
last = 0;
|
||||
fseek( file, base, SEEK_SET );
|
||||
}
|
||||
|
||||
CvCascadeImageReader::PosReader::~PosReader()
|
||||
{
|
||||
if (file)
|
||||
fclose( file );
|
||||
cvFree( &vec );
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
#ifndef _OPENCV_IMAGESTORAGE_H_
|
||||
#define _OPENCV_IMAGESTORAGE_H_
|
||||
|
||||
#include "highgui.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
class CvCascadeImageReader
|
||||
{
|
||||
public:
|
||||
bool create( const String _posFilename, const String _negFilename, Size _winSize );
|
||||
void restart() { posReader.restart(); }
|
||||
bool getNeg(Mat &_img) { return negReader.get( _img ); }
|
||||
bool getPos(Mat &_img) { return posReader.get( _img ); }
|
||||
|
||||
private:
|
||||
class PosReader
|
||||
{
|
||||
public:
|
||||
PosReader();
|
||||
virtual ~PosReader();
|
||||
bool create( const String _filename );
|
||||
bool get( Mat &_img );
|
||||
void restart();
|
||||
|
||||
short* vec;
|
||||
FILE* file;
|
||||
int count;
|
||||
int vecSize;
|
||||
int last;
|
||||
int base;
|
||||
} posReader;
|
||||
|
||||
class NegReader
|
||||
{
|
||||
public:
|
||||
NegReader();
|
||||
bool create( const String _filename, Size _winSize );
|
||||
bool get( Mat& _img );
|
||||
bool nextImg();
|
||||
|
||||
Mat src, img;
|
||||
vector<String> imgFilenames;
|
||||
Point offset, point;
|
||||
float scale;
|
||||
float scaleFactor;
|
||||
float stepFactor;
|
||||
size_t last, round;
|
||||
Size winSize;
|
||||
} negReader;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "lbpfeatures.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
CvLBPFeatureParams::CvLBPFeatureParams()
|
||||
{
|
||||
maxCatCount = 256;
|
||||
name = LBPF_NAME;
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::init(const CvFeatureParams *_featureParams, int _maxSampleCount, Size _winSize)
|
||||
{
|
||||
CV_Assert( _maxSampleCount > 0);
|
||||
sum.create((int)_maxSampleCount, (_winSize.width + 1) * (_winSize.height + 1), CV_32SC1);
|
||||
CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
|
||||
{
|
||||
CV_DbgAssert( !sum.empty() );
|
||||
CvFeatureEvaluator::setImage( img, clsLabel, idx );
|
||||
Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr<int>((int)idx));
|
||||
integral( img, innSum );
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
_writeFeatures( features, fs, featureMap );
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::generateFeatures()
|
||||
{
|
||||
int offset = winSize.width + 1;
|
||||
for( int x = 0; x < winSize.width; x++ )
|
||||
for( int y = 0; y < winSize.height; y++ )
|
||||
for( int w = 1; w <= winSize.width / 3; w++ )
|
||||
for( int h = 1; h <= winSize.height / 3; h++ )
|
||||
if ( (x+3*w <= winSize.width) && (y+3*h <= winSize.height) )
|
||||
features.push_back( Feature(offset, x, y, w, h ) );
|
||||
numFeatures = (int)features.size();
|
||||
}
|
||||
|
||||
CvLBPEvaluator::Feature::Feature()
|
||||
{
|
||||
rect = cvRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
CvLBPEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight )
|
||||
{
|
||||
Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight);
|
||||
CV_SUM_OFFSETS( p[0], p[1], p[4], p[5], tr, offset )
|
||||
tr.x += 2*rect.width;
|
||||
CV_SUM_OFFSETS( p[2], p[3], p[6], p[7], tr, offset )
|
||||
tr.y +=2*rect.height;
|
||||
CV_SUM_OFFSETS( p[10], p[11], p[14], p[15], tr, offset )
|
||||
tr.x -= 2*rect.width;
|
||||
CV_SUM_OFFSETS( p[8], p[9], p[12], p[13], tr, offset )
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::Feature::write(FileStorage &fs) const
|
||||
{
|
||||
fs << CC_RECT << "[:" << rect.x << rect.y << rect.width << rect.height << "]";
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#ifndef _OPENCV_LBPFEATURES_H_
|
||||
#define _OPENCV_LBPFEATURES_H_
|
||||
|
||||
#include "traincascade_features.h"
|
||||
|
||||
#define LBPF_NAME "lbpFeatureParams"
|
||||
struct CvLBPFeatureParams : CvFeatureParams
|
||||
{
|
||||
CvLBPFeatureParams();
|
||||
|
||||
};
|
||||
|
||||
class CvLBPEvaluator : public CvFeatureEvaluator
|
||||
{
|
||||
public:
|
||||
virtual ~CvLBPEvaluator() {}
|
||||
virtual void init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, Size _winSize );
|
||||
virtual void setImage(const Mat& img, uchar clsLabel, int idx);
|
||||
virtual float operator()(int featureIdx, int sampleIdx) const
|
||||
{ return (float)features[featureIdx].calc( sum, sampleIdx); }
|
||||
virtual void writeFeatures( FileStorage &fs, const Mat& featureMap ) const;
|
||||
protected:
|
||||
virtual void generateFeatures();
|
||||
|
||||
class Feature
|
||||
{
|
||||
public:
|
||||
Feature();
|
||||
Feature( int offset, int x, int y, int _block_w, int _block_h );
|
||||
uchar calc( const Mat& _sum, size_t y ) const;
|
||||
void write( FileStorage &fs ) const;
|
||||
|
||||
Rect rect;
|
||||
int p[16];
|
||||
};
|
||||
vector<Feature> features;
|
||||
|
||||
Mat sum;
|
||||
};
|
||||
|
||||
inline uchar CvLBPEvaluator::Feature::calc(const Mat &_sum, size_t y) const
|
||||
{
|
||||
const int* sum = _sum.ptr<int>((int)y);
|
||||
int cval = sum[p[5]] - sum[p[6]] - sum[p[9]] + sum[p[10]];
|
||||
|
||||
return (uchar)((sum[p[0]] - sum[p[1]] - sum[p[4]] + sum[p[5]] >= cval ? 128 : 0) | // 0
|
||||
(sum[p[1]] - sum[p[2]] - sum[p[5]] + sum[p[6]] >= cval ? 64 : 0) | // 1
|
||||
(sum[p[2]] - sum[p[3]] - sum[p[6]] + sum[p[7]] >= cval ? 32 : 0) | // 2
|
||||
(sum[p[6]] - sum[p[7]] - sum[p[10]] + sum[p[11]] >= cval ? 16 : 0) | // 5
|
||||
(sum[p[10]] - sum[p[11]] - sum[p[14]] + sum[p[15]] >= cval ? 8 : 0) | // 8
|
||||
(sum[p[9]] - sum[p[10]] - sum[p[13]] + sum[p[14]] >= cval ? 4 : 0) | // 7
|
||||
(sum[p[8]] - sum[p[9]] - sum[p[12]] + sum[p[13]] >= cval ? 2 : 0) | // 6
|
||||
(sum[p[4]] - sum[p[5]] - sum[p[8]] + sum[p[9]] >= cval ? 1 : 0)); // 3
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,109 +0,0 @@
|
||||
#include "cv.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
CvCascadeClassifier classifier;
|
||||
String cascadeDirName, vecName, bgName;
|
||||
int numPos = 2000;
|
||||
int numNeg = 1000;
|
||||
int numStages = 20;
|
||||
int precalcValBufSize = 256,
|
||||
precalcIdxBufSize = 256;
|
||||
bool baseFormatSave = false;
|
||||
|
||||
CvCascadeParams cascadeParams;
|
||||
CvCascadeBoostParams stageParams;
|
||||
Ptr<CvFeatureParams> featureParams[] = { Ptr<CvFeatureParams>(new CvHaarFeatureParams),
|
||||
Ptr<CvFeatureParams>(new CvLBPFeatureParams),
|
||||
Ptr<CvFeatureParams>(new CvHOGFeatureParams)
|
||||
};
|
||||
int fc = sizeof(featureParams)/sizeof(featureParams[0]);
|
||||
if( argc == 1 )
|
||||
{
|
||||
cout << "Usage: " << argv[0] << endl;
|
||||
cout << " -data <cascade_dir_name>" << endl;
|
||||
cout << " -vec <vec_file_name>" << endl;
|
||||
cout << " -bg <background_file_name>" << endl;
|
||||
cout << " [-numPos <number_of_positive_samples = " << numPos << ">]" << endl;
|
||||
cout << " [-numNeg <number_of_negative_samples = " << numNeg << ">]" << endl;
|
||||
cout << " [-numStages <number_of_stages = " << numStages << ">]" << endl;
|
||||
cout << " [-precalcValBufSize <precalculated_vals_buffer_size_in_Mb = " << precalcValBufSize << ">]" << endl;
|
||||
cout << " [-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb = " << precalcIdxBufSize << ">]" << endl;
|
||||
cout << " [-baseFormatSave]" << endl;
|
||||
cascadeParams.printDefaults();
|
||||
stageParams.printDefaults();
|
||||
for( int fi = 0; fi < fc; fi++ )
|
||||
featureParams[fi]->printDefaults();
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( int i = 1; i < argc; i++ )
|
||||
{
|
||||
bool set = false;
|
||||
if( !strcmp( argv[i], "-data" ) )
|
||||
{
|
||||
cascadeDirName = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-vec" ) )
|
||||
{
|
||||
vecName = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg" ) )
|
||||
{
|
||||
bgName = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-numPos" ) )
|
||||
{
|
||||
numPos = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-numNeg" ) )
|
||||
{
|
||||
numNeg = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-numStages" ) )
|
||||
{
|
||||
numStages = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-precalcValBufSize" ) )
|
||||
{
|
||||
precalcValBufSize = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-precalcIdxBufSize" ) )
|
||||
{
|
||||
precalcIdxBufSize = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-baseFormatSave" ) )
|
||||
{
|
||||
baseFormatSave = true;
|
||||
}
|
||||
else if ( cascadeParams.scanAttr( argv[i], argv[i+1] ) ) { i++; }
|
||||
else if ( stageParams.scanAttr( argv[i], argv[i+1] ) ) { i++; }
|
||||
else if ( !set )
|
||||
{
|
||||
for( int fi = 0; fi < fc; fi++ )
|
||||
{
|
||||
set = featureParams[fi]->scanAttr(argv[i], argv[i+1]);
|
||||
if ( !set )
|
||||
{
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
classifier.train( cascadeDirName,
|
||||
vecName,
|
||||
bgName,
|
||||
numPos, numNeg,
|
||||
precalcValBufSize, precalcIdxBufSize,
|
||||
numStages,
|
||||
cascadeParams,
|
||||
*featureParams[cascadeParams.featureType],
|
||||
stageParams,
|
||||
baseFormatSave );
|
||||
return 0;
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
#ifndef _OPENCV_FEATURES_H_
|
||||
#define _OPENCV_FEATURES_H_
|
||||
|
||||
#include "imagestorage.h"
|
||||
#include "cxcore.h"
|
||||
#include "cv.h"
|
||||
#include "ml.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define FEATURES "features"
|
||||
|
||||
#define CV_SUM_OFFSETS( p0, p1, p2, p3, rect, step ) \
|
||||
/* (x, y) */ \
|
||||
(p0) = (rect).x + (step) * (rect).y; \
|
||||
/* (x + w, y) */ \
|
||||
(p1) = (rect).x + (rect).width + (step) * (rect).y; \
|
||||
/* (x + w, y) */ \
|
||||
(p2) = (rect).x + (step) * ((rect).y + (rect).height); \
|
||||
/* (x + w, y + h) */ \
|
||||
(p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height);
|
||||
|
||||
#define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step ) \
|
||||
/* (x, y) */ \
|
||||
(p0) = (rect).x + (step) * (rect).y; \
|
||||
/* (x - h, y + h) */ \
|
||||
(p1) = (rect).x - (rect).height + (step) * ((rect).y + (rect).height);\
|
||||
/* (x + w, y + w) */ \
|
||||
(p2) = (rect).x + (rect).width + (step) * ((rect).y + (rect).width); \
|
||||
/* (x + w - h, y + w + h) */ \
|
||||
(p3) = (rect).x + (rect).width - (rect).height \
|
||||
+ (step) * ((rect).y + (rect).width + (rect).height);
|
||||
|
||||
float calcNormFactor( const Mat& sum, const Mat& sqSum );
|
||||
|
||||
template<class Feature>
|
||||
void _writeFeatures( const vector<Feature> features, FileStorage &fs, const Mat& featureMap )
|
||||
{
|
||||
fs << FEATURES << "[";
|
||||
const Mat_<int>& featureMap_ = (const Mat_<int>&)featureMap;
|
||||
for ( int fi = 0; fi < featureMap.cols; fi++ )
|
||||
if ( featureMap_(0, fi) >= 0 )
|
||||
{
|
||||
fs << "{";
|
||||
features[fi].write( fs );
|
||||
fs << "}";
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
|
||||
class CvParams
|
||||
{
|
||||
public:
|
||||
CvParams();
|
||||
virtual ~CvParams() {}
|
||||
// from|to file
|
||||
virtual void write( FileStorage &fs ) const = 0;
|
||||
virtual bool read( const FileNode &node ) = 0;
|
||||
// from|to screen
|
||||
virtual void printDefaults() const;
|
||||
virtual void printAttrs() const;
|
||||
virtual bool scanAttr( const String prmName, const String val );
|
||||
String name;
|
||||
};
|
||||
|
||||
class CvFeatureParams : public CvParams
|
||||
{
|
||||
public:
|
||||
enum { HAAR = 0, LBP = 1, HOG = 2 };
|
||||
CvFeatureParams();
|
||||
virtual void init( const CvFeatureParams& fp );
|
||||
virtual void write( FileStorage &fs ) const;
|
||||
virtual bool read( const FileNode &node );
|
||||
static Ptr<CvFeatureParams> create( int featureType );
|
||||
int maxCatCount; // 0 in case of numerical features
|
||||
int featSize; // 1 in case of simple features (HAAR, LBP) and N_BINS(9)*N_CELLS(4) in case of Dalal's HOG features
|
||||
};
|
||||
|
||||
class CvFeatureEvaluator
|
||||
{
|
||||
public:
|
||||
virtual ~CvFeatureEvaluator() {}
|
||||
virtual void init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, Size _winSize );
|
||||
virtual void setImage(const Mat& img, uchar clsLabel, int idx);
|
||||
virtual void writeFeatures( FileStorage &fs, const Mat& featureMap ) const = 0;
|
||||
virtual float operator()(int featureIdx, int sampleIdx) const = 0;
|
||||
static Ptr<CvFeatureEvaluator> create(int type);
|
||||
|
||||
int getNumFeatures() const { return numFeatures; }
|
||||
int getMaxCatCount() const { return featureParams->maxCatCount; }
|
||||
int getFeatureSize() const { return featureParams->featSize; }
|
||||
const Mat& getCls() const { return cls; }
|
||||
float getCls(int si) const { return cls.at<float>(si, 0); }
|
||||
protected:
|
||||
virtual void generateFeatures() = 0;
|
||||
|
||||
int npos, nneg;
|
||||
int numFeatures;
|
||||
Size winSize;
|
||||
CvFeatureParams *featureParams;
|
||||
Mat cls;
|
||||
};
|
||||
|
||||
#endif
|
||||
+23
-15
@@ -1,16 +1,24 @@
|
||||
if(BUILD_TESTS OR BUILD_PERF_TESTS)
|
||||
if(BUILD_SHARED_LIBS AND NOT MINGW)
|
||||
add_definitions(-DGTEST_CREATE_SHARED_LIBRARY=1)
|
||||
if (MSVC)
|
||||
add_definitions( "/wd4251 /wd4275")
|
||||
endif()
|
||||
else()
|
||||
add_definitions(-DGTEST_CREATE_SHARED_LIBRARY=0)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
set(OPENCV_TS_MODULE_TYPE STATIC)
|
||||
endif()
|
||||
|
||||
define_opencv_module(ts opencv_core)
|
||||
if(IOS)
|
||||
ocv_module_disable(ts)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
set(OPENCV_MODULE_TYPE STATIC)
|
||||
endif()
|
||||
|
||||
set(the_description "The ts module")
|
||||
ocv_add_module(ts opencv_core)
|
||||
ocv_glob_module_sources()
|
||||
ocv_module_include_directories()
|
||||
ocv_create_module()
|
||||
|
||||
if(BUILD_SHARED_LIBS AND NOT MINGW)
|
||||
add_definitions(-DGTEST_CREATE_SHARED_LIBRARY=1)
|
||||
if (MSVC)
|
||||
add_definitions( "/wd4251 /wd4275")
|
||||
endif()
|
||||
else()
|
||||
add_definitions(-DGTEST_CREATE_SHARED_LIBRARY=0)
|
||||
endif()
|
||||
|
||||
ocv_add_precompiled_headers(${the_module})
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
define_opencv_module(video opencv_core opencv_imgproc)
|
||||
set(the_description "Video Analysis")
|
||||
ocv_define_module(video opencv_imgproc)
|
||||
|
||||
Reference in New Issue
Block a user