Compare commits
414 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b38c50b3d0 | |||
| dd06540e1f | |||
| 50b61668e2 | |||
| 1df84f7246 | |||
| bdc34984f1 | |||
| af0c930e77 | |||
| bb45bf9695 | |||
| 4e0d2a3e6c | |||
| da6d8961fc | |||
| 3e027df583 | |||
| 6477262e63 | |||
| f79599f949 | |||
| c94d75874b | |||
| 21f3987d53 | |||
| d10a219833 | |||
| bd7bf39b4b | |||
| 472b71ecef | |||
| 4f360f8b1a | |||
| e8d45a9cdd | |||
| ff2eface19 | |||
| 29ce348c4d | |||
| b2a4069f55 | |||
| 4d78342919 | |||
| 1272332ae3 | |||
| b47c9ac643 | |||
| 1c20a7f008 | |||
| 6700fdb81f | |||
| 096366738b | |||
| 6a6506b02d | |||
| 59ccf2c9e0 | |||
| 2c42361ecd | |||
| 18833d5121 | |||
| f25450791b | |||
| c9faa09d55 | |||
| 1deeca985f | |||
| 6acabd1fd8 | |||
| 5ac9a2a7d0 | |||
| 808c89adc1 | |||
| a527e8cc73 | |||
| 10c570b558 | |||
| 76f47548b3 | |||
| 67d46dfc6c | |||
| 3c03fb56e0 | |||
| 378cf2ab63 | |||
| c6f5b013ec | |||
| e593d5bbc5 | |||
| 3f5c3ddd27 | |||
| ab8ba047a5 | |||
| cecc19381f | |||
| 6e84abc746 | |||
| 322c6b1ba4 | |||
| 73d44c7881 | |||
| 31fef14d76 | |||
| 7ee69740e8 | |||
| c61bc3a0cb | |||
| b24fc6954d | |||
| 828cb4286d | |||
| ee5e0e16d9 | |||
| b907bfe3e7 | |||
| f84eb3dde6 | |||
| b996b618e0 | |||
| 98c5ce9347 | |||
| f89defad5d | |||
| 96f92c6705 | |||
| f0c46a4c74 | |||
| 9752d45c87 | |||
| 860ae77ec9 | |||
| 1567a65475 | |||
| d2e08a524e | |||
| c1df9ad456 | |||
| 781721ca50 | |||
| b9b66ca437 | |||
| 22cb65ada9 | |||
| 90b8a03a89 | |||
| f056c0f137 | |||
| 49e0126b8e | |||
| a24a829490 | |||
| 615883977f | |||
| 216cd7dc61 | |||
| 4910f16f16 | |||
| f2d363feb2 | |||
| 8b2122e12f | |||
| f16f818f5f | |||
| 5b3ac112fe | |||
| a0cff0be94 | |||
| 509de3fa2c | |||
| b00758babe | |||
| 9f2edc1135 | |||
| a56b221559 | |||
| fb2b26c419 | |||
| 377e51df83 | |||
| 7453a6938a | |||
| 39f5e57321 | |||
| f49f6d52b4 | |||
| 715f23127c | |||
| f0f652f9e9 | |||
| 731aa963bd | |||
| 7e353a1ec5 | |||
| 4fe900c399 | |||
| 5c3880d302 | |||
| 9eaa583bfb | |||
| 6500700d6f | |||
| f95a411ba3 | |||
| 7c8ab271fc | |||
| 70b893333d | |||
| 449696f1e5 | |||
| e0c93bcf6c | |||
| 23022f3ffb | |||
| ac4a6aad15 | |||
| 7d7767ba42 | |||
| 183cfd3a2e | |||
| 9cb3e9abf0 | |||
| b4cea8d6d1 | |||
| 8f57fc93ec | |||
| 9ff4475695 | |||
| 1c73e66edf | |||
| 061149cbbd | |||
| a2daf0c83c | |||
| 2dbb5871e0 | |||
| be08730cd6 | |||
| 3082ea82f9 | |||
| 5131619a1a | |||
| b056ce33aa | |||
| df9efbbd1f | |||
| f2e1710dd5 | |||
| 05830874d7 | |||
| 4fb086d6c3 | |||
| 3ea2586a5a | |||
| 2df0345985 | |||
| 47e3e89e30 | |||
| 3f302cabb8 | |||
| 8e034053af | |||
| 67f79aabdd | |||
| 5aceee5a36 | |||
| 1e1a1855ae | |||
| 2003eb1b9b | |||
| 17196bb4fa | |||
| 7e71b1079e | |||
| 814ebe39ae | |||
| 61c870ae09 | |||
| 6949bc9ef9 | |||
| 7cf52de47e | |||
| 9433784e47 | |||
| ed0e79cb61 | |||
| bb82cdc928 | |||
| db8585701d | |||
| 28d0e97c09 | |||
| 5d12c070ea | |||
| 5bde800ee3 | |||
| 29a1dc5719 | |||
| dbf3362c4d | |||
| c4e0f4b2b5 | |||
| e90e398e7a | |||
| 4937eeddb5 | |||
| 2988260107 | |||
| 83039c8752 | |||
| 6499263b41 | |||
| 80cab4a163 | |||
| 47202b3349 | |||
| 9076bb6089 | |||
| 89528d7c3a | |||
| 0bef42ba12 | |||
| b41bc0ae59 | |||
| fb1f12021b | |||
| dd8e990451 | |||
| e031bada7d | |||
| 2b7ff90e63 | |||
| b597c87bed | |||
| 0aded5aae6 | |||
| a8e9a3a88d | |||
| 2f0fc920dd | |||
| 9137e2d635 | |||
| c37d1a53b5 | |||
| 1165fdd0f5 | |||
| 597db69151 | |||
| 9eb79926df | |||
| fa466b022d | |||
| 43820d89b4 | |||
| faa6c4e1e1 | |||
| dd8701c1a0 | |||
| 74cf48b5d7 | |||
| 45b5b3c13a | |||
| 5336b9ad19 | |||
| a16254de2b | |||
| 8a2ce75d96 | |||
| 9c7040802c | |||
| cbb1e867e5 | |||
| 8de08e0463 | |||
| 236f383969 | |||
| 93abdbf25e | |||
| 8f80565d9c | |||
| 391b9586ac | |||
| 4283309daa | |||
| 6e767e2376 | |||
| 0c4d5ffecd | |||
| 28e08ae0bd | |||
| e0603bb45f | |||
| 7d40fcead5 | |||
| 8c7555523b | |||
| b117302bca | |||
| e1205d046a | |||
| dadde75ef0 | |||
| ee743afebe | |||
| 767b31cfbf | |||
| 18abe54497 | |||
| 05f0cb16de | |||
| a4060e15a4 | |||
| 7198b9e461 | |||
| ab9b6e806c | |||
| 270cc3bcbc | |||
| c213a3823e | |||
| 51074b9743 | |||
| 070393dfda | |||
| f4df537e27 | |||
| 905da2994a | |||
| e526c4bfe4 | |||
| fe806878be | |||
| a2a9a01e05 | |||
| 6c4f618db5 | |||
| f3ee07ca11 | |||
| 7cc84ce8ab | |||
| 40b8ca2eed | |||
| 4dcef28023 | |||
| 0a41b3df45 | |||
| f086fc5b18 | |||
| c473718bc2 | |||
| 1da46fe6fb | |||
| 5b72e83687 | |||
| 78d07e841d | |||
| f38808a39f | |||
| 540415dc5e | |||
| f0cadaa6e3 | |||
| f058b5fb1e | |||
| 481829a81b | |||
| c9439476da | |||
| 60994389a6 | |||
| b0ee5d9023 | |||
| 84f2f37680 | |||
| d5951bc033 | |||
| a5e8ae2183 | |||
| 1dec480974 | |||
| d6c669f5cf | |||
| 014ae55379 | |||
| 53eb27f508 | |||
| 4a3dfffd46 | |||
| 50751ae6ff | |||
| 10676f86d5 | |||
| dee5f9a67b | |||
| 2b6aa50b81 | |||
| 3c74fde349 | |||
| 6eb8faea85 | |||
| 23fc96e98f | |||
| abceae1ac0 | |||
| eed1130327 | |||
| 41b95cae38 | |||
| de6f0a537d | |||
| 4dc7e617a4 | |||
| 0155851929 | |||
| 71c6cb9c22 | |||
| 2170811e48 | |||
| 9d8495f8b3 | |||
| 5385086fef | |||
| dcc1beb1f8 | |||
| e38ea3a888 | |||
| 33b7028be2 | |||
| 850a8577b2 | |||
| e79c729b20 | |||
| 625d20b9b4 | |||
| 1c75f3d037 | |||
| 9c3ec05825 | |||
| 875f23881f | |||
| d0a3686812 | |||
| c9fe6f1afe | |||
| 2508f7f971 | |||
| 8b5f061dae | |||
| 999aba3807 | |||
| 82c7ab0231 | |||
| 4c5a86828a | |||
| a7b502f04a | |||
| e4b5e9b9c9 | |||
| e9bb26267e | |||
| d7bd662c95 | |||
| 452fa3011c | |||
| d57e5406f0 | |||
| 7fe0727930 | |||
| 529d38613b | |||
| 88d56dc700 | |||
| 7ba66a1682 | |||
| b6255ab9e7 | |||
| 924ff903ad | |||
| e2b5d11290 | |||
| e41f19d2f3 | |||
| 52b151dceb | |||
| 362d4f5395 | |||
| a29d11240e | |||
| 61d8719b8d | |||
| 0fd74fa177 | |||
| 45677819e8 | |||
| e14b2ba43c | |||
| 81325a3fa0 | |||
| aa0c6ddb4c | |||
| 5e6a3f1f6c | |||
| 523b6f32ba | |||
| fc59498b2b | |||
| 3b01777c98 | |||
| aa10cdbfa2 | |||
| 06fc77610b | |||
| 019c2f2115 | |||
| 4bc080dc50 | |||
| c7fc563dc0 | |||
| 0bb2c115aa | |||
| ccd2370bb7 | |||
| c0d0cf5e74 | |||
| b09a4a98d4 | |||
| 135ea264ef | |||
| f25a01bb5a | |||
| 6309e28dd0 | |||
| bd8c8e720e | |||
| 9e1b1e5389 | |||
| 36288eebe7 | |||
| a0baae8a55 | |||
| 9a66331984 | |||
| c9fab28214 | |||
| e93e1ba2c9 | |||
| f545aee66d | |||
| 203f95d3be | |||
| b3578710cf | |||
| 117e97adac | |||
| 0c4328fbf3 | |||
| 7ed5d85f25 | |||
| c52b4cf450 | |||
| 481af5c469 | |||
| 74da80dbda | |||
| f73eff7517 | |||
| 5557474467 | |||
| 8e24a8b7c0 | |||
| 5a27f7c81f | |||
| 6ce26b72b1 | |||
| 86885c5ed0 | |||
| 2dbaba077a | |||
| 7a2448672c | |||
| 9be3f7d41a | |||
| f40231af5d | |||
| c3a90ccbad | |||
| 145eae321e | |||
| d971678add | |||
| 6c196d3066 | |||
| 346871e27f | |||
| e4b51fa8ad | |||
| 67259d7082 | |||
| 7469981d1a | |||
| db48f7b5d1 | |||
| 75ee536d6d | |||
| 0081dc478f | |||
| 5dc0e51682 | |||
| ba1a6ad4cc | |||
| 34ad9b8a42 | |||
| dbeb4a11be | |||
| b11e22c25b | |||
| 53a475d63c | |||
| e87425f047 | |||
| 67b67003c5 | |||
| 9510551c63 | |||
| b80c7bca0d | |||
| dc27d52221 | |||
| 715f40a48d | |||
| ab8022f74e | |||
| a2bc075924 | |||
| e3dc7e5ec9 | |||
| 18bc2a1a93 | |||
| df38624e10 | |||
| 70d6b8774d | |||
| fa813d02fa | |||
| ffb9ce8287 | |||
| 8b5e29c234 | |||
| e8e9d1d021 | |||
| e324d2e534 | |||
| 1894f1a37f | |||
| 50c607d206 | |||
| 443670262d | |||
| 4626246087 | |||
| fe20fa8326 | |||
| 86c1114463 | |||
| 40b85c1cd9 | |||
| 8f7a3b15b2 | |||
| eed43a231b | |||
| 8622b1254e | |||
| 5e2c112697 | |||
| ecf4b639e1 | |||
| db1550a410 | |||
| 9629af1aa9 | |||
| 30d4e0261a | |||
| 001f5faa0d | |||
| a6ad44a7c7 | |||
| bd87eb6e66 | |||
| 2bb5d1bca3 | |||
| 693a7663e7 | |||
| 8f24db048c | |||
| 13a4700084 | |||
| 018eab7040 | |||
| 5fd7cfbcad | |||
| 54e8487f56 | |||
| 1c2ee8a5f1 | |||
| 09c63e4f00 | |||
| f040282bf8 | |||
| 4fe648b15c | |||
| aef16d51ec | |||
| ff3d4d8b7f | |||
| a11ef2650e | |||
| 8c4e0dfd13 | |||
| 7d727ac2fb | |||
| 0d249c7448 | |||
| 2c291bc2fb | |||
| f581992a62 |
@@ -1531,7 +1531,7 @@ class TegraCvtColor_##name##_Invoker : public cv::ParallelLoopBody \
|
||||
public: \
|
||||
TegraCvtColor_##name##_Invoker(const uchar * src_data_, size_t src_step_, uchar * dst_data_, size_t dst_step_, int width_, int height_) : \
|
||||
cv::ParallelLoopBody(), src_data(src_data_), src_step(src_step_), dst_data(dst_data_), dst_step(dst_step_), width(width_), height(height_) {} \
|
||||
virtual void operator()(const cv::Range& range) const \
|
||||
virtual void operator()(const cv::Range& range) const CV_OVERRIDE \
|
||||
{ \
|
||||
CAROTENE_NS::func(CAROTENE_NS::Size2D(width, range.end-range.start), __VA_ARGS__); \
|
||||
} \
|
||||
|
||||
@@ -335,7 +335,7 @@ ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
|
||||
#ifdef SDL_STRNCPY_S
|
||||
#define __itt_fstrcpyn(s1, b, s2, l) SDL_STRNCPY_S(s1, b, s2, l)
|
||||
#else
|
||||
#define __itt_fstrcpyn(s1, b, s2, l) strncpy(s1, s2, l)
|
||||
#define __itt_fstrcpyn(s1, b, s2, l) strncpy(s1, s2, b)
|
||||
#endif /* SDL_STRNCPY_S */
|
||||
|
||||
#define __itt_fstrdup(s) strdup(s)
|
||||
|
||||
@@ -47,6 +47,10 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow -Wunused -Wsign-compare -Wundef -W
|
||||
-Wsuggest-override -Winconsistent-missing-override
|
||||
-Wimplicit-fallthrough
|
||||
)
|
||||
if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wclass-memaccess)
|
||||
endif()
|
||||
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4018 /wd4099 /wd4100 /wd4101 /wd4127 /wd4189 /wd4245 /wd4305 /wd4389 /wd4512 /wd4701 /wd4702 /wd4706 /wd4800) # vs2005
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4334) # vs2005 Win64
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244) # vs2008
|
||||
|
||||
@@ -29,6 +29,9 @@ if(CV_ICC)
|
||||
-wd265 -wd858 -wd873 -wd2196
|
||||
)
|
||||
endif()
|
||||
if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wclass-memaccess)
|
||||
endif()
|
||||
|
||||
# Easier to support different versions of protobufs
|
||||
function(append_if_exist OUTPUT_LIST)
|
||||
|
||||
@@ -276,7 +276,7 @@ OCV_OPTION(WITH_VA "Include VA support" OFF
|
||||
OCV_OPTION(WITH_VA_INTEL "Include Intel VA-API/OpenCL support" OFF IF (UNIX AND NOT ANDROID) )
|
||||
OCV_OPTION(WITH_MFX "Include Intel Media SDK support" OFF IF ((UNIX AND NOT ANDROID) OR (WIN32 AND NOT WINRT AND NOT MINGW)) )
|
||||
OCV_OPTION(WITH_GDAL "Include GDAL Support" OFF IF (NOT ANDROID AND NOT IOS AND NOT WINRT) )
|
||||
OCV_OPTION(WITH_GPHOTO2 "Include gPhoto2 library support" ON IF (UNIX AND NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_GPHOTO2 "Include gPhoto2 library support" OFF IF (UNIX AND NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_LAPACK "Include Lapack library support" (NOT CV_DISABLE_OPTIMIZATION) IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_ITT "Include Intel ITT support" ON IF (NOT APPLE_FRAMEWORK) )
|
||||
OCV_OPTION(WITH_PROTOBUF "Enable libprotobuf" ON )
|
||||
@@ -1407,8 +1407,22 @@ if(WITH_HALIDE OR HAVE_HALIDE)
|
||||
status(" Halide:" HAVE_HALIDE THEN "YES (${HALIDE_LIBRARIES} ${HALIDE_INCLUDE_DIRS})" ELSE NO)
|
||||
endif()
|
||||
|
||||
if(WITH_INF_ENGINE OR HAVE_INF_ENGINE)
|
||||
status(" Inference Engine:" HAVE_INF_ENGINE THEN "YES (${INF_ENGINE_LIBRARIES} ${INF_ENGINE_INCLUDE_DIRS})" ELSE NO)
|
||||
if(WITH_INF_ENGINE OR INF_ENGINE_TARGET)
|
||||
if(INF_ENGINE_TARGET)
|
||||
set(__msg "YES (${INF_ENGINE_RELEASE} / ${INF_ENGINE_VERSION})")
|
||||
get_target_property(_lib ${INF_ENGINE_TARGET} IMPORTED_LOCATION)
|
||||
if(NOT _lib)
|
||||
get_target_property(_lib_rel ${INF_ENGINE_TARGET} IMPORTED_IMPLIB_RELEASE)
|
||||
get_target_property(_lib_dbg ${INF_ENGINE_TARGET} IMPORTED_IMPLIB_DEBUG)
|
||||
set(_lib "${_lib_rel} / ${_lib_dbg}")
|
||||
endif()
|
||||
get_target_property(_inc ${INF_ENGINE_TARGET} INTERFACE_INCLUDE_DIRECTORIES)
|
||||
status(" Inference Engine:" "${__msg}")
|
||||
status(" libs:" "${_lib}")
|
||||
status(" includes:" "${_inc}")
|
||||
else()
|
||||
status(" Inference Engine:" "NO")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_EIGEN OR HAVE_EIGEN)
|
||||
|
||||
@@ -1,6 +1,39 @@
|
||||
add_definitions(-D__OPENCV_BUILD=1)
|
||||
add_definitions(-D__OPENCV_APPS=1)
|
||||
|
||||
# Unified function for creating OpenCV applications:
|
||||
# ocv_add_application(tgt [MODULES <m1> [<m2> ...]] SRCS <src1> [<src2> ...])
|
||||
function(ocv_add_application the_target)
|
||||
cmake_parse_arguments(APP "" "" "MODULES;SRCS" ${ARGN})
|
||||
ocv_check_dependencies(${APP_MODULES})
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(${the_target})
|
||||
ocv_target_include_modules_recurse(${the_target} ${APP_MODULES})
|
||||
ocv_target_include_directories(${the_target} PRIVATE "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_add_executable(${the_target} ${APP_SRCS})
|
||||
ocv_target_link_libraries(${the_target} ${APP_MODULES})
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "${the_target}")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
link_libraries(${OPENCV_LINKER_LIBS})
|
||||
|
||||
macro(ocv_add_app directory)
|
||||
|
||||
@@ -1,36 +1,3 @@
|
||||
SET(OPENCV_ANNOTATION_DEPS opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs opencv_videoio)
|
||||
ocv_check_dependencies(${OPENCV_ANNOTATION_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(annotation)
|
||||
set(the_target opencv_annotation)
|
||||
|
||||
ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_target_include_modules_recurse(${the_target} ${OPENCV_ANNOTATION_DEPS})
|
||||
|
||||
file(GLOB SRCS *.cpp)
|
||||
|
||||
set(annotation_files ${SRCS})
|
||||
ocv_add_executable(${the_target} ${annotation_files})
|
||||
ocv_target_link_libraries(${the_target} ${OPENCV_ANNOTATION_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "opencv_annotation")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
ocv_add_application(opencv_annotation
|
||||
MODULES opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs opencv_videoio
|
||||
SRCS opencv_annotation.cpp)
|
||||
|
||||
@@ -1,38 +1,4 @@
|
||||
set(OPENCV_CREATESAMPLES_DEPS opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d opencv_videoio)
|
||||
ocv_check_dependencies(${OPENCV_CREATESAMPLES_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(createsamples)
|
||||
set(the_target opencv_createsamples)
|
||||
|
||||
ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_target_include_modules_recurse(${the_target} ${OPENCV_CREATESAMPLES_DEPS})
|
||||
|
||||
file(GLOB SRCS *.cpp)
|
||||
file(GLOB HDRS *.h*)
|
||||
|
||||
set(createsamples_files ${SRCS} ${HDRS})
|
||||
|
||||
ocv_add_executable(${the_target} ${createsamples_files})
|
||||
ocv_target_link_libraries(${the_target} ${OPENCV_CREATESAMPLES_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "opencv_createsamples")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} OPTIONAL RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
ocv_add_application(opencv_createsamples
|
||||
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d opencv_videoio
|
||||
SRCS ${SRCS})
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/calib3d.hpp"
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 8
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
||||
#endif
|
||||
|
||||
using namespace cv;
|
||||
|
||||
#ifndef PATH_MAX
|
||||
@@ -1040,12 +1044,10 @@ void cvCreateTrainingSamples( const char* filename,
|
||||
output = fopen( filename, "wb" );
|
||||
if( output != NULL )
|
||||
{
|
||||
int hasbg;
|
||||
int i;
|
||||
int inverse;
|
||||
|
||||
hasbg = 0;
|
||||
hasbg = (bgfilename != NULL && icvInitBackgroundReaders( bgfilename,
|
||||
const int hasbg = (bgfilename != NULL && icvInitBackgroundReaders( bgfilename,
|
||||
Size( winwidth,winheight ) ) );
|
||||
|
||||
Mat sample( winheight, winwidth, CV_8UC1 );
|
||||
@@ -1372,7 +1374,7 @@ int icvGetTraininDataFromVec( Mat& img, CvVecFile& userdata )
|
||||
|
||||
size_t elements_read = fread( &tmp, sizeof( tmp ), 1, userdata.input );
|
||||
CV_Assert(elements_read == 1);
|
||||
elements_read = fread( vector, sizeof( short ), userdata.vecsize, userdata.input );
|
||||
elements_read = fread(vector.data(), sizeof(short), userdata.vecsize, userdata.input);
|
||||
CV_Assert(elements_read == (size_t)userdata.vecsize);
|
||||
|
||||
if( feof( userdata.input ) || userdata.last++ >= userdata.count )
|
||||
|
||||
@@ -1,41 +1,6 @@
|
||||
set(OPENCV_INTERACTIVECALIBRATION_DEPS opencv_core opencv_imgproc opencv_features2d opencv_highgui opencv_calib3d opencv_videoio)
|
||||
set(DEPS opencv_core opencv_imgproc opencv_features2d opencv_highgui opencv_calib3d opencv_videoio)
|
||||
if(${BUILD_opencv_aruco})
|
||||
list(APPEND OPENCV_INTERACTIVECALIBRATION_DEPS opencv_aruco)
|
||||
list(APPEND DEPS opencv_aruco)
|
||||
endif()
|
||||
ocv_check_dependencies(${OPENCV_INTERACTIVECALIBRATION_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(interactive-calibration)
|
||||
set(the_target opencv_interactive-calibration)
|
||||
|
||||
ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_target_include_modules_recurse(${the_target} ${OPENCV_INTERACTIVECALIBRATION_DEPS})
|
||||
|
||||
file(GLOB SRCS *.cpp)
|
||||
file(GLOB HDRS *.h*)
|
||||
|
||||
set(interactive-calibration_files ${SRCS} ${HDRS})
|
||||
|
||||
ocv_add_executable(${the_target} ${interactive-calibration_files})
|
||||
ocv_target_link_libraries(${the_target} ${OPENCV_INTERACTIVECALIBRATION_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "opencv_interactive-calibration")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} OPTIONAL RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
ocv_add_application(opencv_interactive-calibration MODULES ${DEPS} SRCS ${SRCS})
|
||||
|
||||
@@ -224,8 +224,10 @@ void calib::calibDataController::filterFrames()
|
||||
cv::Mat newErrorsVec = cv::Mat((int)numberOfFrames - 1, 1, CV_64F);
|
||||
std::copy(mCalibData->perViewErrors.ptr<double>(0),
|
||||
mCalibData->perViewErrors.ptr<double>((int)worstElemIndex), newErrorsVec.ptr<double>(0));
|
||||
std::copy(mCalibData->perViewErrors.ptr<double>((int)worstElemIndex + 1), mCalibData->perViewErrors.ptr<double>((int)numberOfFrames),
|
||||
if((int)worstElemIndex < (int)numberOfFrames-1) {
|
||||
std::copy(mCalibData->perViewErrors.ptr<double>((int)worstElemIndex + 1), mCalibData->perViewErrors.ptr<double>((int)numberOfFrames),
|
||||
newErrorsVec.ptr<double>((int)worstElemIndex));
|
||||
}
|
||||
mCalibData->perViewErrors = newErrorsVec;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ void calib::Euler(const cv::Mat& src, cv::Mat& dst, int argType)
|
||||
{
|
||||
if((src.rows == 3) && (src.cols == 3))
|
||||
{
|
||||
//convert rotaion matrix to 3 angles (pitch, yaw, roll)
|
||||
//convert rotation matrix to 3 angles (pitch, yaw, roll)
|
||||
dst = cv::Mat(3, 1, CV_64F);
|
||||
double pitch, yaw, roll;
|
||||
|
||||
@@ -55,7 +55,7 @@ void calib::Euler(const cv::Mat& src, cv::Mat& dst, int argType)
|
||||
else if( (src.cols == 1 && src.rows == 3) ||
|
||||
(src.cols == 3 && src.rows == 1 ) )
|
||||
{
|
||||
//convert vector which contains 3 angles (pitch, yaw, roll) to rotaion matrix
|
||||
//convert vector which contains 3 angles (pitch, yaw, roll) to rotation matrix
|
||||
double pitch, yaw, roll;
|
||||
if(src.cols == 1 && src.rows == 3)
|
||||
{
|
||||
|
||||
@@ -1,42 +1,5 @@
|
||||
set(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d)
|
||||
ocv_check_dependencies(${OPENCV_TRAINCASCADE_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(traincascade)
|
||||
set(the_target opencv_traincascade)
|
||||
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Woverloaded-virtual
|
||||
-Winconsistent-missing-override -Wsuggest-override
|
||||
)
|
||||
|
||||
ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_target_include_modules_recurse(${the_target} ${OPENCV_TRAINCASCADE_DEPS})
|
||||
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Woverloaded-virtual -Winconsistent-missing-override -Wsuggest-override)
|
||||
file(GLOB SRCS *.cpp)
|
||||
file(GLOB HDRS *.h*)
|
||||
|
||||
set(traincascade_files ${SRCS} ${HDRS})
|
||||
|
||||
ocv_add_executable(${the_target} ${traincascade_files})
|
||||
ocv_target_link_libraries(${the_target} ${OPENCV_TRAINCASCADE_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "opencv_traincascade")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} OPTIONAL RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
ocv_add_application(opencv_traincascade
|
||||
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d
|
||||
SRCS ${SRCS})
|
||||
|
||||
@@ -165,7 +165,7 @@ void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, M
|
||||
Mat qangle(gradSize, CV_8U);
|
||||
|
||||
AutoBuffer<int> mapbuf(gradSize.width + gradSize.height + 4);
|
||||
int* xmap = (int*)mapbuf + 1;
|
||||
int* xmap = mapbuf.data() + 1;
|
||||
int* ymap = xmap + gradSize.width + 2;
|
||||
|
||||
const int borderType = (int)BORDER_REPLICATE;
|
||||
@@ -177,7 +177,7 @@ void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, M
|
||||
|
||||
int width = gradSize.width;
|
||||
AutoBuffer<float> _dbuf(width*4);
|
||||
float* dbuf = _dbuf;
|
||||
float* dbuf = _dbuf.data();
|
||||
Mat Dx(1, width, CV_32F, dbuf);
|
||||
Mat Dy(1, width, CV_32F, dbuf + width);
|
||||
Mat Mag(1, width, CV_32F, dbuf + width*2);
|
||||
|
||||
@@ -383,7 +383,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id
|
||||
int ci = get_var_type(vi);
|
||||
CV_Assert( ci < 0 );
|
||||
|
||||
int *src_idx_buf = (int*)(uchar*)inn_buf;
|
||||
int *src_idx_buf = (int*)inn_buf.data();
|
||||
float *src_val_buf = (float*)(src_idx_buf + sample_count);
|
||||
int* sample_indices_buf = (int*)(src_val_buf + sample_count);
|
||||
const int* src_idx = 0;
|
||||
@@ -423,7 +423,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id
|
||||
}
|
||||
|
||||
// subsample cv_lables
|
||||
const int* src_lbls = get_cv_labels(data_root, (int*)(uchar*)inn_buf);
|
||||
const int* src_lbls = get_cv_labels(data_root, (int*)inn_buf.data());
|
||||
if (is_buf_16u)
|
||||
{
|
||||
unsigned short* udst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() +
|
||||
@@ -440,7 +440,7 @@ CvDTreeNode* CvCascadeBoostTrainData::subsample_data( const CvMat* _subsample_id
|
||||
}
|
||||
|
||||
// subsample sample_indices
|
||||
const int* sample_idx_src = get_sample_indices(data_root, (int*)(uchar*)inn_buf);
|
||||
const int* sample_idx_src = get_sample_indices(data_root, (int*)inn_buf.data());
|
||||
if (is_buf_16u)
|
||||
{
|
||||
unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() +
|
||||
@@ -815,7 +815,7 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody
|
||||
void operator()( const Range& range ) const
|
||||
{
|
||||
cv::AutoBuffer<float> valCache(sample_count);
|
||||
float* valCachePtr = (float*)valCache;
|
||||
float* valCachePtr = valCache.data();
|
||||
for ( int fi = range.start; fi < range.end; fi++)
|
||||
{
|
||||
for( int si = 0; si < sample_count; si++ )
|
||||
@@ -1084,7 +1084,7 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
|
||||
CvMat* buf = data->buf;
|
||||
size_t length_buf_row = data->get_length_subbuf();
|
||||
cv::AutoBuffer<uchar> inn_buf(n*(3*sizeof(int)+sizeof(float)));
|
||||
int* tempBuf = (int*)(uchar*)inn_buf;
|
||||
int* tempBuf = (int*)inn_buf.data();
|
||||
bool splitInputData;
|
||||
|
||||
complete_node_dir(node);
|
||||
@@ -1398,7 +1398,7 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
|
||||
int inn_buf_size = ((params.boost_type == LOGIT) || (params.boost_type == GENTLE) ? n*sizeof(int) : 0) +
|
||||
( !tree ? n*sizeof(int) : 0 );
|
||||
cv::AutoBuffer<uchar> inn_buf(inn_buf_size);
|
||||
uchar* cur_inn_buf_pos = (uchar*)inn_buf;
|
||||
uchar* cur_inn_buf_pos = inn_buf.data();
|
||||
if ( (params.boost_type == LOGIT) || (params.boost_type == GENTLE) )
|
||||
{
|
||||
step = CV_IS_MAT_CONT(data->responses_copy->type) ?
|
||||
|
||||
@@ -168,7 +168,7 @@ CvBoostTree::try_split_node( CvDTreeNode* node )
|
||||
// store the responses for the corresponding training samples
|
||||
double* weak_eval = ensemble->get_weak_response()->data.db;
|
||||
cv::AutoBuffer<int> inn_buf(node->sample_count);
|
||||
const int* labels = data->get_cv_labels( node, (int*)inn_buf );
|
||||
const int* labels = data->get_cv_labels(node, inn_buf.data());
|
||||
int i, count = node->sample_count;
|
||||
double value = node->value;
|
||||
|
||||
@@ -191,7 +191,7 @@ CvBoostTree::calc_node_dir( CvDTreeNode* node )
|
||||
if( data->get_var_type(vi) >= 0 ) // split on categorical var
|
||||
{
|
||||
cv::AutoBuffer<int> inn_buf(n);
|
||||
const int* cat_labels = data->get_cat_var_data( node, vi, (int*)inn_buf );
|
||||
const int* cat_labels = data->get_cat_var_data(node, vi, inn_buf.data());
|
||||
const int* subset = node->split->subset;
|
||||
double sum = 0, sum_abs = 0;
|
||||
|
||||
@@ -210,7 +210,7 @@ CvBoostTree::calc_node_dir( CvDTreeNode* node )
|
||||
else // split on ordered var
|
||||
{
|
||||
cv::AutoBuffer<uchar> inn_buf(2*n*sizeof(int)+n*sizeof(float));
|
||||
float* values_buf = (float*)(uchar*)inn_buf;
|
||||
float* values_buf = (float*)inn_buf.data();
|
||||
int* sorted_indices_buf = (int*)(values_buf + n);
|
||||
int* sample_indices_buf = sorted_indices_buf + n;
|
||||
const float* values = 0;
|
||||
@@ -260,7 +260,7 @@ CvBoostTree::find_split_ord_class( CvDTreeNode* node, int vi, float init_quality
|
||||
cv::AutoBuffer<uchar> inn_buf;
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(n*(3*sizeof(int)+sizeof(float)));
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : (uchar*)inn_buf;
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data();
|
||||
float* values_buf = (float*)ext_buf;
|
||||
int* sorted_indices_buf = (int*)(values_buf + n);
|
||||
int* sample_indices_buf = sorted_indices_buf + n;
|
||||
@@ -369,7 +369,7 @@ CvBoostTree::find_split_cat_class( CvDTreeNode* node, int vi, float init_quality
|
||||
cv::AutoBuffer<uchar> inn_buf((2*mi+3)*sizeof(double) + mi*sizeof(double*));
|
||||
if( !_ext_buf)
|
||||
inn_buf.allocate( base_size + 2*n*sizeof(int) );
|
||||
uchar* base_buf = (uchar*)inn_buf;
|
||||
uchar* base_buf = inn_buf.data();
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size;
|
||||
|
||||
int* cat_labels_buf = (int*)ext_buf;
|
||||
@@ -490,7 +490,7 @@ CvBoostTree::find_split_ord_reg( CvDTreeNode* node, int vi, float init_quality,
|
||||
cv::AutoBuffer<uchar> inn_buf;
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(2*n*(sizeof(int)+sizeof(float)));
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : (uchar*)inn_buf;
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data();
|
||||
|
||||
float* values_buf = (float*)ext_buf;
|
||||
int* indices_buf = (int*)(values_buf + n);
|
||||
@@ -559,7 +559,7 @@ CvBoostTree::find_split_cat_reg( CvDTreeNode* node, int vi, float init_quality,
|
||||
cv::AutoBuffer<uchar> inn_buf(base_size);
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(base_size + n*(2*sizeof(int) + sizeof(float)));
|
||||
uchar* base_buf = (uchar*)inn_buf;
|
||||
uchar* base_buf = inn_buf.data();
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size;
|
||||
|
||||
int* cat_labels_buf = (int*)ext_buf;
|
||||
@@ -652,7 +652,7 @@ CvBoostTree::find_surrogate_split_ord( CvDTreeNode* node, int vi, uchar* _ext_bu
|
||||
cv::AutoBuffer<uchar> inn_buf;
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(n*(2*sizeof(int)+sizeof(float)));
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : (uchar*)inn_buf;
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data();
|
||||
float* values_buf = (float*)ext_buf;
|
||||
int* indices_buf = (int*)(values_buf + n);
|
||||
int* sample_indices_buf = indices_buf + n;
|
||||
@@ -733,7 +733,7 @@ CvBoostTree::find_surrogate_split_cat( CvDTreeNode* node, int vi, uchar* _ext_bu
|
||||
cv::AutoBuffer<uchar> inn_buf(base_size);
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(base_size + n*sizeof(int));
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : (uchar*)inn_buf;
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data();
|
||||
int* cat_labels_buf = (int*)ext_buf;
|
||||
const int* cat_labels = data->get_cat_var_data(node, vi, cat_labels_buf);
|
||||
|
||||
@@ -797,7 +797,7 @@ CvBoostTree::calc_node_value( CvDTreeNode* node )
|
||||
int i, n = node->sample_count;
|
||||
const double* weights = ensemble->get_weights()->data.db;
|
||||
cv::AutoBuffer<uchar> inn_buf(n*(sizeof(int) + ( data->is_classifier ? sizeof(int) : sizeof(int) + sizeof(float))));
|
||||
int* labels_buf = (int*)(uchar*)inn_buf;
|
||||
int* labels_buf = (int*)inn_buf.data();
|
||||
const int* labels = data->get_cv_labels(node, labels_buf);
|
||||
double* subtree_weights = ensemble->get_subtree_weights()->data.db;
|
||||
double rcw[2] = {0,0};
|
||||
@@ -1147,7 +1147,7 @@ CvBoost::update_weights( CvBoostTree* tree )
|
||||
_buf_size += data->get_length_subbuf()*(sizeof(float)+sizeof(uchar));
|
||||
}
|
||||
inn_buf.allocate(_buf_size);
|
||||
uchar* cur_buf_pos = (uchar*)inn_buf;
|
||||
uchar* cur_buf_pos = inn_buf.data();
|
||||
|
||||
if ( (params.boost_type == LOGIT) || (params.boost_type == GENTLE) )
|
||||
{
|
||||
|
||||
@@ -780,7 +780,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx )
|
||||
if( ci >= 0 || vi >= var_count )
|
||||
{
|
||||
int num_valid = 0;
|
||||
const int* src = CvDTreeTrainData::get_cat_var_data( data_root, vi, (int*)(uchar*)inn_buf );
|
||||
const int* src = CvDTreeTrainData::get_cat_var_data(data_root, vi, (int*)inn_buf.data());
|
||||
|
||||
if (is_buf_16u)
|
||||
{
|
||||
@@ -810,7 +810,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx )
|
||||
}
|
||||
else
|
||||
{
|
||||
int *src_idx_buf = (int*)(uchar*)inn_buf;
|
||||
int *src_idx_buf = (int*)inn_buf.data();
|
||||
float *src_val_buf = (float*)(src_idx_buf + sample_count);
|
||||
int* sample_indices_buf = (int*)(src_val_buf + sample_count);
|
||||
const int* src_idx = 0;
|
||||
@@ -870,7 +870,7 @@ CvDTreeNode* CvDTreeTrainData::subsample_data( const CvMat* _subsample_idx )
|
||||
}
|
||||
}
|
||||
// sample indices subsampling
|
||||
const int* sample_idx_src = get_sample_indices(data_root, (int*)(uchar*)inn_buf);
|
||||
const int* sample_idx_src = get_sample_indices(data_root, (int*)inn_buf.data());
|
||||
if (is_buf_16u)
|
||||
{
|
||||
unsigned short* sample_idx_dst = (unsigned short*)(buf->data.s + root->buf_idx*get_length_subbuf() +
|
||||
@@ -943,7 +943,7 @@ void CvDTreeTrainData::get_vectors( const CvMat* _subsample_idx,
|
||||
{
|
||||
float* dst = values + vi;
|
||||
uchar* m = missing ? missing + vi : 0;
|
||||
const int* src = get_cat_var_data(data_root, vi, (int*)(uchar*)inn_buf);
|
||||
const int* src = get_cat_var_data(data_root, vi, (int*)inn_buf.data());
|
||||
|
||||
for( i = 0; i < count; i++, dst += var_count )
|
||||
{
|
||||
@@ -962,7 +962,7 @@ void CvDTreeTrainData::get_vectors( const CvMat* _subsample_idx,
|
||||
float* dst = values + vi;
|
||||
uchar* m = missing ? missing + vi : 0;
|
||||
int count1 = data_root->get_num_valid(vi);
|
||||
float *src_val_buf = (float*)(uchar*)inn_buf;
|
||||
float *src_val_buf = (float*)inn_buf.data();
|
||||
int* src_idx_buf = (int*)(src_val_buf + sample_count);
|
||||
int* sample_indices_buf = src_idx_buf + sample_count;
|
||||
const float *src_val = 0;
|
||||
@@ -999,7 +999,7 @@ void CvDTreeTrainData::get_vectors( const CvMat* _subsample_idx,
|
||||
{
|
||||
if( is_classifier )
|
||||
{
|
||||
const int* src = get_class_labels(data_root, (int*)(uchar*)inn_buf);
|
||||
const int* src = get_class_labels(data_root, (int*)inn_buf.data());
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
int idx = sidx ? sidx[i] : i;
|
||||
@@ -1010,7 +1010,7 @@ void CvDTreeTrainData::get_vectors( const CvMat* _subsample_idx,
|
||||
}
|
||||
else
|
||||
{
|
||||
float* val_buf = (float*)(uchar*)inn_buf;
|
||||
float* val_buf = (float*)inn_buf.data();
|
||||
int* sample_idx_buf = (int*)(val_buf + sample_count);
|
||||
const float* _values = get_ord_responses(data_root, val_buf, sample_idx_buf);
|
||||
for( i = 0; i < count; i++ )
|
||||
@@ -1780,7 +1780,7 @@ double CvDTree::calc_node_dir( CvDTreeNode* node )
|
||||
if( data->get_var_type(vi) >= 0 ) // split on categorical var
|
||||
{
|
||||
cv::AutoBuffer<int> inn_buf(n*(!data->have_priors ? 1 : 2));
|
||||
int* labels_buf = (int*)inn_buf;
|
||||
int* labels_buf = inn_buf.data();
|
||||
const int* labels = data->get_cat_var_data( node, vi, labels_buf );
|
||||
const int* subset = node->split->subset;
|
||||
if( !data->have_priors )
|
||||
@@ -1824,7 +1824,7 @@ double CvDTree::calc_node_dir( CvDTreeNode* node )
|
||||
int split_point = node->split->ord.split_point;
|
||||
int n1 = node->get_num_valid(vi);
|
||||
cv::AutoBuffer<uchar> inn_buf(n*(sizeof(int)*(data->have_priors ? 3 : 2) + sizeof(float)));
|
||||
float* val_buf = (float*)(uchar*)inn_buf;
|
||||
float* val_buf = (float*)inn_buf.data();
|
||||
int* sorted_buf = (int*)(val_buf + n);
|
||||
int* sample_idx_buf = sorted_buf + n;
|
||||
const float* val = 0;
|
||||
@@ -1929,16 +1929,16 @@ void DTreeBestSplitFinder::operator()(const BlockedRange& range)
|
||||
if( data->is_classifier )
|
||||
{
|
||||
if( ci >= 0 )
|
||||
res = tree->find_split_cat_class( node, vi, bestSplit->quality, split, (uchar*)inn_buf );
|
||||
res = tree->find_split_cat_class( node, vi, bestSplit->quality, split, inn_buf.data() );
|
||||
else
|
||||
res = tree->find_split_ord_class( node, vi, bestSplit->quality, split, (uchar*)inn_buf );
|
||||
res = tree->find_split_ord_class( node, vi, bestSplit->quality, split, inn_buf.data() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ci >= 0 )
|
||||
res = tree->find_split_cat_reg( node, vi, bestSplit->quality, split, (uchar*)inn_buf );
|
||||
res = tree->find_split_cat_reg( node, vi, bestSplit->quality, split, inn_buf.data() );
|
||||
else
|
||||
res = tree->find_split_ord_reg( node, vi, bestSplit->quality, split, (uchar*)inn_buf );
|
||||
res = tree->find_split_ord_reg( node, vi, bestSplit->quality, split, inn_buf.data() );
|
||||
}
|
||||
|
||||
if( res && bestSplit->quality < split->quality )
|
||||
@@ -1982,7 +1982,7 @@ CvDTreeSplit* CvDTree::find_split_ord_class( CvDTreeNode* node, int vi,
|
||||
cv::AutoBuffer<uchar> inn_buf(base_size);
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(base_size + n*(3*sizeof(int)+sizeof(float)));
|
||||
uchar* base_buf = (uchar*)inn_buf;
|
||||
uchar* base_buf = inn_buf.data();
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size;
|
||||
float* values_buf = (float*)ext_buf;
|
||||
int* sorted_indices_buf = (int*)(values_buf + n);
|
||||
@@ -2096,7 +2096,7 @@ void CvDTree::cluster_categories( const int* vectors, int n, int m,
|
||||
int iters = 0, max_iters = 100;
|
||||
int i, j, idx;
|
||||
cv::AutoBuffer<double> buf(n + k);
|
||||
double *v_weights = buf, *c_weights = buf + n;
|
||||
double *v_weights = buf.data(), *c_weights = buf.data() + n;
|
||||
bool modified = true;
|
||||
RNG* r = data->rng;
|
||||
|
||||
@@ -2201,7 +2201,7 @@ CvDTreeSplit* CvDTree::find_split_cat_class( CvDTreeNode* node, int vi, float in
|
||||
cv::AutoBuffer<uchar> inn_buf(base_size);
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(base_size + 2*n*sizeof(int));
|
||||
uchar* base_buf = (uchar*)inn_buf;
|
||||
uchar* base_buf = inn_buf.data();
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size;
|
||||
|
||||
int* lc = (int*)base_buf;
|
||||
@@ -2383,7 +2383,7 @@ CvDTreeSplit* CvDTree::find_split_ord_reg( CvDTreeNode* node, int vi, float init
|
||||
cv::AutoBuffer<uchar> inn_buf;
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(2*n*(sizeof(int) + sizeof(float)));
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : (uchar*)inn_buf;
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data();
|
||||
float* values_buf = (float*)ext_buf;
|
||||
int* sorted_indices_buf = (int*)(values_buf + n);
|
||||
int* sample_indices_buf = sorted_indices_buf + n;
|
||||
@@ -2443,7 +2443,7 @@ CvDTreeSplit* CvDTree::find_split_cat_reg( CvDTreeNode* node, int vi, float init
|
||||
cv::AutoBuffer<uchar> inn_buf(base_size);
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(base_size + n*(2*sizeof(int) + sizeof(float)));
|
||||
uchar* base_buf = (uchar*)inn_buf;
|
||||
uchar* base_buf = inn_buf.data();
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size;
|
||||
int* labels_buf = (int*)ext_buf;
|
||||
const int* labels = data->get_cat_var_data(node, vi, labels_buf);
|
||||
@@ -2534,7 +2534,7 @@ CvDTreeSplit* CvDTree::find_surrogate_split_ord( CvDTreeNode* node, int vi, ucha
|
||||
cv::AutoBuffer<uchar> inn_buf;
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate( n*(sizeof(int)*(data->have_priors ? 3 : 2) + sizeof(float)) );
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : (uchar*)inn_buf;
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : inn_buf.data();
|
||||
float* values_buf = (float*)ext_buf;
|
||||
int* sorted_indices_buf = (int*)(values_buf + n);
|
||||
int* sample_indices_buf = sorted_indices_buf + n;
|
||||
@@ -2658,7 +2658,7 @@ CvDTreeSplit* CvDTree::find_surrogate_split_cat( CvDTreeNode* node, int vi, ucha
|
||||
cv::AutoBuffer<uchar> inn_buf(base_size);
|
||||
if( !_ext_buf )
|
||||
inn_buf.allocate(base_size + n*(sizeof(int) + (data->have_priors ? sizeof(int) : 0)));
|
||||
uchar* base_buf = (uchar*)inn_buf;
|
||||
uchar* base_buf = inn_buf.data();
|
||||
uchar* ext_buf = _ext_buf ? _ext_buf : base_buf + base_size;
|
||||
|
||||
int* labels_buf = (int*)ext_buf;
|
||||
@@ -2758,7 +2758,7 @@ void CvDTree::calc_node_value( CvDTreeNode* node )
|
||||
int base_size = data->is_classifier ? m*cv_n*sizeof(int) : 2*cv_n*sizeof(double)+cv_n*sizeof(int);
|
||||
int ext_size = n*(sizeof(int) + (data->is_classifier ? sizeof(int) : sizeof(int)+sizeof(float)));
|
||||
cv::AutoBuffer<uchar> inn_buf(base_size + ext_size);
|
||||
uchar* base_buf = (uchar*)inn_buf;
|
||||
uchar* base_buf = inn_buf.data();
|
||||
uchar* ext_buf = base_buf + base_size;
|
||||
|
||||
int* cv_labels_buf = (int*)ext_buf;
|
||||
@@ -2961,7 +2961,7 @@ void CvDTree::complete_node_dir( CvDTreeNode* node )
|
||||
|
||||
if( data->get_var_type(vi) >= 0 ) // split on categorical var
|
||||
{
|
||||
int* labels_buf = (int*)(uchar*)inn_buf;
|
||||
int* labels_buf = (int*)inn_buf.data();
|
||||
const int* labels = data->get_cat_var_data(node, vi, labels_buf);
|
||||
const int* subset = split->subset;
|
||||
|
||||
@@ -2980,7 +2980,7 @@ void CvDTree::complete_node_dir( CvDTreeNode* node )
|
||||
}
|
||||
else // split on ordered var
|
||||
{
|
||||
float* values_buf = (float*)(uchar*)inn_buf;
|
||||
float* values_buf = (float*)inn_buf.data();
|
||||
int* sorted_indices_buf = (int*)(values_buf + n);
|
||||
int* sample_indices_buf = sorted_indices_buf + n;
|
||||
const float* values = 0;
|
||||
@@ -3042,7 +3042,7 @@ void CvDTree::split_node_data( CvDTreeNode* node )
|
||||
CvMat* buf = data->buf;
|
||||
size_t length_buf_row = data->get_length_subbuf();
|
||||
cv::AutoBuffer<uchar> inn_buf(n*(3*sizeof(int) + sizeof(float)));
|
||||
int* temp_buf = (int*)(uchar*)inn_buf;
|
||||
int* temp_buf = (int*)inn_buf.data();
|
||||
|
||||
complete_node_dir(node);
|
||||
|
||||
|
||||
@@ -1,49 +1,5 @@
|
||||
set(OPENCV_APPLICATION_DEPS opencv_core)
|
||||
ocv_check_dependencies(${OPENCV_APPLICATION_DEPS})
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(opencv_version)
|
||||
set(the_target opencv_version)
|
||||
ocv_target_include_modules_recurse(${the_target} ${OPENCV_APPLICATION_DEPS})
|
||||
ocv_add_executable(${the_target} opencv_version.cpp)
|
||||
ocv_target_link_libraries(${the_target} ${OPENCV_APPLICATION_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "opencv_version")
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT libs)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT libs)
|
||||
endif()
|
||||
|
||||
ocv_add_application(opencv_version MODULES opencv_core SRCS opencv_version.cpp)
|
||||
if(WIN32)
|
||||
project(opencv_version_win32)
|
||||
set(the_target opencv_version_win32)
|
||||
ocv_target_include_modules_recurse(${the_target} ${OPENCV_APPLICATION_DEPS})
|
||||
ocv_add_executable(${the_target} opencv_version.cpp)
|
||||
ocv_target_link_libraries(${the_target} ${OPENCV_APPLICATION_DEPS})
|
||||
target_compile_definitions(${the_target} PRIVATE "OPENCV_WIN32_API=1")
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "opencv_version_win32")
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT libs)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT libs)
|
||||
endif()
|
||||
ocv_add_application(opencv_version_win32 MODULES opencv_core SRCS opencv_version.cpp)
|
||||
target_compile_definitions(opencv_version_win32 PRIVATE "OPENCV_WIN32_API=1")
|
||||
endif()
|
||||
|
||||
@@ -1,36 +1,3 @@
|
||||
SET(OPENCV_VISUALISATION_DEPS opencv_core opencv_highgui opencv_imgproc opencv_videoio opencv_imgcodecs)
|
||||
ocv_check_dependencies(${OPENCV_VISUALISATION_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(visualisation)
|
||||
set(the_target opencv_visualisation)
|
||||
|
||||
ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_target_include_modules_recurse(${the_target} ${OPENCV_VISUALISATION_DEPS})
|
||||
|
||||
file(GLOB SRCS *.cpp)
|
||||
|
||||
set(visualisation_files ${SRCS})
|
||||
ocv_add_executable(${the_target} ${visualisation_files})
|
||||
ocv_target_link_libraries(${the_target} ${OPENCV_VISUALISATION_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "opencv_visualisation")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
ocv_add_application(opencv_visualisation
|
||||
MODULES opencv_core opencv_highgui opencv_imgproc opencv_videoio opencv_imgcodecs
|
||||
SRCS opencv_visualisation.cpp)
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
# -- Same as CUDA_ADD_EXECUTABLE except that a library is created.
|
||||
#
|
||||
# CUDA_BUILD_CLEAN_TARGET()
|
||||
# -- Creates a convience target that deletes all the dependency files
|
||||
# -- Creates a convenience target that deletes all the dependency files
|
||||
# generated. You should make clean after running this target to ensure the
|
||||
# dependency files get regenerated.
|
||||
#
|
||||
@@ -473,7 +473,7 @@ else()
|
||||
endif()
|
||||
|
||||
# Propagate the host flags to the host compiler via -Xcompiler
|
||||
option(CUDA_PROPAGATE_HOST_FLAGS "Propage C/CXX_FLAGS and friends to the host compiler via -Xcompile" ON)
|
||||
option(CUDA_PROPAGATE_HOST_FLAGS "Propagate C/CXX_FLAGS and friends to the host compiler via -Xcompile" ON)
|
||||
|
||||
# Enable CUDA_SEPARABLE_COMPILATION
|
||||
option(CUDA_SEPARABLE_COMPILATION "Compile CUDA objects with separable compilation enabled. Requires CUDA 5.0+" OFF)
|
||||
|
||||
@@ -700,12 +700,21 @@ macro(ocv_compiler_optimization_fill_cpu_config)
|
||||
list(APPEND __dispatch_modes ${CPU_DISPATCH_${OPT}_FORCE} ${OPT})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES __dispatch_modes)
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "")
|
||||
foreach(OPT ${__dispatch_modes})
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
|
||||
#define CV_CPU_DISPATCH_COMPILE_${OPT} 1")
|
||||
endforeach()
|
||||
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
|
||||
\n\n#define CV_CPU_DISPATCH_FEATURES 0 \\")
|
||||
foreach(OPT ${__dispatch_modes})
|
||||
if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
|
||||
, CV_CPU_${OPT} \\")
|
||||
endif()
|
||||
endforeach()
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}\n")
|
||||
|
||||
set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "// AUTOGENERATED, DO NOT EDIT\n")
|
||||
foreach(OPT ${CPU_ALL_OPTIMIZATIONS})
|
||||
if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
|
||||
@@ -740,7 +749,7 @@ macro(ocv_compiler_optimization_fill_cpu_config)
|
||||
")
|
||||
|
||||
|
||||
set(__file "${CMAKE_SOURCE_DIR}/modules/core/include/opencv2/core/cv_cpu_helper.h")
|
||||
set(__file "${OpenCV_SOURCE_DIR}/modules/core/include/opencv2/core/cv_cpu_helper.h")
|
||||
if(EXISTS "${__file}")
|
||||
file(READ "${__file}" __content)
|
||||
endif()
|
||||
@@ -752,24 +761,24 @@ macro(ocv_compiler_optimization_fill_cpu_config)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_add_dispatched_file filename)
|
||||
macro(__ocv_add_dispatched_file filename target_src_var src_directory dst_directory precomp_hpp optimizations_var)
|
||||
if(NOT OPENCV_INITIAL_PASS)
|
||||
set(__codestr "
|
||||
#include \"${CMAKE_CURRENT_LIST_DIR}/src/precomp.hpp\"
|
||||
#include \"${CMAKE_CURRENT_LIST_DIR}/src/${filename}.simd.hpp\"
|
||||
#include \"${src_directory}/${precomp_hpp}\"
|
||||
#include \"${src_directory}/${filename}.simd.hpp\"
|
||||
")
|
||||
|
||||
set(__declarations_str "#define CV_CPU_SIMD_FILENAME \"${CMAKE_CURRENT_LIST_DIR}/src/${filename}.simd.hpp\"")
|
||||
set(__declarations_str "#define CV_CPU_SIMD_FILENAME \"${src_directory}/${filename}.simd.hpp\"")
|
||||
set(__dispatch_modes "BASELINE")
|
||||
|
||||
set(__optimizations "${ARGN}")
|
||||
set(__optimizations "${${optimizations_var}}")
|
||||
if(CV_DISABLE_OPTIMIZATION OR NOT CV_ENABLE_INTRINSICS)
|
||||
set(__optimizations "")
|
||||
endif()
|
||||
|
||||
foreach(OPT ${__optimizations})
|
||||
string(TOLOWER "${OPT}" OPT_LOWER)
|
||||
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${filename}.${OPT_LOWER}.cpp")
|
||||
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${dst_directory}${filename}.${OPT_LOWER}.cpp")
|
||||
if(EXISTS "${__file}")
|
||||
file(READ "${__file}" __content)
|
||||
else()
|
||||
@@ -782,7 +791,11 @@ macro(ocv_add_dispatched_file filename)
|
||||
endif()
|
||||
|
||||
if(";${CPU_DISPATCH};" MATCHES "${OPT}" OR __CPU_DISPATCH_INCLUDE_ALL)
|
||||
list(APPEND OPENCV_MODULE_${the_module}_SOURCES_DISPATCHED "${__file}")
|
||||
if(EXISTS "${src_directory}/${filename}.${OPT_LOWER}.cpp")
|
||||
message(STATUS "Using overrided ${OPT} source: ${src_directory}/${filename}.${OPT_LOWER}.cpp")
|
||||
else()
|
||||
list(APPEND ${target_src_var} "${__file}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(__declarations_str "${__declarations_str}
|
||||
@@ -794,9 +807,11 @@ macro(ocv_add_dispatched_file filename)
|
||||
|
||||
set(__declarations_str "${__declarations_str}
|
||||
#define CV_CPU_DISPATCH_MODES_ALL ${__dispatch_modes}
|
||||
|
||||
#undef CV_CPU_SIMD_FILENAME
|
||||
")
|
||||
|
||||
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${filename}.simd_declarations.hpp")
|
||||
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${dst_directory}${filename}.simd_declarations.hpp")
|
||||
if(EXISTS "${__file}")
|
||||
file(READ "${__file}" __content)
|
||||
endif()
|
||||
@@ -808,6 +823,17 @@ macro(ocv_add_dispatched_file filename)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_add_dispatched_file filename)
|
||||
set(__optimizations "${ARGN}")
|
||||
if(" ${ARGV1}" STREQUAL " TEST")
|
||||
list(REMOVE_AT __optimizations 0)
|
||||
__ocv_add_dispatched_file("${filename}" "OPENCV_MODULE_${the_module}_TEST_SOURCES_DISPATCHED" "${CMAKE_CURRENT_LIST_DIR}/test" "test/" "test_precomp.hpp" __optimizations)
|
||||
else()
|
||||
__ocv_add_dispatched_file("${filename}" "OPENCV_MODULE_${the_module}_SOURCES_DISPATCHED" "${CMAKE_CURRENT_LIST_DIR}/src" "" "precomp.hpp" __optimizations)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
# Workaround to support code which always require all code paths
|
||||
macro(ocv_add_dispatched_file_force_all)
|
||||
set(__CPU_DISPATCH_INCLUDE_ALL 1)
|
||||
|
||||
@@ -3,19 +3,28 @@ if(WIN32 AND NOT MSVC)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT APPLE AND CV_CLANG)
|
||||
if(NOT UNIX AND CV_CLANG)
|
||||
message(STATUS "CUDA compilation is disabled (due to Clang unsupported on your platform).")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
if(ANDROID)
|
||||
set(CUDA_TARGET_OS_VARIANT "Android")
|
||||
if(((NOT CMAKE_VERSION VERSION_LESS "3.9.0") # requires https://gitlab.kitware.com/cmake/cmake/merge_requests/663
|
||||
OR OPENCV_CUDA_FORCE_EXTERNAL_CMAKE_MODULE)
|
||||
AND NOT OPENCV_CUDA_FORCE_BUILTIN_CMAKE_MODULE)
|
||||
ocv_update(CUDA_LINK_LIBRARIES_KEYWORD "LINK_PRIVATE")
|
||||
find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
|
||||
else()
|
||||
# Use OpenCV's patched "FindCUDA" module
|
||||
set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
if(ANDROID)
|
||||
set(CUDA_TARGET_OS_VARIANT "Android")
|
||||
endif()
|
||||
find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
|
||||
|
||||
list(REMOVE_AT CMAKE_MODULE_PATH 0)
|
||||
endif()
|
||||
find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
|
||||
|
||||
list(REMOVE_AT CMAKE_MODULE_PATH 0)
|
||||
|
||||
if(CUDA_FOUND)
|
||||
set(HAVE_CUDA 1)
|
||||
@@ -179,6 +188,13 @@ if(CUDA_FOUND)
|
||||
foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
|
||||
set(${var}_backup_in_cuda_compile_ "${${var}}")
|
||||
|
||||
if (CV_CLANG)
|
||||
# we remove -Winconsistent-missing-override and -Qunused-arguments
|
||||
# just in case we are compiling CUDA with gcc but OpenCV with clang
|
||||
string(REPLACE "-Winconsistent-missing-override" "" ${var} "${${var}}")
|
||||
string(REPLACE "-Qunused-arguments" "" ${var} "${${var}}")
|
||||
endif()
|
||||
|
||||
# we remove /EHa as it generates warnings under windows
|
||||
string(REPLACE "/EHa" "" ${var} "${${var}}")
|
||||
|
||||
|
||||
@@ -1,71 +1,87 @@
|
||||
# The script detects Intel(R) Inference Engine installation
|
||||
#
|
||||
# Parameters:
|
||||
# INTEL_CVSDK_DIR - Path to Inference Engine root folder
|
||||
# IE_PLUGINS_PATH - Path to folder with Inference Engine plugins
|
||||
# Cache variables:
|
||||
# INF_ENGINE_OMP_DIR - directory with OpenMP library to link with (needed by some versions of IE)
|
||||
# INF_ENGINE_RELEASE - a number reflecting IE source interface (linked with OpenVINO release)
|
||||
#
|
||||
# On return this will define:
|
||||
# Detect parameters:
|
||||
# 1. Native cmake IE package:
|
||||
# - enironment variable InferenceEngine_DIR is set to location of cmake module
|
||||
# 2. Custom location:
|
||||
# - INF_ENGINE_INCLUDE_DIRS - headers search location
|
||||
# - INF_ENGINE_LIB_DIRS - library search location
|
||||
# 3. OpenVINO location:
|
||||
# - environment variable INTEL_CVSDK_DIR is set to location of OpenVINO installation dir
|
||||
# - INF_ENGINE_PLATFORM - part of name of library directory representing its platform (default ubuntu_16.04)
|
||||
#
|
||||
# HAVE_INF_ENGINE - True if Intel Inference Engine was found
|
||||
# INF_ENGINE_INCLUDE_DIRS - Inference Engine include folder
|
||||
# INF_ENGINE_LIBRARIES - Inference Engine libraries and it's dependencies
|
||||
# Result:
|
||||
# INF_ENGINE_TARGET - set to name of imported library target representing InferenceEngine
|
||||
#
|
||||
macro(ie_fail)
|
||||
set(HAVE_INF_ENGINE FALSE)
|
||||
return()
|
||||
endmacro()
|
||||
|
||||
if(NOT HAVE_CXX11)
|
||||
ie_fail()
|
||||
message(WARNING "DL Inference engine requires C++11. You can turn it on via ENABLE_CXX11=ON CMake flag.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT INF_ENGINE_ROOT_DIR OR NOT EXISTS "${INF_ENGINE_ROOT_DIR}/include/inference_engine.hpp")
|
||||
set(ie_root_paths "${INF_ENGINE_ROOT_DIR}")
|
||||
if(DEFINED ENV{INTEL_CVSDK_DIR})
|
||||
list(APPEND ie_root_paths "$ENV{INTEL_CVSDK_DIR}")
|
||||
list(APPEND ie_root_paths "$ENV{INTEL_CVSDK_DIR}/inference_engine")
|
||||
endif()
|
||||
if(DEFINED INTEL_CVSDK_DIR)
|
||||
list(APPEND ie_root_paths "${INTEL_CVSDK_DIR}")
|
||||
list(APPEND ie_root_paths "${INTEL_CVSDK_DIR}/inference_engine")
|
||||
endif()
|
||||
# =======================
|
||||
|
||||
if(NOT ie_root_paths)
|
||||
list(APPEND ie_root_paths "/opt/intel/deeplearning_deploymenttoolkit/deployment_tools/inference_engine")
|
||||
endif()
|
||||
function(add_custom_ie_build _inc _lib _lib_rel _lib_dbg _msg)
|
||||
if(NOT _inc OR NOT (_lib OR _lib_rel OR _lib_dbg))
|
||||
return()
|
||||
endif()
|
||||
add_library(inference_engine UNKNOWN IMPORTED)
|
||||
set_target_properties(inference_engine PROPERTIES
|
||||
IMPORTED_LOCATION "${_lib}"
|
||||
IMPORTED_IMPLIB_RELEASE "${_lib_rel}"
|
||||
IMPORTED_IMPLIB_DEBUG "${_lib_dbg}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_inc}"
|
||||
)
|
||||
find_library(omp_lib iomp5 PATHS "${INF_ENGINE_OMP_DIR}" NO_DEFAULT_PATH)
|
||||
if(NOT omp_lib)
|
||||
message(WARNING "OpenMP for IE have not been found. Set INF_ENGINE_OMP_DIR variable if you experience build errors.")
|
||||
else()
|
||||
set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${omp_lib}")
|
||||
endif()
|
||||
set(INF_ENGINE_VERSION "Unknown" CACHE STRING "")
|
||||
set(INF_ENGINE_TARGET inference_engine PARENT_SCOPE)
|
||||
message(STATUS "Detected InferenceEngine: ${_msg}")
|
||||
endfunction()
|
||||
|
||||
find_path(INF_ENGINE_ROOT_DIR include/inference_engine.hpp PATHS ${ie_root_paths})
|
||||
# ======================
|
||||
|
||||
find_package(InferenceEngine QUIET)
|
||||
if(InferenceEngine_FOUND)
|
||||
set(INF_ENGINE_TARGET IE::inference_engine)
|
||||
set(INF_ENGINE_VERSION "${InferenceEngine_VERSION}" CACHE STRING "")
|
||||
message(STATUS "Detected InferenceEngine: cmake package")
|
||||
endif()
|
||||
|
||||
set(INF_ENGINE_INCLUDE_DIRS "${INF_ENGINE_ROOT_DIR}/include" CACHE PATH "Path to Inference Engine include directory")
|
||||
|
||||
if(NOT INF_ENGINE_ROOT_DIR
|
||||
OR NOT EXISTS "${INF_ENGINE_ROOT_DIR}"
|
||||
OR NOT EXISTS "${INF_ENGINE_ROOT_DIR}/include/inference_engine.hpp"
|
||||
)
|
||||
ie_fail()
|
||||
if(NOT INF_ENGINE_TARGET AND INF_ENGINE_LIB_DIRS AND INF_ENGINE_INCLUDE_DIRS)
|
||||
find_path(ie_custom_inc "inference_engine.hpp" PATHS "${INF_ENGINE_INCLUDE_DIRS}" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_lib "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_lib_rel "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}/Release" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_lib_dbg "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}/Debug" NO_DEFAULT_PATH)
|
||||
add_custom_ie_build("${ie_custom_inc}" "${ie_custom_lib}" "${ie_custom_lib_rel}" "${ie_custom_lib_dbg}" "INF_ENGINE_{INCLUDE,LIB}_DIRS")
|
||||
endif()
|
||||
|
||||
set(INF_ENGINE_LIBRARIES "")
|
||||
set(_loc "$ENV{INTEL_CVSDK_DIR}")
|
||||
if(NOT INF_ENGINE_TARGET AND _loc)
|
||||
set(INF_ENGINE_PLATFORM "ubuntu_16.04" CACHE STRING "InferenceEngine platform (library dir)")
|
||||
find_path(ie_custom_env_inc "inference_engine.hpp" PATHS "${_loc}/deployment_tools/inference_engine/include" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/${INF_ENGINE_PLATFORM}/intel64" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib_rel "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Release" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib_dbg "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Debug" NO_DEFAULT_PATH)
|
||||
add_custom_ie_build("${ie_custom_env_inc}" "${ie_custom_env_lib}" "${ie_custom_env_lib_rel}" "${ie_custom_env_lib_dbg}" "OpenVINO (${_loc})")
|
||||
endif()
|
||||
|
||||
set(ie_lib_list inference_engine)
|
||||
# Add more features to the target
|
||||
|
||||
link_directories(
|
||||
${INTEL_CVSDK_DIR}/inference_engine/external/mkltiny_lnx/lib
|
||||
${INTEL_CVSDK_DIR}/inference_engine/external/cldnn/lib
|
||||
)
|
||||
|
||||
foreach(lib ${ie_lib_list})
|
||||
find_library(${lib}
|
||||
NAMES ${lib}
|
||||
# For inference_engine
|
||||
HINTS ${IE_PLUGINS_PATH}
|
||||
HINTS "$ENV{IE_PLUGINS_PATH}"
|
||||
)
|
||||
if(NOT ${lib})
|
||||
ie_fail()
|
||||
endif()
|
||||
list(APPEND INF_ENGINE_LIBRARIES ${${lib}})
|
||||
endforeach()
|
||||
|
||||
set(HAVE_INF_ENGINE TRUE)
|
||||
if(INF_ENGINE_TARGET)
|
||||
if(NOT INF_ENGINE_RELEASE)
|
||||
message(WARNING "InferenceEngine version have not been set, 2018R3 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
endif()
|
||||
set(INF_ENGINE_RELEASE "2018030000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
|
||||
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -20,16 +20,19 @@ if(DEFINED ENV{OPENCV_DOWNLOAD_PATH})
|
||||
endif()
|
||||
set(OPENCV_DOWNLOAD_PATH "${OpenCV_SOURCE_DIR}/.cache" CACHE PATH "${HELP_OPENCV_DOWNLOAD_PATH}")
|
||||
set(OPENCV_DOWNLOAD_LOG "${OpenCV_BINARY_DIR}/CMakeDownloadLog.txt")
|
||||
set(OPENCV_DOWNLOAD_WITH_CURL "${OpenCV_BINARY_DIR}/download_with_curl.sh")
|
||||
set(OPENCV_DOWNLOAD_WITH_WGET "${OpenCV_BINARY_DIR}/download_with_wget.sh")
|
||||
|
||||
# Init download cache directory and log file
|
||||
# Init download cache directory and log file and helper scripts
|
||||
if(NOT EXISTS "${OPENCV_DOWNLOAD_PATH}")
|
||||
file(MAKE_DIRECTORY ${OPENCV_DOWNLOAD_PATH})
|
||||
endif()
|
||||
if(NOT EXISTS "${OPENCV_DOWNLOAD_PATH}/.gitignore")
|
||||
file(WRITE "${OPENCV_DOWNLOAD_PATH}/.gitignore" "*\n")
|
||||
endif()
|
||||
file(WRITE "${OPENCV_DOWNLOAD_LOG}" "use_cache \"${OPENCV_DOWNLOAD_PATH}\"\n")
|
||||
|
||||
file(WRITE "${OPENCV_DOWNLOAD_LOG}" "#use_cache \"${OPENCV_DOWNLOAD_PATH}\"\n")
|
||||
file(REMOVE "${OPENCV_DOWNLOAD_WITH_CURL}")
|
||||
file(REMOVE "${OPENCV_DOWNLOAD_WITH_WGET}")
|
||||
|
||||
function(ocv_download)
|
||||
cmake_parse_arguments(DL "UNPACK;RELATIVE_URL" "FILENAME;HASH;DESTINATION_DIR;ID;STATUS" "URL" ${ARGN})
|
||||
@@ -103,7 +106,7 @@ function(ocv_download)
|
||||
endif()
|
||||
|
||||
# Log all calls to file
|
||||
ocv_download_log("do_${mode} \"${DL_FILENAME}\" \"${DL_HASH}\" \"${DL_URL}\" \"${DL_DESTINATION_DIR}\"")
|
||||
ocv_download_log("#do_${mode} \"${DL_FILENAME}\" \"${DL_HASH}\" \"${DL_URL}\" \"${DL_DESTINATION_DIR}\"")
|
||||
# ... and to console
|
||||
set(__msg_prefix "")
|
||||
if(DL_ID)
|
||||
@@ -191,6 +194,9 @@ function(ocv_download)
|
||||
For details please refer to the download log file:
|
||||
${OPENCV_DOWNLOAD_LOG}
|
||||
")
|
||||
# write helper scripts for failed downloads
|
||||
file(APPEND "${OPENCV_DOWNLOAD_WITH_CURL}" "curl --output \"${CACHE_CANDIDATE}\" \"${DL_URL}\"\n")
|
||||
file(APPEND "${OPENCV_DOWNLOAD_WITH_WGET}" "wget -O \"${CACHE_CANDIDATE}\" \"${DL_URL}\"\n")
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@ endif()
|
||||
|
||||
if(VA_INCLUDE_DIR)
|
||||
set(HAVE_VA TRUE)
|
||||
set(VA_LIBRARIES "-lva" "-lva-drm")
|
||||
if(NOT DEFINED VA_LIBRARIES)
|
||||
set(VA_LIBRARIES "va" "va-drm")
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_VA FALSE)
|
||||
message(WARNING "libva installation is not found.")
|
||||
|
||||
@@ -1132,7 +1132,7 @@ function(ocv_add_perf_tests)
|
||||
source_group("Src" FILES "${${the_target}_pch}")
|
||||
ocv_add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch})
|
||||
ocv_target_include_modules(${the_target} ${perf_deps} "${perf_path}")
|
||||
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${perf_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS})
|
||||
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${perf_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_PERF_${the_module}_DEPS})
|
||||
add_dependencies(opencv_perf_tests ${the_target})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES LABELS "${OPENCV_MODULE_${the_module}_LABEL};PerfTest")
|
||||
@@ -1175,7 +1175,7 @@ function(ocv_add_perf_tests)
|
||||
endfunction()
|
||||
|
||||
# this is a command for adding OpenCV accuracy/regression tests to the module
|
||||
# ocv_add_accuracy_tests([FILES <source group name> <list of sources>] [DEPENDS_ON] <list of extra dependencies>)
|
||||
# ocv_add_accuracy_tests(<list of extra dependencies>)
|
||||
function(ocv_add_accuracy_tests)
|
||||
ocv_debug_message("ocv_add_accuracy_tests(" ${ARGN} ")")
|
||||
|
||||
@@ -1202,6 +1202,9 @@ function(ocv_add_accuracy_tests)
|
||||
set(OPENCV_TEST_${the_module}_SOURCES ${test_srcs} ${test_hdrs})
|
||||
endif()
|
||||
|
||||
if(OPENCV_MODULE_${the_module}_TEST_SOURCES_DISPATCHED)
|
||||
list(APPEND OPENCV_TEST_${the_module}_SOURCES ${OPENCV_MODULE_${the_module}_TEST_SOURCES_DISPATCHED})
|
||||
endif()
|
||||
ocv_compiler_optimization_process_sources(OPENCV_TEST_${the_module}_SOURCES OPENCV_TEST_${the_module}_DEPS ${the_target})
|
||||
|
||||
if(NOT BUILD_opencv_world)
|
||||
@@ -1211,7 +1214,10 @@ function(ocv_add_accuracy_tests)
|
||||
source_group("Src" FILES "${${the_target}_pch}")
|
||||
ocv_add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
|
||||
ocv_target_include_modules(${the_target} ${test_deps} "${test_path}")
|
||||
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${test_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS})
|
||||
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/test")
|
||||
ocv_target_include_directories(${the_target} "${CMAKE_CURRENT_BINARY_DIR}/test")
|
||||
endif()
|
||||
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${test_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_TEST_${the_module}_DEPS})
|
||||
add_dependencies(opencv_tests ${the_target})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES LABELS "${OPENCV_MODULE_${the_module}_LABEL};AccuracyTest")
|
||||
|
||||
@@ -362,7 +362,7 @@ MACRO(ADD_NATIVE_PRECOMPILED_HEADER _targetName _input)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
#also inlude ${oldProps} to have the same compile options
|
||||
#also include ${oldProps} to have the same compile options
|
||||
GET_TARGET_PROPERTY(oldProps ${_targetName} COMPILE_FLAGS)
|
||||
if (oldProps MATCHES NOTFOUND)
|
||||
SET(oldProps "")
|
||||
|
||||
@@ -1624,7 +1624,7 @@ endif()
|
||||
|
||||
macro(ocv_git_describe var_name path)
|
||||
if(GIT_FOUND)
|
||||
execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --tags --exact-match --dirty
|
||||
execute_process(COMMAND "${GIT_EXECUTABLE}" describe --tags --exact-match --dirty
|
||||
WORKING_DIRECTORY "${path}"
|
||||
OUTPUT_VARIABLE ${var_name}
|
||||
RESULT_VARIABLE GIT_RESULT
|
||||
|
||||
@@ -260,7 +260,7 @@ endif()
|
||||
set(OpenCV_LIBRARIES ${OpenCV_LIBS})
|
||||
|
||||
#
|
||||
# Some macroses for samples
|
||||
# Some macros for samples
|
||||
#
|
||||
macro(ocv_check_dependencies)
|
||||
set(OCV_DEPENDENCIES_FOUND TRUE)
|
||||
|
||||
@@ -29,7 +29,7 @@ What happens in background ?
|
||||
objects). Everything inside rectangle is unknown. Similarly any user input specifying
|
||||
foreground and background are considered as hard-labelling which means they won't change in
|
||||
the process.
|
||||
- Computer does an initial labelling depeding on the data we gave. It labels the foreground and
|
||||
- Computer does an initial labelling depending on the data we gave. It labels the foreground and
|
||||
background pixels (or it hard-labels)
|
||||
- Now a Gaussian Mixture Model(GMM) is used to model the foreground and background.
|
||||
- Depending on the data we gave, GMM learns and create new pixel distribution. That is, the
|
||||
|
||||
@@ -129,7 +129,7 @@ function onOpenCvReady() {
|
||||
</html>
|
||||
@endcode
|
||||
|
||||
@note You have to call delete method of cv.Mat to free memory allocated in Emscripten's heap. Please refer to [Memeory management of Emscripten](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management) for details.
|
||||
@note You have to call delete method of cv.Mat to free memory allocated in Emscripten's heap. Please refer to [Memory management of Emscripten](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management) for details.
|
||||
|
||||
Try it
|
||||
------
|
||||
|
||||
@@ -1016,3 +1016,17 @@
|
||||
year = {2017},
|
||||
organization = {IEEE}
|
||||
}
|
||||
|
||||
@ARTICLE{gonzalez,
|
||||
title={Digital Image Fundamentals, Digital Imaging Processing},
|
||||
author={Gonzalez, Rafael C and others},
|
||||
year={1987},
|
||||
publisher={Addison Wesley Publishing Company}
|
||||
}
|
||||
|
||||
@ARTICLE{gruzman,
|
||||
title={Цифровая обработка изображений в информационных системах},
|
||||
author={Грузман, И.С. and Киричук, В.С. and Косых, В.П. and Перетягин, Г.И. and Спектор, А.А.},
|
||||
year={2000},
|
||||
publisher={Изд-во НГТУ Новосибирск}
|
||||
}
|
||||
|
||||
@@ -4,32 +4,34 @@ Camera Calibration {#tutorial_py_calibration}
|
||||
Goal
|
||||
----
|
||||
|
||||
In this section,
|
||||
- We will learn about distortions in camera, intrinsic and extrinsic parameters of camera etc.
|
||||
- We will learn to find these parameters, undistort images etc.
|
||||
In this section, we will learn about
|
||||
|
||||
* types of distortion caused by cameras
|
||||
* how to find the intrinsic and extrinsic properties of a camera
|
||||
* how to undistort images based off these properties
|
||||
|
||||
Basics
|
||||
------
|
||||
|
||||
Today's cheap pinhole cameras introduces a lot of distortion to images. Two major distortions are
|
||||
Some pinhole cameras introduce significant distortion to images. Two major kinds of distortion are
|
||||
radial distortion and tangential distortion.
|
||||
|
||||
Due to radial distortion, straight lines will appear curved. Its effect is more as we move away from
|
||||
the center of image. For example, one image is shown below, where two edges of a chess board are
|
||||
marked with red lines. But you can see that border is not a straight line and doesn't match with the
|
||||
Radial distortion causes straight lines to appear curved. Radial distortion becomes larger the farther points are from
|
||||
the center of the image. For example, one image is shown below in which two edges of a chess board are
|
||||
marked with red lines. But, you can see that the border of the chess board is not a straight line and doesn't match with the
|
||||
red line. All the expected straight lines are bulged out. Visit [Distortion
|
||||
(optics)](http://en.wikipedia.org/wiki/Distortion_%28optics%29) for more details.
|
||||
|
||||

|
||||
|
||||
This distortion is represented as follows:
|
||||
Radial distortion can be represented as follows:
|
||||
|
||||
\f[x_{distorted} = x( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6) \\
|
||||
y_{distorted} = y( 1 + k_1 r^2 + k_2 r^4 + k_3 r^6)\f]
|
||||
|
||||
Similarly, another distortion is the tangential distortion which occurs because image taking lense
|
||||
is not aligned perfectly parallel to the imaging plane. So some areas in image may look nearer than
|
||||
expected. It is represented as below:
|
||||
Similarly, tangential distortion occurs because the image-taking lense
|
||||
is not aligned perfectly parallel to the imaging plane. So, some areas in the image may look nearer than
|
||||
expected. The amount of tangential distortion can be represented as below:
|
||||
|
||||
\f[x_{distorted} = x + [ 2p_1xy + p_2(r^2+2x^2)] \\
|
||||
y_{distorted} = y + [ p_1(r^2+ 2y^2)+ 2p_2xy]\f]
|
||||
@@ -38,10 +40,9 @@ In short, we need to find five parameters, known as distortion coefficients give
|
||||
|
||||
\f[Distortion \; coefficients=(k_1 \hspace{10pt} k_2 \hspace{10pt} p_1 \hspace{10pt} p_2 \hspace{10pt} k_3)\f]
|
||||
|
||||
In addition to this, we need to find a few more information, like intrinsic and extrinsic parameters
|
||||
of a camera. Intrinsic parameters are specific to a camera. It includes information like focal
|
||||
length (\f$f_x,f_y\f$), optical centers (\f$c_x, c_y\f$) etc. It is also called camera matrix. It depends on
|
||||
the camera only, so once calculated, it can be stored for future purposes. It is expressed as a 3x3
|
||||
In addition to this, we need to some other information, like the intrinsic and extrinsic parameters
|
||||
of the camera. Intrinsic parameters are specific to a camera. They include information like focal
|
||||
length (\f$f_x,f_y\f$) and optical centers (\f$c_x, c_y\f$). The focal length and optical centers can be used to create a camera matrix, which can be used to remove distortion due to the lenses of a specific camera. The camera matrix is unique to a specific camera, so once calculated, it can be reused on other images taken by the same camera. It is expressed as a 3x3
|
||||
matrix:
|
||||
|
||||
\f[camera \; matrix = \left [ \begin{matrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{matrix} \right ]\f]
|
||||
@@ -49,20 +50,16 @@ matrix:
|
||||
Extrinsic parameters corresponds to rotation and translation vectors which translates a coordinates
|
||||
of a 3D point to a coordinate system.
|
||||
|
||||
For stereo applications, these distortions need to be corrected first. To find all these parameters,
|
||||
what we have to do is to provide some sample images of a well defined pattern (eg, chess board). We
|
||||
find some specific points in it ( square corners in chess board). We know its coordinates in real
|
||||
world space and we know its coordinates in image. With these data, some mathematical problem is
|
||||
solved in background to get the distortion coefficients. That is the summary of the whole story. For
|
||||
better results, we need atleast 10 test patterns.
|
||||
For stereo applications, these distortions need to be corrected first. To find these parameters,
|
||||
we must provide some sample images of a well defined pattern (e.g. a chess board). We
|
||||
find some specific points of which we already know the relative positions (e.g. square corners in the chess board). We know the coordinates of these points in real world space and we know the coordinates in the image, so we can solve for the distortion coefficients. For better results, we need at least 10 test patterns.
|
||||
|
||||
Code
|
||||
----
|
||||
|
||||
As mentioned above, we need atleast 10 test patterns for camera calibration. OpenCV comes with some
|
||||
images of chess board (see samples/cpp/left01.jpg -- left14.jpg), so we will utilize it. For sake of
|
||||
understanding, consider just one image of a chess board. Important input datas needed for camera
|
||||
calibration is a set of 3D real world points and its corresponding 2D image points. 2D image points
|
||||
As mentioned above, we need at least 10 test patterns for camera calibration. OpenCV comes with some
|
||||
images of a chess board (see samples/data/left01.jpg -- left14.jpg), so we will utilize these. Consider an image of a chess board. The important input data needed for calibration of the camera
|
||||
is the set of 3D real world points and the corresponding 2D coordinates of these points in the image. 2D image points
|
||||
are OK which we can easily find from the image. (These image points are locations where two black
|
||||
squares touch each other in chess boards)
|
||||
|
||||
@@ -72,7 +69,7 @@ values. But for simplicity, we can say chess board was kept stationary at XY pla
|
||||
and camera was moved accordingly. This consideration helps us to find only X,Y values. Now for X,Y
|
||||
values, we can simply pass the points as (0,0), (1,0), (2,0), ... which denotes the location of
|
||||
points. In this case, the results we get will be in the scale of size of chess board square. But if
|
||||
we know the square size, (say 30 mm), and we can pass the values as (0,0),(30,0),(60,0),..., we get
|
||||
we know the square size, (say 30 mm), we can pass the values as (0,0), (30,0), (60,0), ... . Thus, we get
|
||||
the results in mm. (In this case, we don't know square size since we didn't take those images, so we
|
||||
pass in terms of square size).
|
||||
|
||||
@@ -80,23 +77,22 @@ pass in terms of square size).
|
||||
|
||||
### Setup
|
||||
|
||||
So to find pattern in chess board, we use the function, **cv.findChessboardCorners()**. We also
|
||||
need to pass what kind of pattern we are looking, like 8x8 grid, 5x5 grid etc. In this example, we
|
||||
So to find pattern in chess board, we can use the function, **cv.findChessboardCorners()**. We also
|
||||
need to pass what kind of pattern we are looking for, like 8x8 grid, 5x5 grid etc. In this example, we
|
||||
use 7x6 grid. (Normally a chess board has 8x8 squares and 7x7 internal corners). It returns the
|
||||
corner points and retval which will be True if pattern is obtained. These corners will be placed in
|
||||
an order (from left-to-right, top-to-bottom)
|
||||
|
||||
@sa This function may not be able to find the required pattern in all the images. So one good option
|
||||
@sa This function may not be able to find the required pattern in all the images. So, one good option
|
||||
is to write the code such that, it starts the camera and check each frame for required pattern. Once
|
||||
pattern is obtained, find the corners and store it in a list. Also provides some interval before
|
||||
the pattern is obtained, find the corners and store it in a list. Also, provide some interval before
|
||||
reading next frame so that we can adjust our chess board in different direction. Continue this
|
||||
process until required number of good patterns are obtained. Even in the example provided here, we
|
||||
are not sure out of 14 images given, how many are good. So we read all the images and take the good
|
||||
process until the required number of good patterns are obtained. Even in the example provided here, we
|
||||
are not sure how many images out of the 14 given are good. Thus, we must read all the images and take only the good
|
||||
ones.
|
||||
|
||||
@sa Instead of chess board, we can use some circular grid, but then use the function
|
||||
**cv.findCirclesGrid()** to find the pattern. It is said that less number of images are enough when
|
||||
using circular grid.
|
||||
@sa Instead of chess board, we can alternatively use a circular grid. In this case, we must use the function
|
||||
**cv.findCirclesGrid()** to find the pattern. Fewer images are sufficient to perform camera calibration using a circular grid.
|
||||
|
||||
Once we find the corners, we can increase their accuracy using **cv.cornerSubPix()**. We can also
|
||||
draw the pattern using **cv.drawChessboardCorners()**. All these steps are included in below code:
|
||||
@@ -146,22 +142,23 @@ One image with pattern drawn on it is shown below:
|
||||
|
||||
### Calibration
|
||||
|
||||
So now we have our object points and image points we are ready to go for calibration. For that we
|
||||
use the function, **cv.calibrateCamera()**. It returns the camera matrix, distortion coefficients,
|
||||
Now that we have our object points and image points, we are ready to go for calibration. We can
|
||||
use the function, **cv.calibrateCamera()** which returns the camera matrix, distortion coefficients,
|
||||
rotation and translation vectors etc.
|
||||
@code{.py}
|
||||
ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
|
||||
@endcode
|
||||
|
||||
### Undistortion
|
||||
|
||||
We have got what we were trying. Now we can take an image and undistort it. OpenCV comes with two
|
||||
methods, we will see both. But before that, we can refine the camera matrix based on a free scaling
|
||||
Now, we can take an image and undistort it. OpenCV comes with two
|
||||
methods for doing this. However first, we can refine the camera matrix based on a free scaling
|
||||
parameter using **cv.getOptimalNewCameraMatrix()**. If the scaling parameter alpha=0, it returns
|
||||
undistorted image with minimum unwanted pixels. So it may even remove some pixels at image corners.
|
||||
If alpha=1, all pixels are retained with some extra black images. It also returns an image ROI which
|
||||
If alpha=1, all pixels are retained with some extra black images. This function also returns an image ROI which
|
||||
can be used to crop the result.
|
||||
|
||||
So we take a new image (left12.jpg in this case. That is the first image in this chapter)
|
||||
So, we take a new image (left12.jpg in this case. That is the first image in this chapter)
|
||||
@code{.py}
|
||||
img = cv.imread('left12.jpg')
|
||||
h, w = img.shape[:2]
|
||||
@@ -169,7 +166,7 @@ newcameramtx, roi = cv.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
|
||||
@endcode
|
||||
#### 1. Using **cv.undistort()**
|
||||
|
||||
This is the shortest path. Just call the function and use ROI obtained above to crop the result.
|
||||
This is the easiest way. Just call the function and use ROI obtained above to crop the result.
|
||||
@code{.py}
|
||||
# undistort
|
||||
dst = cv.undistort(img, mtx, dist, None, newcameramtx)
|
||||
@@ -181,7 +178,7 @@ cv.imwrite('calibresult.png', dst)
|
||||
@endcode
|
||||
#### 2. Using **remapping**
|
||||
|
||||
This is curved path. First find a mapping function from distorted image to undistorted image. Then
|
||||
This way is a little bit more difficult. First, find a mapping function from the distorted image to the undistorted image. Then
|
||||
use the remap function.
|
||||
@code{.py}
|
||||
# undistort
|
||||
@@ -193,23 +190,22 @@ x, y, w, h = roi
|
||||
dst = dst[y:y+h, x:x+w]
|
||||
cv.imwrite('calibresult.png', dst)
|
||||
@endcode
|
||||
Both the methods give the same result. See the result below:
|
||||
Still, both the methods give the same result. See the result below:
|
||||
|
||||

|
||||
|
||||
You can see in the result that all the edges are straight.
|
||||
|
||||
Now you can store the camera matrix and distortion coefficients using write functions in Numpy
|
||||
Now you can store the camera matrix and distortion coefficients using write functions in NumPy
|
||||
(np.savez, np.savetxt etc) for future uses.
|
||||
|
||||
Re-projection Error
|
||||
-------------------
|
||||
|
||||
Re-projection error gives a good estimation of just how exact is the found parameters. This should
|
||||
be as close to zero as possible. Given the intrinsic, distortion, rotation and translation matrices,
|
||||
we first transform the object point to image point using **cv.projectPoints()**. Then we calculate
|
||||
Re-projection error gives a good estimation of just how exact the found parameters are. The closer the re-projection error is to zero, the more accurate the parameters we found are. Given the intrinsic, distortion, rotation and translation matrices,
|
||||
we must first transform the object point to image point using **cv.projectPoints()**. Then, we can calculate
|
||||
the absolute norm between what we got with our transformation and the corner finding algorithm. To
|
||||
find the average error we calculate the arithmetical mean of the errors calculate for all the
|
||||
find the average error, we calculate the arithmetical mean of the errors calculated for all the
|
||||
calibration images.
|
||||
@code{.py}
|
||||
mean_error = 0
|
||||
|
||||
@@ -37,7 +37,7 @@ So what happens in background ?
|
||||
objects). Everything inside rectangle is unknown. Similarly any user input specifying
|
||||
foreground and background are considered as hard-labelling which means they won't change in
|
||||
the process.
|
||||
- Computer does an initial labelling depeding on the data we gave. It labels the foreground and
|
||||
- Computer does an initial labelling depending on the data we gave. It labels the foreground and
|
||||
background pixels (or it hard-labels)
|
||||
- Now a Gaussian Mixture Model(GMM) is used to model the foreground and background.
|
||||
- Depending on the data we gave, GMM learns and create new pixel distribution. That is, the
|
||||
|
||||
@@ -183,7 +183,7 @@ minimizes the **weighted within-class variance** given by the relation :
|
||||
|
||||
where
|
||||
|
||||
\f[q_1(t) = \sum_{i=1}^{t} P(i) \quad \& \quad q_1(t) = \sum_{i=t+1}^{I} P(i)\f]\f[\mu_1(t) = \sum_{i=1}^{t} \frac{iP(i)}{q_1(t)} \quad \& \quad \mu_2(t) = \sum_{i=t+1}^{I} \frac{iP(i)}{q_2(t)}\f]\f[\sigma_1^2(t) = \sum_{i=1}^{t} [i-\mu_1(t)]^2 \frac{P(i)}{q_1(t)} \quad \& \quad \sigma_2^2(t) = \sum_{i=t+1}^{I} [i-\mu_1(t)]^2 \frac{P(i)}{q_2(t)}\f]
|
||||
\f[q_1(t) = \sum_{i=1}^{t} P(i) \quad \& \quad q_2(t) = \sum_{i=t+1}^{I} P(i)\f]\f[\mu_1(t) = \sum_{i=1}^{t} \frac{iP(i)}{q_1(t)} \quad \& \quad \mu_2(t) = \sum_{i=t+1}^{I} \frac{iP(i)}{q_2(t)}\f]\f[\sigma_1^2(t) = \sum_{i=1}^{t} [i-\mu_1(t)]^2 \frac{P(i)}{q_1(t)} \quad \& \quad \sigma_2^2(t) = \sum_{i=t+1}^{I} [i-\mu_2(t)]^2 \frac{P(i)}{q_2(t)}\f]
|
||||
|
||||
It actually finds a value of t which lies in between two peaks such that variances to both classes
|
||||
are minimum. It can be simply implemented in Python as follows:
|
||||
|
||||
@@ -16,7 +16,7 @@ In this tutorial is explained how to build a real time application to estimate t
|
||||
order to track a textured object with six degrees of freedom given a 2D image and its 3D textured
|
||||
model.
|
||||
|
||||
The application will have the followings parts:
|
||||
The application will have the following parts:
|
||||
|
||||
- Read 3D textured object model and object mesh.
|
||||
- Take input from Camera or Video.
|
||||
@@ -426,16 +426,16 @@ Here is explained in detail the code for the real time application:
|
||||
@endcode
|
||||
OpenCV provides four PnP methods: ITERATIVE, EPNP, P3P and DLS. Depending on the application type,
|
||||
the estimation method will be different. In the case that we want to make a real time application,
|
||||
the more suitable methods are EPNP and P3P due to that are faster than ITERATIVE and DLS at
|
||||
the more suitable methods are EPNP and P3P since they are faster than ITERATIVE and DLS at
|
||||
finding an optimal solution. However, EPNP and P3P are not especially robust in front of planar
|
||||
surfaces and sometimes the pose estimation seems to have a mirror effect. Therefore, in this this
|
||||
tutorial is used ITERATIVE method due to the object to be detected has planar surfaces.
|
||||
surfaces and sometimes the pose estimation seems to have a mirror effect. Therefore, in this
|
||||
tutorial an ITERATIVE method is used due to the object to be detected has planar surfaces.
|
||||
|
||||
The OpenCV RANSAC implementation wants you to provide three parameters: the maximum number of
|
||||
iterations until stop the algorithm, the maximum allowed distance between the observed and
|
||||
computed point projections to consider it an inlier and the confidence to obtain a good result.
|
||||
The OpenCV RANSAC implementation wants you to provide three parameters: 1) the maximum number of
|
||||
iterations until the algorithm stops, 2) the maximum allowed distance between the observed and
|
||||
computed point projections to consider it an inlier and 3) the confidence to obtain a good result.
|
||||
You can tune these parameters in order to improve your algorithm performance. Increasing the
|
||||
number of iterations you will have a more accurate solution, but will take more time to find a
|
||||
number of iterations will have a more accurate solution, but will take more time to find a
|
||||
solution. Increasing the reprojection error will reduce the computation time, but your solution
|
||||
will be unaccurate. Decreasing the confidence your algorithm will be faster, but the obtained
|
||||
solution will be unaccurate.
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Changing the contrast and brightness of an image! {#tutorial_basic_linear_transform}
|
||||
=================================================
|
||||
|
||||
@prev_tutorial{tutorial_adding_images}
|
||||
@next_tutorial{tutorial_discrete_fourier_transform}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -53,48 +56,143 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp)
|
||||
|
||||
- The following code performs the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ :
|
||||
@include BasicLinearTransforms.cpp
|
||||
@include samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java)
|
||||
|
||||
- The following code performs the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ :
|
||||
@include samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py)
|
||||
|
||||
- The following code performs the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ :
|
||||
@include samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# We begin by creating parameters to save \f$\alpha\f$ and \f$\beta\f$ to be entered by the user:
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-parameters
|
||||
- We load an image using @ref cv::imread and save it in a Mat object:
|
||||
|
||||
-# We load an image using @ref cv::imread and save it in a Mat object:
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-load
|
||||
-# Now, since we will make some transformations to this image, we need a new Mat object to store
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-load
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-load
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-load
|
||||
@end_toggle
|
||||
|
||||
- Now, since we will make some transformations to this image, we need a new Mat object to store
|
||||
it. Also, we want this to have the following features:
|
||||
|
||||
- Initial pixel values equal to zero
|
||||
- Same size and type as the original image
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-output
|
||||
We observe that @ref cv::Mat::zeros returns a Matlab-style zero initializer based on
|
||||
*image.size()* and *image.type()*
|
||||
|
||||
-# Now, to perform the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ we will access to each
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-output
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-output
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-output
|
||||
@end_toggle
|
||||
|
||||
We observe that @ref cv::Mat::zeros returns a Matlab-style zero initializer based on
|
||||
*image.size()* and *image.type()*
|
||||
|
||||
- We ask now the values of \f$\alpha\f$ and \f$\beta\f$ to be entered by the user:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-parameters
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-parameters
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-parameters
|
||||
@end_toggle
|
||||
|
||||
- Now, to perform the operation \f$g(i,j) = \alpha \cdot f(i,j) + \beta\f$ we will access to each
|
||||
pixel in image. Since we are operating with BGR images, we will have three values per pixel (B,
|
||||
G and R), so we will also access them separately. Here is the piece of code:
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-operation
|
||||
Notice the following:
|
||||
- To access each pixel in the images we are using this syntax: *image.at\<Vec3b\>(y,x)[c]*
|
||||
where *y* is the row, *x* is the column and *c* is R, G or B (0, 1 or 2).
|
||||
- Since the operation \f$\alpha \cdot p(i,j) + \beta\f$ can give values out of range or not
|
||||
integers (if \f$\alpha\f$ is float), we use cv::saturate_cast to make sure the
|
||||
values are valid.
|
||||
|
||||
-# Finally, we create windows and show the images, the usual way.
|
||||
@snippet BasicLinearTransforms.cpp basic-linear-transform-display
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-operation
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-operation
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-operation
|
||||
@end_toggle
|
||||
|
||||
Notice the following (**C++ code only**):
|
||||
- To access each pixel in the images we are using this syntax: *image.at\<Vec3b\>(y,x)[c]*
|
||||
where *y* is the row, *x* is the column and *c* is R, G or B (0, 1 or 2).
|
||||
- Since the operation \f$\alpha \cdot p(i,j) + \beta\f$ can give values out of range or not
|
||||
integers (if \f$\alpha\f$ is float), we use cv::saturate_cast to make sure the
|
||||
values are valid.
|
||||
|
||||
- Finally, we create windows and show the images, the usual way.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/BasicLinearTransforms.cpp basic-linear-transform-display
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/BasicLinearTransformsDemo.java basic-linear-transform-display
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/BasicLinearTransforms.py basic-linear-transform-display
|
||||
@end_toggle
|
||||
|
||||
@note
|
||||
Instead of using the **for** loops to access each pixel, we could have simply used this command:
|
||||
@code{.cpp}
|
||||
image.convertTo(new_image, -1, alpha, beta);
|
||||
@endcode
|
||||
where @ref cv::Mat::convertTo would effectively perform *new_image = a*image + beta\*. However, we
|
||||
wanted to show you how to access each pixel. In any case, both methods give the same result but
|
||||
convertTo is more optimized and works a lot faster.
|
||||
|
||||
@add_toggle_cpp
|
||||
@code{.cpp}
|
||||
image.convertTo(new_image, -1, alpha, beta);
|
||||
@endcode
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@code{.java}
|
||||
image.convertTo(newImage, -1, alpha, beta);
|
||||
@endcode
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@code{.py}
|
||||
new_image = cv.convertScaleAbs(image, alpha=alpha, beta=beta)
|
||||
@endcode
|
||||
@end_toggle
|
||||
|
||||
where @ref cv::Mat::convertTo would effectively perform *new_image = a*image + beta\*. However, we
|
||||
wanted to show you how to access each pixel. In any case, both methods give the same result but
|
||||
convertTo is more optimized and works a lot faster.
|
||||
|
||||
Result
|
||||
------
|
||||
@@ -185,10 +283,31 @@ and are not intended to be used as a replacement of a raster graphics editor!**
|
||||
|
||||
### Code
|
||||
|
||||
@add_toggle_cpp
|
||||
Code for the tutorial is [here](https://github.com/opencv/opencv/blob/3.4/samples/cpp/tutorial_code/ImgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.cpp).
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
Code for the tutorial is [here](https://github.com/opencv/opencv/blob/3.4/samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/ChangingContrastBrightnessImageDemo.java).
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
Code for the tutorial is [here](https://github.com/opencv/opencv/blob/3.4/samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.py).
|
||||
@end_toggle
|
||||
|
||||
Code for the gamma correction:
|
||||
|
||||
@snippet changing_contrast_brightness_image.cpp changing-contrast-brightness-gamma-correction
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.cpp changing-contrast-brightness-gamma-correction
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgProc/changing_contrast_brightness_image/ChangingContrastBrightnessImageDemo.java changing-contrast-brightness-gamma-correction
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/changing_contrast_brightness_image/changing_contrast_brightness_image.py changing-contrast-brightness-gamma-correction
|
||||
@end_toggle
|
||||
|
||||
A look-up table is used to improve the performance of the computation as only 256 values needs to be calculated once.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Discrete Fourier Transform {#tutorial_discrete_fourier_transform}
|
||||
==========================
|
||||
|
||||
@prev_tutorial{tutorial_random_generator_and_text}
|
||||
@prev_tutorial{tutorial_basic_linear_transform}
|
||||
@next_tutorial{tutorial_file_input_output_with_xml_yml}
|
||||
|
||||
Goal
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
File Input and Output using XML and YAML files {#tutorial_file_input_output_with_xml_yml}
|
||||
==============================================
|
||||
|
||||
@prev_tutorial{tutorial_discrete_fourier_transform}
|
||||
@next_tutorial{tutorial_interoperability_with_OpenCV_1}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
How to scan images, lookup tables and time measurement with OpenCV {#tutorial_how_to_scan_images}
|
||||
==================================================================
|
||||
|
||||
@prev_tutorial{tutorial_mat_the_basic_image_container}
|
||||
@next_tutorial{tutorial_mat_mask_operations}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
How to use the OpenCV parallel_for_ to parallelize your code {#tutorial_how_to_use_OpenCV_parallel_for_}
|
||||
==================================================================
|
||||
|
||||
@prev_tutorial{tutorial_how_to_use_ippa_conversion}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Intel® IPP Asynchronous C/C++ library in OpenCV {#tutorial_how_to_use_ippa_conversion}
|
||||
===============================================
|
||||
|
||||
@prev_tutorial{tutorial_interoperability_with_OpenCV_1}
|
||||
@next_tutorial{tutorial_how_to_use_OpenCV_parallel_for_}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Interoperability with OpenCV 1 {#tutorial_interoperability_with_OpenCV_1}
|
||||
==============================
|
||||
|
||||
@prev_tutorial{tutorial_file_input_output_with_xml_yml}
|
||||
@next_tutorial{tutorial_how_to_use_ippa_conversion}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,31 +1,59 @@
|
||||
Operations with images {#tutorial_mat_operations}
|
||||
======================
|
||||
|
||||
@prev_tutorial{tutorial_mat_mask_operations}
|
||||
@next_tutorial{tutorial_adding_images}
|
||||
|
||||
Input/Output
|
||||
------------
|
||||
|
||||
### Images
|
||||
|
||||
Load an image from a file:
|
||||
@code{.cpp}
|
||||
Mat img = imread(filename)
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Load an image from a file
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Load an image from a file
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Load an image from a file
|
||||
@end_toggle
|
||||
|
||||
If you read a jpg file, a 3 channel image is created by default. If you need a grayscale image, use:
|
||||
|
||||
@code{.cpp}
|
||||
Mat img = imread(filename, IMREAD_GRAYSCALE);
|
||||
@endcode
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Load an image from a file in grayscale
|
||||
@end_toggle
|
||||
|
||||
@note format of the file is determined by its content (first few bytes) Save an image to a file:
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Load an image from a file in grayscale
|
||||
@end_toggle
|
||||
|
||||
@code{.cpp}
|
||||
imwrite(filename, img);
|
||||
@endcode
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Load an image from a file in grayscale
|
||||
@end_toggle
|
||||
|
||||
@note format of the file is determined by its extension.
|
||||
@note Format of the file is determined by its content (first few bytes). To save an image to a file:
|
||||
|
||||
@note use imdecode and imencode to read and write image from/to memory rather than a file.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Save image
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Save image
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Save image
|
||||
@end_toggle
|
||||
|
||||
@note Format of the file is determined by its extension.
|
||||
|
||||
@note Use cv::imdecode and cv::imencode to read and write an image from/to memory rather than a file.
|
||||
|
||||
Basic operations with images
|
||||
----------------------------
|
||||
@@ -35,49 +63,65 @@ Basic operations with images
|
||||
In order to get pixel intensity value, you have to know the type of an image and the number of
|
||||
channels. Here is an example for a single channel grey scale image (type 8UC1) and pixel coordinates
|
||||
x and y:
|
||||
@code{.cpp}
|
||||
Scalar intensity = img.at<uchar>(y, x);
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Pixel access 1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Pixel access 1
|
||||
@end_toggle
|
||||
|
||||
C++ version only:
|
||||
intensity.val[0] contains a value from 0 to 255. Note the ordering of x and y. Since in OpenCV
|
||||
images are represented by the same structure as matrices, we use the same convention for both
|
||||
cases - the 0-based row index (or y-coordinate) goes first and the 0-based column index (or
|
||||
x-coordinate) follows it. Alternatively, you can use the following notation:
|
||||
@code{.cpp}
|
||||
Scalar intensity = img.at<uchar>(Point(x, y));
|
||||
@endcode
|
||||
x-coordinate) follows it. Alternatively, you can use the following notation (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 2
|
||||
|
||||
Now let us consider a 3 channel image with BGR color ordering (the default format returned by
|
||||
imread):
|
||||
@code{.cpp}
|
||||
Vec3b intensity = img.at<Vec3b>(y, x);
|
||||
uchar blue = intensity.val[0];
|
||||
uchar green = intensity.val[1];
|
||||
uchar red = intensity.val[2];
|
||||
@endcode
|
||||
|
||||
**C++ code**
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 3
|
||||
|
||||
**Python Python**
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Pixel access 3
|
||||
|
||||
You can use the same method for floating-point images (for example, you can get such an image by
|
||||
running Sobel on a 3 channel image):
|
||||
@code{.cpp}
|
||||
Vec3f intensity = img.at<Vec3f>(y, x);
|
||||
float blue = intensity.val[0];
|
||||
float green = intensity.val[1];
|
||||
float red = intensity.val[2];
|
||||
@endcode
|
||||
running Sobel on a 3 channel image) (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 4
|
||||
|
||||
The same method can be used to change pixel intensities:
|
||||
@code{.cpp}
|
||||
img.at<uchar>(y, x) = 128;
|
||||
@endcode
|
||||
There are functions in OpenCV, especially from calib3d module, such as projectPoints, that take an
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Pixel access 5
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Pixel access 5
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Pixel access 5
|
||||
@end_toggle
|
||||
|
||||
There are functions in OpenCV, especially from calib3d module, such as cv::projectPoints, that take an
|
||||
array of 2D or 3D points in the form of Mat. Matrix should contain exactly one column, each row
|
||||
corresponds to a point, matrix type should be 32FC2 or 32FC3 correspondingly. Such a matrix can be
|
||||
easily constructed from `std::vector`:
|
||||
@code{.cpp}
|
||||
vector<Point2f> points;
|
||||
//... fill the array
|
||||
Mat pointsMat = Mat(points);
|
||||
@endcode
|
||||
One can access a point in this matrix using the same method Mat::at :
|
||||
@code{.cpp}
|
||||
Point2f point = pointsMat.at<Point2f>(i, 0);
|
||||
@endcode
|
||||
easily constructed from `std::vector` (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Mat from points vector
|
||||
|
||||
One can access a point in this matrix using the same method `Mat::at` (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Point access
|
||||
|
||||
### Memory management and reference counting
|
||||
|
||||
@@ -85,91 +129,141 @@ Mat is a structure that keeps matrix/image characteristics (rows and columns num
|
||||
and a pointer to data. So nothing prevents us from having several instances of Mat corresponding to
|
||||
the same data. A Mat keeps a reference count that tells if data has to be deallocated when a
|
||||
particular instance of Mat is destroyed. Here is an example of creating two matrices without copying
|
||||
data:
|
||||
@code{.cpp}
|
||||
std::vector<Point3f> points;
|
||||
// .. fill the array
|
||||
Mat pointsMat = Mat(points).reshape(1);
|
||||
@endcode
|
||||
As a result we get a 32FC1 matrix with 3 columns instead of 32FC3 matrix with 1 column. pointsMat
|
||||
data (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Reference counting 1
|
||||
|
||||
As a result, we get a 32FC1 matrix with 3 columns instead of 32FC3 matrix with 1 column. `pointsMat`
|
||||
uses data from points and will not deallocate the memory when destroyed. In this particular
|
||||
instance, however, developer has to make sure that lifetime of points is longer than of pointsMat.
|
||||
instance, however, developer has to make sure that lifetime of `points` is longer than of `pointsMat`
|
||||
If we need to copy the data, this is done using, for example, cv::Mat::copyTo or cv::Mat::clone:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
Mat img1 = img.clone();
|
||||
@endcode
|
||||
To the contrary with C API where an output image had to be created by developer, an empty output Mat
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Reference counting 2
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Reference counting 2
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Reference counting 2
|
||||
@end_toggle
|
||||
|
||||
To the contrary with C API where an output image had to be created by the developer, an empty output Mat
|
||||
can be supplied to each function. Each implementation calls Mat::create for a destination matrix.
|
||||
This method allocates data for a matrix if it is empty. If it is not empty and has the correct size
|
||||
and type, the method does nothing. If, however, size or type are different from input arguments, the
|
||||
and type, the method does nothing. If however, size or type are different from the input arguments, the
|
||||
data is deallocated (and lost) and a new data is allocated. For example:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
Mat sobelx;
|
||||
Sobel(img, sobelx, CV_32F, 1, 0);
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Reference counting 3
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Reference counting 3
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Reference counting 3
|
||||
@end_toggle
|
||||
|
||||
### Primitive operations
|
||||
|
||||
There is a number of convenient operators defined on a matrix. For example, here is how we can make
|
||||
a black image from an existing greyscale image \`img\`:
|
||||
@code{.cpp}
|
||||
img = Scalar(0);
|
||||
@endcode
|
||||
a black image from an existing greyscale image `img`
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Set image to black
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Set image to black
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Set image to black
|
||||
@end_toggle
|
||||
|
||||
Selecting a region of interest:
|
||||
@code{.cpp}
|
||||
Rect r(10, 10, 100, 100);
|
||||
Mat smallImg = img(r);
|
||||
@endcode
|
||||
A conversion from Mat to C API data structures:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
IplImage img1 = img;
|
||||
CvMat m = img;
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Select ROI
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Select ROI
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Select ROI
|
||||
@end_toggle
|
||||
|
||||
A conversion from Mat to C API data structures (**C++ only**):
|
||||
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp C-API conversion
|
||||
|
||||
Note that there is no data copying here.
|
||||
|
||||
Conversion from color to grey scale:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg"); // loading a 8UC3 image
|
||||
Mat grey;
|
||||
cvtColor(img, grey, COLOR_BGR2GRAY);
|
||||
@endcode
|
||||
Conversion from color to greyscale:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp BGR to Gray
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java BGR to Gray
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py BGR to Gray
|
||||
@end_toggle
|
||||
|
||||
Change image type from 8UC1 to 32FC1:
|
||||
@code{.cpp}
|
||||
src.convertTo(dst, CV_32F);
|
||||
@endcode
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp Convert to CV_32F
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java Convert to CV_32F
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py Convert to CV_32F
|
||||
@end_toggle
|
||||
|
||||
### Visualizing images
|
||||
|
||||
It is very useful to see intermediate results of your algorithm during development process. OpenCV
|
||||
provides a convenient way of visualizing images. A 8U image can be shown using:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
|
||||
namedWindow("image", WINDOW_AUTOSIZE);
|
||||
imshow("image", img);
|
||||
waitKey();
|
||||
@endcode
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp imshow 1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java imshow 1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py imshow 1
|
||||
@end_toggle
|
||||
|
||||
A call to waitKey() starts a message passing cycle that waits for a key stroke in the "image"
|
||||
window. A 32F image needs to be converted to 8U type. For example:
|
||||
@code{.cpp}
|
||||
Mat img = imread("image.jpg");
|
||||
Mat grey;
|
||||
cvtColor(img, grey, COLOR_BGR2GRAY);
|
||||
|
||||
Mat sobelx;
|
||||
Sobel(grey, sobelx, CV_32F, 1, 0);
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/core/mat_operations/mat_operations.cpp imshow 2
|
||||
@end_toggle
|
||||
|
||||
double minVal, maxVal;
|
||||
minMaxLoc(sobelx, &minVal, &maxVal); //find minimum and maximum intensities
|
||||
Mat draw;
|
||||
sobelx.convertTo(draw, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal));
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/core/mat_operations/MatOperations.java imshow 2
|
||||
@end_toggle
|
||||
|
||||
namedWindow("image", WINDOW_AUTOSIZE);
|
||||
imshow("image", draw);
|
||||
waitKey();
|
||||
@endcode
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/core/mat_operations/mat_operations.py imshow 2
|
||||
@end_toggle
|
||||
|
||||
@note Here cv::namedWindow is not necessary since it is immediately followed by cv::imshow.
|
||||
Nevertheless, it can be used to change the window properties or when using cv::createTrackbar
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Mat - The Basic Image Container {#tutorial_mat_the_basic_image_container}
|
||||
===============================
|
||||
|
||||
@next_tutorial{tutorial_how_to_scan_images}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@ understanding how to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_mat_operations
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
Reading/writing images from file, accessing pixels, primitive operations, visualizing images.
|
||||
|
||||
- @subpage tutorial_adding_images
|
||||
@@ -50,29 +54,13 @@ understanding how to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_basic_linear_transform
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
||||
We will learn how to change our image appearance!
|
||||
|
||||
- @subpage tutorial_basic_geometric_drawing
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
||||
We will learn how to draw simple geometry with OpenCV!
|
||||
|
||||
- @subpage tutorial_random_generator_and_text
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
||||
We will draw some *fancy-looking* stuff using OpenCV!
|
||||
We will learn how to change our image appearance!
|
||||
|
||||
- @subpage tutorial_discrete_fourier_transform
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Tutorial was written for the following versions of corresponding software:
|
||||
|
||||
- Download and install Android Studio from https://developer.android.com/studio.
|
||||
|
||||
- Get the latest pre-built OpenCV for Android release from https://github.com/opencv/opencv/releases and unpack it (for example, `opencv-3.4.2-android-sdk.zip`).
|
||||
- Get the latest pre-built OpenCV for Android release from https://github.com/opencv/opencv/releases and unpack it (for example, `opencv-3.4.3-android-sdk.zip`).
|
||||
|
||||
- Download MobileNet object detection model from https://github.com/chuanqi305/MobileNet-SSD. We need a configuration file `MobileNetSSD_deploy.prototxt` and weights `MobileNetSSD_deploy.caffemodel`.
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ Introduction
|
||||
In this tutorial we will learn how to use AKAZE @cite ANB13 local features to detect and match keypoints on
|
||||
two images.
|
||||
We will find keypoints on a pair of images with given homography matrix, match them and count the
|
||||
|
||||
number of inliers (i. e. matches that fit in the given homography).
|
||||
number of inliers (i.e. matches that fit in the given homography).
|
||||
|
||||
You can find expanded version of this example here:
|
||||
<https://github.com/pablofdezalc/test_kaze_akaze_opencv>
|
||||
@@ -16,7 +15,7 @@ You can find expanded version of this example here:
|
||||
Data
|
||||
----
|
||||
|
||||
We are going to use images 1 and 3 from *Graffity* sequence of Oxford dataset.
|
||||
We are going to use images 1 and 3 from *Graffiti* sequence of [Oxford dataset](http://www.robots.ox.ac.uk/~vgg/data/data-aff.html).
|
||||
|
||||

|
||||
|
||||
@@ -27,107 +26,148 @@ Homography is given by a 3 by 3 matrix:
|
||||
3.4663091e-04 -1.4364524e-05 1.0000000e+00
|
||||
@endcode
|
||||
You can find the images (*graf1.png*, *graf3.png*) and homography (*H1to3p.xml*) in
|
||||
*opencv/samples/cpp*.
|
||||
*opencv/samples/data/*.
|
||||
|
||||
### Source Code
|
||||
|
||||
@include cpp/tutorial_code/features2D/AKAZE_match.cpp
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/cpp/tutorial_code/features2D/AKAZE_match.cpp)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/cpp/tutorial_code/features2D/AKAZE_match.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py
|
||||
@end_toggle
|
||||
|
||||
### Explanation
|
||||
|
||||
-# **Load images and homography**
|
||||
@code{.cpp}
|
||||
Mat img1 = imread("graf1.png", IMREAD_GRAYSCALE);
|
||||
Mat img2 = imread("graf3.png", IMREAD_GRAYSCALE);
|
||||
- **Load images and homography**
|
||||
|
||||
Mat homography;
|
||||
FileStorage fs("H1to3p.xml", FileStorage::READ);
|
||||
fs.getFirstTopLevelNode() >> homography;
|
||||
@endcode
|
||||
We are loading grayscale images here. Homography is stored in the xml created with FileStorage.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp load
|
||||
@end_toggle
|
||||
|
||||
-# **Detect keypoints and compute descriptors using AKAZE**
|
||||
@code{.cpp}
|
||||
vector<KeyPoint> kpts1, kpts2;
|
||||
Mat desc1, desc2;
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java load
|
||||
@end_toggle
|
||||
|
||||
AKAZE akaze;
|
||||
akaze(img1, noArray(), kpts1, desc1);
|
||||
akaze(img2, noArray(), kpts2, desc2);
|
||||
@endcode
|
||||
We create AKAZE object and use it's *operator()* functionality. Since we don't need the *mask*
|
||||
parameter, *noArray()* is used.
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py load
|
||||
@end_toggle
|
||||
|
||||
-# **Use brute-force matcher to find 2-nn matches**
|
||||
@code{.cpp}
|
||||
BFMatcher matcher(NORM_HAMMING);
|
||||
vector< vector<DMatch> > nn_matches;
|
||||
matcher.knnMatch(desc1, desc2, nn_matches, 2);
|
||||
@endcode
|
||||
We use Hamming distance, because AKAZE uses binary descriptor by default.
|
||||
We are loading grayscale images here. Homography is stored in the xml created with FileStorage.
|
||||
|
||||
-# **Use 2-nn matches to find correct keypoint matches**
|
||||
@code{.cpp}
|
||||
for(size_t i = 0; i < nn_matches.size(); i++) {
|
||||
DMatch first = nn_matches[i][0];
|
||||
float dist1 = nn_matches[i][0].distance;
|
||||
float dist2 = nn_matches[i][1].distance;
|
||||
- **Detect keypoints and compute descriptors using AKAZE**
|
||||
|
||||
if(dist1 < nn_match_ratio * dist2) {
|
||||
matched1.push_back(kpts1[first.queryIdx]);
|
||||
matched2.push_back(kpts2[first.trainIdx]);
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
If the closest match is *ratio* closer than the second closest one, then the match is correct.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp AKAZE
|
||||
@end_toggle
|
||||
|
||||
-# **Check if our matches fit in the homography model**
|
||||
@code{.cpp}
|
||||
for(int i = 0; i < matched1.size(); i++) {
|
||||
Mat col = Mat::ones(3, 1, CV_64F);
|
||||
col.at<double>(0) = matched1[i].pt.x;
|
||||
col.at<double>(1) = matched1[i].pt.y;
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java AKAZE
|
||||
@end_toggle
|
||||
|
||||
col = homography * col;
|
||||
col /= col.at<double>(2);
|
||||
float dist = sqrt( pow(col.at<double>(0) - matched2[i].pt.x, 2) +
|
||||
pow(col.at<double>(1) - matched2[i].pt.y, 2));
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py AKAZE
|
||||
@end_toggle
|
||||
|
||||
if(dist < inlier_threshold) {
|
||||
int new_i = inliers1.size();
|
||||
inliers1.push_back(matched1[i]);
|
||||
inliers2.push_back(matched2[i]);
|
||||
good_matches.push_back(DMatch(new_i, new_i, 0));
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
If the distance from first keypoint's projection to the second keypoint is less than threshold,
|
||||
then it it fits in the homography.
|
||||
We create AKAZE and detect and compute AKAZE keypoints and descriptors. Since we don't need the *mask*
|
||||
parameter, *noArray()* is used.
|
||||
|
||||
We create a new set of matches for the inliers, because it is required by the drawing function.
|
||||
- **Use brute-force matcher to find 2-nn matches**
|
||||
|
||||
-# **Output results**
|
||||
@code{.cpp}
|
||||
Mat res;
|
||||
drawMatches(img1, inliers1, img2, inliers2, good_matches, res);
|
||||
imwrite("res.png", res);
|
||||
...
|
||||
@endcode
|
||||
Here we save the resulting image and print some statistics.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp 2-nn matching
|
||||
@end_toggle
|
||||
|
||||
### Results
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java 2-nn matching
|
||||
@end_toggle
|
||||
|
||||
Found matches
|
||||
-------------
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py 2-nn matching
|
||||
@end_toggle
|
||||
|
||||
We use Hamming distance, because AKAZE uses binary descriptor by default.
|
||||
|
||||
- **Use 2-nn matches and ratio criterion to find correct keypoint matches**
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp ratio test filtering
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java ratio test filtering
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py ratio test filtering
|
||||
@end_toggle
|
||||
|
||||
If the closest match distance is significantly lower than the second closest one, then the match is correct (match is not ambiguous).
|
||||
|
||||
- **Check if our matches fit in the homography model**
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp homography check
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java homography check
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py homography check
|
||||
@end_toggle
|
||||
|
||||
If the distance from first keypoint's projection to the second keypoint is less than threshold,
|
||||
then it fits the homography model.
|
||||
|
||||
We create a new set of matches for the inliers, because it is required by the drawing function.
|
||||
|
||||
- **Output results**
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/features2D/AKAZE_match.cpp draw final matches
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java draw final matches
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py draw final matches
|
||||
@end_toggle
|
||||
|
||||
Here we save the resulting image and print some statistics.
|
||||
|
||||
Results
|
||||
-------
|
||||
|
||||
### Found matches
|
||||
|
||||

|
||||
|
||||
A-KAZE Matching Results
|
||||
-----------------------
|
||||
Depending on your OpenCV version, you should get results coherent with:
|
||||
|
||||
@code{.none}
|
||||
Keypoints 1: 2943
|
||||
Keypoints 2: 3511
|
||||
Matches: 447
|
||||
Inliers: 308
|
||||
Inlier Ratio: 0.689038}
|
||||
Inlier Ratio: 0.689038
|
||||
@endcode
|
||||
|
||||
@@ -98,6 +98,8 @@ OpenCV.
|
||||
|
||||
- @subpage tutorial_akaze_matching
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 3.0
|
||||
|
||||
*Author:* Fedor Morozov
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
Basic Drawing {#tutorial_basic_geometric_drawing}
|
||||
=============
|
||||
|
||||
@prev_tutorial{tutorial_basic_linear_transform}
|
||||
@next_tutorial{tutorial_random_generator_and_text}
|
||||
|
||||
Goals
|
||||
@@ -82,20 +81,20 @@ Code
|
||||
|
||||
@add_toggle_cpp
|
||||
- This code is in your OpenCV sample folder. Otherwise you can grab it from
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp)
|
||||
@include samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp)
|
||||
@include samples/cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- This code is in your OpenCV sample folder. Otherwise you can grab it from
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java)
|
||||
@include samples/java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java)
|
||||
@include samples/java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- This code is in your OpenCV sample folder. Otherwise you can grab it from
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py)
|
||||
@include samples/python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py
|
||||
[here](https://raw.githubusercontent.com/opencv/opencv/3.4/samples/python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py)
|
||||
@include samples/python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
@@ -104,42 +103,42 @@ Explanation
|
||||
Since we plan to draw two examples (an atom and a rook), we have to create two images and two
|
||||
windows to display them.
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp create_images
|
||||
@snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp create_images
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java create_images
|
||||
@snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java create_images
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py create_images
|
||||
@snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py create_images
|
||||
@end_toggle
|
||||
|
||||
We created functions to draw different geometric shapes. For instance, to draw the atom we used
|
||||
**MyEllipse** and **MyFilledCircle**:
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_atom
|
||||
@snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp draw_atom
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java draw_atom
|
||||
@snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java draw_atom
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py draw_atom
|
||||
@snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py draw_atom
|
||||
@end_toggle
|
||||
|
||||
And to draw the rook we employed **MyLine**, **rectangle** and a **MyPolygon**:
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp draw_rook
|
||||
@snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp draw_rook
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java draw_rook
|
||||
@snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java draw_rook
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py draw_rook
|
||||
@snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py draw_rook
|
||||
@end_toggle
|
||||
|
||||
|
||||
@@ -149,15 +148,15 @@ Let's check what is inside each of these functions:
|
||||
|
||||
<H4>MyLine</H4>
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_line
|
||||
@snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp my_line
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_line
|
||||
@snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java my_line
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_line
|
||||
@snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py my_line
|
||||
@end_toggle
|
||||
|
||||
- As we can see, **MyLine** just call the function **line()** , which does the following:
|
||||
@@ -170,15 +169,15 @@ Let's check what is inside each of these functions:
|
||||
|
||||
<H4>MyEllipse</H4>
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_ellipse
|
||||
@snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp my_ellipse
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_ellipse
|
||||
@snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java my_ellipse
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_ellipse
|
||||
@snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py my_ellipse
|
||||
@end_toggle
|
||||
|
||||
- From the code above, we can observe that the function **ellipse()** draws an ellipse such
|
||||
@@ -194,15 +193,15 @@ Let's check what is inside each of these functions:
|
||||
|
||||
<H4>MyFilledCircle</H4>
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_filled_circle
|
||||
@snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp my_filled_circle
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_filled_circle
|
||||
@snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java my_filled_circle
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_filled_circle
|
||||
@snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py my_filled_circle
|
||||
@end_toggle
|
||||
|
||||
- Similar to the ellipse function, we can observe that *circle* receives as arguments:
|
||||
@@ -215,15 +214,15 @@ Let's check what is inside each of these functions:
|
||||
|
||||
<H4>MyPolygon</H4>
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp my_polygon
|
||||
@snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp my_polygon
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java my_polygon
|
||||
@snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java my_polygon
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py my_polygon
|
||||
@snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py my_polygon
|
||||
@end_toggle
|
||||
|
||||
- To draw a filled polygon we use the function **fillPoly()** . We note that:
|
||||
@@ -235,15 +234,15 @@ Let's check what is inside each of these functions:
|
||||
|
||||
<H4>rectangle</H4>
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/Matrix/Drawing_1.cpp rectangle
|
||||
@snippet cpp/tutorial_code/ImgProc/basic_drawing/Drawing_1.cpp rectangle
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet java/tutorial_code/core/BasicGeometricDrawing/BasicGeometricDrawing.java rectangle
|
||||
@snippet java/tutorial_code/ImgProc/BasicGeometricDrawing/BasicGeometricDrawing.java rectangle
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet python/tutorial_code/core/BasicGeometricDrawing/basic_geometric_drawing.py rectangle
|
||||
@snippet python/tutorial_code/imgProc/BasicGeometricDrawing/basic_geometric_drawing.py rectangle
|
||||
@end_toggle
|
||||
|
||||
- Finally we have the @ref cv::rectangle function (we did not create a special function for
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -1,6 +1,9 @@
|
||||
Eroding and Dilating {#tutorial_erosion_dilatation}
|
||||
====================
|
||||
|
||||
@prev_tutorial{tutorial_gausian_median_blur_bilateral_filter}
|
||||
@next_tutorial{tutorial_opening_closing_hats}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
Smoothing Images {#tutorial_gausian_median_blur_bilateral_filter}
|
||||
================
|
||||
|
||||
@prev_tutorial{tutorial_random_generator_and_text}
|
||||
@next_tutorial{tutorial_erosion_dilatation}
|
||||
|
||||
Goal
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Back Projection {#tutorial_back_projection}
|
||||
===============
|
||||
|
||||
@prev_tutorial{tutorial_histogram_comparison}
|
||||
@next_tutorial{tutorial_template_matching}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Histogram Calculation {#tutorial_histogram_calculation}
|
||||
=====================
|
||||
|
||||
@prev_tutorial{tutorial_histogram_equalization}
|
||||
@next_tutorial{tutorial_histogram_comparison}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Histogram Comparison {#tutorial_histogram_comparison}
|
||||
====================
|
||||
|
||||
@prev_tutorial{tutorial_histogram_calculation}
|
||||
@next_tutorial{tutorial_back_projection}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Histogram Equalization {#tutorial_histogram_equalization}
|
||||
======================
|
||||
|
||||
@prev_tutorial{tutorial_warp_affine}
|
||||
@next_tutorial{tutorial_histogram_calculation}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Canny Edge Detector {#tutorial_canny_detector}
|
||||
===================
|
||||
|
||||
@prev_tutorial{tutorial_laplace_operator}
|
||||
@next_tutorial{tutorial_hough_lines}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Image Segmentation with Distance Transform and Watershed Algorithm {#tutorial_distance_transform}
|
||||
=============
|
||||
|
||||
@prev_tutorial{tutorial_point_polygon_test}
|
||||
@next_tutorial{tutorial_out_of_focus_deblur_filter}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -16,42 +19,152 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp).
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp).
|
||||
@include samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java)
|
||||
@include samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py)
|
||||
@include samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py
|
||||
@end_toggle
|
||||
|
||||
Explanation / Result
|
||||
--------------------
|
||||
|
||||
-# Load the source image and check if it is loaded without any problem, then show it:
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp load_image
|
||||

|
||||
- Load the source image and check if it is loaded without any problem, then show it:
|
||||
|
||||
-# Then if we have an image with a white background, it is good to transform it to black. This will help us to discriminate the foreground objects easier when we will apply the Distance Transform:
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp black_bg
|
||||

|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp load_image
|
||||
@end_toggle
|
||||
|
||||
-# Afterwards we will sharpen our image in order to acute the edges of the foreground objects. We will apply a laplacian filter with a quite strong filter (an approximation of second derivative):
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp sharp
|
||||

|
||||

|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java load_image
|
||||
@end_toggle
|
||||
|
||||
-# Now we transform our new sharpened source image to a grayscale and a binary one, respectively:
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp bin
|
||||

|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py load_image
|
||||
@end_toggle
|
||||
|
||||
-# We are ready now to apply the Distance Transform on the binary image. Moreover, we normalize the output image in order to be able visualize and threshold the result:
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp dist
|
||||

|
||||

|
||||
|
||||
-# We threshold the *dist* image and then perform some morphology operation (i.e. dilation) in order to extract the peaks from the above image:
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp peaks
|
||||

|
||||
- Then if we have an image with a white background, it is good to transform it to black. This will help us to discriminate the foreground objects easier when we will apply the Distance Transform:
|
||||
|
||||
-# From each blob then we create a seed/marker for the watershed algorithm with the help of the @ref cv::findContours function:
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp seeds
|
||||

|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp black_bg
|
||||
@end_toggle
|
||||
|
||||
-# Finally, we can apply the watershed algorithm, and visualize the result:
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp watershed
|
||||

|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java black_bg
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py black_bg
|
||||
@end_toggle
|
||||
|
||||

|
||||
|
||||
- Afterwards we will sharpen our image in order to acute the edges of the foreground objects. We will apply a laplacian filter with a quite strong filter (an approximation of second derivative):
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp sharp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java sharp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py sharp
|
||||
@end_toggle
|
||||
|
||||

|
||||

|
||||
|
||||
- Now we transform our new sharpened source image to a grayscale and a binary one, respectively:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp bin
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java bin
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py bin
|
||||
@end_toggle
|
||||
|
||||

|
||||
|
||||
- We are ready now to apply the Distance Transform on the binary image. Moreover, we normalize the output image in order to be able visualize and threshold the result:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp dist
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java dist
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py dist
|
||||
@end_toggle
|
||||
|
||||

|
||||
|
||||
- We threshold the *dist* image and then perform some morphology operation (i.e. dilation) in order to extract the peaks from the above image:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp peaks
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java peaks
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py peaks
|
||||
@end_toggle
|
||||
|
||||

|
||||
|
||||
- From each blob then we create a seed/marker for the watershed algorithm with the help of the @ref cv::findContours function:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp seeds
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java seeds
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py seeds
|
||||
@end_toggle
|
||||
|
||||

|
||||
|
||||
- Finally, we can apply the watershed algorithm, and visualize the result:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgTrans/imageSegmentation.cpp watershed
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ImgTrans/distance_transformation/ImageSegmentationDemo.java watershed
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ImgTrans/distance_transformation/imageSegmentation.py watershed
|
||||
@end_toggle
|
||||
|
||||

|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Remapping {#tutorial_remap}
|
||||
=========
|
||||
|
||||
@prev_tutorial{tutorial_hough_circle}
|
||||
@next_tutorial{tutorial_warp_affine}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Affine Transformations {#tutorial_warp_affine}
|
||||
======================
|
||||
|
||||
@prev_tutorial{tutorial_remap}
|
||||
@next_tutorial{tutorial_histogram_equalization}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
More Morphology Transformations {#tutorial_opening_closing_hats}
|
||||
===============================
|
||||
|
||||
@prev_tutorial{tutorial_erosion_dilatation}
|
||||
@next_tutorial{tutorial_hitOrMiss}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 630 B |
|
After Width: | Height: | Size: 42 KiB |
@@ -0,0 +1,114 @@
|
||||
Out-of-focus Deblur Filter {#tutorial_out_of_focus_deblur_filter}
|
||||
==========================
|
||||
|
||||
@prev_tutorial{tutorial_distance_transform}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
In this tutorial you will learn:
|
||||
|
||||
- what is a degradation image model
|
||||
- what is PSF of out-of-focus image
|
||||
- how to restore a blurred image
|
||||
- what is Wiener filter
|
||||
|
||||
Theory
|
||||
------
|
||||
|
||||
@note The explanation is based on the books @cite gonzalez and @cite gruzman. Also, you can refer to Matlab's tutorial [Image Deblurring in Matlab] and an article [SmartDeblur].
|
||||
@note An out-of-focus image on this page is a real world image. An out-of-focus was done manually by camera optics.
|
||||
|
||||
### What is a degradation image model?
|
||||
|
||||
A mathematical model of the image degradation in frequency domain representation is:
|
||||
|
||||
\f[S = H\cdot U + N\f]
|
||||
|
||||
where
|
||||
\f$S\f$ is a spectrum of blurred (degraded) image,
|
||||
\f$U\f$ is a spectrum of original true (undegraded) image,
|
||||
\f$H\f$ is frequency response of point spread function (PSF),
|
||||
\f$N\f$ is a spectrum of additive noise.
|
||||
|
||||
Circular PSF is a good approximation of out-of-focus distortion. Such PSF is specified by only one parameter - radius \f$R\f$. Circular PSF is used in this work.
|
||||
|
||||

|
||||
|
||||
### How to restore an blurred image?
|
||||
|
||||
The objective of restoration (deblurring) is to obtain an estimate of the original image. Restoration formula in frequency domain is:
|
||||
|
||||
\f[U' = H_w\cdot S\f]
|
||||
|
||||
where
|
||||
\f$U'\f$ is spectrum of estimation of original image \f$U\f$,
|
||||
\f$H_w\f$ is restoration filter, for example, Wiener filter.
|
||||
|
||||
### What is Wiener filter?
|
||||
|
||||
Wiener filter is a way to restore a blurred image. Let's suppose that PSF is a real and symmetric signal, a power spectrum of the original true image and noise are not known,
|
||||
then simplified Wiener formula is:
|
||||
|
||||
\f[H_w = \frac{H}{|H|^2+\frac{1}{SNR}} \f]
|
||||
|
||||
where
|
||||
\f$SNR\f$ is signal-to-noise ratio.
|
||||
|
||||
So, in order to recover an out-of-focus image by Wiener filter, it needs to know \f$SNR\f$ and \f$R\f$ of circular PSF.
|
||||
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
You can find source code in the `samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp` of the OpenCV source code library.
|
||||
|
||||
@include cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
An out-of-focus image recovering algorithm consists of PSF generation, Wiener filter generation and filtering an blurred image in frequency domain:
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp main
|
||||
|
||||
A function calcPSF() forms an circular PSF according to input parameter radius \f$R\f$:
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp calcPSF
|
||||
|
||||
A function calcWnrFilter() synthesizes simplified Wiener filter \f$H_w\f$ according to formula described above:
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp calcWnrFilter
|
||||
|
||||
A function fftshift() rearranges PSF. This code was just copied from tutorial @ref tutorial_discrete_fourier_transform "Discrete Fourier Transform":
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp fftshift
|
||||
|
||||
A function filter2DFreq() filters an blurred image in frequency domain:
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp filter2DFreq
|
||||
|
||||
Result
|
||||
------
|
||||
|
||||
Below you can see real out-of-focus image:
|
||||

|
||||
|
||||
|
||||
Below result was done by \f$R\f$ = 53 and \f$SNR\f$ = 5200 parameters:
|
||||

|
||||
|
||||
The Wiener filter was used, values of \f$R\f$ and \f$SNR\f$ were selected manually to give the best possible visual result.
|
||||
We can see that the result is not perfect, but it gives us a hint to the image content. With some difficulty, the text is readable.
|
||||
|
||||
@note The parameter \f$R\f$ is the most important. So you should adjust \f$R\f$ first, then \f$SNR\f$.
|
||||
@note Sometimes you can observe the ringing effect in an restored image. This effect can be reduced by several methods. For example, you can taper input image edges.
|
||||
|
||||
You can also find a quick video demonstration of this on
|
||||
[YouTube](https://youtu.be/0bEcE4B0XP4).
|
||||
@youtube{0bEcE4B0XP4}
|
||||
|
||||
References
|
||||
------
|
||||
- [Image Deblurring in Matlab] - Image Deblurring in Matlab
|
||||
- [SmartDeblur] - SmartDeblur site
|
||||
|
||||
<!-- invisible references list -->
|
||||
[Digital Image Processing]: http://web.ipac.caltech.edu/staff/fmasci/home/astro_refs/Digital_Image_Processing_2ndEd.pdf
|
||||
[Image Deblurring in Matlab]: https://www.mathworks.com/help/images/image-deblurring.html
|
||||
[SmartDeblur]: http://yuzhikov.com/articles/BlurredImagesRestoration1.htm
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -1,6 +1,9 @@
|
||||
Random generator and text with OpenCV {#tutorial_random_generator_and_text}
|
||||
=====================================
|
||||
|
||||
@prev_tutorial{tutorial_basic_geometric_drawing}
|
||||
@next_tutorial{tutorial_gausian_median_blur_bilateral_filter}
|
||||
|
||||
Goals
|
||||
-----
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Creating Bounding boxes and circles for contours {#tutorial_bounding_rects_circles}
|
||||
================================================
|
||||
|
||||
@prev_tutorial{tutorial_hull}
|
||||
@next_tutorial{tutorial_bounding_rotated_ellipses}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -15,55 +18,167 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
The main function is rather simple, as follows from the comments we do the following:
|
||||
-# Open the image, convert it into grayscale and blur it to get rid of the noise.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup
|
||||
-# Create a window with header "Source" and display the source file in it.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow
|
||||
-# Create a trackbar on the source_window and assign a callback function to it
|
||||
- Open the image, convert it into grayscale and blur it to get rid of the noise.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp setup
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java setup
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py setup
|
||||
@end_toggle
|
||||
|
||||
- Create a window with header "Source" and display the source file in it.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp createWindow
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java createWindow
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py createWindow
|
||||
@end_toggle
|
||||
|
||||
- Create a trackbar on the `source_window` and assign a callback function to it.
|
||||
In general callback functions are used to react to some kind of signal, in our
|
||||
case it's trackbar's state change.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp taskbar
|
||||
-# Explicit one-time call of `thresh_callback` is necessary to display
|
||||
Explicit one-time call of `thresh_callback` is necessary to display
|
||||
the "Contours" window simultaniously with the "Source" window.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp callback00
|
||||
-# Wait for user to close the windows.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp waitForIt
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp trackbar
|
||||
@end_toggle
|
||||
|
||||
The callback function `thresh_callback` does all the interesting job.
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java trackbar
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py trackbar
|
||||
@end_toggle
|
||||
|
||||
-# Writes to `threshold_output` the threshold of the grayscale picture (you can check out about thresholding @ref tutorial_threshold "here").
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp threshold
|
||||
-# Finds contours and saves them to the vectors `contour` and `hierarchy`.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours
|
||||
-# For every found contour we now apply approximation to polygons
|
||||
with accuracy +-3 and stating that the curve must me closed.
|
||||
The callback function does all the interesting job.
|
||||
|
||||
- Use @ref cv::Canny to detect edges in the images.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp Canny
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java Canny
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py Canny
|
||||
@end_toggle
|
||||
|
||||
- Finds contours and saves them to the vectors `contour` and `hierarchy`.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp findContours
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java findContours
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py findContours
|
||||
@end_toggle
|
||||
|
||||
- For every found contour we now apply approximation to polygons
|
||||
with accuracy +-3 and stating that the curve must be closed.
|
||||
After that we find a bounding rect for every polygon and save it to `boundRect`.
|
||||
|
||||
At last we find a minimum enclosing circle for every polygon and
|
||||
save it to `center` and `radius` vectors.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp allthework
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java allthework
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py allthework
|
||||
@end_toggle
|
||||
|
||||
We found everything we need, all we have to do is to draw.
|
||||
|
||||
-# Create new Mat of unsigned 8-bit chars, filled with zeros.
|
||||
- Create new Mat of unsigned 8-bit chars, filled with zeros.
|
||||
It will contain all the drawings we are going to make (rects and circles).
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat
|
||||
-# For every contour: pick a random color, draw the contour, the bounding rectangle and
|
||||
the minimal enclosing circle with it,
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour
|
||||
-# Display the results: create a new window "Contours" and show everything we added to drawings on it.
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp zeroMat
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java zeroMat
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py zeroMat
|
||||
@end_toggle
|
||||
|
||||
- For every contour: pick a random color, draw the contour, the bounding rectangle and
|
||||
the minimal enclosing circle with it.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp forContour
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java forContour
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py forContour
|
||||
@end_toggle
|
||||
|
||||
- Display the results: create a new window "Contours" and show everything we added to drawings on it.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp showDrawings
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ShapeDescriptors/bounding_rects_circles/GeneralContoursDemo1.java showDrawings
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ShapeDescriptors/bounding_rects_circles/generalContours_demo1.py showDrawings
|
||||
@end_toggle
|
||||
|
||||
Result
|
||||
------
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Creating Bounding rotated boxes and ellipses for contours {#tutorial_bounding_rotated_ellipses}
|
||||
=========================================================
|
||||
|
||||
@prev_tutorial{tutorial_bounding_rects_circles}
|
||||
@next_tutorial{tutorial_moments}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -15,9 +18,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/GeneralContoursDemo2.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/bounding_rotated_ellipses/generalContours_demo2.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Finding contours in your image {#tutorial_find_contours}
|
||||
==============================
|
||||
|
||||
@prev_tutorial{tutorial_template_matching}
|
||||
@next_tutorial{tutorial_hull}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -15,9 +18,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/find_contours/FindContoursDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/find_contours/findContours_demo.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Convex Hull {#tutorial_hull}
|
||||
===========
|
||||
|
||||
@prev_tutorial{tutorial_find_contours}
|
||||
@next_tutorial{tutorial_bounding_rects_circles}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -14,10 +17,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp)
|
||||
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/hull/HullDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/hull/hull_demo.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Image Moments {#tutorial_moments}
|
||||
=============
|
||||
|
||||
@prev_tutorial{tutorial_bounding_rotated_ellipses}
|
||||
@next_tutorial{tutorial_point_polygon_test}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -16,9 +19,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/moments/MomentsDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/moments/moments_demo.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Point Polygon Test {#tutorial_point_polygon_test}
|
||||
==================
|
||||
|
||||
@prev_tutorial{tutorial_moments}
|
||||
@next_tutorial{tutorial_distance_transform}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -14,9 +17,23 @@ Theory
|
||||
Code
|
||||
----
|
||||
|
||||
@add_toggle_cpp
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp)
|
||||
@include samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java)
|
||||
@include samples/java/tutorial_code/ShapeDescriptors/point_polygon_test/PointPolygonTestDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py)
|
||||
@include samples/python/tutorial_code/ShapeDescriptors/point_polygon_test/pointPolygonTest_demo.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
@@ -3,6 +3,24 @@ Image Processing (imgproc module) {#tutorial_table_of_content_imgproc}
|
||||
|
||||
In this section you will learn about the image processing (manipulation) functions inside OpenCV.
|
||||
|
||||
- @subpage tutorial_basic_geometric_drawing
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
||||
We will learn how to draw simple geometry with OpenCV!
|
||||
|
||||
- @subpage tutorial_random_generator_and_text
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
|
||||
We will draw some *fancy-looking* stuff using OpenCV!
|
||||
|
||||
- @subpage tutorial_gausian_median_blur_bilateral_filter
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
@@ -225,6 +243,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_find_contours
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -233,6 +253,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_hull
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -241,6 +263,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_bounding_rects_circles
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -249,6 +273,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_bounding_rotated_ellipses
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -257,6 +283,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_moments
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -265,6 +293,8 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_point_polygon_test
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Ana Huamán
|
||||
@@ -273,8 +303,20 @@ In this section you will learn about the image processing (manipulation) functio
|
||||
|
||||
- @subpage tutorial_distance_transform
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Theodore Tsesmelis
|
||||
|
||||
Where we learn to segment objects using Laplacian filtering, the Distance Transformation and the Watershed algorithm.
|
||||
|
||||
- @subpage tutorial_out_of_focus_deblur_filter
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Karpushin Vladislav
|
||||
|
||||
You will learn how to recover an out-of-focus image by Wiener filter.
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Basic Thresholding Operations {#tutorial_threshold}
|
||||
=============================
|
||||
|
||||
@prev_tutorial{tutorial_pyramids}
|
||||
@next_tutorial{tutorial_threshold_inRange}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Thresholding Operations using inRange {#tutorial_threshold_inRange}
|
||||
=====================================
|
||||
|
||||
@prev_tutorial{tutorial_threshold}
|
||||
@next_tutorial{tutorial_filter_2d}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -36,14 +36,14 @@ Open your Doxyfile using your favorite text editor and search for the key
|
||||
`TAGFILES`. Change it as follows:
|
||||
|
||||
@code
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.2
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.3
|
||||
@endcode
|
||||
|
||||
If you had other definitions already, you can append the line using a `\`:
|
||||
|
||||
@code
|
||||
TAGFILES = ./docs/doxygen-tags/libstdc++.tag=https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen \
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.2
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.3
|
||||
@endcode
|
||||
|
||||
Doxygen can now use the information from the tag file to link to the OpenCV
|
||||
|
||||
@@ -46,7 +46,7 @@ cd /c/lib
|
||||
myRepo=$(pwd)
|
||||
CMAKE_CONFIG_GENERATOR="Visual Studio 14 2015 Win64"
|
||||
if [ ! -d "$myRepo/opencv" ]; then
|
||||
echo "clonning opencv"
|
||||
echo "cloning opencv"
|
||||
git clone https://github.com/opencv/opencv.git
|
||||
mkdir Build
|
||||
mkdir Build/opencv
|
||||
@@ -58,7 +58,7 @@ else
|
||||
cd ..
|
||||
fi
|
||||
if [ ! -d "$myRepo/opencv_contrib" ]; then
|
||||
echo "clonning opencv_contrib"
|
||||
echo "cloning opencv_contrib"
|
||||
git clone https://github.com/opencv/opencv_contrib.git
|
||||
mkdir Build
|
||||
mkdir Build/opencv_contrib
|
||||
|
||||
@@ -91,37 +91,112 @@ __Find the eigenvectors and eigenvalues of the covariance matrix__
|
||||
Source Code
|
||||
-----------
|
||||
|
||||
This tutorial code's is shown lines below. You can also download it from
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp).
|
||||
@include cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py
|
||||
@end_toggle
|
||||
|
||||
@note Another example using PCA for dimensionality reduction while maintaining an amount of variance can be found at [opencv_source_code/samples/cpp/pca.cpp](https://github.com/opencv/opencv/tree/3.4/samples/cpp/pca.cpp)
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# __Read image and convert it to binary__
|
||||
- __Read image and convert it to binary__
|
||||
|
||||
Here we apply the necessary pre-processing procedures in order to be able to detect the objects of interest.
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp pre-process
|
||||
Here we apply the necessary pre-processing procedures in order to be able to detect the objects of interest.
|
||||
|
||||
-# __Extract objects of interest__
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp pre-process
|
||||
@end_toggle
|
||||
|
||||
Then find and filter contours by size and obtain the orientation of the remaining ones.
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp contours
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java pre-process
|
||||
@end_toggle
|
||||
|
||||
-# __Extract orientation__
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py pre-process
|
||||
@end_toggle
|
||||
|
||||
Orientation is extracted by the call of getOrientation() function, which performs all the PCA procedure.
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp pca
|
||||
- __Extract objects of interest__
|
||||
|
||||
First the data need to be arranged in a matrix with size n x 2, where n is the number of data points we have. Then we can perform that PCA analysis. The calculated mean (i.e. center of mass) is stored in the _cntr_ variable and the eigenvectors and eigenvalues are stored in the corresponding std::vector’s.
|
||||
Then find and filter contours by size and obtain the orientation of the remaining ones.
|
||||
|
||||
-# __Visualize result__
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp contours
|
||||
@end_toggle
|
||||
|
||||
The final result is visualized through the drawAxis() function, where the principal components are drawn in lines, and each eigenvector is multiplied by its eigenvalue and translated to the mean position.
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp visualization
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp visualization1
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java contours
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py contours
|
||||
@end_toggle
|
||||
|
||||
- __Extract orientation__
|
||||
|
||||
Orientation is extracted by the call of getOrientation() function, which performs all the PCA procedure.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp pca
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java pca
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py pca
|
||||
@end_toggle
|
||||
|
||||
First the data need to be arranged in a matrix with size n x 2, where n is the number of data points we have. Then we can perform that PCA analysis. The calculated mean (i.e. center of mass) is stored in the _cntr_ variable and the eigenvectors and eigenvalues are stored in the corresponding std::vector’s.
|
||||
|
||||
- __Visualize result__
|
||||
|
||||
The final result is visualized through the drawAxis() function, where the principal components are drawn in lines, and each eigenvector is multiplied by its eigenvalue and translated to the mean position.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp visualization
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java visualization
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py visualization
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_pca/introduction_to_pca.cpp visualization1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_pca/IntroductionToPCADemo.java visualization1
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_pca/introduction_to_pca.py visualization1
|
||||
@end_toggle
|
||||
|
||||
Results
|
||||
-------
|
||||
|
||||
@@ -96,25 +96,67 @@ Source Code
|
||||
|
||||
@note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html#introductiontosvms)
|
||||
|
||||
@include cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# **Set up the training data**
|
||||
- **Set up the training data**
|
||||
|
||||
The training data of this exercise is formed by a set of labeled 2D-points that belong to one of
|
||||
two different classes; one of the classes consists of one point and the other of three points.
|
||||
The training data of this exercise is formed by a set of labeled 2D-points that belong to one of
|
||||
two different classes; one of the classes consists of one point and the other of three points.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp setup1
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp setup1
|
||||
@end_toggle
|
||||
|
||||
The function @ref cv::ml::SVM::train that will be used afterwards requires the training data to be
|
||||
stored as @ref cv::Mat objects of floats. Therefore, we create these objects from the arrays
|
||||
defined above:
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java setup1
|
||||
@end_toggle
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp setup2
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py setup1
|
||||
@end_toggle
|
||||
|
||||
-# **Set up SVM's parameters**
|
||||
The function @ref cv::ml::SVM::train that will be used afterwards requires the training data to be
|
||||
stored as @ref cv::Mat objects of floats. Therefore, we create these objects from the arrays
|
||||
defined above:
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp setup2
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java setup2
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py setup1
|
||||
@end_toggle
|
||||
|
||||
- **Set up SVM's parameters**
|
||||
|
||||
In this tutorial we have introduced the theory of SVMs in the most simple case, when the
|
||||
training examples are spread into two classes that are linearly separable. However, SVMs can be
|
||||
@@ -123,35 +165,55 @@ Explanation
|
||||
we have to define some parameters before training the SVM. These parameters are stored in an
|
||||
object of the class @ref cv::ml::SVM.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp init
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp init
|
||||
@end_toggle
|
||||
|
||||
Here:
|
||||
- *Type of SVM*. We choose here the type @ref cv::ml::SVM::C_SVC "C_SVC" that can be used for
|
||||
n-class classification (n \f$\geq\f$ 2). The important feature of this type is that it deals
|
||||
with imperfect separation of classes (i.e. when the training data is non-linearly separable).
|
||||
This feature is not important here since the data is linearly separable and we chose this SVM
|
||||
type only for being the most commonly used.
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java init
|
||||
@end_toggle
|
||||
|
||||
- *Type of SVM kernel*. We have not talked about kernel functions since they are not
|
||||
interesting for the training data we are dealing with. Nevertheless, let's explain briefly now
|
||||
the main idea behind a kernel function. It is a mapping done to the training data to improve
|
||||
its resemblance to a linearly separable set of data. This mapping consists of increasing the
|
||||
dimensionality of the data and is done efficiently using a kernel function. We choose here the
|
||||
type @ref cv::ml::SVM::LINEAR "LINEAR" which means that no mapping is done. This parameter is
|
||||
defined using cv::ml::SVM::setKernel.
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py init
|
||||
@end_toggle
|
||||
|
||||
- *Termination criteria of the algorithm*. The SVM training procedure is implemented solving a
|
||||
constrained quadratic optimization problem in an **iterative** fashion. Here we specify a
|
||||
maximum number of iterations and a tolerance error so we allow the algorithm to finish in
|
||||
less number of steps even if the optimal hyperplane has not been computed yet. This
|
||||
parameter is defined in a structure @ref cv::TermCriteria .
|
||||
Here:
|
||||
- *Type of SVM*. We choose here the type @ref cv::ml::SVM::C_SVC "C_SVC" that can be used for
|
||||
n-class classification (n \f$\geq\f$ 2). The important feature of this type is that it deals
|
||||
with imperfect separation of classes (i.e. when the training data is non-linearly separable).
|
||||
This feature is not important here since the data is linearly separable and we chose this SVM
|
||||
type only for being the most commonly used.
|
||||
|
||||
-# **Train the SVM**
|
||||
- *Type of SVM kernel*. We have not talked about kernel functions since they are not
|
||||
interesting for the training data we are dealing with. Nevertheless, let's explain briefly now
|
||||
the main idea behind a kernel function. It is a mapping done to the training data to improve
|
||||
its resemblance to a linearly separable set of data. This mapping consists of increasing the
|
||||
dimensionality of the data and is done efficiently using a kernel function. We choose here the
|
||||
type @ref cv::ml::SVM::LINEAR "LINEAR" which means that no mapping is done. This parameter is
|
||||
defined using cv::ml::SVM::setKernel.
|
||||
|
||||
- *Termination criteria of the algorithm*. The SVM training procedure is implemented solving a
|
||||
constrained quadratic optimization problem in an **iterative** fashion. Here we specify a
|
||||
maximum number of iterations and a tolerance error so we allow the algorithm to finish in
|
||||
less number of steps even if the optimal hyperplane has not been computed yet. This
|
||||
parameter is defined in a structure @ref cv::TermCriteria .
|
||||
|
||||
- **Train the SVM**
|
||||
We call the method @ref cv::ml::SVM::train to build the SVM model.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp train
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp train
|
||||
@end_toggle
|
||||
|
||||
-# **Regions classified by the SVM**
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java train
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py train
|
||||
@end_toggle
|
||||
|
||||
- **Regions classified by the SVM**
|
||||
|
||||
The method @ref cv::ml::SVM::predict is used to classify an input sample using a trained SVM. In
|
||||
this example we have used this method in order to color the space depending on the prediction done
|
||||
@@ -159,16 +221,36 @@ Explanation
|
||||
Cartesian plane. Each of the points is colored depending on the class predicted by the SVM; in
|
||||
green if it is the class with label 1 and in blue if it is the class with label -1.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp show
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp show
|
||||
@end_toggle
|
||||
|
||||
-# **Support vectors**
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java show
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py show
|
||||
@end_toggle
|
||||
|
||||
- **Support vectors**
|
||||
|
||||
We use here a couple of methods to obtain information about the support vectors.
|
||||
The method @ref cv::ml::SVM::getSupportVectors obtain all of the support
|
||||
vectors. We have used this methods here to find the training examples that are
|
||||
support vectors and highlight them.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp show_vectors
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp show_vectors
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/introduction_to_svm/IntroductionToSVMDemo.java show_vectors
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/introduction_to_svm/introduction_to_svm.py show_vectors
|
||||
@end_toggle
|
||||
|
||||
Results
|
||||
-------
|
||||
|
||||
@@ -92,81 +92,175 @@ You may also find the source code in `samples/cpp/tutorial_code/ml/non_linear_sv
|
||||
@note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code
|
||||
using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/non_linear_svms/non_linear_svms.html#nonlinearsvms)
|
||||
|
||||
@include cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/3.4/samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py)
|
||||
|
||||
- **Code at glance:**
|
||||
@include samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
-# __Set up the training data__
|
||||
- __Set up the training data__
|
||||
|
||||
The training data of this exercise is formed by a set of labeled 2D-points that belong to one of
|
||||
two different classes. To make the exercise more appealing, the training data is generated
|
||||
randomly using a uniform probability density functions (PDFs).
|
||||
The training data of this exercise is formed by a set of labeled 2D-points that belong to one of
|
||||
two different classes. To make the exercise more appealing, the training data is generated
|
||||
randomly using a uniform probability density functions (PDFs).
|
||||
|
||||
We have divided the generation of the training data into two main parts.
|
||||
We have divided the generation of the training data into two main parts.
|
||||
|
||||
In the first part we generate data for both classes that is linearly separable.
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp setup1
|
||||
In the first part we generate data for both classes that is linearly separable.
|
||||
|
||||
In the second part we create data for both classes that is non-linearly separable, data that
|
||||
overlaps.
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp setup2
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp setup1
|
||||
@end_toggle
|
||||
|
||||
-# __Set up SVM's parameters__
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java setup1
|
||||
@end_toggle
|
||||
|
||||
@note In the previous tutorial @ref tutorial_introduction_to_svm there is an explanation of the
|
||||
attributes of the class @ref cv::ml::SVM that we configure here before training the SVM.
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py setup1
|
||||
@end_toggle
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp init
|
||||
In the second part we create data for both classes that is non-linearly separable, data that
|
||||
overlaps.
|
||||
|
||||
There are just two differences between the configuration we do here and the one that was done in
|
||||
the previous tutorial (@ref tutorial_introduction_to_svm) that we use as reference.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp setup2
|
||||
@end_toggle
|
||||
|
||||
- _C_. We chose here a small value of this parameter in order not to punish too much the
|
||||
misclassification errors in the optimization. The idea of doing this stems from the will of
|
||||
obtaining a solution close to the one intuitively expected. However, we recommend to get a
|
||||
better insight of the problem by making adjustments to this parameter.
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java setup2
|
||||
@end_toggle
|
||||
|
||||
@note In this case there are just very few points in the overlapping region between classes.
|
||||
By giving a smaller value to __FRAC_LINEAR_SEP__ the density of points can be incremented and the
|
||||
impact of the parameter _C_ explored deeply.
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py setup2
|
||||
@end_toggle
|
||||
|
||||
- _Termination Criteria of the algorithm_. The maximum number of iterations has to be
|
||||
increased considerably in order to solve correctly a problem with non-linearly separable
|
||||
training data. In particular, we have increased in five orders of magnitude this value.
|
||||
- __Set up SVM's parameters__
|
||||
|
||||
-# __Train the SVM__
|
||||
@note In the previous tutorial @ref tutorial_introduction_to_svm there is an explanation of the
|
||||
attributes of the class @ref cv::ml::SVM that we configure here before training the SVM.
|
||||
|
||||
We call the method @ref cv::ml::SVM::train to build the SVM model. Watch out that the training
|
||||
process may take a quite long time. Have patiance when your run the program.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp init
|
||||
@end_toggle
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp train
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java init
|
||||
@end_toggle
|
||||
|
||||
-# __Show the Decision Regions__
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py init
|
||||
@end_toggle
|
||||
|
||||
The method @ref cv::ml::SVM::predict is used to classify an input sample using a trained SVM. In
|
||||
this example we have used this method in order to color the space depending on the prediction done
|
||||
by the SVM. In other words, an image is traversed interpreting its pixels as points of the
|
||||
Cartesian plane. Each of the points is colored depending on the class predicted by the SVM; in
|
||||
dark green if it is the class with label 1 and in dark blue if it is the class with label 2.
|
||||
There are just two differences between the configuration we do here and the one that was done in
|
||||
the previous tutorial (@ref tutorial_introduction_to_svm) that we use as reference.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show
|
||||
- _C_. We chose here a small value of this parameter in order not to punish too much the
|
||||
misclassification errors in the optimization. The idea of doing this stems from the will of
|
||||
obtaining a solution close to the one intuitively expected. However, we recommend to get a
|
||||
better insight of the problem by making adjustments to this parameter.
|
||||
|
||||
-# __Show the training data__
|
||||
@note In this case there are just very few points in the overlapping region between classes.
|
||||
By giving a smaller value to __FRAC_LINEAR_SEP__ the density of points can be incremented and the
|
||||
impact of the parameter _C_ explored deeply.
|
||||
|
||||
The method @ref cv::circle is used to show the samples that compose the training data. The samples
|
||||
of the class labeled with 1 are shown in light green and in light blue the samples of the class
|
||||
labeled with 2.
|
||||
- _Termination Criteria of the algorithm_. The maximum number of iterations has to be
|
||||
increased considerably in order to solve correctly a problem with non-linearly separable
|
||||
training data. In particular, we have increased in five orders of magnitude this value.
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show_data
|
||||
- __Train the SVM__
|
||||
|
||||
-# __Support vectors__
|
||||
We call the method @ref cv::ml::SVM::train to build the SVM model. Watch out that the training
|
||||
process may take a quite long time. Have patiance when your run the program.
|
||||
|
||||
We use here a couple of methods to obtain information about the support vectors. The method
|
||||
@ref cv::ml::SVM::getSupportVectors obtain all support vectors. We have used this methods here
|
||||
to find the training examples that are support vectors and highlight them.
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp train
|
||||
@end_toggle
|
||||
|
||||
@snippet cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show_vectors
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java train
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py train
|
||||
@end_toggle
|
||||
|
||||
- __Show the Decision Regions__
|
||||
|
||||
The method @ref cv::ml::SVM::predict is used to classify an input sample using a trained SVM. In
|
||||
this example we have used this method in order to color the space depending on the prediction done
|
||||
by the SVM. In other words, an image is traversed interpreting its pixels as points of the
|
||||
Cartesian plane. Each of the points is colored depending on the class predicted by the SVM; in
|
||||
dark green if it is the class with label 1 and in dark blue if it is the class with label 2.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java show
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py show
|
||||
@end_toggle
|
||||
|
||||
- __Show the training data__
|
||||
|
||||
The method @ref cv::circle is used to show the samples that compose the training data. The samples
|
||||
of the class labeled with 1 are shown in light green and in light blue the samples of the class
|
||||
labeled with 2.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show_data
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java show_data
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py show_data
|
||||
@end_toggle
|
||||
|
||||
- __Support vectors__
|
||||
|
||||
We use here a couple of methods to obtain information about the support vectors. The method
|
||||
@ref cv::ml::SVM::getSupportVectors obtain all support vectors. We have used this methods here
|
||||
to find the training examples that are support vectors and highlight them.
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp show_vectors
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_java
|
||||
@snippet samples/java/tutorial_code/ml/non_linear_svms/NonLinearSVMsDemo.java show_vectors
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/ml/non_linear_svms/non_linear_svms.py show_vectors
|
||||
@end_toggle
|
||||
|
||||
Results
|
||||
-------
|
||||
|
||||
@@ -6,6 +6,8 @@ of data.
|
||||
|
||||
- @subpage tutorial_introduction_to_svm
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Fernando Iglesias García
|
||||
@@ -14,6 +16,8 @@ of data.
|
||||
|
||||
- @subpage tutorial_non_linear_svms
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Fernando Iglesias García
|
||||
@@ -23,6 +27,8 @@ of data.
|
||||
|
||||
- @subpage tutorial_introduction_to_pca
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Theodore Tsesmelis
|
||||
|
||||
@@ -24,17 +24,7 @@ Explanation
|
||||
|
||||
The most important code part is:
|
||||
|
||||
@code{.cpp}
|
||||
Mat pano;
|
||||
Ptr<Stitcher> stitcher = Stitcher::create(mode, try_use_gpu);
|
||||
Stitcher::Status status = stitcher->stitch(imgs, pano);
|
||||
|
||||
if (status != Stitcher::OK)
|
||||
{
|
||||
cout << "Can't stitch images, error code = " << int(status) << endl;
|
||||
return -1;
|
||||
}
|
||||
@endcode
|
||||
@snippet cpp/stitching.cpp stitching
|
||||
|
||||
A new instance of stitcher is created and the @ref cv::Stitcher::stitch will
|
||||
do all the hard work.
|
||||
|
||||
@@ -15,7 +15,7 @@ As always, we would be happy to hear your comments and receive your contribution
|
||||
- @subpage tutorial_table_of_content_core
|
||||
|
||||
Here you will learn
|
||||
the about the basic building blocks of this library. A must read for understanding how
|
||||
about the basic building blocks of this library. A must read for understanding how
|
||||
to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_table_of_content_imgproc
|
||||
|
||||
@@ -118,7 +118,7 @@ v = f_y*y'' + c_y
|
||||
tangential distortion coefficients. \f$s_1\f$, \f$s_2\f$, \f$s_3\f$, and \f$s_4\f$, are the thin prism distortion
|
||||
coefficients. Higher-order coefficients are not considered in OpenCV.
|
||||
|
||||
The next figure shows two common types of radial distortion: barrel distortion (typically \f$ k_1 > 0 \f$ and pincushion distortion (typically \f$ k_1 < 0 \f$).
|
||||
The next figure shows two common types of radial distortion: barrel distortion (typically \f$ k_1 > 0 \f$) and pincushion distortion (typically \f$ k_1 < 0 \f$).
|
||||
|
||||

|
||||
|
||||
@@ -307,11 +307,11 @@ optimization procedures like calibrateCamera, stereoCalibrate, or solvePnP .
|
||||
*/
|
||||
CV_EXPORTS_W void Rodrigues( InputArray src, OutputArray dst, OutputArray jacobian = noArray() );
|
||||
|
||||
/** @example pose_from_homography.cpp
|
||||
An example program about pose estimation from coplanar points
|
||||
/** @example samples/cpp/tutorial_code/features2D/Homography/pose_from_homography.cpp
|
||||
An example program about pose estimation from coplanar points
|
||||
|
||||
Check @ref tutorial_homography "the corresponding tutorial" for more details
|
||||
*/
|
||||
Check @ref tutorial_homography "the corresponding tutorial" for more details
|
||||
*/
|
||||
|
||||
/** @brief Finds a perspective transformation between two planes.
|
||||
|
||||
@@ -526,11 +526,11 @@ CV_EXPORTS_W void projectPoints( InputArray objectPoints,
|
||||
OutputArray jacobian = noArray(),
|
||||
double aspectRatio = 0 );
|
||||
|
||||
/** @example homography_from_camera_displacement.cpp
|
||||
An example program about homography from the camera displacement
|
||||
/** @example samples/cpp/tutorial_code/features2D/Homography/homography_from_camera_displacement.cpp
|
||||
An example program about homography from the camera displacement
|
||||
|
||||
Check @ref tutorial_homography "the corresponding tutorial" for more details
|
||||
*/
|
||||
Check @ref tutorial_homography "the corresponding tutorial" for more details
|
||||
*/
|
||||
|
||||
/** @brief Finds an object pose from 3D-2D point correspondences.
|
||||
|
||||
@@ -1966,11 +1966,11 @@ CV_EXPORTS_W cv::Mat estimateAffinePartial2D(InputArray from, InputArray to, Out
|
||||
size_t maxIters = 2000, double confidence = 0.99,
|
||||
size_t refineIters = 10);
|
||||
|
||||
/** @example decompose_homography.cpp
|
||||
An example program with homography decomposition.
|
||||
/** @example samples/cpp/tutorial_code/features2D/Homography/decompose_homography.cpp
|
||||
An example program with homography decomposition.
|
||||
|
||||
Check @ref tutorial_homography "the corresponding tutorial" for more details.
|
||||
*/
|
||||
Check @ref tutorial_homography "the corresponding tutorial" for more details.
|
||||
*/
|
||||
|
||||
/** @brief Decompose a homography matrix to rotation(s), translation(s) and plane normal(s).
|
||||
|
||||
@@ -1992,6 +1992,31 @@ CV_EXPORTS_W int decomposeHomographyMat(InputArray H,
|
||||
OutputArrayOfArrays translations,
|
||||
OutputArrayOfArrays normals);
|
||||
|
||||
/** @brief Filters homography decompositions based on additional information.
|
||||
|
||||
@param rotations Vector of rotation matrices.
|
||||
@param normals Vector of plane normal matrices.
|
||||
@param beforePoints Vector of (rectified) visible reference points before the homography is applied
|
||||
@param afterPoints Vector of (rectified) visible reference points after the homography is applied
|
||||
@param possibleSolutions Vector of int indices representing the viable solution set after filtering
|
||||
@param pointsMask optional Mat/Vector of 8u type representing the mask for the inliers as given by the findHomography function
|
||||
|
||||
This function is intended to filter the output of the decomposeHomographyMat based on additional
|
||||
information as described in @cite Malis . The summary of the method: the decomposeHomographyMat function
|
||||
returns 2 unique solutions and their "opposites" for a total of 4 solutions. If we have access to the
|
||||
sets of points visible in the camera frame before and after the homography transformation is applied,
|
||||
we can determine which are the true potential solutions and which are the opposites by verifying which
|
||||
homographies are consistent with all visible reference points being in front of the camera. The inputs
|
||||
are left unchanged; the filtered solution set is returned as indices into the existing one.
|
||||
|
||||
*/
|
||||
CV_EXPORTS_W void filterHomographyDecompByVisibleRefpoints(InputArrayOfArrays rotations,
|
||||
InputArrayOfArrays normals,
|
||||
InputArray beforePoints,
|
||||
InputArray afterPoints,
|
||||
OutputArray possibleSolutions,
|
||||
InputArray pointsMask = noArray());
|
||||
|
||||
/** @brief The base class for stereo correspondence algorithms.
|
||||
*/
|
||||
class CV_EXPORTS_W StereoMatcher : public Algorithm
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"namespaces_dict": {
|
||||
"cv.fisheye": "fisheye"
|
||||
},
|
||||
"func_arg_fix" : {
|
||||
"findFundamentalMat" : { "points1" : {"ctype" : "vector_Point2f"},
|
||||
"points2" : {"ctype" : "vector_Point2f"} },
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// This file contains wrappers for legacy OpenCV C API
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/calib3d/calib3d_c.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
CV_IMPL void
|
||||
cvDrawChessboardCorners(CvArr* _image, CvSize pattern_size,
|
||||
CvPoint2D32f* corners, int count, int found)
|
||||
{
|
||||
CV_Assert(corners != NULL); //CV_CheckNULL(corners, "NULL is not allowed for 'corners' parameter");
|
||||
Mat image = cvarrToMat(_image);
|
||||
CV_StaticAssert(sizeof(CvPoint2D32f) == sizeof(Point2f), "");
|
||||
drawChessboardCorners(image, pattern_size, Mat(1, count, traits::Type<Point2f>::value, corners), found != 0);
|
||||
}
|
||||
|
||||
CV_IMPL int
|
||||
cvFindChessboardCorners(const void* arr, CvSize pattern_size,
|
||||
CvPoint2D32f* out_corners_, int* out_corner_count,
|
||||
int flags)
|
||||
{
|
||||
if (!out_corners_)
|
||||
CV_Error( CV_StsNullPtr, "Null pointer to corners" );
|
||||
|
||||
Mat image = cvarrToMat(arr);
|
||||
std::vector<Point2f> out_corners;
|
||||
|
||||
if (out_corner_count)
|
||||
*out_corner_count = 0;
|
||||
|
||||
bool res = cv::findChessboardCorners(image, pattern_size, out_corners, flags);
|
||||
|
||||
int corner_count = (int)out_corners.size();
|
||||
if (out_corner_count)
|
||||
*out_corner_count = corner_count;
|
||||
CV_CheckLE(corner_count, Size(pattern_size).area(), "Unexpected number of corners");
|
||||
for (int i = 0; i < corner_count; ++i)
|
||||
{
|
||||
out_corners_[i] = cvPoint2D32f(out_corners[i]);
|
||||
}
|
||||
return res ? 1 : 0;
|
||||
}
|
||||
@@ -2336,10 +2336,13 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2,
|
||||
_uu[2] = 1;
|
||||
cvCrossProduct(&uu, &t, &ww);
|
||||
nt = cvNorm(&t, 0, CV_L2);
|
||||
CV_Assert(fabs(nt) > 0);
|
||||
nw = cvNorm(&ww, 0, CV_L2);
|
||||
CV_Assert(fabs(nw) > 0);
|
||||
cvConvertScale(&ww, &ww, 1 / nw);
|
||||
cvCrossProduct(&t, &ww, &w3);
|
||||
nw = cvNorm(&w3, 0, CV_L2);
|
||||
CV_Assert(fabs(nw) > 0);
|
||||
cvConvertScale(&w3, &w3, 1 / nw);
|
||||
_uu[2] = 0;
|
||||
|
||||
@@ -3159,6 +3162,10 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints,
|
||||
Point3f* objPtData = objPtMat.ptr<Point3f>();
|
||||
Point2f* imgPtData1 = imgPtMat1.ptr<Point2f>();
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 8
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
||||
#endif
|
||||
for( i = 0; i < nimages; i++, j += ni )
|
||||
{
|
||||
Mat objpt = objectPoints.getMat(i);
|
||||
@@ -3176,6 +3183,9 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints,
|
||||
memcpy( imgPtData2 + j, imgpt2.ptr(), ni*sizeof(imgPtData2[0]) );
|
||||
}
|
||||
}
|
||||
#if defined __GNUC__ && __GNUC__ >= 8
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
static Mat prepareCameraMatrix(Mat& cameraMatrix0, int rtype)
|
||||
@@ -3870,12 +3880,14 @@ float cv::rectify3Collinear( InputArray _cameraMatrix1, InputArray _distCoeffs1,
|
||||
|
||||
int idx = fabs(t12(0,0)) > fabs(t12(1,0)) ? 0 : 1;
|
||||
double c = t12(idx,0), nt = norm(t12, CV_L2);
|
||||
CV_Assert(fabs(nt) > 0);
|
||||
Mat_<double> uu = Mat_<double>::zeros(3,1);
|
||||
uu(idx, 0) = c > 0 ? 1 : -1;
|
||||
|
||||
// calculate global Z rotation
|
||||
Mat_<double> ww = t12.cross(uu), wR;
|
||||
double nw = norm(ww, CV_L2);
|
||||
CV_Assert(fabs(nw) > 0);
|
||||
ww *= acos(fabs(c)/nt)/nw;
|
||||
Rodrigues(ww, wR);
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ void CirclesGridClusterFinder::findOutsideCorners(const std::vector<cv::Point2f>
|
||||
CV_Assert(!corners.empty());
|
||||
outsideCorners.clear();
|
||||
//find two pairs of the most nearest corners
|
||||
int i, j, n = (int)corners.size();
|
||||
const size_t n = corners.size();
|
||||
|
||||
#ifdef DEBUG_CIRCLES
|
||||
Mat cornersImage(1024, 1248, CV_8UC1, Scalar(0));
|
||||
@@ -232,22 +232,22 @@ void CirclesGridClusterFinder::findOutsideCorners(const std::vector<cv::Point2f>
|
||||
imshow("corners", cornersImage);
|
||||
#endif
|
||||
|
||||
std::vector<Point2f> tangentVectors(corners.size());
|
||||
for(size_t k=0; k<corners.size(); k++)
|
||||
std::vector<Point2f> tangentVectors(n);
|
||||
for(size_t k=0; k < n; k++)
|
||||
{
|
||||
Point2f diff = corners[(k + 1) % corners.size()] - corners[k];
|
||||
Point2f diff = corners[(k + 1) % n] - corners[k];
|
||||
tangentVectors[k] = diff * (1.0f / norm(diff));
|
||||
}
|
||||
|
||||
//compute angles between all sides
|
||||
Mat cosAngles(n, n, CV_32FC1, 0.0f);
|
||||
for(i = 0; i < n; i++)
|
||||
Mat cosAngles((int)n, (int)n, CV_32FC1, 0.0f);
|
||||
for(size_t i = 0; i < n; i++)
|
||||
{
|
||||
for(j = i + 1; j < n; j++)
|
||||
for(size_t j = i + 1; j < n; j++)
|
||||
{
|
||||
float val = fabs(tangentVectors[i].dot(tangentVectors[j]));
|
||||
cosAngles.at<float>(i, j) = val;
|
||||
cosAngles.at<float>(j, i) = val;
|
||||
cosAngles.at<float>((int)i, (int)j) = val;
|
||||
cosAngles.at<float>((int)j, (int)i) = val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,10 +276,10 @@ void CirclesGridClusterFinder::findOutsideCorners(const std::vector<cv::Point2f>
|
||||
const int bigDiff = 4;
|
||||
if(maxIdx - minIdx == bigDiff)
|
||||
{
|
||||
minIdx += n;
|
||||
minIdx += (int)n;
|
||||
std::swap(maxIdx, minIdx);
|
||||
}
|
||||
if(maxIdx - minIdx != n - bigDiff)
|
||||
if(maxIdx - minIdx != (int)n - bigDiff)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -206,6 +206,7 @@ void dls::run_kernel(const cv::Mat& pp)
|
||||
|
||||
void dls::build_coeff_matrix(const cv::Mat& pp, cv::Mat& Mtilde, cv::Mat& D)
|
||||
{
|
||||
CV_Assert(!pp.empty() && N > 0);
|
||||
cv::Mat eye = cv::Mat::eye(3, 3, CV_64F);
|
||||
|
||||
// build coeff matrix
|
||||
|
||||
@@ -126,7 +126,8 @@ void cv::fisheye::projectPoints(InputArray objectPoints, OutputArray imagePoints
|
||||
{
|
||||
Vec3d Xi = objectPoints.depth() == CV_32F ? (Vec3d)Xf[i] : Xd[i];
|
||||
Vec3d Y = aff*Xi;
|
||||
|
||||
if (fabs(Y[2]) < DBL_MIN)
|
||||
Y[2] = 1;
|
||||
Vec2d x(Y[0]/Y[2], Y[1]/Y[2]);
|
||||
|
||||
double r2 = x.dot(x);
|
||||
@@ -1186,6 +1187,7 @@ void cv::internal::ComputeExtrinsicRefine(const Mat& imagePoints, const Mat& obj
|
||||
{
|
||||
CV_Assert(!objectPoints.empty() && objectPoints.type() == CV_64FC3);
|
||||
CV_Assert(!imagePoints.empty() && imagePoints.type() == CV_64FC2);
|
||||
CV_Assert(rvec.total() > 2 && tvec.total() > 2);
|
||||
Vec6d extrinsics(rvec.at<double>(0), rvec.at<double>(1), rvec.at<double>(2),
|
||||
tvec.at<double>(0), tvec.at<double>(1), tvec.at<double>(2));
|
||||
double change = 1;
|
||||
@@ -1365,9 +1367,13 @@ void cv::internal::InitExtrinsics(const Mat& _imagePoints, const Mat& _objectPoi
|
||||
double sc = .5 * (norm(H.col(0)) + norm(H.col(1)));
|
||||
H = H / sc;
|
||||
Mat u1 = H.col(0).clone();
|
||||
u1 = u1 / norm(u1);
|
||||
double norm_u1 = norm(u1);
|
||||
CV_Assert(fabs(norm_u1) > 0);
|
||||
u1 = u1 / norm_u1;
|
||||
Mat u2 = H.col(1).clone() - u1.dot(H.col(1).clone()) * u1;
|
||||
u2 = u2 / norm(u2);
|
||||
double norm_u2 = norm(u2);
|
||||
CV_Assert(fabs(norm_u2) > 0);
|
||||
u2 = u2 / norm_u2;
|
||||
Mat u3 = u1.cross(u2);
|
||||
Mat RRR;
|
||||
hconcat(u1, u2, RRR);
|
||||
|
||||
@@ -1,50 +1,51 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This is a homography decomposition implementation contributed to OpenCV
|
||||
// by Samson Yilma. It implements the homography decomposition algorithm
|
||||
// described in the research report:
|
||||
// Malis, E and Vargas, M, "Deeper understanding of the homography decomposition
|
||||
// for vision-based control", Research Report 6303, INRIA (2007)
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2014, Samson Yilma (samson_yilma@yahoo.com), all rights reserved.
|
||||
//
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
//
|
||||
// This is a homography decomposition implementation contributed to OpenCV
|
||||
// by Samson Yilma. It implements the homography decomposition algorithm
|
||||
// described in the research report:
|
||||
// Malis, E and Vargas, M, "Deeper understanding of the homography decomposition
|
||||
// for vision-based control", Research Report 6303, INRIA (2007)
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2014, Samson Yilma (samson_yilma@yahoo.com), all rights reserved.
|
||||
// Copyright (C) 2018, 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 the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <memory>
|
||||
@@ -193,6 +194,7 @@ void HomographyDecompZhang::decompose(std::vector<CameraMotion>& camMotions)
|
||||
{
|
||||
Mat W, U, Vt;
|
||||
SVD::compute(getHnorm(), W, U, Vt);
|
||||
CV_Assert(W.total() > 2 && Vt.total() > 7);
|
||||
double lambda1=W.at<double>(0);
|
||||
double lambda3=W.at<double>(2);
|
||||
double lambda1m3 = (lambda1-lambda3);
|
||||
@@ -489,4 +491,67 @@ int decomposeHomographyMat(InputArray _H,
|
||||
return nsols;
|
||||
}
|
||||
|
||||
void filterHomographyDecompByVisibleRefpoints(InputArrayOfArrays _rotations,
|
||||
InputArrayOfArrays _normals,
|
||||
InputArray _beforeRectifiedPoints,
|
||||
InputArray _afterRectifiedPoints,
|
||||
OutputArray _possibleSolutions,
|
||||
InputArray _pointsMask)
|
||||
{
|
||||
CV_Assert(_beforeRectifiedPoints.type() == CV_32FC2 && _afterRectifiedPoints.type() == CV_32FC2);
|
||||
CV_Assert(_pointsMask.empty() || _pointsMask.type() == CV_8U);
|
||||
|
||||
Mat beforeRectifiedPoints = _beforeRectifiedPoints.getMat();
|
||||
Mat afterRectifiedPoints = _afterRectifiedPoints.getMat();
|
||||
Mat pointsMask = _pointsMask.getMat();
|
||||
int nsolutions = (int)_rotations.total();
|
||||
int npoints = (int)beforeRectifiedPoints.total();
|
||||
CV_Assert(pointsMask.empty() || pointsMask.checkVector(1, CV_8U) == npoints);
|
||||
const uchar* pointsMaskPtr = pointsMask.data;
|
||||
|
||||
std::vector<uchar> solutionMask(nsolutions, (uchar)1);
|
||||
std::vector<Mat> normals(nsolutions);
|
||||
std::vector<Mat> rotnorm(nsolutions);
|
||||
Mat R;
|
||||
|
||||
for( int i = 0; i < nsolutions; i++ )
|
||||
{
|
||||
_normals.getMat(i).convertTo(normals[i], CV_64F);
|
||||
CV_Assert(normals[i].total() == 3);
|
||||
_rotations.getMat(i).convertTo(R, CV_64F);
|
||||
rotnorm[i] = R*normals[i];
|
||||
CV_Assert(rotnorm[i].total() == 3);
|
||||
}
|
||||
|
||||
for( int j = 0; j < npoints; j++ )
|
||||
{
|
||||
if( !pointsMaskPtr || pointsMaskPtr[j] )
|
||||
{
|
||||
Point2f prevPoint = beforeRectifiedPoints.at<Point2f>(j);
|
||||
Point2f currPoint = afterRectifiedPoints.at<Point2f>(j);
|
||||
|
||||
for( int i = 0; i < nsolutions; i++ )
|
||||
{
|
||||
if( !solutionMask[i] )
|
||||
continue;
|
||||
|
||||
const double* normal_i = normals[i].ptr<double>();
|
||||
const double* rotnorm_i = rotnorm[i].ptr<double>();
|
||||
double prevNormDot = normal_i[0]*prevPoint.x + normal_i[1]*prevPoint.y + normal_i[2];
|
||||
double currNormDot = rotnorm_i[0]*currPoint.x + rotnorm_i[1]*currPoint.y + rotnorm_i[2];
|
||||
|
||||
if (prevNormDot <= 0 || currNormDot <= 0)
|
||||
solutionMask[i] = (uchar)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> possibleSolutions;
|
||||
for( int i = 0; i < nsolutions; i++ )
|
||||
if( solutionMask[i] )
|
||||
possibleSolutions.push_back(i);
|
||||
|
||||
Mat(possibleSolutions).copyTo(_possibleSolutions);
|
||||
}
|
||||
|
||||
} //namespace cv
|
||||
|
||||
@@ -42,13 +42,15 @@
|
||||
#ifndef __OPENCV_PRECOMP_H__
|
||||
#define __OPENCV_PRECOMP_H__
|
||||
|
||||
#include "opencv2/calib3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
|
||||
#include "opencv2/core/private.hpp"
|
||||
|
||||
#include "opencv2/calib3d.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
|
||||
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
|
||||
#ifdef HAVE_TEGRA_OPTIMIZATION
|
||||
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
int maxAttempts=1000 ) const
|
||||
{
|
||||
cv::AutoBuffer<int> _idx(modelPoints);
|
||||
int* idx = _idx;
|
||||
int* idx = _idx.data();
|
||||
int i = 0, j, k, iters = 0;
|
||||
int d1 = m1.channels() > 1 ? m1.channels() : m1.cols;
|
||||
int d2 = m2.channels() > 1 ? m2.channels() : m2.cols;
|
||||
|
||||