Merge remote-tracking branch 'upstream/master' into daniel
This commit is contained in:
commit
a9a45e1546
24
3rdparty/ippicv/downloader.cmake
vendored
24
3rdparty/ippicv/downloader.cmake
vendored
@ -8,21 +8,21 @@
|
||||
function(_icv_downloader)
|
||||
# Define actual ICV versions
|
||||
if(APPLE)
|
||||
set(OPENCV_ICV_PACKAGE_NAME "ippicv_macosx_20140429.tgz")
|
||||
set(OPENCV_ICV_PACKAGE_HASH "f2195a60829899983acd4a45794e1717")
|
||||
set(OPENCV_ICV_PACKAGE_NAME "ippicv_macosx_20141027.tgz")
|
||||
set(OPENCV_ICV_PACKAGE_HASH "9662fe0694a67e59491a0dcc82fa26e0")
|
||||
set(OPENCV_ICV_PLATFORM "macosx")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "/ippicv_osx")
|
||||
elseif(UNIX)
|
||||
if(ANDROID AND (NOT ANDROID_ABI STREQUAL x86))
|
||||
return()
|
||||
endif()
|
||||
set(OPENCV_ICV_PACKAGE_NAME "ippicv_linux_20140513.tgz")
|
||||
set(OPENCV_ICV_PACKAGE_HASH "d80cb24f3a565113a9d6dc56344142f6")
|
||||
set(OPENCV_ICV_PACKAGE_NAME "ippicv_linux_20141027.tgz")
|
||||
set(OPENCV_ICV_PACKAGE_HASH "8b449a536a2157bcad08a2b9f266828b")
|
||||
set(OPENCV_ICV_PLATFORM "linux")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "/ippicv_lnx")
|
||||
elseif(WIN32 AND NOT ARM)
|
||||
set(OPENCV_ICV_PACKAGE_NAME "ippicv_windows_20140429.zip")
|
||||
set(OPENCV_ICV_PACKAGE_HASH "b5028a92224ec1fbc554010c52eb3ec8")
|
||||
set(OPENCV_ICV_PACKAGE_NAME "ippicv_windows_20141027.zip")
|
||||
set(OPENCV_ICV_PACKAGE_HASH "b59f865d1ba16e8c84124e19d78eec57")
|
||||
set(OPENCV_ICV_PLATFORM "windows")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "/ippicv_win")
|
||||
else()
|
||||
@ -45,7 +45,7 @@ function(_icv_downloader)
|
||||
endif()
|
||||
endif()
|
||||
unset(OPENCV_ICV_PACKAGE_DOWNLOADED CACHE)
|
||||
|
||||
|
||||
set(OPENCV_ICV_PACKAGE_ARCHIVE "${CMAKE_CURRENT_LIST_DIR}/downloads/${OPENCV_ICV_PLATFORM}-${OPENCV_ICV_PACKAGE_HASH}/${OPENCV_ICV_PACKAGE_NAME}")
|
||||
get_filename_component(OPENCV_ICV_PACKAGE_ARCHIVE_DIR "${OPENCV_ICV_PACKAGE_ARCHIVE}" PATH)
|
||||
if(EXISTS "${OPENCV_ICV_PACKAGE_ARCHIVE}")
|
||||
@ -56,7 +56,7 @@ function(_icv_downloader)
|
||||
file(REMOVE_RECURSE "${OPENCV_ICV_PACKAGE_ARCHIVE_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(NOT EXISTS "${OPENCV_ICV_PACKAGE_ARCHIVE}")
|
||||
if(NOT DEFINED OPENCV_ICV_URL)
|
||||
if(DEFINED ENV{OPENCV_ICV_URL})
|
||||
@ -65,7 +65,7 @@ function(_icv_downloader)
|
||||
set(OPENCV_ICV_URL "http://sourceforge.net/projects/opencvlibrary/files/3rdparty/ippicv")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
file(MAKE_DIRECTORY ${OPENCV_ICV_PACKAGE_ARCHIVE_DIR})
|
||||
message(STATUS "ICV: Downloading ${OPENCV_ICV_PACKAGE_NAME}...")
|
||||
file(DOWNLOAD "${OPENCV_ICV_URL}/${OPENCV_ICV_PACKAGE_NAME}" "${OPENCV_ICV_PACKAGE_ARCHIVE}"
|
||||
@ -82,12 +82,12 @@ function(_icv_downloader)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
ocv_assert(EXISTS "${OPENCV_ICV_PACKAGE_ARCHIVE}")
|
||||
ocv_assert(NOT EXISTS "${OPENCV_ICV_UNPACK_PATH}")
|
||||
file(MAKE_DIRECTORY ${OPENCV_ICV_UNPACK_PATH})
|
||||
ocv_assert(EXISTS "${OPENCV_ICV_UNPACK_PATH}")
|
||||
|
||||
|
||||
message(STATUS "ICV: Unpacking ${OPENCV_ICV_PACKAGE_NAME} to ${OPENCV_ICV_UNPACK_PATH}...")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xz "${OPENCV_ICV_PACKAGE_ARCHIVE}"
|
||||
WORKING_DIRECTORY "${OPENCV_ICV_UNPACK_PATH}"
|
||||
@ -100,7 +100,7 @@ function(_icv_downloader)
|
||||
ocv_assert(EXISTS "${OPENCV_ICV_PATH}")
|
||||
|
||||
set(OPENCV_ICV_PACKAGE_DOWNLOADED "${OPENCV_ICV_PACKAGE_HASH}" CACHE INTERNAL "ICV package hash")
|
||||
|
||||
|
||||
message(STATUS "ICV: Package successfully downloaded")
|
||||
set(OPENCV_ICV_PATH "${OPENCV_ICV_PATH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
@ -49,7 +49,7 @@ if(NOT DEFINED OpenCV_MODULES_SUFFIX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(@USE_IPPICV@) # value is defined by package builder
|
||||
if("@USE_IPPICV@" STREQUAL "TRUE") # value is defined by package builder (use STREQUAL to comply new CMake policy CMP0012)
|
||||
if(NOT TARGET ippicv)
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_PATH_RELATIVE_IPPICV@")
|
||||
add_library(ippicv STATIC IMPORTED)
|
||||
@ -292,7 +292,9 @@ foreach(__opttype OPT DBG)
|
||||
set(OpenCV_CUDA_LIBS_RELPATH "")
|
||||
foreach(l ${OpenCV_CUDA_LIBS_ABSPATH})
|
||||
get_filename_component(_tmp ${l} PATH)
|
||||
list(APPEND OpenCV_CUDA_LIBS_RELPATH ${_tmp})
|
||||
if(NOT ${_tmp} MATCHES "-Wl.*")
|
||||
list(APPEND OpenCV_CUDA_LIBS_RELPATH ${_tmp})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES OpenCV_CUDA_LIBS_RELPATH)
|
||||
|
@ -147,14 +147,18 @@ endif()
|
||||
|
||||
# ========= Doxygen docs =========
|
||||
if(BUILD_DOCS AND HAVE_DOXYGEN)
|
||||
# documented modules list
|
||||
set(candidates)
|
||||
set(all_headers)
|
||||
set(all_images)
|
||||
list(APPEND candidates ${BASE_MODULES} ${EXTRA_MODULES})
|
||||
# blacklisted modules
|
||||
ocv_list_filterout(candidates "^ts$")
|
||||
|
||||
# gathering headers
|
||||
set(all_headers) # files and dirs to process
|
||||
set(all_images) # image search paths
|
||||
set(reflist) # modules reference
|
||||
foreach(m ${candidates})
|
||||
set(reflist "${reflist} \n- @subpage ${m}")
|
||||
set(all_headers ${all_headers} "${OPENCV_MODULE_opencv_${m}_HEADERS}")
|
||||
set(docs_dir "${OPENCV_MODULE_opencv_${m}_LOCATION}/doc")
|
||||
if(EXISTS ${docs_dir})
|
||||
@ -164,15 +168,20 @@ if(BUILD_DOCS AND HAVE_DOXYGEN)
|
||||
endforeach()
|
||||
|
||||
# additional config
|
||||
set(doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
|
||||
set(rootfile "${CMAKE_CURRENT_BINARY_DIR}/root.markdown")
|
||||
set(all_headers ${all_headers} ${rootfile})
|
||||
string(REGEX REPLACE ";" " \\\\\\n" CMAKE_DOXYGEN_INPUT_LIST "${all_headers}")
|
||||
string(REGEX REPLACE ";" " \\\\\\n" CMAKE_DOXYGEN_IMAGE_PATH "${all_images}")
|
||||
set(CMAKE_DOXYGEN_INDEX_MD "${CMAKE_SOURCE_DIR}/README.md")
|
||||
set(CMAKE_DOXYGEN_LAYOUT "${CMAKE_CURRENT_SOURCE_DIR}/DoxygenLayout.xml")
|
||||
set(CMAKE_DOXYGEN_OUTPUT_PATH "doxygen")
|
||||
set(CMAKE_DOXYGEN_MODULES_REFERENCE "${reflist}")
|
||||
set(CMAKE_DOXYGEN_EXAMPLE_PATH "${CMAKE_SOURCE_DIR}/samples/cpp")
|
||||
|
||||
# writing file
|
||||
set(doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
|
||||
configure_file(Doxyfile.in ${doxyfile} @ONLY)
|
||||
configure_file(root.markdown.in ${rootfile} @ONLY)
|
||||
configure_file(mymath.sty "${CMAKE_DOXYGEN_OUTPUT_PATH}/html/mymath.sty" @ONLY)
|
||||
|
||||
add_custom_target(doxygen
|
||||
COMMAND ${DOXYGEN_BUILD} ${doxyfile}
|
||||
|
@ -21,8 +21,8 @@ ABBREVIATE_BRIEF = "The $name class" \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@/modules
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
@ -39,7 +39,7 @@ OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
EXTENSION_MAPPING =
|
||||
MARKDOWN_SUPPORT = YES
|
||||
AUTOLINK_SUPPORT = NO
|
||||
AUTOLINK_SUPPORT = YES
|
||||
BUILTIN_STL_SUPPORT = YES
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
@ -53,7 +53,7 @@ LOOKUP_CACHE_SIZE = 0
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_PACKAGE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
@ -66,11 +66,11 @@ CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
SHOW_GROUPED_MEMB_INC = NO
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
FORCE_LOCAL_INCLUDES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_BRIEF_DOCS = YES
|
||||
SORT_MEMBERS_CTORS_1ST = YES
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
STRICT_PROTO_MATCHING = NO
|
||||
@ -86,7 +86,7 @@ SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE = @CMAKE_DOXYGEN_LAYOUT@
|
||||
CITE_BIB_FILES =
|
||||
QUIET = NO
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
@ -100,19 +100,16 @@ RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS = CV_WRAP \
|
||||
CV_EXPORTS \
|
||||
CV_EXPORTS_W \
|
||||
CV_WRAP_AS
|
||||
EXAMPLE_PATH =
|
||||
EXCLUDE_SYMBOLS = cv::DataType<*>
|
||||
EXAMPLE_PATH = @CMAKE_DOXYGEN_EXAMPLE_PATH@
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
EXAMPLE_RECURSIVE = YES
|
||||
IMAGE_PATH = @CMAKE_DOXYGEN_IMAGE_PATH@
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
USE_MDFILE_AS_MAINPAGE = @CMAKE_DOXYGEN_INDEX_MD@
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
@ -161,18 +158,18 @@ QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = YES
|
||||
DISABLE_INDEX = NO
|
||||
GENERATE_TREEVIEW = YES
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
ENUM_VALUES_PER_LINE = 0
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = YES
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_FONTSIZE = 14
|
||||
FORMULA_TRANSPARENT = YES
|
||||
USE_MATHJAX = NO
|
||||
USE_MATHJAX = YES
|
||||
MATHJAX_FORMAT = HTML-CSS
|
||||
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
|
||||
MATHJAX_EXTENSIONS =
|
||||
MATHJAX_CODEFILE =
|
||||
MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
||||
MATHJAX_CODEFILE = @CMAKE_CURRENT_SOURCE_DIR@/mymath.js
|
||||
SEARCHENGINE = YES
|
||||
SERVER_BASED_SEARCH = NO
|
||||
EXTERNAL_SEARCH = NO
|
||||
@ -180,13 +177,13 @@ SEARCHENGINE_URL =
|
||||
SEARCHDATA_FILE = searchdata.xml
|
||||
EXTERNAL_SEARCH_ID =
|
||||
EXTRA_SEARCH_MAPPINGS =
|
||||
GENERATE_LATEX = YES
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4
|
||||
EXTRA_PACKAGES =
|
||||
EXTRA_PACKAGES = mymath
|
||||
LATEX_HEADER =
|
||||
LATEX_FOOTER =
|
||||
LATEX_EXTRA_FILES =
|
||||
@ -222,12 +219,29 @@ EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = CV_WRAP= \
|
||||
__cplusplus=1 \
|
||||
PREDEFINED = __cplusplus=1 \
|
||||
HAVE_IPP_A=1 \
|
||||
CVAPI(x)=x \
|
||||
CV_PROP_RW= \
|
||||
CV_EXPORTS= \
|
||||
CV_EXPORTS_W=
|
||||
CV_EXPORTS_W= \
|
||||
CV_EXPORTS_W_SIMPLE= \
|
||||
CV_EXPORTS_AS(x)= \
|
||||
CV_EXPORTS_W_MAP= \
|
||||
CV_IN_OUT= \
|
||||
CV_OUT= \
|
||||
CV_PROP= \
|
||||
CV_PROP_RW= \
|
||||
CV_WRAP= \
|
||||
CV_WRAP_AS(x)= \
|
||||
CV_CDECL= \
|
||||
CV_Func = \
|
||||
CV_DO_PRAGMA(x)= \
|
||||
CV_SUPPRESS_DEPRECATED_START= \
|
||||
CV_SUPPRESS_DEPRECATED_END= \
|
||||
CV_INLINE= \
|
||||
CV_NORETURN= \
|
||||
CV_DEFAULT(x)=" = x" \
|
||||
CV_NEON=1
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
TAGFILES =
|
||||
|
12
doc/mymath.js
Normal file
12
doc/mymath.js
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
MathJax.Hub.Config({
|
||||
TeX: {
|
||||
Macros: {
|
||||
matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
|
||||
fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
|
||||
forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
|
||||
vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
|
||||
vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9]
|
||||
}
|
||||
}
|
||||
});
|
@ -1,5 +1,9 @@
|
||||
\ProvidesPackage{mymath}
|
||||
|
||||
\usepackage{euler}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{amsmath}
|
||||
|
||||
\newcommand{\matTT}[9]{
|
||||
\[
|
||||
\left|\begin{array}{ccc}
|
||||
|
7
doc/root.markdown.in
Normal file
7
doc/root.markdown.in
Normal file
@ -0,0 +1,7 @@
|
||||
OpenCV modules {#mainpage}
|
||||
==============
|
||||
|
||||
- @subpage intro
|
||||
- @subpage core
|
||||
|
||||
<!-- @CMAKE_DOXYGEN_MODULES_REFERENCE@ -->
|
@ -126,7 +126,7 @@ In this sample I'll show how to calculate and show the *magnitude* image of a Fo
|
||||
Result
|
||||
======
|
||||
|
||||
An application idea would be to determine the geometrical orientation present in the image. For example, let us find out if a text is horizontal or not? Looking at some text you'll notice that the text lines sort of form also horizontal lines and the letters form sort of vertical lines. These two main components of a text snippet may be also seen in case of the Fourier transform. Let us use :download:`this horizontal <../../../../samples/cpp/tutorial_code/images/imageTextN.png>` and :download:`this rotated<../../../../samples/cpp/tutorial_code/images/imageTextR.png>` image about a text.
|
||||
An application idea would be to determine the geometrical orientation present in the image. For example, let us find out if a text is horizontal or not? Looking at some text you'll notice that the text lines sort of form also horizontal lines and the letters form sort of vertical lines. These two main components of a text snippet may be also seen in case of the Fourier transform. Let us use :download:`this horizontal <../../../../samples/data/imageTextN.png>` and :download:`this rotated<../../../../samples/data/imageTextR.png>` image about a text.
|
||||
|
||||
In case of the horizontal text:
|
||||
|
||||
|
@ -39,28 +39,28 @@ You'll almost always end up using the:
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/introduction/display_image/display_image.cpp
|
||||
:language: cpp
|
||||
:tab-width: 4
|
||||
:lines: 1-4
|
||||
:lines: 1-6
|
||||
|
||||
We also include the *iostream* to facilitate console line output and input. To avoid data structure and function name conflicts with other libraries, OpenCV has its own namespace: *cv*. To avoid the need appending prior each of these the *cv::* keyword you can import the namespace in the whole file by using the lines:
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/introduction/display_image/display_image.cpp
|
||||
:language: cpp
|
||||
:tab-width: 4
|
||||
:lines: 6-7
|
||||
:lines: 8-9
|
||||
|
||||
This is true for the STL library too (used for console I/O). Now, let's analyze the *main* function. We start up assuring that we acquire a valid image name argument from the command line.
|
||||
This is true for the STL library too (used for console I/O). Now, let's analyze the *main* function. We start up assuring that we acquire a valid image name argument from the command line. Otherwise take a picture by default: "HappyFish.jpg".
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/introduction/display_image/display_image.cpp
|
||||
:language: cpp
|
||||
:tab-width: 4
|
||||
:lines: 11-15
|
||||
:lines: 13-17
|
||||
|
||||
Then create a *Mat* object that will store the data of the loaded image.
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/introduction/display_image/display_image.cpp
|
||||
:language: cpp
|
||||
:tab-width: 4
|
||||
:lines: 17
|
||||
:lines: 19
|
||||
|
||||
Now we call the :imread:`imread <>` function which loads the image name specified by the first argument (*argv[1]*). The second argument specifies the format in what we want the image. This may be:
|
||||
|
||||
@ -73,7 +73,7 @@ Now we call the :imread:`imread <>` function which loads the image name specifie
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/introduction/display_image/display_image.cpp
|
||||
:language: cpp
|
||||
:tab-width: 4
|
||||
:lines: 18
|
||||
:lines: 20
|
||||
|
||||
.. note::
|
||||
|
||||
@ -88,21 +88,21 @@ After checking that the image data was loaded correctly, we want to display our
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/introduction/display_image/display_image.cpp
|
||||
:language: cpp
|
||||
:lines: 26
|
||||
:lines: 28
|
||||
:tab-width: 4
|
||||
|
||||
Finally, to update the content of the OpenCV window with a new image use the :imshow:`imshow <>` function. Specify the OpenCV window name to update and the image to use during this operation:
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/introduction/display_image/display_image.cpp
|
||||
:language: cpp
|
||||
:lines: 27
|
||||
:lines: 29
|
||||
:tab-width: 4
|
||||
|
||||
Because we want our window to be displayed until the user presses a key (otherwise the program would end far too quickly), we use the :wait_key:`waitKey <>` function whose only parameter is just how long should it wait for a user input (measured in milliseconds). Zero means to wait forever.
|
||||
|
||||
.. literalinclude:: ../../../../samples/cpp/tutorial_code/introduction/display_image/display_image.cpp
|
||||
:language: cpp
|
||||
:lines: 29
|
||||
:lines: 31
|
||||
:tab-width: 4
|
||||
|
||||
Result
|
||||
|
@ -160,7 +160,7 @@ You can start a Visual Studio build from two places. Either inside from the *IDE
|
||||
|
||||
.. |voila| unicode:: voil U+00E1
|
||||
|
||||
This is important to remember when you code inside the code open and save commands. You're resources will be saved ( and queried for at opening!!!) relatively to your working directory. This is unless you give a full, explicit path as parameter for the I/O functions. In the code above we open :download:`this OpenCV logo<../../../../samples/cpp/tutorial_code/images/opencv-logo.png>`. Before starting up the application make sure you place the image file in your current working directory. Modify the image file name inside the code to try it out on other images too. Run it and |voila|:
|
||||
This is important to remember when you code inside the code open and save commands. You're resources will be saved ( and queried for at opening!!!) relatively to your working directory. This is unless you give a full, explicit path as parameter for the I/O functions. In the code above we open :download:`this OpenCV logo<../../../../samples/data/opencv-logo.png>`. Before starting up the application make sure you place the image file in your current working directory. Modify the image file name inside the code to try it out on other images too. Run it and |voila|:
|
||||
|
||||
.. image:: images/SuccessVisualStudioWindows.jpg
|
||||
:alt: You should have this.
|
||||
|
@ -160,7 +160,7 @@ public:
|
||||
|
||||
Mat opoints = _m1.getMat(), ipoints = _m2.getMat(), model = _model.getMat();
|
||||
|
||||
int i, count = opoints.cols;
|
||||
int i, count = opoints.checkVector(3);
|
||||
Mat _rvec = model.col(0);
|
||||
Mat _tvec = model.col(1);
|
||||
|
||||
@ -251,14 +251,10 @@ bool cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
|
||||
if(_inliers.needed())
|
||||
{
|
||||
Mat _local_inliers;
|
||||
int count = 0;
|
||||
for (int i = 0; i < _mask_local_inliers.rows; ++i)
|
||||
for (int i = 0; i < npoints; ++i)
|
||||
{
|
||||
if((int)_mask_local_inliers.at<uchar>(i) == 1) // inliers mask
|
||||
{
|
||||
_local_inliers.push_back(count); // output inliers vector
|
||||
count++;
|
||||
}
|
||||
if((int)_mask_local_inliers.at<uchar>(i) != 0) // inliers mask
|
||||
_local_inliers.push_back(i); // output inliers vector
|
||||
}
|
||||
_local_inliers.copyTo(_inliers);
|
||||
}
|
||||
|
140
modules/calib3d/test/test_decompose_projection.cpp
Normal file
140
modules/calib3d/test/test_decompose_projection.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
class CV_DecomposeProjectionMatrixTest : public cvtest::BaseTest
|
||||
{
|
||||
public:
|
||||
CV_DecomposeProjectionMatrixTest();
|
||||
protected:
|
||||
void run(int);
|
||||
};
|
||||
|
||||
CV_DecomposeProjectionMatrixTest::CV_DecomposeProjectionMatrixTest()
|
||||
{
|
||||
test_case_count = 30;
|
||||
}
|
||||
|
||||
|
||||
void CV_DecomposeProjectionMatrixTest::run(int start_from)
|
||||
{
|
||||
|
||||
ts->set_failed_test_info(cvtest::TS::OK);
|
||||
|
||||
cv::RNG& rng = ts->get_rng();
|
||||
int progress = 0;
|
||||
|
||||
|
||||
for (int iter = start_from; iter < test_case_count; ++iter)
|
||||
{
|
||||
ts->update_context(this, iter, true);
|
||||
progress = update_progress(progress, iter, test_case_count, 0);
|
||||
|
||||
// Create the original (and random) camera matrix, rotation, and translation
|
||||
cv::Vec2d f, c;
|
||||
rng.fill(f, cv::RNG::UNIFORM, 300, 1000);
|
||||
rng.fill(c, cv::RNG::UNIFORM, 150, 600);
|
||||
|
||||
double alpha = 0.01*rng.gaussian(1);
|
||||
|
||||
cv::Matx33d origK(f(0), alpha*f(0), c(0),
|
||||
0, f(1), c(1),
|
||||
0, 0, 1);
|
||||
|
||||
|
||||
cv::Vec3d rVec;
|
||||
rng.fill(rVec, cv::RNG::UNIFORM, -CV_PI, CV_PI);
|
||||
|
||||
cv::Matx33d origR;
|
||||
Rodrigues(rVec, origR);
|
||||
|
||||
cv::Vec3d origT;
|
||||
rng.fill(origT, cv::RNG::NORMAL, 0, 1);
|
||||
|
||||
|
||||
// Compose the projection matrix
|
||||
cv::Matx34d P(3,4);
|
||||
hconcat(origK*origR, origK*origT, P);
|
||||
|
||||
|
||||
// Decompose
|
||||
cv::Matx33d K, R;
|
||||
cv::Vec4d homogCameraCenter;
|
||||
decomposeProjectionMatrix(P, K, R, homogCameraCenter);
|
||||
|
||||
|
||||
// Recover translation from the camera center
|
||||
cv::Vec3d cameraCenter(homogCameraCenter(0), homogCameraCenter(1), homogCameraCenter(2));
|
||||
cameraCenter /= homogCameraCenter(3);
|
||||
|
||||
cv::Vec3d t = -R*cameraCenter;
|
||||
|
||||
|
||||
const double thresh = 1e-6;
|
||||
if ( norm(origK, K, cv::NORM_INF) > thresh )
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( norm(origR, R, cv::NORM_INF) > thresh )
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( norm(origT, t, cv::NORM_INF) > thresh )
|
||||
{
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(Calib3d_DecomposeProjectionMatrix, accuracy)
|
||||
{
|
||||
CV_DecomposeProjectionMatrixTest test;
|
||||
test.safe_run();
|
||||
}
|
318
modules/core/doc/intro.markdown
Normal file
318
modules/core/doc/intro.markdown
Normal file
@ -0,0 +1,318 @@
|
||||
Introduction {#intro}
|
||||
============
|
||||
|
||||
OpenCV (Open Source Computer Vision Library: <http://opencv.org>) is an open-source BSD-licensed
|
||||
library that includes several hundreds of computer vision algorithms. The document describes the
|
||||
so-called OpenCV 2.x API, which is essentially a C++ API, as opposite to the C-based OpenCV 1.x API.
|
||||
The latter is described in opencv1x.pdf.
|
||||
|
||||
OpenCV has a modular structure, which means that the package includes several shared or static
|
||||
libraries. The following modules are available:
|
||||
|
||||
- @ref core - a compact module defining basic data structures, including the dense
|
||||
multi-dimensional array Mat and basic functions used by all other modules.
|
||||
- **imgproc** - an image processing module that includes linear and non-linear image filtering,
|
||||
geometrical image transformations (resize, affine and perspective warping, generic table-based
|
||||
remapping), color space conversion, histograms, and so on.
|
||||
- **video** - a video analysis module that includes motion estimation, background subtraction,
|
||||
and object tracking algorithms.
|
||||
- **calib3d** - basic multiple-view geometry algorithms, single and stereo camera calibration,
|
||||
object pose estimation, stereo correspondence algorithms, and elements of 3D reconstruction.
|
||||
- **features2d** - salient feature detectors, descriptors, and descriptor matchers.
|
||||
- **objdetect** - detection of objects and instances of the predefined classes (for example,
|
||||
faces, eyes, mugs, people, cars, and so on).
|
||||
- **highgui** - an easy-to-use interface to simple UI capabilities.
|
||||
- **videoio** - an easy-to-use interface to video capturing and video codecs.
|
||||
- **gpu** - GPU-accelerated algorithms from different OpenCV modules.
|
||||
- ... some other helper modules, such as FLANN and Google test wrappers, Python bindings, and
|
||||
others.
|
||||
|
||||
The further chapters of the document describe functionality of each module. But first, make sure to
|
||||
get familiar with the common API concepts used thoroughly in the library.
|
||||
|
||||
API Concepts
|
||||
------------
|
||||
|
||||
### cv Namespace
|
||||
|
||||
All the OpenCV classes and functions are placed into the cv namespace. Therefore, to access this
|
||||
functionality from your code, use the cv:: specifier or using namespace cv; directive:
|
||||
@code
|
||||
#include "opencv2/core.hpp"
|
||||
...
|
||||
cv::Mat H = cv::findHomography(points1, points2, CV_RANSAC, 5);
|
||||
...
|
||||
@endcode
|
||||
or :
|
||||
~~~
|
||||
#include "opencv2/core.hpp"
|
||||
using namespace cv;
|
||||
...
|
||||
Mat H = findHomography(points1, points2, CV_RANSAC, 5 );
|
||||
...
|
||||
~~~
|
||||
Some of the current or future OpenCV external names may conflict with STL or other libraries. In
|
||||
this case, use explicit namespace specifiers to resolve the name conflicts:
|
||||
@code
|
||||
Mat a(100, 100, CV_32F);
|
||||
randu(a, Scalar::all(1), Scalar::all(std::rand()));
|
||||
cv::log(a, a);
|
||||
a /= std::log(2.);
|
||||
@endcode
|
||||
|
||||
### Automatic Memory Management
|
||||
|
||||
OpenCV handles all the memory automatically.
|
||||
|
||||
First of all, std::vector, Mat, and other data structures used by the functions and methods have
|
||||
destructors that deallocate the underlying memory buffers when needed. This means that the
|
||||
destructors do not always deallocate the buffers as in case of Mat. They take into account possible
|
||||
data sharing. A destructor decrements the reference counter associated with the matrix data buffer.
|
||||
The buffer is deallocated if and only if the reference counter reaches zero, that is, when no other
|
||||
structures refer to the same buffer. Similarly, when a Mat instance is copied, no actual data is
|
||||
really copied. Instead, the reference counter is incremented to memorize that there is another owner
|
||||
of the same data. There is also the Mat::clone method that creates a full copy of the matrix data.
|
||||
See the example below:
|
||||
@code
|
||||
// create a big 8Mb matrix
|
||||
Mat A(1000, 1000, CV_64F);
|
||||
|
||||
// create another header for the same matrix;
|
||||
// this is an instant operation, regardless of the matrix size.
|
||||
Mat B = A;
|
||||
// create another header for the 3-rd row of A; no data is copied either
|
||||
Mat C = B.row(3);
|
||||
// now create a separate copy of the matrix
|
||||
Mat D = B.clone();
|
||||
// copy the 5-th row of B to C, that is, copy the 5-th row of A
|
||||
// to the 3-rd row of A.
|
||||
B.row(5).copyTo(C);
|
||||
// now let A and D share the data; after that the modified version
|
||||
// of A is still referenced by B and C.
|
||||
A = D;
|
||||
// now make B an empty matrix (which references no memory buffers),
|
||||
// but the modified version of A will still be referenced by C,
|
||||
// despite that C is just a single row of the original A
|
||||
B.release();
|
||||
|
||||
// finally, make a full copy of C. As a result, the big modified
|
||||
// matrix will be deallocated, since it is not referenced by anyone
|
||||
C = C.clone();
|
||||
@endcode
|
||||
You see that the use of Mat and other basic structures is simple. But what about high-level classes
|
||||
or even user data types created without taking automatic memory management into account? For them,
|
||||
OpenCV offers the Ptr template class that is similar to std::shared\_ptr from C++11. So, instead of
|
||||
using plain pointers:
|
||||
@code
|
||||
T* ptr = new T(...);
|
||||
@endcode
|
||||
you can use:
|
||||
@code
|
||||
Ptr<T> ptr(new T(...));
|
||||
@endcode
|
||||
or:
|
||||
@code
|
||||
Ptr<T> ptr = makePtr<T>(...);
|
||||
@endcode
|
||||
Ptr\<T\> encapsulates a pointer to a T instance and a reference counter associated with the pointer.
|
||||
See the Ptr description for details.
|
||||
|
||||
### Automatic Allocation of the Output Data
|
||||
|
||||
OpenCV deallocates the memory automatically, as well as automatically allocates the memory for
|
||||
output function parameters most of the time. So, if a function has one or more input arrays (cv::Mat
|
||||
instances) and some output arrays, the output arrays are automatically allocated or reallocated. The
|
||||
size and type of the output arrays are determined from the size and type of input arrays. If needed,
|
||||
the functions take extra parameters that help to figure out the output array properties.
|
||||
|
||||
Example:
|
||||
@code
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
VideoCapture cap(0);
|
||||
if(!cap.isOpened()) return -1;
|
||||
|
||||
Mat frame, edges;
|
||||
namedWindow("edges",1);
|
||||
for(;;)
|
||||
{
|
||||
cap >> frame;
|
||||
cvtColor(frame, edges, COLOR_BGR2GRAY);
|
||||
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
|
||||
Canny(edges, edges, 0, 30, 3);
|
||||
imshow("edges", edges);
|
||||
if(waitKey(30) >= 0) break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
The array frame is automatically allocated by the \>\> operator since the video frame resolution and
|
||||
the bit-depth is known to the video capturing module. The array edges is automatically allocated by
|
||||
the cvtColor function. It has the same size and the bit-depth as the input array. The number of
|
||||
channels is 1 because the color conversion code COLOR\_BGR2GRAY is passed, which means a color to
|
||||
grayscale conversion. Note that frame and edges are allocated only once during the first execution
|
||||
of the loop body since all the next video frames have the same resolution. If you somehow change the
|
||||
video resolution, the arrays are automatically reallocated.
|
||||
|
||||
The key component of this technology is the Mat::create method. It takes the desired array size and
|
||||
type. If the array already has the specified size and type, the method does nothing. Otherwise, it
|
||||
releases the previously allocated data, if any (this part involves decrementing the reference
|
||||
counter and comparing it with zero), and then allocates a new buffer of the required size. Most
|
||||
functions call the Mat::create method for each output array, and so the automatic output data
|
||||
allocation is implemented.
|
||||
|
||||
Some notable exceptions from this scheme are cv::mixChannels, cv::RNG::fill, and a few other
|
||||
functions and methods. They are not able to allocate the output array, so you have to do this in
|
||||
advance.
|
||||
|
||||
### Saturation Arithmetics
|
||||
|
||||
As a computer vision library, OpenCV deals a lot with image pixels that are often encoded in a
|
||||
compact, 8- or 16-bit per channel, form and thus have a limited value range. Furthermore, certain
|
||||
operations on images, like color space conversions, brightness/contrast adjustments, sharpening,
|
||||
complex interpolation (bi-cubic, Lanczos) can produce values out of the available range. If you just
|
||||
store the lowest 8 (16) bits of the result, this results in visual artifacts and may affect a
|
||||
further image analysis. To solve this problem, the so-called *saturation* arithmetics is used. For
|
||||
example, to store r, the result of an operation, to an 8-bit image, you find the nearest value
|
||||
within the 0..255 range:
|
||||
|
||||
\f[I(x,y)= \min ( \max (\textrm{round}(r), 0), 255)\f]
|
||||
|
||||
Similar rules are applied to 8-bit signed, 16-bit signed and unsigned types. This semantics is used
|
||||
everywhere in the library. In C++ code, it is done using the saturate\_cast\<\> functions that
|
||||
resemble standard C++ cast operations. See below the implementation of the formula provided above:
|
||||
@code
|
||||
I.at<uchar>(y, x) = saturate_cast<uchar>(r);
|
||||
@endcode
|
||||
where cv::uchar is an OpenCV 8-bit unsigned integer type. In the optimized SIMD code, such SSE2
|
||||
instructions as paddusb, packuswb, and so on are used. They help achieve exactly the same behavior
|
||||
as in C++ code.
|
||||
|
||||
@note Saturation is not applied when the result is 32-bit integer.
|
||||
|
||||
### Fixed Pixel Types. Limited Use of Templates
|
||||
|
||||
Templates is a great feature of C++ that enables implementation of very powerful, efficient and yet
|
||||
safe data structures and algorithms. However, the extensive use of templates may dramatically
|
||||
increase compilation time and code size. Besides, it is difficult to separate an interface and
|
||||
implementation when templates are used exclusively. This could be fine for basic algorithms but not
|
||||
good for computer vision libraries where a single algorithm may span thousands lines of code.
|
||||
Because of this and also to simplify development of bindings for other languages, like Python, Java,
|
||||
Matlab that do not have templates at all or have limited template capabilities, the current OpenCV
|
||||
implementation is based on polymorphism and runtime dispatching over templates. In those places
|
||||
where runtime dispatching would be too slow (like pixel access operators), impossible (generic
|
||||
Ptr\<\> implementation), or just very inconvenient (saturate\_cast\<\>()) the current implementation
|
||||
introduces small template classes, methods, and functions. Anywhere else in the current OpenCV
|
||||
version the use of templates is limited.
|
||||
|
||||
Consequently, there is a limited fixed set of primitive data types the library can operate on. That
|
||||
is, array elements should have one of the following types:
|
||||
|
||||
- 8-bit unsigned integer (uchar)
|
||||
- 8-bit signed integer (schar)
|
||||
- 16-bit unsigned integer (ushort)
|
||||
- 16-bit signed integer (short)
|
||||
- 32-bit signed integer (int)
|
||||
- 32-bit floating-point number (float)
|
||||
- 64-bit floating-point number (double)
|
||||
- a tuple of several elements where all elements have the same type (one of the above). An array
|
||||
whose elements are such tuples, are called multi-channel arrays, as opposite to the
|
||||
single-channel arrays, whose elements are scalar values. The maximum possible number of
|
||||
channels is defined by the CV\_CN\_MAX constant, which is currently set to 512.
|
||||
|
||||
For these basic types, the following enumeration is applied:
|
||||
@code
|
||||
enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 };
|
||||
@endcode
|
||||
Multi-channel (n-channel) types can be specified using the following options:
|
||||
|
||||
- CV_8UC1 ... CV_64FC4 constants (for a number of channels from 1 to 4)
|
||||
- CV_8UC(n) ... CV_64FC(n) or CV_MAKETYPE(CV_8U, n) ... CV_MAKETYPE(CV_64F, n) macros when
|
||||
the number of channels is more than 4 or unknown at the compilation time.
|
||||
|
||||
@note `CV_32FC1 == CV_32F, CV_32FC2 == CV_32FC(2) == CV_MAKETYPE(CV_32F, 2)`, and
|
||||
`CV_MAKETYPE(depth, n) == ((x&7)<<3) + (n-1)``. This means that the constant type is formed from the
|
||||
depth, taking the lowest 3 bits, and the number of channels minus 1, taking the next
|
||||
`log2(CV_CN_MAX)`` bits.
|
||||
|
||||
Examples:
|
||||
@code
|
||||
Mat mtx(3, 3, CV_32F); // make a 3x3 floating-point matrix
|
||||
Mat cmtx(10, 1, CV_64FC2); // make a 10x1 2-channel floating-point
|
||||
// matrix (10-element complex vector)
|
||||
Mat img(Size(1920, 1080), CV_8UC3); // make a 3-channel (color) image
|
||||
// of 1920 columns and 1080 rows.
|
||||
Mat grayscale(image.size(), CV_MAKETYPE(image.depth(), 1)); // make a 1-channel image of
|
||||
// the same size and same
|
||||
// channel type as img
|
||||
@endcode
|
||||
Arrays with more complex elements cannot be constructed or processed using OpenCV. Furthermore, each
|
||||
function or method can handle only a subset of all possible array types. Usually, the more complex
|
||||
the algorithm is, the smaller the supported subset of formats is. See below typical examples of such
|
||||
limitations:
|
||||
|
||||
- The face detection algorithm only works with 8-bit grayscale or color images.
|
||||
- Linear algebra functions and most of the machine learning algorithms work with floating-point
|
||||
arrays only.
|
||||
- Basic functions, such as cv::add, support all types.
|
||||
- Color space conversion functions support 8-bit unsigned, 16-bit unsigned, and 32-bit
|
||||
floating-point types.
|
||||
|
||||
The subset of supported types for each function has been defined from practical needs and could be
|
||||
extended in future based on user requests.
|
||||
|
||||
### InputArray and OutputArray
|
||||
|
||||
Many OpenCV functions process dense 2-dimensional or multi-dimensional numerical arrays. Usually,
|
||||
such functions take cppMat as parameters, but in some cases it's more convenient to use
|
||||
std::vector\<\> (for a point set, for example) or Matx\<\> (for 3x3 homography matrix and such). To
|
||||
avoid many duplicates in the API, special "proxy" classes have been introduced. The base "proxy"
|
||||
class is InputArray. It is used for passing read-only arrays on a function input. The derived from
|
||||
InputArray class OutputArray is used to specify an output array for a function. Normally, you should
|
||||
not care of those intermediate types (and you should not declare variables of those types
|
||||
explicitly) - it will all just work automatically. You can assume that instead of
|
||||
InputArray/OutputArray you can always use Mat, std::vector\<\>, Matx\<\>, Vec\<\> or Scalar. When a
|
||||
function has an optional input or output array, and you do not have or do not want one, pass
|
||||
cv::noArray().
|
||||
|
||||
### Error Handling
|
||||
|
||||
OpenCV uses exceptions to signal critical errors. When the input data has a correct format and
|
||||
belongs to the specified value range, but the algorithm cannot succeed for some reason (for example,
|
||||
the optimization algorithm did not converge), it returns a special error code (typically, just a
|
||||
boolean variable).
|
||||
|
||||
The exceptions can be instances of the cv::Exception class or its derivatives. In its turn,
|
||||
cv::Exception is a derivative of std::exception. So it can be gracefully handled in the code using
|
||||
other standard C++ library components.
|
||||
|
||||
The exception is typically thrown either using the CV\_Error(errcode, description) macro, or its
|
||||
printf-like CV\_Error\_(errcode, printf-spec, (printf-args)) variant, or using the
|
||||
CV\_Assert(condition) macro that checks the condition and throws an exception when it is not
|
||||
satisfied. For performance-critical code, there is CV\_DbgAssert(condition) that is only retained in
|
||||
the Debug configuration. Due to the automatic memory management, all the intermediate buffers are
|
||||
automatically deallocated in case of a sudden error. You only need to add a try statement to catch
|
||||
exceptions, if needed: :
|
||||
@code
|
||||
try
|
||||
{
|
||||
... // call OpenCV
|
||||
}
|
||||
catch( cv::Exception& e )
|
||||
{
|
||||
const char* err_msg = e.what();
|
||||
std::cout << "exception caught: " << err_msg << std::endl;
|
||||
}
|
||||
@endcode
|
||||
|
||||
### Multi-threading and Re-enterability
|
||||
|
||||
The current OpenCV implementation is fully re-enterable. That is, the same function, the same
|
||||
*constant* method of a class instance, or the same *non-constant* method of different class
|
||||
instances can be called from different threads. Also, the same cv::Mat can be used in different
|
||||
threads because the reference-counting operations use the architecture-specific atomic instructions.
|
File diff suppressed because it is too large
Load Diff
@ -48,10 +48,15 @@
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
/*! @file */
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @addtogroup core
|
||||
//! @{
|
||||
|
||||
/** @brief Affine transform
|
||||
@todo document
|
||||
*/
|
||||
template<typename T>
|
||||
class Affine3
|
||||
{
|
||||
@ -63,30 +68,31 @@ namespace cv
|
||||
|
||||
Affine3();
|
||||
|
||||
//Augmented affine matrix
|
||||
//! Augmented affine matrix
|
||||
Affine3(const Mat4& affine);
|
||||
|
||||
//Rotation matrix
|
||||
//! Rotation matrix
|
||||
Affine3(const Mat3& R, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//Rodrigues vector
|
||||
//! Rodrigues vector
|
||||
Affine3(const Vec3& rvec, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix
|
||||
//! Combines all contructors above. Supports 4x4, 4x3, 3x3, 1x3, 3x1 sizes of data matrix
|
||||
explicit Affine3(const Mat& data, const Vec3& t = Vec3::all(0));
|
||||
|
||||
//From 16th element array
|
||||
//! From 16th element array
|
||||
explicit Affine3(const float_type* vals);
|
||||
|
||||
//! Create identity transform
|
||||
static Affine3 Identity();
|
||||
|
||||
//Rotation matrix
|
||||
//! Rotation matrix
|
||||
void rotation(const Mat3& R);
|
||||
|
||||
//Rodrigues vector
|
||||
//! Rodrigues vector
|
||||
void rotation(const Vec3& rvec);
|
||||
|
||||
//Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
//! Combines rotation methods above. Suports 3x3, 1x3, 3x1 sizes of data matrix;
|
||||
void rotation(const Mat& data);
|
||||
|
||||
void linear(const Mat3& L);
|
||||
@ -96,21 +102,21 @@ namespace cv
|
||||
Mat3 linear() const;
|
||||
Vec3 translation() const;
|
||||
|
||||
//Rodrigues vector
|
||||
//! Rodrigues vector
|
||||
Vec3 rvec() const;
|
||||
|
||||
Affine3 inv(int method = cv::DECOMP_SVD) const;
|
||||
|
||||
// a.rotate(R) is equivalent to Affine(R, 0) * a;
|
||||
//! a.rotate(R) is equivalent to Affine(R, 0) * a;
|
||||
Affine3 rotate(const Mat3& R) const;
|
||||
|
||||
// a.rotate(R) is equivalent to Affine(rvec, 0) * a;
|
||||
//! a.rotate(R) is equivalent to Affine(rvec, 0) * a;
|
||||
Affine3 rotate(const Vec3& rvec) const;
|
||||
|
||||
// a.translate(t) is equivalent to Affine(E, t) * a;
|
||||
//! a.translate(t) is equivalent to Affine(E, t) * a;
|
||||
Affine3 translate(const Vec3& t) const;
|
||||
|
||||
// a.concatenate(affine) is equivalent to affine * a;
|
||||
//! a.concatenate(affine) is equivalent to affine * a;
|
||||
Affine3 concatenate(const Affine3& affine) const;
|
||||
|
||||
template <typename Y> operator Affine3<Y>() const;
|
||||
@ -155,11 +161,15 @@ namespace cv
|
||||
|
||||
typedef Vec<channel_type, channels> vec_type;
|
||||
};
|
||||
|
||||
//! @} core
|
||||
|
||||
}
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Implementaiton
|
||||
// Implementaiton
|
||||
|
||||
template<typename T> inline
|
||||
cv::Affine3<T>::Affine3()
|
||||
@ -431,7 +441,6 @@ cv::Affine3<Y> cv::Affine3<T>::cast() const
|
||||
return Affine3<Y>(matrix);
|
||||
}
|
||||
|
||||
/** @cond IGNORED */
|
||||
template<typename T> inline
|
||||
cv::Affine3<T> cv::operator*(const cv::Affine3<T>& affine1, const cv::Affine3<T>& affine2)
|
||||
{
|
||||
@ -449,7 +458,6 @@ V cv::operator*(const cv::Affine3<T>& affine, const V& v)
|
||||
r.z = m.val[8] * v.x + m.val[9] * v.y + m.val[10] * v.z + m.val[11];
|
||||
return r;
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
static inline
|
||||
cv::Vec3f cv::operator*(const cv::Affine3f& affine, const cv::Vec3f& v)
|
||||
@ -507,6 +515,7 @@ cv::Affine3<T>::operator Eigen::Transform<T, 3, Eigen::Affine>() const
|
||||
|
||||
#endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
@ -56,56 +56,59 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
// error codes
|
||||
//! @addtogroup core_utils
|
||||
//! @{
|
||||
|
||||
namespace Error {
|
||||
enum {
|
||||
StsOk= 0, /* everithing is ok */
|
||||
StsBackTrace= -1, /* pseudo error for back trace */
|
||||
StsError= -2, /* unknown /unspecified error */
|
||||
StsInternal= -3, /* internal error (bad state) */
|
||||
StsNoMem= -4, /* insufficient memory */
|
||||
StsBadArg= -5, /* function arg/param is bad */
|
||||
StsBadFunc= -6, /* unsupported function */
|
||||
StsNoConv= -7, /* iter. didn't converge */
|
||||
StsAutoTrace= -8, /* tracing */
|
||||
HeaderIsNull= -9, /* image header is NULL */
|
||||
BadImageSize= -10, /* image size is invalid */
|
||||
BadOffset= -11, /* offset is invalid */
|
||||
BadDataPtr= -12, /**/
|
||||
BadStep= -13, /**/
|
||||
BadModelOrChSeq= -14, /**/
|
||||
BadNumChannels= -15, /**/
|
||||
BadNumChannel1U= -16, /**/
|
||||
BadDepth= -17, /**/
|
||||
BadAlphaChannel= -18, /**/
|
||||
BadOrder= -19, /**/
|
||||
BadOrigin= -20, /**/
|
||||
BadAlign= -21, /**/
|
||||
BadCallBack= -22, /**/
|
||||
BadTileSize= -23, /**/
|
||||
BadCOI= -24, /**/
|
||||
BadROISize= -25, /**/
|
||||
MaskIsTiled= -26, /**/
|
||||
StsNullPtr= -27, /* null pointer */
|
||||
StsVecLengthErr= -28, /* incorrect vector length */
|
||||
StsFilterStructContentErr= -29, /* incorr. filter structure content */
|
||||
StsKernelStructContentErr= -30, /* incorr. transform kernel content */
|
||||
StsFilterOffsetErr= -31, /* incorrect filter ofset value */
|
||||
StsBadSize= -201, /* the input/output structure size is incorrect */
|
||||
StsDivByZero= -202, /* division by zero */
|
||||
StsInplaceNotSupported= -203, /* in-place operation is not supported */
|
||||
StsObjectNotFound= -204, /* request can't be completed */
|
||||
StsUnmatchedFormats= -205, /* formats of input/output arrays differ */
|
||||
StsBadFlag= -206, /* flag is wrong or not supported */
|
||||
StsBadPoint= -207, /* bad CvPoint */
|
||||
StsBadMask= -208, /* bad format of mask (neither 8uC1 nor 8sC1)*/
|
||||
StsUnmatchedSizes= -209, /* sizes of input/output structures do not match */
|
||||
StsUnsupportedFormat= -210, /* the data format/type is not supported by the function*/
|
||||
StsOutOfRange= -211, /* some of parameters are out of range */
|
||||
StsParseError= -212, /* invalid syntax/structure of the parsed file */
|
||||
StsNotImplemented= -213, /* the requested function/feature is not implemented */
|
||||
StsBadMemBlock= -214, /* an allocated block has been corrupted */
|
||||
StsAssert= -215, /* assertion failed */
|
||||
//! error codes
|
||||
enum Code {
|
||||
StsOk= 0, //!< everithing is ok
|
||||
StsBackTrace= -1, //!< pseudo error for back trace
|
||||
StsError= -2, //!< unknown /unspecified error
|
||||
StsInternal= -3, //!< internal error (bad state)
|
||||
StsNoMem= -4, //!< insufficient memory
|
||||
StsBadArg= -5, //!< function arg/param is bad
|
||||
StsBadFunc= -6, //!< unsupported function
|
||||
StsNoConv= -7, //!< iter. didn't converge
|
||||
StsAutoTrace= -8, //!< tracing
|
||||
HeaderIsNull= -9, //!< image header is NULL
|
||||
BadImageSize= -10, //!< image size is invalid
|
||||
BadOffset= -11, //!< offset is invalid
|
||||
BadDataPtr= -12, //!<
|
||||
BadStep= -13, //!<
|
||||
BadModelOrChSeq= -14, //!<
|
||||
BadNumChannels= -15, //!<
|
||||
BadNumChannel1U= -16, //!<
|
||||
BadDepth= -17, //!<
|
||||
BadAlphaChannel= -18, //!<
|
||||
BadOrder= -19, //!<
|
||||
BadOrigin= -20, //!<
|
||||
BadAlign= -21, //!<
|
||||
BadCallBack= -22, //!<
|
||||
BadTileSize= -23, //!<
|
||||
BadCOI= -24, //!<
|
||||
BadROISize= -25, //!<
|
||||
MaskIsTiled= -26, //!<
|
||||
StsNullPtr= -27, //!< null pointer
|
||||
StsVecLengthErr= -28, //!< incorrect vector length
|
||||
StsFilterStructContentErr= -29, //!< incorr. filter structure content
|
||||
StsKernelStructContentErr= -30, //!< incorr. transform kernel content
|
||||
StsFilterOffsetErr= -31, //!< incorrect filter ofset value
|
||||
StsBadSize= -201, //!< the input/output structure size is incorrect
|
||||
StsDivByZero= -202, //!< division by zero
|
||||
StsInplaceNotSupported= -203, //!< in-place operation is not supported
|
||||
StsObjectNotFound= -204, //!< request can't be completed
|
||||
StsUnmatchedFormats= -205, //!< formats of input/output arrays differ
|
||||
StsBadFlag= -206, //!< flag is wrong or not supported
|
||||
StsBadPoint= -207, //!< bad CvPoint
|
||||
StsBadMask= -208, //!< bad format of mask (neither 8uC1 nor 8sC1)
|
||||
StsUnmatchedSizes= -209, //!< sizes of input/output structures do not match
|
||||
StsUnsupportedFormat= -210, //!< the data format/type is not supported by the function
|
||||
StsOutOfRange= -211, //!< some of parameters are out of range
|
||||
StsParseError= -212, //!< invalid syntax/structure of the parsed file
|
||||
StsNotImplemented= -213, //!< the requested function/feature is not implemented
|
||||
StsBadMemBlock= -214, //!< an allocated block has been corrupted
|
||||
StsAssert= -215, //!< assertion failed
|
||||
GpuNotSupported= -216,
|
||||
GpuApiCallError= -217,
|
||||
OpenGlNotSupported= -218,
|
||||
@ -117,68 +120,135 @@ enum {
|
||||
};
|
||||
} //Error
|
||||
|
||||
// matrix decomposition types
|
||||
enum { DECOMP_LU = 0,
|
||||
DECOMP_SVD = 1,
|
||||
DECOMP_EIG = 2,
|
||||
DECOMP_CHOLESKY = 3,
|
||||
DECOMP_QR = 4,
|
||||
DECOMP_NORMAL = 16
|
||||
};
|
||||
//! @} core_utils
|
||||
|
||||
// norm types
|
||||
enum { NORM_INF = 1,
|
||||
NORM_L1 = 2,
|
||||
NORM_L2 = 4,
|
||||
NORM_L2SQR = 5,
|
||||
NORM_HAMMING = 6,
|
||||
NORM_HAMMING2 = 7,
|
||||
NORM_TYPE_MASK = 7,
|
||||
NORM_RELATIVE = 8,
|
||||
NORM_MINMAX = 32
|
||||
};
|
||||
//! @addtogroup core_array
|
||||
//! @{
|
||||
|
||||
// comparison types
|
||||
enum { CMP_EQ = 0,
|
||||
CMP_GT = 1,
|
||||
CMP_GE = 2,
|
||||
CMP_LT = 3,
|
||||
CMP_LE = 4,
|
||||
CMP_NE = 5
|
||||
};
|
||||
//! matrix decomposition types
|
||||
enum DecompTypes {
|
||||
/** Gaussian elimination with the optimal pivot element chosen. */
|
||||
DECOMP_LU = 0,
|
||||
/** singular value decomposition (SVD) method; the system can be over-defined and/or the matrix
|
||||
src1 can be singular */
|
||||
DECOMP_SVD = 1,
|
||||
/** eigenvalue decomposition; the matrix src1 must be symmetrical */
|
||||
DECOMP_EIG = 2,
|
||||
/** Cholesky \f$LL^T\f$ factorization; the matrix src1 must be symmetrical and positively
|
||||
defined */
|
||||
DECOMP_CHOLESKY = 3,
|
||||
/** QR factorization; the system can be over-defined and/or the matrix src1 can be singular */
|
||||
DECOMP_QR = 4,
|
||||
/** while all the previous flags are mutually exclusive, this flag can be used together with
|
||||
any of the previous; it means that the normal equations
|
||||
\f$\texttt{src1}^T\cdot\texttt{src1}\cdot\texttt{dst}=\texttt{src1}^T\texttt{src2}\f$ are
|
||||
solved instead of the original system
|
||||
\f$\texttt{src1}\cdot\texttt{dst}=\texttt{src2}\f$ */
|
||||
DECOMP_NORMAL = 16
|
||||
};
|
||||
|
||||
enum { GEMM_1_T = 1,
|
||||
GEMM_2_T = 2,
|
||||
GEMM_3_T = 4
|
||||
};
|
||||
/** norm types
|
||||
- For one array:
|
||||
\f[norm = \forkthree{\|\texttt{src1}\|_{L_{\infty}} = \max _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM\_INF}\) }
|
||||
{ \| \texttt{src1} \| _{L_1} = \sum _I | \texttt{src1} (I)|}{if \(\texttt{normType} = \texttt{NORM\_L1}\) }
|
||||
{ \| \texttt{src1} \| _{L_2} = \sqrt{\sum_I \texttt{src1}(I)^2} }{if \(\texttt{normType} = \texttt{NORM\_L2}\) }\f]
|
||||
|
||||
enum { DFT_INVERSE = 1,
|
||||
DFT_SCALE = 2,
|
||||
DFT_ROWS = 4,
|
||||
DFT_COMPLEX_OUTPUT = 16,
|
||||
DFT_REAL_OUTPUT = 32,
|
||||
DCT_INVERSE = DFT_INVERSE,
|
||||
DCT_ROWS = DFT_ROWS
|
||||
};
|
||||
- Absolute norm for two arrays
|
||||
\f[norm = \forkthree{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} = \max _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM\_INF}\) }
|
||||
{ \| \texttt{src1} - \texttt{src2} \| _{L_1} = \sum _I | \texttt{src1} (I) - \texttt{src2} (I)|}{if \(\texttt{normType} = \texttt{NORM\_L1}\) }
|
||||
{ \| \texttt{src1} - \texttt{src2} \| _{L_2} = \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if \(\texttt{normType} = \texttt{NORM\_L2}\) }\f]
|
||||
|
||||
//! Various border types, image boundaries are denoted with '|'
|
||||
enum {
|
||||
BORDER_CONSTANT = 0, // iiiiii|abcdefgh|iiiiiii with some specified 'i'
|
||||
BORDER_REPLICATE = 1, // aaaaaa|abcdefgh|hhhhhhh
|
||||
BORDER_REFLECT = 2, // fedcba|abcdefgh|hgfedcb
|
||||
BORDER_WRAP = 3, // cdefgh|abcdefgh|abcdefg
|
||||
BORDER_REFLECT_101 = 4, // gfedcb|abcdefgh|gfedcba
|
||||
BORDER_TRANSPARENT = 5, // uvwxyz|absdefgh|ijklmno
|
||||
- Relative norm for two arrays
|
||||
\f[norm = \forkthree{\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} }{\|\texttt{src2}\|_{L_{\infty}} }}{if \(\texttt{normType} = \texttt{NORM\_RELATIVE\_INF}\) }
|
||||
{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if \(\texttt{normType} = \texttt{NORM\_RELATIVE\_L1}\) }
|
||||
{ \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if \(\texttt{normType} = \texttt{NORM\_RELATIVE\_L2}\) }\f]
|
||||
*/
|
||||
enum NormTypes { NORM_INF = 1,
|
||||
NORM_L1 = 2,
|
||||
NORM_L2 = 4,
|
||||
NORM_L2SQR = 5,
|
||||
NORM_HAMMING = 6,
|
||||
NORM_HAMMING2 = 7,
|
||||
NORM_TYPE_MASK = 7,
|
||||
NORM_RELATIVE = 8, //!< flag
|
||||
NORM_MINMAX = 32 //!< flag
|
||||
};
|
||||
|
||||
BORDER_REFLECT101 = BORDER_REFLECT_101,
|
||||
BORDER_DEFAULT = BORDER_REFLECT_101,
|
||||
BORDER_ISOLATED = 16 // do not look outside of ROI
|
||||
};
|
||||
//! comparison types
|
||||
enum CmpTypes { CMP_EQ = 0, //!< src1 is equal to src2.
|
||||
CMP_GT = 1, //!< src1 is greater than src2.
|
||||
CMP_GE = 2, //!< src1 is greater than or equal to src2.
|
||||
CMP_LT = 3, //!< src1 is less than src2.
|
||||
CMP_LE = 4, //!< src1 is less than or equal to src2.
|
||||
CMP_NE = 5 //!< src1 is unequal to src2.
|
||||
};
|
||||
|
||||
//! generalized matrix multiplication flags
|
||||
enum GemmFlags { GEMM_1_T = 1, //!< transposes src1
|
||||
GEMM_2_T = 2, //!< transposes src2
|
||||
GEMM_3_T = 4 //!< transposes src3
|
||||
};
|
||||
|
||||
enum DftFlags {
|
||||
/** performs an inverse 1D or 2D transform instead of the default forward
|
||||
transform. */
|
||||
DFT_INVERSE = 1,
|
||||
/** scales the result: divide it by the number of array elements. Normally, it is
|
||||
combined with DFT_INVERSE. */
|
||||
DFT_SCALE = 2,
|
||||
/** performs a forward or inverse transform of every individual row of the input
|
||||
matrix; this flag enables you to transform multiple vectors simultaneously and can be used to
|
||||
decrease the overhead (which is sometimes several times larger than the processing itself) to
|
||||
perform 3D and higher-dimensional transformations and so forth.*/
|
||||
DFT_ROWS = 4,
|
||||
/** performs a forward transformation of 1D or 2D real array; the result,
|
||||
though being a complex array, has complex-conjugate symmetry (*CCS*, see the function
|
||||
description below for details), and such an array can be packed into a real array of the same
|
||||
size as input, which is the fastest option and which is what the function does by default;
|
||||
however, you may wish to get a full complex array (for simpler spectrum analysis, and so on) -
|
||||
pass the flag to enable the function to produce a full-size complex output array. */
|
||||
DFT_COMPLEX_OUTPUT = 16,
|
||||
/** performs an inverse transformation of a 1D or 2D complex array; the
|
||||
result is normally a complex array of the same size, however, if the input array has
|
||||
conjugate-complex symmetry (for example, it is a result of forward transformation with
|
||||
DFT_COMPLEX_OUTPUT flag), the output is a real array; while the function itself does not
|
||||
check whether the input is symmetrical or not, you can pass the flag and then the function
|
||||
will assume the symmetry and produce the real output array (note that when the input is packed
|
||||
into a real array and inverse transformation is executed, the function treats the input as a
|
||||
packed complex-conjugate symmetrical array, and the output will also be a real array). */
|
||||
DFT_REAL_OUTPUT = 32,
|
||||
/** performs an inverse 1D or 2D transform instead of the default forward transform. */
|
||||
DCT_INVERSE = DFT_INVERSE,
|
||||
/** performs a forward or inverse transform of every individual row of the input
|
||||
matrix. This flag enables you to transform multiple vectors simultaneously and can be used to
|
||||
decrease the overhead (which is sometimes several times larger than the processing itself) to
|
||||
perform 3D and higher-dimensional transforms and so forth.*/
|
||||
DCT_ROWS = DFT_ROWS
|
||||
};
|
||||
|
||||
//! Various border types, image boundaries are denoted with `|`
|
||||
//! @see borderInterpolate, copyMakeBorder
|
||||
enum BorderTypes {
|
||||
BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
|
||||
BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
|
||||
BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
|
||||
BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
|
||||
BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
|
||||
BORDER_TRANSPARENT = 5, //!< `uvwxyz|absdefgh|ijklmno`
|
||||
|
||||
BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
|
||||
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
|
||||
BORDER_ISOLATED = 16 //!< do not look outside of ROI
|
||||
};
|
||||
|
||||
//! @} core_array
|
||||
|
||||
//! @addtogroup core_utils
|
||||
//! @{
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
//////////////// static assert /////////////////
|
||||
|
||||
#define CVAUX_CONCAT_EXP(a, b) a##b
|
||||
#define CVAUX_CONCAT(a, b) CVAUX_CONCAT_EXP(a,b)
|
||||
|
||||
@ -210,8 +280,7 @@ enum {
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//! Suppress warning "-Wdeprecated-declarations" / C4996
|
||||
|
||||
// Suppress warning "-Wdeprecated-declarations" / C4996
|
||||
#if defined(_MSC_VER)
|
||||
#define CV_DO_PRAGMA(x) __pragma(x)
|
||||
#elif defined(__GNUC__)
|
||||
@ -225,7 +294,7 @@ enum {
|
||||
CV_DO_PRAGMA(warning(push)) \
|
||||
CV_DO_PRAGMA(warning(disable: 4996))
|
||||
#define CV_SUPPRESS_DEPRECATED_END CV_DO_PRAGMA(warning(pop))
|
||||
#elif defined __GNUC__
|
||||
#elif defined (__clang__) || ((__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))
|
||||
#define CV_SUPPRESS_DEPRECATED_START \
|
||||
CV_DO_PRAGMA(GCC diagnostic push) \
|
||||
CV_DO_PRAGMA(GCC diagnostic ignored "-Wdeprecated-declarations")
|
||||
@ -234,16 +303,19 @@ enum {
|
||||
#define CV_SUPPRESS_DEPRECATED_START
|
||||
#define CV_SUPPRESS_DEPRECATED_END
|
||||
#endif
|
||||
//! @endcond
|
||||
|
||||
/*! @brief Signals an error and raises the exception.
|
||||
By default the function prints information about the error to stderr,
|
||||
then it either stops if setBreakOnError() had been called before or raises the exception.
|
||||
It is possible to alternate error processing by using redirectError().
|
||||
@param _code - error code @see CVStatus
|
||||
@param _err - error description
|
||||
@param _func - function name. Available only when the compiler supports getting it
|
||||
@param _file - source file name where the error has occured
|
||||
@param _line - line number in the source file where the error has occured
|
||||
|
||||
By default the function prints information about the error to stderr,
|
||||
then it either stops if setBreakOnError() had been called before or raises the exception.
|
||||
It is possible to alternate error processing by using redirectError().
|
||||
@param _code - error code (Error::Code)
|
||||
@param _err - error description
|
||||
@param _func - function name. Available only when the compiler supports getting it
|
||||
@param _file - source file name where the error has occured
|
||||
@param _line - line number in the source file where the error has occured
|
||||
@see CV_Error, CV_Error_, CV_ErrorNoReturn, CV_ErrorNoReturn_, CV_Assert, CV_DbgAssert
|
||||
*/
|
||||
CV_EXPORTS void error(int _code, const String& _err, const char* _func, const char* _file, int _line);
|
||||
|
||||
@ -253,6 +325,8 @@ CV_EXPORTS void error(int _code, const String& _err, const char* _func, const ch
|
||||
# pragma GCC diagnostic ignored "-Winvalid-noreturn"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/** same as cv::error, but does not return */
|
||||
CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const char* _func, const char* _file, int _line)
|
||||
{
|
||||
error(_code, _err, _func, _file, _line);
|
||||
@ -270,7 +344,6 @@ CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const ch
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined __GNUC__
|
||||
#define CV_Func __func__
|
||||
#elif defined _MSC_VER
|
||||
@ -279,13 +352,47 @@ CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const ch
|
||||
#define CV_Func ""
|
||||
#endif
|
||||
|
||||
/** @brief Call the error handler.
|
||||
|
||||
Currently, the error handler prints the error code and the error message to the standard
|
||||
error stream `stderr`. In the Debug configuration, it then provokes memory access violation, so that
|
||||
the execution stack and all the parameters can be analyzed by the debugger. In the Release
|
||||
configuration, the exception is thrown.
|
||||
|
||||
@param code one of Error::Code
|
||||
@param msg error message
|
||||
*/
|
||||
#define CV_Error( code, msg ) cv::error( code, msg, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
/** @brief Call the error handler.
|
||||
|
||||
This macro can be used to construct an error message on-fly to include some dynamic information,
|
||||
for example:
|
||||
@code
|
||||
// note the extra parentheses around the formatted text message
|
||||
CV_Error_( CV_StsOutOfRange,
|
||||
("the value at (%d, %d)=%g is out of range", badPt.x, badPt.y, badValue));
|
||||
@endcode
|
||||
@param code one of Error::Code
|
||||
@param args printf-like formatted error message in parentheses
|
||||
*/
|
||||
#define CV_Error_( code, args ) cv::error( code, cv::format args, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
/** @brief Checks a condition at runtime and throws exception if it fails
|
||||
|
||||
The macros CV_Assert (and CV_DbgAssert(expr)) evaluate the specified expression. If it is 0, the macros
|
||||
raise an error (see cv::error). The macro CV_Assert checks the condition in both Debug and Release
|
||||
configurations while CV_DbgAssert is only retained in the Debug configuration.
|
||||
*/
|
||||
#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
/** same as CV_Error(code,msg), but does not return */
|
||||
#define CV_ErrorNoReturn( code, msg ) cv::errorNoReturn( code, msg, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
/** same as CV_Error_(code,args), but does not return */
|
||||
#define CV_ErrorNoReturn_( code, args ) cv::errorNoReturn( code, cv::format args, CV_Func, __FILE__, __LINE__ )
|
||||
|
||||
/** replaced with CV_Assert(expr) in Debug configuration */
|
||||
#ifdef _DEBUG
|
||||
# define CV_DbgAssert(expr) CV_Assert(expr)
|
||||
#else
|
||||
@ -293,18 +400,50 @@ CV_INLINE CV_NORETURN void errorNoReturn(int _code, const String& _err, const ch
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/////////////// saturate_cast (used in image & signal processing) ///////////////////
|
||||
|
||||
/**
|
||||
Template function for accurate conversion from one primitive type to another.
|
||||
|
||||
The functions saturate_cast resemble the standard C++ cast operations, such as static_cast\<T\>()
|
||||
and others. They perform an efficient and accurate conversion from one primitive type to another
|
||||
(see the introduction chapter). saturate in the name means that when the input value v is out of the
|
||||
range of the target type, the result is not formed just by taking low bits of the input, but instead
|
||||
the value is clipped. For example:
|
||||
@code
|
||||
uchar a = saturate_cast<uchar>(-100); // a = 0 (UCHAR_MIN)
|
||||
short b = saturate_cast<short>(33333.33333); // b = 32767 (SHRT_MAX)
|
||||
@endcode
|
||||
Such clipping is done when the target type is unsigned char , signed char , unsigned short or
|
||||
signed short . For 32-bit integers, no clipping is done.
|
||||
|
||||
When the parameter is a floating-point value and the target type is an integer (8-, 16- or 32-bit),
|
||||
the floating-point value is first rounded to the nearest integer and then clipped if needed (when
|
||||
the target type is 8- or 16-bit).
|
||||
|
||||
This operation is used in the simplest or most complex image processing functions in OpenCV.
|
||||
|
||||
@param v Function parameter.
|
||||
@sa add, subtract, multiply, divide, Mat::convertTo
|
||||
*/
|
||||
template<typename _Tp> static inline _Tp saturate_cast(uchar v) { return _Tp(v); }
|
||||
/** @overload */
|
||||
template<typename _Tp> static inline _Tp saturate_cast(schar v) { return _Tp(v); }
|
||||
/** @overload */
|
||||
template<typename _Tp> static inline _Tp saturate_cast(ushort v) { return _Tp(v); }
|
||||
/** @overload */
|
||||
template<typename _Tp> static inline _Tp saturate_cast(short v) { return _Tp(v); }
|
||||
/** @overload */
|
||||
template<typename _Tp> static inline _Tp saturate_cast(unsigned v) { return _Tp(v); }
|
||||
/** @overload */
|
||||
template<typename _Tp> static inline _Tp saturate_cast(int v) { return _Tp(v); }
|
||||
/** @overload */
|
||||
template<typename _Tp> static inline _Tp saturate_cast(float v) { return _Tp(v); }
|
||||
/** @overload */
|
||||
template<typename _Tp> static inline _Tp saturate_cast(double v) { return _Tp(v); }
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
template<> inline uchar saturate_cast<uchar>(schar v) { return (uchar)std::max((int)v, 0); }
|
||||
template<> inline uchar saturate_cast<uchar>(ushort v) { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); }
|
||||
template<> inline uchar saturate_cast<uchar>(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
|
||||
@ -341,7 +480,7 @@ template<> inline int saturate_cast<int>(double v) { return cvRound(v)
|
||||
template<> inline unsigned saturate_cast<unsigned>(float v) { return cvRound(v); }
|
||||
template<> inline unsigned saturate_cast<unsigned>(double v) { return cvRound(v); }
|
||||
|
||||
|
||||
//! @endcond
|
||||
|
||||
//////////////////////////////// low-level functions ////////////////////////////////
|
||||
|
||||
@ -358,18 +497,31 @@ CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n);
|
||||
|
||||
CV_EXPORTS void exp(const float* src, float* dst, int n);
|
||||
CV_EXPORTS void log(const float* src, float* dst, int n);
|
||||
|
||||
CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees);
|
||||
CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n);
|
||||
|
||||
//! computes cube root of the argument
|
||||
/** @brief Computes the cube root of an argument.
|
||||
|
||||
The function cubeRoot computes \f$\sqrt[3]{\texttt{val}}\f$. Negative arguments are handled correctly.
|
||||
NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for
|
||||
single-precision data.
|
||||
@param val A function argument.
|
||||
*/
|
||||
CV_EXPORTS_W float cubeRoot(float val);
|
||||
//! computes the angle in degrees (0..360) of the vector (x,y)
|
||||
|
||||
/** @brief Calculates the angle of a 2D vector in degrees.
|
||||
|
||||
The function fastAtan2 calculates the full-range angle of an input 2D vector. The angle is measured
|
||||
in degrees and varies from 0 to 360 degrees. The accuracy is about 0.3 degrees.
|
||||
@param x x-coordinate of the vector.
|
||||
@param y y-coordinate of the vector.
|
||||
*/
|
||||
CV_EXPORTS_W float fastAtan2(float y, float x);
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////// inline norms ////////////////////////////////////
|
||||
|
||||
|
||||
template<typename _Tp, typename _AccTp> static inline
|
||||
_AccTp normL2Sqr(const _Tp* a, int n)
|
||||
{
|
||||
@ -503,9 +655,10 @@ _AccTp normInf(const _Tp* a, const _Tp* b, int n)
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////// forward declarations for important OpenCV types //////////////////
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
template<typename _Tp, int cn> class Vec;
|
||||
template<typename _Tp, int m, int n> class Matx;
|
||||
|
||||
@ -573,6 +726,13 @@ CV_EXPORTS void setUseIPP(bool flag);
|
||||
|
||||
} // ipp
|
||||
|
||||
//! @endcond
|
||||
|
||||
//! @} core_utils
|
||||
|
||||
//! @addtogroup core_utils_neon
|
||||
//! @{
|
||||
|
||||
#if CV_NEON
|
||||
|
||||
inline int32x2_t cv_vrnd_s32_f32(float32x2_t v)
|
||||
@ -605,8 +765,52 @@ inline uint32x4_t cv_vrndq_u32_f32(float32x4_t v)
|
||||
return vcvtq_u32_f32(vaddq_f32(v, v_05));
|
||||
}
|
||||
|
||||
inline float32x4_t cv_vrecpq_f32(float32x4_t val)
|
||||
{
|
||||
float32x4_t reciprocal = vrecpeq_f32(val);
|
||||
reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal);
|
||||
reciprocal = vmulq_f32(vrecpsq_f32(val, reciprocal), reciprocal);
|
||||
return reciprocal;
|
||||
}
|
||||
|
||||
inline float32x2_t cv_vrecp_f32(float32x2_t val)
|
||||
{
|
||||
float32x2_t reciprocal = vrecpe_f32(val);
|
||||
reciprocal = vmul_f32(vrecps_f32(val, reciprocal), reciprocal);
|
||||
reciprocal = vmul_f32(vrecps_f32(val, reciprocal), reciprocal);
|
||||
return reciprocal;
|
||||
}
|
||||
|
||||
inline float32x4_t cv_vrsqrtq_f32(float32x4_t val)
|
||||
{
|
||||
float32x4_t e = vrsqrteq_f32(val);
|
||||
e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), val), e);
|
||||
e = vmulq_f32(vrsqrtsq_f32(vmulq_f32(e, e), val), e);
|
||||
return e;
|
||||
}
|
||||
|
||||
inline float32x2_t cv_vrsqrt_f32(float32x2_t val)
|
||||
{
|
||||
float32x2_t e = vrsqrte_f32(val);
|
||||
e = vmul_f32(vrsqrts_f32(vmul_f32(e, e), val), e);
|
||||
e = vmul_f32(vrsqrts_f32(vmul_f32(e, e), val), e);
|
||||
return e;
|
||||
}
|
||||
|
||||
inline float32x4_t cv_vsqrtq_f32(float32x4_t val)
|
||||
{
|
||||
return cv_vrecpq_f32(cv_vrsqrtq_f32(val));
|
||||
}
|
||||
|
||||
inline float32x2_t cv_vsqrt_f32(float32x2_t val)
|
||||
{
|
||||
return cv_vrecp_f32(cv_vrsqrt_f32(val));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//! @} core_utils_neon
|
||||
|
||||
} // cv
|
||||
|
||||
#endif //__OPENCV_CORE_BASE_HPP__
|
||||
|
@ -10,6 +10,9 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @addtogroup core
|
||||
//! @{
|
||||
|
||||
class BufferPoolController
|
||||
{
|
||||
protected:
|
||||
@ -21,6 +24,8 @@ public:
|
||||
virtual void freeAllReservedBuffers() = 0;
|
||||
};
|
||||
|
||||
//! @}
|
||||
|
||||
}
|
||||
|
||||
#endif // __OPENCV_CORE_BUFFER_POOL_HPP__
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -51,13 +51,22 @@
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/cuda_types.hpp"
|
||||
|
||||
/**
|
||||
@defgroup cuda CUDA-accelerated Computer Vision
|
||||
@{
|
||||
@defgroup cuda_struct Data structures
|
||||
@}
|
||||
*/
|
||||
|
||||
namespace cv { namespace cuda {
|
||||
|
||||
//! @addtogroup cuda_struct
|
||||
//! @{
|
||||
|
||||
//////////////////////////////// GpuMat ///////////////////////////////
|
||||
|
||||
// Smart pointer for GPU memory with reference counting.
|
||||
// Its interface is mostly similar with cv::Mat.
|
||||
|
||||
//! Smart pointer for GPU memory with reference counting.
|
||||
//! Its interface is mostly similar with cv::Mat.
|
||||
class CV_EXPORTS GpuMat
|
||||
{
|
||||
public:
|
||||
@ -283,11 +292,10 @@ CV_EXPORTS void setBufferPoolConfig(int deviceId, size_t stackSize, int stackCou
|
||||
|
||||
//////////////////////////////// CudaMem ////////////////////////////////
|
||||
|
||||
// CudaMem is limited cv::Mat with page locked memory allocation.
|
||||
// Page locked memory is only needed for async and faster coping to GPU.
|
||||
// It is convertable to cv::Mat header without reference counting
|
||||
// so you can use it with other opencv functions.
|
||||
|
||||
//! CudaMem is limited cv::Mat with page locked memory allocation.
|
||||
//! Page locked memory is only needed for async and faster coping to GPU.
|
||||
//! It is convertable to cv::Mat header without reference counting
|
||||
//! so you can use it with other opencv functions.
|
||||
class CV_EXPORTS CudaMem
|
||||
{
|
||||
public:
|
||||
@ -363,10 +371,9 @@ CV_EXPORTS void unregisterPageLocked(Mat& m);
|
||||
|
||||
///////////////////////////////// Stream //////////////////////////////////
|
||||
|
||||
// Encapculates Cuda Stream. Provides interface for async coping.
|
||||
// Passed to each function that supports async kernel execution.
|
||||
// Reference counting is enabled.
|
||||
|
||||
//! Encapculates Cuda Stream. Provides interface for async coping.
|
||||
//! Passed to each function that supports async kernel execution.
|
||||
//! Reference counting is enabled.
|
||||
class CV_EXPORTS Stream
|
||||
{
|
||||
typedef void (Stream::*bool_type)() const;
|
||||
@ -563,10 +570,10 @@ public:
|
||||
|
||||
enum ComputeMode
|
||||
{
|
||||
ComputeModeDefault, /**< default compute mode (Multiple threads can use ::cudaSetDevice() with this device) */
|
||||
ComputeModeExclusive, /**< compute-exclusive-thread mode (Only one thread in one process will be able to use ::cudaSetDevice() with this device) */
|
||||
ComputeModeProhibited, /**< compute-prohibited mode (No threads can use ::cudaSetDevice() with this device) */
|
||||
ComputeModeExclusiveProcess /**< compute-exclusive-process mode (Many threads in one process will be able to use ::cudaSetDevice() with this device) */
|
||||
ComputeModeDefault, /**< default compute mode (Multiple threads can use cudaSetDevice with this device) */
|
||||
ComputeModeExclusive, /**< compute-exclusive-thread mode (Only one thread in one process will be able to use cudaSetDevice with this device) */
|
||||
ComputeModeProhibited, /**< compute-prohibited mode (No threads can use cudaSetDevice with this device) */
|
||||
ComputeModeExclusiveProcess /**< compute-exclusive-process mode (Many threads in one process will be able to use cudaSetDevice with this device) */
|
||||
};
|
||||
|
||||
//! compute mode
|
||||
@ -686,6 +693,8 @@ private:
|
||||
CV_EXPORTS void printCudaDeviceInfo(int device);
|
||||
CV_EXPORTS void printShortCudaDeviceInfo(int device);
|
||||
|
||||
//! @}
|
||||
|
||||
}} // namespace cv { namespace cuda {
|
||||
|
||||
|
||||
|
@ -46,6 +46,8 @@
|
||||
|
||||
#include "opencv2/core/cuda.hpp"
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { namespace cuda {
|
||||
|
||||
//////////////////////////////// GpuMat ///////////////////////////////
|
||||
@ -224,7 +226,6 @@ const _Tp* GpuMat::ptr(int y) const
|
||||
return (const _Tp*)ptr(y);
|
||||
}
|
||||
|
||||
/** @cond IGNORED */
|
||||
template <class T> inline
|
||||
GpuMat::operator PtrStepSz<T>() const
|
||||
{
|
||||
@ -236,7 +237,6 @@ GpuMat::operator PtrStep<T>() const
|
||||
{
|
||||
return PtrStep<T>((T*)data, step);
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
inline
|
||||
GpuMat GpuMat::row(int y) const
|
||||
@ -589,6 +589,7 @@ bool DeviceInfo::supports(FeatureSet feature_set) const
|
||||
return version >= feature_set;
|
||||
}
|
||||
|
||||
|
||||
}} // namespace cv { namespace cuda {
|
||||
|
||||
//////////////////////////////// Mat ////////////////////////////////
|
||||
@ -604,4 +605,6 @@ Mat::Mat(const cuda::GpuMat& m)
|
||||
|
||||
}
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CORE_CUDAINL_HPP__
|
||||
|
@ -43,8 +43,11 @@
|
||||
#ifndef __OPENCV_CUDA_DEVICE_BLOCK_HPP__
|
||||
#define __OPENCV_CUDA_DEVICE_BLOCK_HPP__
|
||||
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
struct Block
|
||||
{
|
||||
static __device__ __forceinline__ unsigned int id()
|
||||
@ -198,6 +201,7 @@ namespace cv { namespace cuda { namespace device
|
||||
}
|
||||
}
|
||||
};
|
||||
//!@}
|
||||
}}}
|
||||
|
||||
#endif /* __OPENCV_CUDA_DEVICE_BLOCK_HPP__ */
|
||||
|
@ -49,6 +49,9 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// BrdConstant
|
||||
|
||||
@ -709,6 +712,7 @@ namespace cv { namespace cuda { namespace device
|
||||
int width;
|
||||
D val;
|
||||
};
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif // __OPENCV_CUDA_BORDER_INTERPOLATE_HPP__
|
||||
|
@ -47,6 +47,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
// All OPENCV_CUDA_IMPLEMENT_*_TRAITS(ColorSpace1_to_ColorSpace2, ...) macros implements
|
||||
// template <typename T> class ColorSpace1_to_ColorSpace2_traits
|
||||
// {
|
||||
@ -296,6 +298,7 @@ namespace cv { namespace cuda { namespace device
|
||||
OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS(luv4_to_lbgra, 4, 4, false, 0)
|
||||
|
||||
#undef OPENCV_CUDA_IMPLEMENT_Luv2RGB_TRAITS
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif // __OPENCV_CUDA_BORDER_INTERPOLATE_HPP__
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "opencv2/core/cvdef.h"
|
||||
#include "opencv2/core/base.hpp"
|
||||
|
||||
|
||||
#ifndef CV_PI_F
|
||||
#ifndef CV_PI
|
||||
#define CV_PI_F 3.14159265f
|
||||
@ -57,11 +58,14 @@
|
||||
#endif
|
||||
|
||||
namespace cv { namespace cuda {
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
static inline void checkCudaError(cudaError_t err, const char* file, const int line, const char* func)
|
||||
{
|
||||
if (cudaSuccess != err)
|
||||
cv::error(cv::Error::GpuApiCallError, cudaGetErrorString(err), func, file, line);
|
||||
}
|
||||
//! @}
|
||||
}}
|
||||
|
||||
#ifndef cudaSafeCall
|
||||
@ -70,6 +74,8 @@ namespace cv { namespace cuda {
|
||||
|
||||
namespace cv { namespace cuda
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <typename T> static inline bool isAligned(const T* ptr, size_t size)
|
||||
{
|
||||
return reinterpret_cast<size_t>(ptr) % size == 0;
|
||||
@ -79,12 +85,15 @@ namespace cv { namespace cuda
|
||||
{
|
||||
return step % size == 0;
|
||||
}
|
||||
//! @}
|
||||
}}
|
||||
|
||||
namespace cv { namespace cuda
|
||||
{
|
||||
namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
__host__ __device__ __forceinline__ int divUp(int total, int grain)
|
||||
{
|
||||
return (total + grain - 1) / grain;
|
||||
@ -95,9 +104,8 @@ namespace cv { namespace cuda
|
||||
cudaChannelFormatDesc desc = cudaCreateChannelDesc<T>();
|
||||
cudaSafeCall( cudaBindTexture2D(0, tex, img.ptr(), &desc, img.cols, img.rows, img.step) );
|
||||
}
|
||||
//! @}
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
|
||||
#endif // __OPENCV_CUDA_COMMON_HPP__
|
||||
|
@ -47,6 +47,9 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
|
||||
#if defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 200
|
||||
|
||||
// for Fermi memory space is detected automatically
|
||||
@ -100,6 +103,7 @@ namespace cv { namespace cuda { namespace device
|
||||
#undef OPENCV_CUDA_ASM_PTR
|
||||
|
||||
#endif // __CUDA_ARCH__ >= 200
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif // __OPENCV_CUDA_DATAMOV_UTILS_HPP__
|
||||
|
@ -49,6 +49,8 @@
|
||||
#include "../limits.hpp"
|
||||
#include "../functional.hpp"
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
#ifndef CV_DESCALE
|
||||
@ -1973,4 +1975,6 @@ namespace cv { namespace cuda { namespace device
|
||||
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CUDA_COLOR_DETAIL_HPP__
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include "../warp.hpp"
|
||||
#include "../warp_shuffle.hpp"
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
namespace reduce_detail
|
||||
@ -358,4 +360,6 @@ namespace cv { namespace cuda { namespace device
|
||||
}
|
||||
}}}
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CUDA_REDUCE_DETAIL_HPP__
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include "../warp.hpp"
|
||||
#include "../warp_shuffle.hpp"
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
namespace reduce_key_val_detail
|
||||
@ -495,4 +497,6 @@ namespace cv { namespace cuda { namespace device
|
||||
}
|
||||
}}}
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CUDA_PRED_VAL_REDUCE_DETAIL_HPP__
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include "../vec_traits.hpp"
|
||||
#include "../functional.hpp"
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
namespace transform_detail
|
||||
@ -392,4 +394,6 @@ namespace cv { namespace cuda { namespace device
|
||||
} // namespace transform_detail
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CUDA_TRANSFORM_DETAIL_HPP__
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "../common.hpp"
|
||||
#include "../vec_traits.hpp"
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
namespace type_traits_detail
|
||||
@ -184,4 +186,6 @@ namespace cv { namespace cuda { namespace device
|
||||
} // namespace type_traits_detail
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CUDA_TYPE_TRAITS_DETAIL_HPP__
|
||||
|
@ -45,6 +45,8 @@
|
||||
|
||||
#include "../datamov_utils.hpp"
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
namespace vec_distance_detail
|
||||
@ -114,4 +116,6 @@ namespace cv { namespace cuda { namespace device
|
||||
} // namespace vec_distance_detail
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CUDA_VEC_DISTANCE_DETAIL_HPP__
|
||||
|
@ -45,6 +45,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template<class T> struct DynamicSharedMem
|
||||
{
|
||||
__device__ __forceinline__ operator T*()
|
||||
@ -75,6 +77,7 @@ namespace cv { namespace cuda { namespace device
|
||||
return (double*)__smem_d;
|
||||
}
|
||||
};
|
||||
//! @}
|
||||
}}}
|
||||
|
||||
#endif // __OPENCV_CUDA_DYNAMIC_SMEM_HPP__
|
||||
|
@ -48,6 +48,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
struct Emulation
|
||||
{
|
||||
|
||||
@ -256,6 +258,7 @@ namespace cv { namespace cuda { namespace device
|
||||
}
|
||||
};
|
||||
}; //struct Emulation
|
||||
//!@}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif /* OPENCV_CUDA_EMULATION_HPP_ */
|
||||
|
@ -50,6 +50,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <typename Ptr2D> struct PointFilter
|
||||
{
|
||||
typedef typename Ptr2D::elem_type elem_type;
|
||||
@ -273,6 +275,7 @@ namespace cv { namespace cuda { namespace device
|
||||
float scale_x, scale_y;
|
||||
int width, haight;
|
||||
};
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif // __OPENCV_CUDA_FILTERS_HPP__
|
||||
|
@ -47,6 +47,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template<class Func>
|
||||
void printFuncAttrib(Func& func)
|
||||
{
|
||||
@ -66,6 +68,7 @@ namespace cv { namespace cuda { namespace device
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif /* __OPENCV_CUDA_DEVICE_FUNCATTRIB_HPP_ */
|
||||
|
@ -51,6 +51,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
// Function Objects
|
||||
template<typename Argument, typename Result> struct unary_function : public std::unary_function<Argument, Result> {};
|
||||
template<typename Argument1, typename Argument2, typename Result> struct binary_function : public std::binary_function<Argument1, Argument2, Result> {};
|
||||
@ -784,6 +786,7 @@ namespace cv { namespace cuda { namespace device
|
||||
|
||||
#define OPENCV_CUDA_TRANSFORM_FUNCTOR_TRAITS(type) \
|
||||
template <> struct TransformFunctorTraits< type > : DefaultTransformFunctorTraits< type >
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif // __OPENCV_CUDA_FUNCTIONAL_HPP__
|
||||
|
@ -49,7 +49,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <class T> struct numeric_limits;
|
||||
|
||||
template <> struct numeric_limits<bool>
|
||||
@ -116,7 +117,7 @@ template <> struct numeric_limits<double>
|
||||
__device__ __forceinline__ static double epsilon() { return DBL_EPSILON; }
|
||||
static const bool is_signed = true;
|
||||
};
|
||||
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev {
|
||||
|
||||
#endif // __OPENCV_CUDA_LIMITS_HPP__
|
||||
|
@ -49,6 +49,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <int N, typename T, class Op>
|
||||
__device__ __forceinline__ void reduce(volatile T* smem, T& val, unsigned int tid, const Op& op)
|
||||
{
|
||||
@ -192,6 +194,7 @@ namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
return thrust::make_tuple((volatile T0*) t0, (volatile T1*) t1, (volatile T2*) t2, (volatile T3*) t3, (volatile T4*) t4, (volatile T5*) t5, (volatile T6*) t6, (volatile T7*) t7, (volatile T8*) t8, (volatile T9*) t9);
|
||||
}
|
||||
//! @}
|
||||
}}}
|
||||
|
||||
#endif // __OPENCV_CUDA_UTILITY_HPP__
|
||||
|
@ -47,6 +47,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template<typename _Tp> __device__ __forceinline__ _Tp saturate_cast(uchar v) { return _Tp(v); }
|
||||
template<typename _Tp> __device__ __forceinline__ _Tp saturate_cast(schar v) { return _Tp(v); }
|
||||
template<typename _Tp> __device__ __forceinline__ _Tp saturate_cast(ushort v) { return _Tp(v); }
|
||||
@ -279,6 +281,7 @@ namespace cv { namespace cuda { namespace device
|
||||
return saturate_cast<uint>((float)v);
|
||||
#endif
|
||||
}
|
||||
//! @}
|
||||
}}}
|
||||
|
||||
#endif /* __OPENCV_CUDA_SATURATE_CAST_HPP__ */
|
||||
|
@ -50,6 +50,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
enum ScanKind { EXCLUSIVE = 0, INCLUSIVE = 1 };
|
||||
|
||||
template <ScanKind Kind, typename T, typename F> struct WarpScan
|
||||
@ -245,6 +247,7 @@ namespace cv { namespace cuda { namespace device
|
||||
return warpScanInclusive(idata, s_Data, tid);
|
||||
}
|
||||
}
|
||||
//! @}
|
||||
}}}
|
||||
|
||||
#endif // __OPENCV_CUDA_SCAN_HPP__
|
||||
|
@ -75,7 +75,7 @@
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
/*
|
||||
/** @file
|
||||
This header file contains inline functions that implement intra-word SIMD
|
||||
operations, that are hardware accelerated on sm_3x (Kepler) GPUs. Efficient
|
||||
emulation code paths are provided for earlier architectures (sm_1x, sm_2x)
|
||||
@ -125,6 +125,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
// 2
|
||||
|
||||
static __device__ __forceinline__ unsigned int vadd2(unsigned int a, unsigned int b)
|
||||
@ -904,6 +906,7 @@ namespace cv { namespace cuda { namespace device
|
||||
|
||||
return r;
|
||||
}
|
||||
//! @}
|
||||
}}}
|
||||
|
||||
#endif // __OPENCV_CUDA_SIMD_FUNCTIONS_HPP__
|
||||
|
@ -49,6 +49,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <typename T, typename D, typename UnOp, typename Mask>
|
||||
static inline void transform(PtrStepSz<T> src, PtrStepSz<D> dst, UnOp op, const Mask& mask, cudaStream_t stream)
|
||||
{
|
||||
@ -62,6 +64,7 @@ namespace cv { namespace cuda { namespace device
|
||||
typedef TransformFunctorTraits<BinOp> ft;
|
||||
transform_detail::TransformDispatcher<VecTraits<T1>::cn == 1 && VecTraits<T2>::cn == 1 && VecTraits<D>::cn == 1 && ft::smart_shift != 1>::call(src1, src2, dst, op, mask, stream);
|
||||
}
|
||||
//! @}
|
||||
}}}
|
||||
|
||||
#endif // __OPENCV_CUDA_TRANSFORM_HPP__
|
||||
|
@ -47,6 +47,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <typename T> struct IsSimpleParameter
|
||||
{
|
||||
enum {value = type_traits_detail::IsIntegral<T>::value || type_traits_detail::IsFloat<T>::value ||
|
||||
@ -77,6 +79,7 @@ namespace cv { namespace cuda { namespace device
|
||||
typedef typename type_traits_detail::Select<IsSimpleParameter<UnqualifiedType>::value,
|
||||
T, typename type_traits_detail::AddParameterType<T>::type>::type ParameterType;
|
||||
};
|
||||
//! @}
|
||||
}}}
|
||||
|
||||
#endif // __OPENCV_CUDA_TYPE_TRAITS_HPP__
|
||||
|
@ -48,6 +48,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
#define OPENCV_CUDA_LOG_WARP_SIZE (5)
|
||||
#define OPENCV_CUDA_WARP_SIZE (1 << OPENCV_CUDA_LOG_WARP_SIZE)
|
||||
#define OPENCV_CUDA_LOG_MEM_BANKS ((__CUDA_ARCH__ >= 200) ? 5 : 4) // 32 banks on fermi, 16 on tesla
|
||||
@ -208,6 +210,7 @@ namespace cv { namespace cuda { namespace device
|
||||
|
||||
return false;
|
||||
}
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif // __OPENCV_CUDA_UTILITY_HPP__
|
||||
|
@ -49,6 +49,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <typename T> struct L1Dist
|
||||
{
|
||||
typedef int value_type;
|
||||
@ -219,6 +221,7 @@ namespace cv { namespace cuda { namespace device
|
||||
|
||||
U vec1Vals[MAX_LEN / THREAD_DIM];
|
||||
};
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif // __OPENCV_CUDA_VEC_DISTANCE_HPP__
|
||||
|
@ -49,6 +49,9 @@
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
|
||||
// saturate_cast
|
||||
|
||||
namespace vec_math_detail
|
||||
@ -917,6 +920,8 @@ CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC(atan2, ::atan2, double, double, double)
|
||||
|
||||
#undef CV_CUDEV_IMPLEMENT_SCALAR_BINARY_FUNC
|
||||
|
||||
//! @}
|
||||
|
||||
}}} // namespace cv { namespace cuda { namespace device
|
||||
|
||||
#endif // __OPENCV_CUDA_VECMATH_HPP__
|
||||
|
@ -47,6 +47,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template<typename T, int N> struct TypeVec;
|
||||
|
||||
struct __align__(8) uchar8
|
||||
@ -275,6 +277,7 @@ namespace cv { namespace cuda { namespace device
|
||||
static __device__ __host__ __forceinline__ char8 make(schar a0, schar a1, schar a2, schar a3, schar a4, schar a5, schar a6, schar a7) {return make_char8(a0, a1, a2, a3, a4, a5, a6, a7);}
|
||||
static __device__ __host__ __forceinline__ char8 make(const schar* v) {return make_char8(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);}
|
||||
};
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif // __OPENCV_CUDA_VEC_TRAITS_HPP__
|
||||
|
@ -45,6 +45,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
struct Warp
|
||||
{
|
||||
enum
|
||||
@ -126,6 +128,7 @@ namespace cv { namespace cuda { namespace device
|
||||
*t = value;
|
||||
}
|
||||
};
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev
|
||||
|
||||
#endif /* __OPENCV_CUDA_DEVICE_WARP_HPP__ */
|
||||
|
@ -45,6 +45,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <class T>
|
||||
__device__ __forceinline__ T warp_reduce(volatile T *ptr , const unsigned int tid = threadIdx.x)
|
||||
{
|
||||
@ -63,6 +65,7 @@ namespace cv { namespace cuda { namespace device
|
||||
|
||||
return ptr[tid - lane];
|
||||
}
|
||||
//! @}
|
||||
}}} // namespace cv { namespace cuda { namespace cudev {
|
||||
|
||||
#endif /* OPENCV_CUDA_WARP_REDUCE_HPP__ */
|
||||
|
@ -45,6 +45,8 @@
|
||||
|
||||
namespace cv { namespace cuda { namespace device
|
||||
{
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
template <typename T>
|
||||
__device__ __forceinline__ T shfl(T val, int srcLane, int width = warpSize)
|
||||
{
|
||||
@ -140,6 +142,7 @@ namespace cv { namespace cuda { namespace device
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
//! @}
|
||||
}}}
|
||||
|
||||
#endif // __OPENCV_CUDA_WARP_SHUFFLE_HPP__
|
||||
|
@ -59,6 +59,10 @@ namespace cv
|
||||
{
|
||||
namespace cuda
|
||||
{
|
||||
|
||||
//! @addtogroup cuda_struct
|
||||
//! @{
|
||||
|
||||
class Stream;
|
||||
class Event;
|
||||
|
||||
@ -71,6 +75,9 @@ namespace cv
|
||||
{
|
||||
CV_EXPORTS static cudaEvent_t getEvent(const Event& event);
|
||||
};
|
||||
|
||||
//! @}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,10 @@ namespace cv
|
||||
{
|
||||
namespace cuda
|
||||
{
|
||||
|
||||
//! @addtogroup cuda_struct
|
||||
//! @{
|
||||
|
||||
// Simple lightweight structures that encapsulates information about an image on device.
|
||||
// It is intended to pass to nvcc-compiled code. GpuMat depends on headers that nvcc can't compile
|
||||
|
||||
@ -120,6 +124,9 @@ namespace cv
|
||||
typedef PtrStep<unsigned char> PtrStepb;
|
||||
typedef PtrStep<float> PtrStepf;
|
||||
typedef PtrStep<int> PtrStepi;
|
||||
|
||||
//! @}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,6 +358,14 @@ typedef signed char schar;
|
||||
# include "tegra_round.hpp"
|
||||
#endif
|
||||
|
||||
//! @addtogroup core_utils
|
||||
//! @{
|
||||
|
||||
/** @brief Rounds floating-point number to the nearest integer
|
||||
|
||||
@param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
|
||||
result is not defined.
|
||||
*/
|
||||
CV_INLINE int cvRound( double value )
|
||||
{
|
||||
#if ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
|
||||
@ -389,6 +397,13 @@ CV_INLINE int cvRound( double value )
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Rounds floating-point number to the nearest integer not larger than the original.
|
||||
|
||||
The function computes an integer i such that:
|
||||
\f[i \le \texttt{value} < i+1\f]
|
||||
@param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
|
||||
result is not defined.
|
||||
*/
|
||||
CV_INLINE int cvFloor( double value )
|
||||
{
|
||||
#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__ && !defined __APPLE__)) && !defined(__CUDACC__)
|
||||
@ -405,6 +420,13 @@ CV_INLINE int cvFloor( double value )
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Rounds floating-point number to the nearest integer not larger than the original.
|
||||
|
||||
The function computes an integer i such that:
|
||||
\f[i \le \texttt{value} < i+1\f]
|
||||
@param value floating-point number. If the value is outside of INT_MIN ... INT_MAX range, the
|
||||
result is not defined.
|
||||
*/
|
||||
CV_INLINE int cvCeil( double value )
|
||||
{
|
||||
#if (defined _MSC_VER && defined _M_X64 || (defined __GNUC__ && defined __SSE2__&& !defined __APPLE__)) && !defined(__CUDACC__)
|
||||
@ -421,6 +443,12 @@ CV_INLINE int cvCeil( double value )
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Determines if the argument is Not A Number.
|
||||
|
||||
@param value The input floating-point value
|
||||
|
||||
The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0
|
||||
otherwise. */
|
||||
CV_INLINE int cvIsNaN( double value )
|
||||
{
|
||||
union { uint64 u; double f; } ieee754;
|
||||
@ -429,6 +457,12 @@ CV_INLINE int cvIsNaN( double value )
|
||||
((unsigned)ieee754.u != 0) > 0x7ff00000;
|
||||
}
|
||||
|
||||
/** @brief Determines if the argument is Infinity.
|
||||
|
||||
@param value The input floating-point value
|
||||
|
||||
The function returns 1 if the argument is a plus or minus infinity (as defined by IEEE754 standard)
|
||||
and 0 otherwise. */
|
||||
CV_INLINE int cvIsInf( double value )
|
||||
{
|
||||
union { uint64 u; double f; } ieee754;
|
||||
@ -437,6 +471,8 @@ CV_INLINE int cvIsInf( double value )
|
||||
(unsigned)ieee754.u == 0;
|
||||
}
|
||||
|
||||
//! @} core_utils
|
||||
|
||||
/****************************************************************************************\
|
||||
* exchange-add operation for atomic operations on reference counters *
|
||||
\****************************************************************************************/
|
||||
|
@ -102,26 +102,26 @@ namespace cv
|
||||
|
||||
namespace cv {
|
||||
|
||||
//! @addtogroup core_utils
|
||||
//! @{
|
||||
|
||||
//////////////////////////// memory management functions ////////////////////////////
|
||||
|
||||
/*!
|
||||
Allocates memory buffer
|
||||
/** @brief Allocates an aligned memory buffer.
|
||||
|
||||
This is specialized OpenCV memory allocation function that returns properly aligned memory buffers.
|
||||
The usage is identical to malloc(). The allocated buffers must be freed with cv::fastFree().
|
||||
If there is not enough memory, the function calls cv::error(), which raises an exception.
|
||||
|
||||
\param bufSize buffer size in bytes
|
||||
\return the allocated memory buffer.
|
||||
*/
|
||||
The function allocates the buffer of the specified size and returns it. When the buffer size is 16
|
||||
bytes or more, the returned buffer is aligned to 16 bytes.
|
||||
@param bufSize Allocated buffer size.
|
||||
*/
|
||||
CV_EXPORTS void* fastMalloc(size_t bufSize);
|
||||
|
||||
/*!
|
||||
Frees the memory allocated with cv::fastMalloc
|
||||
/** @brief Deallocates a memory buffer.
|
||||
|
||||
This is the corresponding deallocation function for cv::fastMalloc().
|
||||
When ptr==NULL, the function has no effect.
|
||||
*/
|
||||
The function deallocates the buffer allocated with fastMalloc . If NULL pointer is passed, the
|
||||
function does nothing. C version of the function clears the pointer *pptr* to avoid problems with
|
||||
double memory deallocation.
|
||||
@param ptr Pointer to the allocated buffer.
|
||||
*/
|
||||
CV_EXPORTS void fastFree(void* ptr);
|
||||
|
||||
/*!
|
||||
@ -158,6 +158,10 @@ public:
|
||||
size_type max_size() const { return cv::max(static_cast<_Tp>(-1)/sizeof(_Tp), 1); }
|
||||
};
|
||||
|
||||
//! @} core_utils
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
@ -188,102 +192,219 @@ struct DefaultDeleter
|
||||
void operator () (Y* p) const;
|
||||
};
|
||||
|
||||
/*
|
||||
A smart shared pointer class with reference counting.
|
||||
//! @endcond
|
||||
|
||||
A Ptr<T> stores a pointer and owns a (potentially different) pointer.
|
||||
The stored pointer has type T and is the one returned by get() et al,
|
||||
while the owned pointer can have any type and is the one deleted
|
||||
when there are no more Ptrs that own it. You can't directly obtain the
|
||||
owned pointer.
|
||||
//! @addtogroup core_basic
|
||||
//! @{
|
||||
|
||||
The interface of this class is mostly a subset of that of C++11's
|
||||
std::shared_ptr.
|
||||
/** @brief Template class for smart pointers with shared ownership
|
||||
|
||||
A Ptr\<T\> pretends to be a pointer to an object of type T. Unlike an ordinary pointer, however, the
|
||||
object will be automatically cleaned up once all Ptr instances pointing to it are destroyed.
|
||||
|
||||
Ptr is similar to boost::shared_ptr that is part of the Boost library
|
||||
(<http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm>) and std::shared_ptr from
|
||||
the [C++11](http://en.wikipedia.org/wiki/C++11) standard.
|
||||
|
||||
This class provides the following advantages:
|
||||
- Default constructor, copy constructor, and assignment operator for an arbitrary C++ class or C
|
||||
structure. For some objects, like files, windows, mutexes, sockets, and others, a copy
|
||||
constructor or an assignment operator are difficult to define. For some other objects, like
|
||||
complex classifiers in OpenCV, copy constructors are absent and not easy to implement. Finally,
|
||||
some of complex OpenCV and your own data structures may be written in C. However, copy
|
||||
constructors and default constructors can simplify programming a lot. Besides, they are often
|
||||
required (for example, by STL containers). By using a Ptr to such an object instead of the
|
||||
object itself, you automatically get all of the necessary constructors and the assignment
|
||||
operator.
|
||||
- *O(1)* complexity of the above-mentioned operations. While some structures, like std::vector,
|
||||
provide a copy constructor and an assignment operator, the operations may take a considerable
|
||||
amount of time if the data structures are large. But if the structures are put into a Ptr, the
|
||||
overhead is small and independent of the data size.
|
||||
- Automatic and customizable cleanup, even for C structures. See the example below with FILE\*.
|
||||
- Heterogeneous collections of objects. The standard STL and most other C++ and OpenCV containers
|
||||
can store only objects of the same type and the same size. The classical solution to store
|
||||
objects of different types in the same container is to store pointers to the base class (Base\*)
|
||||
instead but then you lose the automatic memory management. Again, by using Ptr\<Base\> instead
|
||||
of raw pointers, you can solve the problem.
|
||||
|
||||
A Ptr is said to *own* a pointer - that is, for each Ptr there is a pointer that will be deleted
|
||||
once all Ptr instances that own it are destroyed. The owned pointer may be null, in which case
|
||||
nothing is deleted. Each Ptr also *stores* a pointer. The stored pointer is the pointer the Ptr
|
||||
pretends to be; that is, the one you get when you use Ptr::get or the conversion to T\*. It's
|
||||
usually the same as the owned pointer, but if you use casts or the general shared-ownership
|
||||
constructor, the two may diverge: the Ptr will still own the original pointer, but will itself point
|
||||
to something else.
|
||||
|
||||
The owned pointer is treated as a black box. The only thing Ptr needs to know about it is how to
|
||||
delete it. This knowledge is encapsulated in the *deleter* - an auxiliary object that is associated
|
||||
with the owned pointer and shared between all Ptr instances that own it. The default deleter is an
|
||||
instance of DefaultDeleter, which uses the standard C++ delete operator; as such it will work with
|
||||
any pointer allocated with the standard new operator.
|
||||
|
||||
However, if the pointer must be deleted in a different way, you must specify a custom deleter upon
|
||||
Ptr construction. A deleter is simply a callable object that accepts the pointer as its sole
|
||||
argument. For example, if you want to wrap FILE, you may do so as follows:
|
||||
@code
|
||||
Ptr<FILE> f(fopen("myfile.txt", "w"), fclose);
|
||||
if(!f) throw ...;
|
||||
fprintf(f, ....);
|
||||
...
|
||||
// the file will be closed automatically by f's destructor.
|
||||
@endcode
|
||||
Alternatively, if you want all pointers of a particular type to be deleted the same way, you can
|
||||
specialize DefaultDeleter<T>::operator() for that type, like this:
|
||||
@code
|
||||
namespace cv {
|
||||
template<> void DefaultDeleter<FILE>::operator ()(FILE * obj) const
|
||||
{
|
||||
fclose(obj);
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
For convenience, the following types from the OpenCV C API already have such a specialization that
|
||||
calls the appropriate release function:
|
||||
- CvCapture
|
||||
- CvFileStorage
|
||||
- CvHaarClassifierCascade
|
||||
- CvMat
|
||||
- CvMatND
|
||||
- CvMemStorage
|
||||
- CvSparseMat
|
||||
- CvVideoWriter
|
||||
- IplImage
|
||||
@note The shared ownership mechanism is implemented with reference counting. As such, cyclic
|
||||
ownership (e.g. when object a contains a Ptr to object b, which contains a Ptr to object a) will
|
||||
lead to all involved objects never being cleaned up. Avoid such situations.
|
||||
@note It is safe to concurrently read (but not write) a Ptr instance from multiple threads and
|
||||
therefore it is normally safe to use it in multi-threaded applications. The same is true for Mat and
|
||||
other C++ OpenCV classes that use internal reference counts.
|
||||
*/
|
||||
template<typename T>
|
||||
struct Ptr
|
||||
{
|
||||
/* Generic programming support. */
|
||||
/** Generic programming support. */
|
||||
typedef T element_type;
|
||||
|
||||
/* Ptr that owns NULL and stores NULL. */
|
||||
/** The default constructor creates a null Ptr - one that owns and stores a null pointer.
|
||||
*/
|
||||
Ptr();
|
||||
|
||||
/* Ptr that owns p and stores p. The owned pointer will be deleted with
|
||||
DefaultDeleter<Y>. Y must be a complete type and Y* must be
|
||||
convertible to T*. */
|
||||
/**
|
||||
If p is null, these are equivalent to the default constructor.
|
||||
Otherwise, these constructors assume ownership of p - that is, the created Ptr owns and stores p
|
||||
and assumes it is the sole owner of it. Don't use them if p is already owned by another Ptr, or
|
||||
else p will get deleted twice.
|
||||
With the first constructor, DefaultDeleter\<Y\>() becomes the associated deleter (so p will
|
||||
eventually be deleted with the standard delete operator). Y must be a complete type at the point
|
||||
of invocation.
|
||||
With the second constructor, d becomes the associated deleter.
|
||||
Y\* must be convertible to T\*.
|
||||
@param p Pointer to own.
|
||||
@note It is often easier to use makePtr instead.
|
||||
*/
|
||||
template<typename Y>
|
||||
explicit Ptr(Y* p);
|
||||
|
||||
/* Ptr that owns p and stores p. The owned pointer will be deleted by
|
||||
calling d(p). Y* must be convertible to T*. */
|
||||
/** @overload
|
||||
@param d Deleter to use for the owned pointer.
|
||||
@param p Pointer to own.
|
||||
*/
|
||||
template<typename Y, typename D>
|
||||
Ptr(Y* p, D d);
|
||||
|
||||
/* Same as the constructor below; it exists to suppress the generation
|
||||
of the implicit copy constructor. */
|
||||
/**
|
||||
These constructors create a Ptr that shares ownership with another Ptr - that is, own the same
|
||||
pointer as o.
|
||||
With the first two, the same pointer is stored, as well; for the second, Y\* must be convertible
|
||||
to T\*.
|
||||
With the third, p is stored, and Y may be any type. This constructor allows to have completely
|
||||
unrelated owned and stored pointers, and should be used with care to avoid confusion. A relatively
|
||||
benign use is to create a non-owning Ptr, like this:
|
||||
@code
|
||||
ptr = Ptr<T>(Ptr<T>(), dont_delete_me); // owns nothing; will not delete the pointer.
|
||||
@endcode
|
||||
@param o Ptr to share ownership with.
|
||||
*/
|
||||
Ptr(const Ptr& o);
|
||||
|
||||
/* Ptr that owns the same pointer as o and stores the same pointer as o,
|
||||
converted to T*. Naturally, Y* must be convertible to T*. */
|
||||
/** @overload
|
||||
@param o Ptr to share ownership with.
|
||||
*/
|
||||
template<typename Y>
|
||||
Ptr(const Ptr<Y>& o);
|
||||
|
||||
/* Ptr that owns same pointer as o, and stores p. Useful for casts and
|
||||
creating non-owning Ptrs. */
|
||||
/** @overload
|
||||
@param o Ptr to share ownership with.
|
||||
@param p Pointer to store.
|
||||
*/
|
||||
template<typename Y>
|
||||
Ptr(const Ptr<Y>& o, T* p);
|
||||
|
||||
/* Equivalent to release(). */
|
||||
/** The destructor is equivalent to calling Ptr::release. */
|
||||
~Ptr();
|
||||
|
||||
/* Same as assignment below; exists to suppress the generation of the
|
||||
implicit assignment operator. */
|
||||
/**
|
||||
Assignment replaces the current Ptr instance with one that owns and stores same pointers as o and
|
||||
then destroys the old instance.
|
||||
@param o Ptr to share ownership with.
|
||||
*/
|
||||
Ptr& operator = (const Ptr& o);
|
||||
|
||||
/** @overload */
|
||||
template<typename Y>
|
||||
Ptr& operator = (const Ptr<Y>& o);
|
||||
|
||||
/* Resets both the owned and stored pointers to NULL. Deletes the owned
|
||||
pointer with the associated deleter if it's not owned by any other
|
||||
Ptr and is non-zero. It's called reset() in std::shared_ptr; here
|
||||
it is release() for compatibility with old OpenCV versions. */
|
||||
/** If no other Ptr instance owns the owned pointer, deletes it with the associated deleter. Then sets
|
||||
both the owned and the stored pointers to NULL.
|
||||
*/
|
||||
void release();
|
||||
|
||||
/* Equivalent to assigning from Ptr<T>(p). */
|
||||
/**
|
||||
`ptr.reset(...)` is equivalent to `ptr = Ptr<T>(...)`.
|
||||
@param p Pointer to own.
|
||||
*/
|
||||
template<typename Y>
|
||||
void reset(Y* p);
|
||||
|
||||
/* Equivalent to assigning from Ptr<T>(p, d). */
|
||||
/** @overload
|
||||
@param d Deleter to use for the owned pointer.
|
||||
@param p Pointer to own.
|
||||
*/
|
||||
template<typename Y, typename D>
|
||||
void reset(Y* p, D d);
|
||||
|
||||
/* Swaps the stored and owned pointers of this and o. */
|
||||
/**
|
||||
Swaps the owned and stored pointers (and deleters, if any) of this and o.
|
||||
@param o Ptr to swap with.
|
||||
*/
|
||||
void swap(Ptr& o);
|
||||
|
||||
/* Returns the stored pointer. */
|
||||
/** Returns the stored pointer. */
|
||||
T* get() const;
|
||||
|
||||
/* Ordinary pointer emulation. */
|
||||
/** Ordinary pointer emulation. */
|
||||
typename detail::RefOrVoid<T>::type operator * () const;
|
||||
|
||||
/** Ordinary pointer emulation. */
|
||||
T* operator -> () const;
|
||||
|
||||
/* Equivalent to get(). */
|
||||
/** Equivalent to get(). */
|
||||
operator T* () const;
|
||||
|
||||
/* Equivalent to !*this. */
|
||||
/** ptr.empty() is equivalent to `!ptr.get()`. */
|
||||
bool empty() const;
|
||||
|
||||
/* Returns a Ptr that owns the same pointer as this, and stores the same
|
||||
pointer as this, except converted via static_cast to Y*. */
|
||||
/** Returns a Ptr that owns the same pointer as this, and stores the same
|
||||
pointer as this, except converted via static_cast to Y*.
|
||||
*/
|
||||
template<typename Y>
|
||||
Ptr<Y> staticCast() const;
|
||||
|
||||
/* Ditto for const_cast. */
|
||||
/** Ditto for const_cast. */
|
||||
template<typename Y>
|
||||
Ptr<Y> constCast() const;
|
||||
|
||||
/* Ditto for dynamic_cast. */
|
||||
/** Ditto for dynamic_cast. */
|
||||
template<typename Y>
|
||||
Ptr<Y> dynamicCast() const;
|
||||
|
||||
@ -295,41 +416,55 @@ private:
|
||||
friend struct Ptr; // have to do this for the cross-type copy constructor
|
||||
};
|
||||
|
||||
/* Overload of the generic swap. */
|
||||
/** Equivalent to ptr1.swap(ptr2). Provided to help write generic algorithms. */
|
||||
template<typename T>
|
||||
void swap(Ptr<T>& ptr1, Ptr<T>& ptr2);
|
||||
|
||||
/* Obvious comparisons. */
|
||||
/** Return whether ptr1.get() and ptr2.get() are equal and not equal, respectively. */
|
||||
template<typename T>
|
||||
bool operator == (const Ptr<T>& ptr1, const Ptr<T>& ptr2);
|
||||
template<typename T>
|
||||
bool operator != (const Ptr<T>& ptr1, const Ptr<T>& ptr2);
|
||||
|
||||
/* Convenience creation functions. In the far future, there may be variadic templates here. */
|
||||
/** `makePtr<T>(...)` is equivalent to `Ptr<T>(new T(...))`. It is shorter than the latter, and it's
|
||||
marginally safer than using a constructor or Ptr::reset, since it ensures that the owned pointer
|
||||
is new and thus not owned by any other Ptr instance.
|
||||
Unfortunately, perfect forwarding is impossible to implement in C++03, and so makePtr is limited
|
||||
to constructors of T that have up to 10 arguments, none of which are non-const references.
|
||||
*/
|
||||
template<typename T>
|
||||
Ptr<T> makePtr();
|
||||
/** @overload */
|
||||
template<typename T, typename A1>
|
||||
Ptr<T> makePtr(const A1& a1);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2, typename A3>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9);
|
||||
/** @overload */
|
||||
template<typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
|
||||
Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10);
|
||||
|
||||
|
||||
//////////////////////////////// string class ////////////////////////////////
|
||||
|
||||
class CV_EXPORTS FileNode; //for string constructor from FileNode
|
||||
@ -435,9 +570,12 @@ private:
|
||||
void deallocate();
|
||||
};
|
||||
|
||||
//! @} core_basic
|
||||
|
||||
////////////////////////// cv::String implementation /////////////////////////
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
inline
|
||||
String::String()
|
||||
: cstr_(0), len_(0)
|
||||
@ -815,8 +953,13 @@ String String::toLowerCase() const
|
||||
return res;
|
||||
}
|
||||
|
||||
//! @endcond
|
||||
|
||||
// ************************* cv::String non-member functions *************************
|
||||
|
||||
//! @relates cv::String
|
||||
//! @{
|
||||
|
||||
inline
|
||||
String operator + (const String& lhs, const String& rhs)
|
||||
{
|
||||
@ -888,6 +1031,8 @@ static inline bool operator>= (const String& lhs, const String& rhs) { return lh
|
||||
static inline bool operator>= (const char* lhs, const String& rhs) { return rhs.compare(lhs) <= 0; }
|
||||
static inline bool operator>= (const String& lhs, const char* rhs) { return lhs.compare(rhs) >= 0; }
|
||||
|
||||
//! @} relates cv::String
|
||||
|
||||
} // cv
|
||||
|
||||
#ifndef OPENCV_NOSTL_TRANSITIONAL
|
||||
|
@ -49,6 +49,8 @@
|
||||
# include <ostream>
|
||||
#endif
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv
|
||||
{
|
||||
#ifndef OPENCV_NOSTL
|
||||
@ -260,4 +262,6 @@ std::ostream& operator << (std::ostream& out, const Rect_<_Tp>& rect)
|
||||
#endif // OPENCV_NOSTL
|
||||
} // cv
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CORE_CVSTDINL_HPP__
|
||||
|
@ -61,19 +61,28 @@ struct IDirect3DDevice9Ex;
|
||||
struct IDirect3DSurface9;
|
||||
#endif
|
||||
|
||||
|
||||
namespace cv { namespace directx {
|
||||
|
||||
namespace ocl {
|
||||
using namespace cv::ocl;
|
||||
|
||||
//! @addtogroup core_directx
|
||||
//! @{
|
||||
|
||||
// TODO static functions in the Context class
|
||||
CV_EXPORTS Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device);
|
||||
CV_EXPORTS Context& initializeContextFromD3D10Device(ID3D10Device* pD3D10Device);
|
||||
CV_EXPORTS Context& initializeContextFromDirect3DDevice9Ex(IDirect3DDevice9Ex* pDirect3DDevice9Ex);
|
||||
CV_EXPORTS Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9);
|
||||
|
||||
//! @}
|
||||
|
||||
} // namespace cv::directx::ocl
|
||||
|
||||
//! @addtogroup core_directx
|
||||
//! @{
|
||||
|
||||
CV_EXPORTS void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D);
|
||||
CV_EXPORTS void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst);
|
||||
|
||||
@ -89,6 +98,7 @@ CV_EXPORTS int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT); // enum DXGI_FORM
|
||||
// Get OpenCV type from DirectX type, return -1 if there is no equivalent
|
||||
CV_EXPORTS int getTypeFromD3DFORMAT(const int iD3DFORMAT); // enum D3DTYPE for D3D9
|
||||
|
||||
//! @}
|
||||
|
||||
} } // namespace cv::directx
|
||||
|
||||
|
@ -56,6 +56,9 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @addtogroup core_eigen
|
||||
//! @{
|
||||
|
||||
template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
|
||||
void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, Mat& dst )
|
||||
{
|
||||
@ -270,6 +273,8 @@ void cv2eigen( const Matx<_Tp, 1, _cols>& src,
|
||||
}
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
||||
} // cv
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,16 @@ namespace cv
|
||||
|
||||
namespace hpp
|
||||
{
|
||||
//convert OpenCV data type to hppDataType
|
||||
|
||||
/** @addtogroup core_ipp
|
||||
This section describes conversion between OpenCV and [Intel® IPP Asynchronous
|
||||
C/C++](http://software.intel.com/en-us/intel-ipp-preview) library. [Getting Started
|
||||
Guide](http://registrationcenter.intel.com/irc_nas/3727/ipp_async_get_started.htm) help you to
|
||||
install the library, configure header and library build paths.
|
||||
*/
|
||||
//! @{
|
||||
|
||||
//! convert OpenCV data type to hppDataType
|
||||
inline int toHppType(const int cvType)
|
||||
{
|
||||
int depth = CV_MAT_DEPTH(cvType);
|
||||
@ -26,7 +35,7 @@ namespace hpp
|
||||
return hppType;
|
||||
}
|
||||
|
||||
//convert hppDataType to OpenCV data type
|
||||
//! convert hppDataType to OpenCV data type
|
||||
inline int toCvType(const int hppType)
|
||||
{
|
||||
int cvType = hppType == HPP_DATA_TYPE_8U ? CV_8U :
|
||||
@ -39,6 +48,15 @@ namespace hpp
|
||||
return cvType;
|
||||
}
|
||||
|
||||
/** @brief Convert hppiMatrix to Mat.
|
||||
|
||||
This function allocates and initializes new matrix (if needed) that has the same size and type as
|
||||
input matrix. Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F.
|
||||
@param src input hppiMatrix.
|
||||
@param dst output matrix.
|
||||
@param accel accelerator instance (see hpp::getHpp for the list of acceleration framework types).
|
||||
@param cn number of channels.
|
||||
*/
|
||||
inline void copyHppToMat(hppiMatrix* src, Mat& dst, hppAccel accel, int cn)
|
||||
{
|
||||
hppDataType type;
|
||||
@ -67,7 +85,15 @@ namespace hpp
|
||||
CV_Assert( sts == HPP_STATUS_NO_ERROR);
|
||||
}
|
||||
|
||||
//create cv::Mat from hppiMatrix
|
||||
/** @brief Create Mat from hppiMatrix.
|
||||
|
||||
This function allocates and initializes the Mat that has the same size and type as input matrix.
|
||||
Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F.
|
||||
@param src input hppiMatrix.
|
||||
@param accel accelerator instance (see hpp::getHpp for the list of acceleration framework types).
|
||||
@param cn number of channels.
|
||||
@sa howToUseIPPAconversion, hpp::copyHppToMat, hpp::getHpp.
|
||||
*/
|
||||
inline Mat getMat(hppiMatrix* src, hppAccel accel, int cn)
|
||||
{
|
||||
Mat dst;
|
||||
@ -75,7 +101,26 @@ namespace hpp
|
||||
return dst;
|
||||
}
|
||||
|
||||
//create hppiMatrix from cv::Mat
|
||||
/** @brief Create hppiMatrix from Mat.
|
||||
|
||||
This function allocates and initializes the hppiMatrix that has the same size and type as input
|
||||
matrix, returns the hppiMatrix*.
|
||||
|
||||
If you want to use zero-copy for GPU you should to have 4KB aligned matrix data. See details
|
||||
[hppiCreateSharedMatrix](http://software.intel.com/ru-ru/node/501697).
|
||||
|
||||
Supports CV_8U, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F.
|
||||
|
||||
@note The hppiMatrix pointer to the image buffer in system memory refers to the src.data. Control
|
||||
the lifetime of the matrix and don't change its data, if there is no special need.
|
||||
@param src input matrix.
|
||||
@param accel accelerator instance. Supports type:
|
||||
- **HPP_ACCEL_TYPE_CPU** - accelerated by optimized CPU instructions.
|
||||
- **HPP_ACCEL_TYPE_GPU** - accelerated by GPU programmable units or fixed-function
|
||||
accelerators.
|
||||
- **HPP_ACCEL_TYPE_ANY** - any acceleration or no acceleration available.
|
||||
@sa howToUseIPPAconversion, hpp::getMat
|
||||
*/
|
||||
inline hppiMatrix* getHpp(const Mat& src, hppAccel accel)
|
||||
{
|
||||
int htype = toHppType(src.type());
|
||||
@ -98,8 +143,9 @@ namespace hpp
|
||||
return hppiCreateMatrix(htype, src.cols*cn, src.rows, src.data, (hpp32s)(src.step));;
|
||||
}
|
||||
|
||||
//! @}
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -50,6 +50,8 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
//////////////////////// Input/Output Arrays ////////////////////////
|
||||
|
||||
inline void _InputArray::init(int _flags, const void* _obj)
|
||||
@ -3402,6 +3404,8 @@ inline void UMatData::markDeviceCopyObsolete(bool flag)
|
||||
inline UMatDataAutoLock::UMatDataAutoLock(UMatData* _u) : u(_u) { u->lock(); }
|
||||
inline UMatDataAutoLock::~UMatDataAutoLock() { u->unlock(); }
|
||||
|
||||
//! @endcond
|
||||
|
||||
} //cv
|
||||
|
||||
#endif
|
||||
|
@ -55,24 +55,12 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @addtogroup core_basic
|
||||
//! @{
|
||||
|
||||
////////////////////////////// Small Matrix ///////////////////////////
|
||||
|
||||
/*!
|
||||
A short numerical vector.
|
||||
|
||||
This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements)
|
||||
on which you can perform basic arithmetical operations, access individual elements using [] operator etc.
|
||||
The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc.,
|
||||
which elements are dynamically allocated in the heap.
|
||||
|
||||
The template takes 2 parameters:
|
||||
-# _Tp element type
|
||||
-# cn the number of elements
|
||||
|
||||
In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
|
||||
for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
|
||||
*/
|
||||
|
||||
//! @cond IGNORED
|
||||
struct CV_EXPORTS Matx_AddOp {};
|
||||
struct CV_EXPORTS Matx_SubOp {};
|
||||
struct CV_EXPORTS Matx_ScaleOp {};
|
||||
@ -80,7 +68,21 @@ struct CV_EXPORTS Matx_MulOp {};
|
||||
struct CV_EXPORTS Matx_DivOp {};
|
||||
struct CV_EXPORTS Matx_MatMulOp {};
|
||||
struct CV_EXPORTS Matx_TOp {};
|
||||
//! @endcond
|
||||
|
||||
/** @brief Template class for small matrices whose type and size are known at compilation time
|
||||
|
||||
If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the
|
||||
M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are
|
||||
available. To do an operation on Matx that is not implemented, you can easily convert the matrix to
|
||||
Mat and backwards:
|
||||
@code
|
||||
Matx33f m(1, 2, 3,
|
||||
4, 5, 6,
|
||||
7, 8, 9);
|
||||
cout << sum(Mat(m*m.t())) << endl;
|
||||
@endcode
|
||||
*/
|
||||
template<typename _Tp, int m, int n> class Matx
|
||||
{
|
||||
public:
|
||||
@ -242,8 +244,7 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
/*!
|
||||
Comma-separated Matrix Initializer
|
||||
/** @brief Comma-separated Matrix Initializer
|
||||
*/
|
||||
template<typename _Tp, int m, int n> class MatxCommaInitializer
|
||||
{
|
||||
@ -256,7 +257,7 @@ public:
|
||||
int idx;
|
||||
};
|
||||
|
||||
/*!
|
||||
/*
|
||||
Utility methods
|
||||
*/
|
||||
template<typename _Tp, int m> static double determinant(const Matx<_Tp, m, m>& a);
|
||||
@ -268,20 +269,33 @@ template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M
|
||||
|
||||
/////////////////////// Vec (used as element of multi-channel images /////////////////////
|
||||
|
||||
/*!
|
||||
A short numerical vector.
|
||||
/** @brief Template class for short numerical vectors, a partial case of Matx
|
||||
|
||||
This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements)
|
||||
on which you can perform basic arithmetical operations, access individual elements using [] operator etc.
|
||||
The vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc.,
|
||||
which elements are dynamically allocated in the heap.
|
||||
This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) on which you
|
||||
can perform basic arithmetical operations, access individual elements using [] operator etc. The
|
||||
vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., which
|
||||
elements are dynamically allocated in the heap.
|
||||
|
||||
The template takes 2 parameters:
|
||||
-# _Tp element type
|
||||
-# cn the number of elements
|
||||
The template takes 2 parameters:
|
||||
@tparam _Tp element type
|
||||
@tparam cn the number of elements
|
||||
|
||||
In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
|
||||
for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
|
||||
In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
|
||||
for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
|
||||
|
||||
It is possible to convert Vec\<T,2\> to/from Point_, Vec\<T,3\> to/from Point3_ , and Vec\<T,4\>
|
||||
to CvScalar or Scalar_. Use operator[] to access the elements of Vec.
|
||||
|
||||
All the expected vector operations are also implemented:
|
||||
- v1 = v2 + v3
|
||||
- v1 = v2 - v3
|
||||
- v1 = v2 \* scale
|
||||
- v1 = scale \* v2
|
||||
- v1 = -v2
|
||||
- v1 += v2 and other augmenting operations
|
||||
- v1 == v2, v1 != v2
|
||||
- norm(v1) (euclidean norm)
|
||||
The Vec class is commonly used to describe pixel types of multi-channel arrays. See Mat for details.
|
||||
*/
|
||||
template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
|
||||
{
|
||||
@ -337,8 +351,8 @@ public:
|
||||
template<typename _T2> Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp);
|
||||
};
|
||||
|
||||
/* \typedef
|
||||
Shorter aliases for the most popular specializations of Vec<T,n>
|
||||
/** @name Shorter aliases for the most popular specializations of Vec<T,n>
|
||||
@{
|
||||
*/
|
||||
typedef Vec<uchar, 2> Vec2b;
|
||||
typedef Vec<uchar, 3> Vec3b;
|
||||
@ -367,6 +381,7 @@ typedef Vec<double, 2> Vec2d;
|
||||
typedef Vec<double, 3> Vec3d;
|
||||
typedef Vec<double, 4> Vec4d;
|
||||
typedef Vec<double, 6> Vec6d;
|
||||
/** @} */
|
||||
|
||||
/*!
|
||||
traits
|
||||
@ -387,8 +402,7 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
/*!
|
||||
Comma-separated Vec Initializer
|
||||
/** @brief Comma-separated Vec Initializer
|
||||
*/
|
||||
template<typename _Tp, int m> class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1>
|
||||
{
|
||||
@ -398,12 +412,11 @@ public:
|
||||
Vec<_Tp, m> operator *() const;
|
||||
};
|
||||
|
||||
/*!
|
||||
Utility methods
|
||||
*/
|
||||
template<typename _Tp, int cn> static Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v);
|
||||
|
||||
//! @} core_basic
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
///////////////////////////////////// helper classes /////////////////////////////////////
|
||||
namespace internal
|
||||
@ -628,7 +641,6 @@ double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
|
||||
return s;
|
||||
}
|
||||
|
||||
/** @cond IGNORED */
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d)
|
||||
{
|
||||
@ -637,7 +649,6 @@ Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d)
|
||||
M(i,i) = d(i, 0);
|
||||
return M;
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
template<typename _Tp, int m, int n> template<typename T2>
|
||||
inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
|
||||
@ -1068,10 +1079,13 @@ Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const
|
||||
return *this->dst;
|
||||
}
|
||||
|
||||
|
||||
//! @endcond
|
||||
|
||||
///////////////////////////// Matx out-of-class operators ////////////////////////////////
|
||||
|
||||
//! @relates cv::Matx
|
||||
//! @{
|
||||
|
||||
template<typename _Tp1, typename _Tp2, int m, int n> static inline
|
||||
Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
|
||||
{
|
||||
@ -1193,10 +1207,13 @@ bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
////////////////////////////// Vec out-of-class operators ////////////////////////////////
|
||||
|
||||
//! @relates cv::Vec
|
||||
//! @{
|
||||
|
||||
template<typename _Tp1, typename _Tp2, int cn> static inline
|
||||
Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
|
||||
{
|
||||
@ -1352,6 +1369,8 @@ template<typename _Tp> inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const V
|
||||
return v1;
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
||||
} // cv
|
||||
|
||||
#endif // __OPENCV_CORE_MATX_HPP__
|
||||
|
@ -46,6 +46,9 @@
|
||||
|
||||
namespace cv { namespace ocl {
|
||||
|
||||
//! @addtogroup core_opencl
|
||||
//! @{
|
||||
|
||||
CV_EXPORTS_W bool haveOpenCL();
|
||||
CV_EXPORTS_W bool useOpenCL();
|
||||
CV_EXPORTS_W bool haveAmdBlas();
|
||||
@ -666,6 +669,8 @@ CV_EXPORTS MatAllocator* getOpenCLAllocator();
|
||||
CV_EXPORTS_W bool isPerformanceCheckBypassed();
|
||||
#define OCL_PERFORMANCE_CHECK(condition) (cv::ocl::isPerformanceCheckBypassed() || (condition))
|
||||
|
||||
//! @}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,8 @@ namespace cv
|
||||
namespace ocl
|
||||
{
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
struct ProgramEntry
|
||||
{
|
||||
const char* name;
|
||||
@ -54,6 +56,8 @@ struct ProgramEntry
|
||||
const char* programHash;
|
||||
};
|
||||
|
||||
//! @endcond
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,12 +51,35 @@
|
||||
|
||||
namespace cv { namespace ogl {
|
||||
|
||||
/** @addtogroup core_opengl
|
||||
This section describes OpenGL interoperability.
|
||||
|
||||
To enable OpenGL support, configure OpenCV using CMake with WITH_OPENGL=ON . Currently OpenGL is
|
||||
supported only with WIN32, GTK and Qt backends on Windows and Linux (MacOS and Android are not
|
||||
supported). For GTK backend gtkglext-1.0 library is required.
|
||||
|
||||
To use OpenGL functionality you should first create OpenGL context (window or frame buffer). You can
|
||||
do this with namedWindow function or with other OpenGL toolkit (GLUT, for example).
|
||||
*/
|
||||
//! @{
|
||||
|
||||
/////////////////// OpenGL Objects ///////////////////
|
||||
|
||||
//! Smart pointer for OpenGL buffer memory with reference counting.
|
||||
/** @brief Smart pointer for OpenGL buffer object with reference counting.
|
||||
|
||||
Buffer Objects are OpenGL objects that store an array of unformatted memory allocated by the OpenGL
|
||||
context. These can be used to store vertex data, pixel data retrieved from images or the
|
||||
framebuffer, and a variety of other things.
|
||||
|
||||
ogl::Buffer has interface similar with Mat interface and represents 2D array memory.
|
||||
|
||||
ogl::Buffer supports memory transfers between host and device and also can be mapped to CUDA memory.
|
||||
*/
|
||||
class CV_EXPORTS Buffer
|
||||
{
|
||||
public:
|
||||
/** @brief The target defines how you intend to use the buffer object.
|
||||
*/
|
||||
enum Target
|
||||
{
|
||||
ARRAY_BUFFER = 0x8892, //!< The buffer will be used as a source for vertex data
|
||||
@ -72,59 +95,163 @@ public:
|
||||
READ_WRITE = 0x88BA
|
||||
};
|
||||
|
||||
//! create empty buffer
|
||||
/** @brief The constructors.
|
||||
|
||||
Creates empty ogl::Buffer object, creates ogl::Buffer object from existed buffer ( abufId
|
||||
parameter), allocates memory for ogl::Buffer object or copies from host/device memory.
|
||||
*/
|
||||
Buffer();
|
||||
|
||||
//! create buffer from existed buffer id
|
||||
/** @overload
|
||||
@param arows Number of rows in a 2D array.
|
||||
@param acols Number of columns in a 2D array.
|
||||
@param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
|
||||
@param abufId Buffer object name.
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
Buffer(int arows, int acols, int atype, unsigned int abufId, bool autoRelease = false);
|
||||
|
||||
/** @overload
|
||||
@param asize 2D array size.
|
||||
@param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
|
||||
@param abufId Buffer object name.
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
Buffer(Size asize, int atype, unsigned int abufId, bool autoRelease = false);
|
||||
|
||||
//! create buffer
|
||||
/** @overload
|
||||
@param arows Number of rows in a 2D array.
|
||||
@param acols Number of columns in a 2D array.
|
||||
@param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
|
||||
@param target Buffer usage. See cv::ogl::Buffer::Target .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
Buffer(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false);
|
||||
|
||||
/** @overload
|
||||
@param asize 2D array size.
|
||||
@param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
|
||||
@param target Buffer usage. See cv::ogl::Buffer::Target .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
Buffer(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false);
|
||||
|
||||
//! copy from host/device memory
|
||||
/** @overload
|
||||
@param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or std::vector ).
|
||||
@param target Buffer usage. See cv::ogl::Buffer::Target .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
explicit Buffer(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false);
|
||||
|
||||
//! create buffer
|
||||
/** @brief Allocates memory for ogl::Buffer object.
|
||||
|
||||
@param arows Number of rows in a 2D array.
|
||||
@param acols Number of columns in a 2D array.
|
||||
@param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
|
||||
@param target Buffer usage. See cv::ogl::Buffer::Target .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
void create(int arows, int acols, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false);
|
||||
|
||||
/** @overload
|
||||
@param asize 2D array size.
|
||||
@param atype Array type ( CV_8UC1, ..., CV_64FC4 ). See Mat for details.
|
||||
@param target Buffer usage. See cv::ogl::Buffer::Target .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
void create(Size asize, int atype, Target target = ARRAY_BUFFER, bool autoRelease = false);
|
||||
|
||||
//! release memory and delete buffer object
|
||||
/** @brief Decrements the reference counter and destroys the buffer object if needed.
|
||||
|
||||
The function will call setAutoRelease(true) .
|
||||
*/
|
||||
void release();
|
||||
|
||||
//! set auto release mode (if true, release will be called in object's destructor)
|
||||
/** @brief Sets auto release mode.
|
||||
|
||||
The lifetime of the OpenGL object is tied to the lifetime of the context. If OpenGL context was
|
||||
bound to a window it could be released at any time (user can close a window). If object's destructor
|
||||
is called after destruction of the context it will cause an error. Thus ogl::Buffer doesn't destroy
|
||||
OpenGL object in destructor by default (all OpenGL resources will be released with OpenGL context).
|
||||
This function can force ogl::Buffer destructor to destroy OpenGL object.
|
||||
@param flag Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
void setAutoRelease(bool flag);
|
||||
|
||||
//! copy from host/device memory (blocking)
|
||||
/** @brief Copies from host/device memory to OpenGL buffer.
|
||||
@param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or std::vector ).
|
||||
@param target Buffer usage. See cv::ogl::Buffer::Target .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
void copyFrom(InputArray arr, Target target = ARRAY_BUFFER, bool autoRelease = false);
|
||||
//! copy from device memory (non blocking)
|
||||
|
||||
/** @overload */
|
||||
void copyFrom(InputArray arr, cuda::Stream& stream, Target target = ARRAY_BUFFER, bool autoRelease = false);
|
||||
|
||||
//! copy to host/device memory (blocking)
|
||||
/** @brief Copies from OpenGL buffer to host/device memory or another OpenGL buffer object.
|
||||
|
||||
@param arr Destination array (host or device memory, can be Mat , cuda::GpuMat , std::vector or
|
||||
ogl::Buffer ).
|
||||
*/
|
||||
void copyTo(OutputArray arr) const;
|
||||
//! copy to device memory (non blocking)
|
||||
|
||||
/** @overload */
|
||||
void copyTo(OutputArray arr, cuda::Stream& stream) const;
|
||||
|
||||
//! create copy of current buffer
|
||||
/** @brief Creates a full copy of the buffer object and the underlying data.
|
||||
|
||||
@param target Buffer usage for destination buffer.
|
||||
@param autoRelease Auto release mode for destination buffer.
|
||||
*/
|
||||
Buffer clone(Target target = ARRAY_BUFFER, bool autoRelease = false) const;
|
||||
|
||||
//! bind buffer for specified target
|
||||
/** @brief Binds OpenGL buffer to the specified buffer binding point.
|
||||
|
||||
@param target Binding point. See cv::ogl::Buffer::Target .
|
||||
*/
|
||||
void bind(Target target) const;
|
||||
|
||||
//! unbind any buffers from specified target
|
||||
/** @brief Unbind any buffers from the specified binding point.
|
||||
|
||||
@param target Binding point. See cv::ogl::Buffer::Target .
|
||||
*/
|
||||
static void unbind(Target target);
|
||||
|
||||
//! map to host memory
|
||||
/** @brief Maps OpenGL buffer to host memory.
|
||||
|
||||
mapHost maps to the client's address space the entire data store of the buffer object. The data can
|
||||
then be directly read and/or written relative to the returned pointer, depending on the specified
|
||||
access policy.
|
||||
|
||||
A mapped data store must be unmapped with ogl::Buffer::unmapHost before its buffer object is used.
|
||||
|
||||
This operation can lead to memory transfers between host and device.
|
||||
|
||||
Only one buffer object can be mapped at a time.
|
||||
@param access Access policy, indicating whether it will be possible to read from, write to, or both
|
||||
read from and write to the buffer object's mapped data store. The symbolic constant must be
|
||||
ogl::Buffer::READ_ONLY , ogl::Buffer::WRITE_ONLY or ogl::Buffer::READ_WRITE .
|
||||
*/
|
||||
Mat mapHost(Access access);
|
||||
|
||||
/** @brief Unmaps OpenGL buffer.
|
||||
*/
|
||||
void unmapHost();
|
||||
|
||||
//! map to device memory (blocking)
|
||||
cuda::GpuMat mapDevice();
|
||||
void unmapDevice();
|
||||
|
||||
//! map to device memory (non blocking)
|
||||
/** @brief Maps OpenGL buffer to CUDA device memory.
|
||||
|
||||
This operatation doesn't copy data. Several buffer objects can be mapped to CUDA memory at a time.
|
||||
|
||||
A mapped data store must be unmapped with ogl::Buffer::unmapDevice before its buffer object is used.
|
||||
*/
|
||||
cuda::GpuMat mapDevice(cuda::Stream& stream);
|
||||
|
||||
/** @brief Unmaps OpenGL buffer.
|
||||
*/
|
||||
void unmapDevice(cuda::Stream& stream);
|
||||
|
||||
int rows() const;
|
||||
@ -150,10 +277,13 @@ private:
|
||||
int type_;
|
||||
};
|
||||
|
||||
//! Smart pointer for OpenGL 2D texture memory with reference counting.
|
||||
/** @brief Smart pointer for OpenGL 2D texture memory with reference counting.
|
||||
*/
|
||||
class CV_EXPORTS Texture2D
|
||||
{
|
||||
public:
|
||||
/** @brief An Image Format describes the way that the images in Textures store their data.
|
||||
*/
|
||||
enum Format
|
||||
{
|
||||
NONE = 0,
|
||||
@ -162,37 +292,91 @@ public:
|
||||
RGBA = 0x1908 //!< Red, Green, Blue, Alpha
|
||||
};
|
||||
|
||||
//! create empty texture
|
||||
/** @brief The constructors.
|
||||
|
||||
Creates empty ogl::Texture2D object, allocates memory for ogl::Texture2D object or copies from
|
||||
host/device memory.
|
||||
*/
|
||||
Texture2D();
|
||||
|
||||
//! create texture from existed texture id
|
||||
/** @overload */
|
||||
Texture2D(int arows, int acols, Format aformat, unsigned int atexId, bool autoRelease = false);
|
||||
|
||||
/** @overload */
|
||||
Texture2D(Size asize, Format aformat, unsigned int atexId, bool autoRelease = false);
|
||||
|
||||
//! create texture
|
||||
/** @overload
|
||||
@param arows Number of rows.
|
||||
@param acols Number of columns.
|
||||
@param aformat Image format. See cv::ogl::Texture2D::Format .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
Texture2D(int arows, int acols, Format aformat, bool autoRelease = false);
|
||||
|
||||
/** @overload
|
||||
@param asize 2D array size.
|
||||
@param aformat Image format. See cv::ogl::Texture2D::Format .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
Texture2D(Size asize, Format aformat, bool autoRelease = false);
|
||||
|
||||
//! copy from host/device memory
|
||||
/** @overload
|
||||
@param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or ogl::Buffer ).
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
explicit Texture2D(InputArray arr, bool autoRelease = false);
|
||||
|
||||
//! create texture
|
||||
/** @brief Allocates memory for ogl::Texture2D object.
|
||||
|
||||
@param arows Number of rows.
|
||||
@param acols Number of columns.
|
||||
@param aformat Image format. See cv::ogl::Texture2D::Format .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
void create(int arows, int acols, Format aformat, bool autoRelease = false);
|
||||
/** @overload
|
||||
@param asize 2D array size.
|
||||
@param aformat Image format. See cv::ogl::Texture2D::Format .
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
void create(Size asize, Format aformat, bool autoRelease = false);
|
||||
|
||||
//! release memory and delete texture object
|
||||
/** @brief Decrements the reference counter and destroys the texture object if needed.
|
||||
|
||||
The function will call setAutoRelease(true) .
|
||||
*/
|
||||
void release();
|
||||
|
||||
//! set auto release mode (if true, release will be called in object's destructor)
|
||||
/** @brief Sets auto release mode.
|
||||
|
||||
@param flag Auto release mode (if true, release will be called in object's destructor).
|
||||
|
||||
The lifetime of the OpenGL object is tied to the lifetime of the context. If OpenGL context was
|
||||
bound to a window it could be released at any time (user can close a window). If object's destructor
|
||||
is called after destruction of the context it will cause an error. Thus ogl::Texture2D doesn't
|
||||
destroy OpenGL object in destructor by default (all OpenGL resources will be released with OpenGL
|
||||
context). This function can force ogl::Texture2D destructor to destroy OpenGL object.
|
||||
*/
|
||||
void setAutoRelease(bool flag);
|
||||
|
||||
//! copy from host/device memory
|
||||
/** @brief Copies from host/device memory to OpenGL texture.
|
||||
|
||||
@param arr Input array (host or device memory, it can be Mat , cuda::GpuMat or ogl::Buffer ).
|
||||
@param autoRelease Auto release mode (if true, release will be called in object's destructor).
|
||||
*/
|
||||
void copyFrom(InputArray arr, bool autoRelease = false);
|
||||
|
||||
//! copy to host/device memory
|
||||
/** @brief Copies from OpenGL texture to host/device memory or another OpenGL texture object.
|
||||
|
||||
@param arr Destination array (host or device memory, can be Mat , cuda::GpuMat , ogl::Buffer or
|
||||
ogl::Texture2D ).
|
||||
@param ddepth Destination depth.
|
||||
@param autoRelease Auto release mode for destination buffer (if arr is OpenGL buffer or texture).
|
||||
*/
|
||||
void copyTo(OutputArray arr, int ddepth = CV_32F, bool autoRelease = false) const;
|
||||
|
||||
//! bind texture to current active texture unit for GL_TEXTURE_2D target
|
||||
/** @brief Binds texture to current active texture unit for GL_TEXTURE_2D target.
|
||||
*/
|
||||
void bind() const;
|
||||
|
||||
int rows() const;
|
||||
@ -214,30 +398,68 @@ private:
|
||||
Format format_;
|
||||
};
|
||||
|
||||
//! OpenGL Arrays
|
||||
/** @brief Wrapper for OpenGL Client-Side Vertex arrays.
|
||||
|
||||
ogl::Arrays stores vertex data in ogl::Buffer objects.
|
||||
*/
|
||||
class CV_EXPORTS Arrays
|
||||
{
|
||||
public:
|
||||
/** @brief Default constructor
|
||||
*/
|
||||
Arrays();
|
||||
|
||||
/** @brief Sets an array of vertex coordinates.
|
||||
@param vertex array with vertex coordinates, can be both host and device memory.
|
||||
*/
|
||||
void setVertexArray(InputArray vertex);
|
||||
|
||||
/** @brief Resets vertex coordinates.
|
||||
*/
|
||||
void resetVertexArray();
|
||||
|
||||
/** @brief Sets an array of vertex colors.
|
||||
@param color array with vertex colors, can be both host and device memory.
|
||||
*/
|
||||
void setColorArray(InputArray color);
|
||||
|
||||
/** @brief Resets vertex colors.
|
||||
*/
|
||||
void resetColorArray();
|
||||
|
||||
/** @brief Sets an array of vertex normals.
|
||||
@param normal array with vertex normals, can be both host and device memory.
|
||||
*/
|
||||
void setNormalArray(InputArray normal);
|
||||
|
||||
/** @brief Resets vertex normals.
|
||||
*/
|
||||
void resetNormalArray();
|
||||
|
||||
/** @brief Sets an array of vertex texture coordinates.
|
||||
@param texCoord array with vertex texture coordinates, can be both host and device memory.
|
||||
*/
|
||||
void setTexCoordArray(InputArray texCoord);
|
||||
|
||||
/** @brief Resets vertex texture coordinates.
|
||||
*/
|
||||
void resetTexCoordArray();
|
||||
|
||||
/** @brief Releases all inner buffers.
|
||||
*/
|
||||
void release();
|
||||
|
||||
/** @brief Sets auto release mode all inner buffers.
|
||||
@param flag Auto release mode.
|
||||
*/
|
||||
void setAutoRelease(bool flag);
|
||||
|
||||
/** @brief Binds all vertex arrays.
|
||||
*/
|
||||
void bind() const;
|
||||
|
||||
/** @brief Returns the vertex count.
|
||||
*/
|
||||
int size() const;
|
||||
bool empty() const;
|
||||
|
||||
@ -251,13 +473,8 @@ private:
|
||||
|
||||
/////////////////// Render Functions ///////////////////
|
||||
|
||||
//! render texture rectangle in window
|
||||
CV_EXPORTS void render(const Texture2D& tex,
|
||||
Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0),
|
||||
Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0));
|
||||
|
||||
//! render mode
|
||||
enum {
|
||||
enum RenderModes {
|
||||
POINTS = 0x0000,
|
||||
LINES = 0x0001,
|
||||
LINE_LOOP = 0x0002,
|
||||
@ -270,19 +487,52 @@ enum {
|
||||
POLYGON = 0x0009
|
||||
};
|
||||
|
||||
//! render OpenGL arrays
|
||||
/** @brief Render OpenGL texture or primitives.
|
||||
@param tex Texture to draw.
|
||||
@param wndRect Region of window, where to draw a texture (normalized coordinates).
|
||||
@param texRect Region of texture to draw (normalized coordinates).
|
||||
*/
|
||||
CV_EXPORTS void render(const Texture2D& tex,
|
||||
Rect_<double> wndRect = Rect_<double>(0.0, 0.0, 1.0, 1.0),
|
||||
Rect_<double> texRect = Rect_<double>(0.0, 0.0, 1.0, 1.0));
|
||||
|
||||
/** @overload
|
||||
@param arr Array of privitives vertices.
|
||||
@param mode Render mode. One of cv::ogl::RenderModes
|
||||
@param color Color for all vertices. Will be used if arr doesn't contain color array.
|
||||
*/
|
||||
CV_EXPORTS void render(const Arrays& arr, int mode = POINTS, Scalar color = Scalar::all(255));
|
||||
|
||||
/** @overload
|
||||
@param arr Array of privitives vertices.
|
||||
@param indices Array of vertices indices (host or device memory).
|
||||
@param mode Render mode. One of cv::ogl::RenderModes
|
||||
@param color Color for all vertices. Will be used if arr doesn't contain color array.
|
||||
*/
|
||||
CV_EXPORTS void render(const Arrays& arr, InputArray indices, int mode = POINTS, Scalar color = Scalar::all(255));
|
||||
|
||||
//! @} core_opengl
|
||||
|
||||
}} // namespace cv::ogl
|
||||
|
||||
namespace cv { namespace cuda {
|
||||
|
||||
//! set a CUDA device to use OpenGL interoperability
|
||||
//! @addtogroup cuda
|
||||
//! @{
|
||||
|
||||
/** @brief Sets a CUDA device and initializes it for the current thread with OpenGL interoperability.
|
||||
|
||||
This function should be explicitly called after OpenGL context creation and before any CUDA calls.
|
||||
@param device System index of a CUDA device starting with 0.
|
||||
@ingroup core_opengl
|
||||
*/
|
||||
CV_EXPORTS void setGlDevice(int device = 0);
|
||||
|
||||
//! @}
|
||||
|
||||
}}
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -429,4 +679,6 @@ bool cv::ogl::Arrays::empty() const
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif /* __OPENCV_CORE_OPENGL_HPP__ */
|
||||
|
@ -49,6 +49,8 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@ -525,7 +527,116 @@ void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, Ptr<_Tp>& v
|
||||
(Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
|
||||
}
|
||||
|
||||
//! @endcond
|
||||
|
||||
/****************************************************************************************\
|
||||
* Auxiliary algorithms *
|
||||
\****************************************************************************************/
|
||||
|
||||
/** @brief Splits an element set into equivalency classes.
|
||||
|
||||
The generic function partition implements an \f$O(N^2)\f$ algorithm for splitting a set of \f$N\f$ elements
|
||||
into one or more equivalency classes, as described in
|
||||
<http://en.wikipedia.org/wiki/Disjoint-set_data_structure> . The function returns the number of
|
||||
equivalency classes.
|
||||
@param _vec Set of elements stored as a vector.
|
||||
@param labels Output vector of labels. It contains as many elements as vec. Each label labels[i] is
|
||||
a 0-based cluster index of `vec[i]`.
|
||||
@param predicate Equivalence predicate (pointer to a boolean function of two arguments or an
|
||||
instance of the class that has the method bool operator()(const _Tp& a, const _Tp& b) ). The
|
||||
predicate returns true when the elements are certainly in the same class, and returns false if they
|
||||
may or may not be in the same class.
|
||||
@ingroup core_cluster
|
||||
*/
|
||||
template<typename _Tp, class _EqPredicate> int
|
||||
partition( const std::vector<_Tp>& _vec, std::vector<int>& labels,
|
||||
_EqPredicate predicate=_EqPredicate())
|
||||
{
|
||||
int i, j, N = (int)_vec.size();
|
||||
const _Tp* vec = &_vec[0];
|
||||
|
||||
const int PARENT=0;
|
||||
const int RANK=1;
|
||||
|
||||
std::vector<int> _nodes(N*2);
|
||||
int (*nodes)[2] = (int(*)[2])&_nodes[0];
|
||||
|
||||
// The first O(N) pass: create N single-vertex trees
|
||||
for(i = 0; i < N; i++)
|
||||
{
|
||||
nodes[i][PARENT]=-1;
|
||||
nodes[i][RANK] = 0;
|
||||
}
|
||||
|
||||
// The main O(N^2) pass: merge connected components
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
int root = i;
|
||||
|
||||
// find root
|
||||
while( nodes[root][PARENT] >= 0 )
|
||||
root = nodes[root][PARENT];
|
||||
|
||||
for( j = 0; j < N; j++ )
|
||||
{
|
||||
if( i == j || !predicate(vec[i], vec[j]))
|
||||
continue;
|
||||
int root2 = j;
|
||||
|
||||
while( nodes[root2][PARENT] >= 0 )
|
||||
root2 = nodes[root2][PARENT];
|
||||
|
||||
if( root2 != root )
|
||||
{
|
||||
// unite both trees
|
||||
int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
|
||||
if( rank > rank2 )
|
||||
nodes[root2][PARENT] = root;
|
||||
else
|
||||
{
|
||||
nodes[root][PARENT] = root2;
|
||||
nodes[root2][RANK] += rank == rank2;
|
||||
root = root2;
|
||||
}
|
||||
CV_Assert( nodes[root][PARENT] < 0 );
|
||||
|
||||
int k = j, parent;
|
||||
|
||||
// compress the path from node2 to root
|
||||
while( (parent = nodes[k][PARENT]) >= 0 )
|
||||
{
|
||||
nodes[k][PARENT] = root;
|
||||
k = parent;
|
||||
}
|
||||
|
||||
// compress the path from node to root
|
||||
k = i;
|
||||
while( (parent = nodes[k][PARENT]) >= 0 )
|
||||
{
|
||||
nodes[k][PARENT] = root;
|
||||
k = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Final O(N) pass: enumerate classes
|
||||
labels.resize(N);
|
||||
int nclasses = 0;
|
||||
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
int root = i;
|
||||
while( nodes[root][PARENT] >= 0 )
|
||||
root = nodes[root][PARENT];
|
||||
// re-use the rank as the class label
|
||||
if( nodes[root][RANK] >= 0 )
|
||||
nodes[root][RANK] = ~nclasses++;
|
||||
labels[i] = ~nodes[root][RANK];
|
||||
}
|
||||
|
||||
return nclasses;
|
||||
}
|
||||
|
||||
} // cv
|
||||
|
||||
|
@ -47,9 +47,19 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
/** @addtogroup core_optim
|
||||
The algorithms in this section minimize or maximize function value within specified constraints or
|
||||
without any constraints.
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @brief Basic interface for all solvers
|
||||
*/
|
||||
class CV_EXPORTS MinProblemSolver : public Algorithm
|
||||
{
|
||||
public:
|
||||
/** @brief Represents function being optimized
|
||||
*/
|
||||
class CV_EXPORTS Function
|
||||
{
|
||||
public:
|
||||
@ -58,54 +68,233 @@ public:
|
||||
virtual void getGradient(const double* /*x*/,double* /*grad*/) {}
|
||||
};
|
||||
|
||||
/** @brief Getter for the optimized function.
|
||||
|
||||
The optimized function is represented by Function interface, which requires derivatives to
|
||||
implement the sole method calc(double*) to evaluate the function.
|
||||
|
||||
@return Smart-pointer to an object that implements Function interface - it represents the
|
||||
function that is being optimized. It can be empty, if no function was given so far.
|
||||
*/
|
||||
virtual Ptr<Function> getFunction() const = 0;
|
||||
|
||||
/** @brief Setter for the optimized function.
|
||||
|
||||
*It should be called at least once before the call to* minimize(), as default value is not usable.
|
||||
|
||||
@param f The new function to optimize.
|
||||
*/
|
||||
virtual void setFunction(const Ptr<Function>& f) = 0;
|
||||
|
||||
/** @brief Getter for the previously set terminal criteria for this algorithm.
|
||||
|
||||
@return Deep copy of the terminal criteria used at the moment.
|
||||
*/
|
||||
virtual TermCriteria getTermCriteria() const = 0;
|
||||
|
||||
/** @brief Set terminal criteria for solver.
|
||||
|
||||
This method *is not necessary* to be called before the first call to minimize(), as the default
|
||||
value is sensible.
|
||||
|
||||
Algorithm stops when the number of function evaluations done exceeds termcrit.maxCount, when
|
||||
the function values at the vertices of simplex are within termcrit.epsilon range or simplex
|
||||
becomes so small that it can enclosed in a box with termcrit.epsilon sides, whatever comes
|
||||
first.
|
||||
@param termcrit Terminal criteria to be used, represented as cv::TermCriteria structure.
|
||||
*/
|
||||
virtual void setTermCriteria(const TermCriteria& termcrit) = 0;
|
||||
|
||||
// x contain the initial point before the call and the minima position (if algorithm converged) after. x is assumed to be (something that
|
||||
// after getMat() will return) row-vector or column-vector. *It's size and should
|
||||
// be consisted with previous dimensionality data given, if any (otherwise, it determines dimensionality)*
|
||||
/** @brief actually runs the algorithm and performs the minimization.
|
||||
|
||||
The sole input parameter determines the centroid of the starting simplex (roughly, it tells
|
||||
where to start), all the others (terminal criteria, initial step, function to be minimized) are
|
||||
supposed to be set via the setters before the call to this method or the default values (not
|
||||
always sensible) will be used.
|
||||
|
||||
@param x The initial point, that will become a centroid of an initial simplex. After the algorithm
|
||||
will terminate, it will be setted to the point where the algorithm stops, the point of possible
|
||||
minimum.
|
||||
@return The value of a function at the point found.
|
||||
*/
|
||||
virtual double minimize(InputOutputArray x) = 0;
|
||||
};
|
||||
|
||||
//! downhill simplex class
|
||||
/** @brief This class is used to perform the non-linear non-constrained minimization of a function,
|
||||
|
||||
defined on an `n`-dimensional Euclidean space, using the **Nelder-Mead method**, also known as
|
||||
**downhill simplex method**. The basic idea about the method can be obtained from
|
||||
<http://en.wikipedia.org/wiki/Nelder-Mead_method>.
|
||||
|
||||
It should be noted, that this method, although deterministic, is rather a heuristic and therefore
|
||||
may converge to a local minima, not necessary a global one. It is iterative optimization technique,
|
||||
which at each step uses an information about the values of a function evaluated only at `n+1`
|
||||
points, arranged as a *simplex* in `n`-dimensional space (hence the second name of the method). At
|
||||
each step new point is chosen to evaluate function at, obtained value is compared with previous
|
||||
ones and based on this information simplex changes it's shape , slowly moving to the local minimum.
|
||||
Thus this method is using *only* function values to make decision, on contrary to, say, Nonlinear
|
||||
Conjugate Gradient method (which is also implemented in optim).
|
||||
|
||||
Algorithm stops when the number of function evaluations done exceeds termcrit.maxCount, when the
|
||||
function values at the vertices of simplex are within termcrit.epsilon range or simplex becomes so
|
||||
small that it can enclosed in a box with termcrit.epsilon sides, whatever comes first, for some
|
||||
defined by user positive integer termcrit.maxCount and positive non-integer termcrit.epsilon.
|
||||
|
||||
@note DownhillSolver is a derivative of the abstract interface
|
||||
cv::MinProblemSolver, which in turn is derived from the Algorithm interface and is used to
|
||||
encapsulate the functionality, common to all non-linear optimization algorithms in the optim
|
||||
module.
|
||||
|
||||
@note term criteria should meet following condition:
|
||||
@code
|
||||
termcrit.type == (TermCriteria::MAX_ITER + TermCriteria::EPS) && termcrit.epsilon > 0 && termcrit.maxCount > 0
|
||||
@endcode
|
||||
*/
|
||||
class CV_EXPORTS DownhillSolver : public MinProblemSolver
|
||||
{
|
||||
public:
|
||||
//! returns row-vector, even if the column-vector was given
|
||||
/** @brief Returns the initial step that will be used in downhill simplex algorithm.
|
||||
|
||||
@param step Initial step that will be used in algorithm. Note, that although corresponding setter
|
||||
accepts column-vectors as well as row-vectors, this method will return a row-vector.
|
||||
@see DownhillSolver::setInitStep
|
||||
*/
|
||||
virtual void getInitStep(OutputArray step) const=0;
|
||||
//!This should be called at least once before the first call to minimize() and step is assumed to be (something that
|
||||
//! after getMat() will return) row-vector or column-vector. *It's dimensionality determines the dimensionality of a problem.*
|
||||
|
||||
/** @brief Sets the initial step that will be used in downhill simplex algorithm.
|
||||
|
||||
Step, together with initial point (givin in DownhillSolver::minimize) are two `n`-dimensional
|
||||
vectors that are used to determine the shape of initial simplex. Roughly said, initial point
|
||||
determines the position of a simplex (it will become simplex's centroid), while step determines the
|
||||
spread (size in each dimension) of a simplex. To be more precise, if \f$s,x_0\in\mathbb{R}^n\f$ are
|
||||
the initial step and initial point respectively, the vertices of a simplex will be:
|
||||
\f$v_0:=x_0-\frac{1}{2} s\f$ and \f$v_i:=x_0+s_i\f$ for \f$i=1,2,\dots,n\f$ where \f$s_i\f$ denotes
|
||||
projections of the initial step of *n*-th coordinate (the result of projection is treated to be
|
||||
vector given by \f$s_i:=e_i\cdot\left<e_i\cdot s\right>\f$, where \f$e_i\f$ form canonical basis)
|
||||
|
||||
@param step Initial step that will be used in algorithm. Roughly said, it determines the spread
|
||||
(size in each dimension) of an initial simplex.
|
||||
*/
|
||||
virtual void setInitStep(InputArray step)=0;
|
||||
|
||||
// both minRange & minError are specified by termcrit.epsilon;
|
||||
// In addition, user may specify the number of iterations that the algorithm does.
|
||||
/** @brief This function returns the reference to the ready-to-use DownhillSolver object.
|
||||
|
||||
All the parameters are optional, so this procedure can be called even without parameters at
|
||||
all. In this case, the default values will be used. As default value for terminal criteria are
|
||||
the only sensible ones, MinProblemSolver::setFunction() and DownhillSolver::setInitStep()
|
||||
should be called upon the obtained object, if the respective parameters were not given to
|
||||
create(). Otherwise, the two ways (give parameters to createDownhillSolver() or miss them out
|
||||
and call the MinProblemSolver::setFunction() and DownhillSolver::setInitStep()) are absolutely
|
||||
equivalent (and will drop the same errors in the same way, should invalid input be detected).
|
||||
@param f Pointer to the function that will be minimized, similarly to the one you submit via
|
||||
MinProblemSolver::setFunction.
|
||||
@param initStep Initial step, that will be used to construct the initial simplex, similarly to the one
|
||||
you submit via MinProblemSolver::setInitStep.
|
||||
@param termcrit Terminal criteria to the algorithm, similarly to the one you submit via
|
||||
MinProblemSolver::setTermCriteria.
|
||||
*/
|
||||
static Ptr<DownhillSolver> create(const Ptr<MinProblemSolver::Function>& f=Ptr<MinProblemSolver::Function>(),
|
||||
InputArray initStep=Mat_<double>(1,1,0.0),
|
||||
TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001));
|
||||
};
|
||||
|
||||
//! conjugate gradient method
|
||||
/** @brief This class is used to perform the non-linear non-constrained minimization of a function
|
||||
with known gradient,
|
||||
|
||||
defined on an *n*-dimensional Euclidean space, using the **Nonlinear Conjugate Gradient method**.
|
||||
The implementation was done based on the beautifully clear explanatory article [An Introduction to
|
||||
the Conjugate Gradient Method Without the Agonizing
|
||||
Pain](http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf) by Jonathan Richard
|
||||
Shewchuk. The method can be seen as an adaptation of a standard Conjugate Gradient method (see, for
|
||||
example <http://en.wikipedia.org/wiki/Conjugate_gradient_method>) for numerically solving the
|
||||
systems of linear equations.
|
||||
|
||||
It should be noted, that this method, although deterministic, is rather a heuristic method and
|
||||
therefore may converge to a local minima, not necessary a global one. What is even more disastrous,
|
||||
most of its behaviour is ruled by gradient, therefore it essentially cannot distinguish between
|
||||
local minima and maxima. Therefore, if it starts sufficiently near to the local maximum, it may
|
||||
converge to it. Another obvious restriction is that it should be possible to compute the gradient of
|
||||
a function at any point, thus it is preferable to have analytic expression for gradient and
|
||||
computational burden should be born by the user.
|
||||
|
||||
The latter responsibility is accompilished via the getGradient method of a
|
||||
MinProblemSolver::Function interface (which represents function being optimized). This method takes
|
||||
point a point in *n*-dimensional space (first argument represents the array of coordinates of that
|
||||
point) and comput its gradient (it should be stored in the second argument as an array).
|
||||
|
||||
@note class ConjGradSolver thus does not add any new methods to the basic MinProblemSolver interface.
|
||||
|
||||
@note term criteria should meet following condition:
|
||||
@code
|
||||
termcrit.type == (TermCriteria::MAX_ITER + TermCriteria::EPS) && termcrit.epsilon > 0 && termcrit.maxCount > 0
|
||||
// or
|
||||
termcrit.type == TermCriteria::MAX_ITER) && termcrit.maxCount > 0
|
||||
@endcode
|
||||
*/
|
||||
class CV_EXPORTS ConjGradSolver : public MinProblemSolver
|
||||
{
|
||||
public:
|
||||
/** @brief This function returns the reference to the ready-to-use ConjGradSolver object.
|
||||
|
||||
All the parameters are optional, so this procedure can be called even without parameters at
|
||||
all. In this case, the default values will be used. As default value for terminal criteria are
|
||||
the only sensible ones, MinProblemSolver::setFunction() should be called upon the obtained
|
||||
object, if the function was not given to create(). Otherwise, the two ways (submit it to
|
||||
create() or miss it out and call the MinProblemSolver::setFunction()) are absolutely equivalent
|
||||
(and will drop the same errors in the same way, should invalid input be detected).
|
||||
@param f Pointer to the function that will be minimized, similarly to the one you submit via
|
||||
MinProblemSolver::setFunction.
|
||||
@param termcrit Terminal criteria to the algorithm, similarly to the one you submit via
|
||||
MinProblemSolver::setTermCriteria.
|
||||
*/
|
||||
static Ptr<ConjGradSolver> create(const Ptr<MinProblemSolver::Function>& f=Ptr<ConjGradSolver::Function>(),
|
||||
TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001));
|
||||
};
|
||||
|
||||
//!the return codes for solveLP() function
|
||||
enum
|
||||
//! return codes for cv::solveLP() function
|
||||
enum SolveLPResult
|
||||
{
|
||||
SOLVELP_UNBOUNDED = -2, //problem is unbounded (target function can achieve arbitrary high values)
|
||||
SOLVELP_UNFEASIBLE = -1, //problem is unfeasible (there are no points that satisfy all the constraints imposed)
|
||||
SOLVELP_SINGLE = 0, //there is only one maximum for target function
|
||||
SOLVELP_MULTI = 1 //there are multiple maxima for target function - the arbitrary one is returned
|
||||
SOLVELP_UNBOUNDED = -2, //!< problem is unbounded (target function can achieve arbitrary high values)
|
||||
SOLVELP_UNFEASIBLE = -1, //!< problem is unfeasible (there are no points that satisfy all the constraints imposed)
|
||||
SOLVELP_SINGLE = 0, //!< there is only one maximum for target function
|
||||
SOLVELP_MULTI = 1 //!< there are multiple maxima for target function - the arbitrary one is returned
|
||||
};
|
||||
|
||||
/** @brief Solve given (non-integer) linear programming problem using the Simplex Algorithm (Simplex Method).
|
||||
|
||||
What we mean here by "linear programming problem" (or LP problem, for short) can be formulated as:
|
||||
|
||||
\f[\mbox{Maximize } c\cdot x\\
|
||||
\mbox{Subject to:}\\
|
||||
Ax\leq b\\
|
||||
x\geq 0\f]
|
||||
|
||||
Where \f$c\f$ is fixed `1`-by-`n` row-vector, \f$A\f$ is fixed `m`-by-`n` matrix, \f$b\f$ is fixed `m`-by-`1`
|
||||
column vector and \f$x\f$ is an arbitrary `n`-by-`1` column vector, which satisfies the constraints.
|
||||
|
||||
Simplex algorithm is one of many algorithms that are designed to handle this sort of problems
|
||||
efficiently. Although it is not optimal in theoretical sense (there exist algorithms that can solve
|
||||
any problem written as above in polynomial type, while simplex method degenerates to exponential
|
||||
time for some special cases), it is well-studied, easy to implement and is shown to work well for
|
||||
real-life purposes.
|
||||
|
||||
The particular implementation is taken almost verbatim from **Introduction to Algorithms, third
|
||||
edition** by T. H. Cormen, C. E. Leiserson, R. L. Rivest and Clifford Stein. In particular, the
|
||||
Bland's rule <http://en.wikipedia.org/wiki/Bland%27s_rule> is used to prevent cycling.
|
||||
|
||||
@param Func This row-vector corresponds to \f$c\f$ in the LP problem formulation (see above). It should
|
||||
contain 32- or 64-bit floating point numbers. As a convenience, column-vector may be also submitted,
|
||||
in the latter case it is understood to correspond to \f$c^T\f$.
|
||||
@param Constr `m`-by-`n+1` matrix, whose rightmost column corresponds to \f$b\f$ in formulation above
|
||||
and the remaining to \f$A\f$. It should containt 32- or 64-bit floating point numbers.
|
||||
@param z The solution will be returned here as a column-vector - it corresponds to \f$c\f$ in the
|
||||
formulation above. It will contain 64-bit floating point numbers.
|
||||
@return One of cv::SolveLPResult
|
||||
*/
|
||||
CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z);
|
||||
|
||||
//! @}
|
||||
|
||||
}// cv
|
||||
|
||||
#endif
|
||||
|
@ -48,131 +48,268 @@
|
||||
# error persistence.hpp header must be compiled as C++
|
||||
#endif
|
||||
|
||||
// black-box structures used by FileStorage
|
||||
//! @addtogroup core_c
|
||||
//! @{
|
||||
|
||||
/** @brief "black box" representation of the file storage associated with a file on disk.
|
||||
|
||||
Several functions that are described below take CvFileStorage\* as inputs and allow the user to
|
||||
save or to load hierarchical collections that consist of scalar values, standard CXCore objects
|
||||
(such as matrices, sequences, graphs), and user-defined objects.
|
||||
|
||||
OpenCV can read and write data in XML (<http://www.w3c.org/XML>) or YAML (<http://www.yaml.org>)
|
||||
formats. Below is an example of 3x3 floating-point identity matrix A, stored in XML and YAML files
|
||||
using CXCore functions:
|
||||
XML:
|
||||
@code{.xml}
|
||||
<?xml version="1.0">
|
||||
<opencv_storage>
|
||||
<A type_id="opencv-matrix">
|
||||
<rows>3</rows>
|
||||
<cols>3</cols>
|
||||
<dt>f</dt>
|
||||
<data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data>
|
||||
</A>
|
||||
</opencv_storage>
|
||||
@endcode
|
||||
YAML:
|
||||
@code{.yaml}
|
||||
%YAML:1.0
|
||||
A: !!opencv-matrix
|
||||
rows: 3
|
||||
cols: 3
|
||||
dt: f
|
||||
data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]
|
||||
@endcode
|
||||
As it can be seen from the examples, XML uses nested tags to represent hierarchy, while YAML uses
|
||||
indentation for that purpose (similar to the Python programming language).
|
||||
|
||||
The same functions can read and write data in both formats; the particular format is determined by
|
||||
the extension of the opened file, ".xml" for XML files and ".yml" or ".yaml" for YAML.
|
||||
*/
|
||||
typedef struct CvFileStorage CvFileStorage;
|
||||
typedef struct CvFileNode CvFileNode;
|
||||
|
||||
//! @} core_c
|
||||
|
||||
#include "opencv2/core/types.hpp"
|
||||
#include "opencv2/core/mat.hpp"
|
||||
|
||||
namespace cv {
|
||||
|
||||
/** @addtogroup core_xml
|
||||
|
||||
XML/YAML file storages. {#xml_storage}
|
||||
=======================
|
||||
Writing to a file storage.
|
||||
--------------------------
|
||||
You can store and then restore various OpenCV data structures to/from XML (<http://www.w3c.org/XML>)
|
||||
or YAML (<http://www.yaml.org>) formats. Also, it is possible store and load arbitrarily complex
|
||||
data structures, which include OpenCV data structures, as well as primitive data types (integer and
|
||||
floating-point numbers and text strings) as their elements.
|
||||
|
||||
Use the following procedure to write something to XML or YAML:
|
||||
-# Create new FileStorage and open it for writing. It can be done with a single call to
|
||||
FileStorage::FileStorage constructor that takes a filename, or you can use the default constructor
|
||||
and then call FileStorage::open. Format of the file (XML or YAML) is determined from the filename
|
||||
extension (".xml" and ".yml"/".yaml", respectively)
|
||||
-# Write all the data you want using the streaming operator `<<`, just like in the case of STL
|
||||
streams.
|
||||
-# Close the file using FileStorage::release. FileStorage destructor also closes the file.
|
||||
|
||||
Here is an example:
|
||||
@code
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include <time.h>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int main(int, char** argv)
|
||||
{
|
||||
FileStorage fs("test.yml", FileStorage::WRITE);
|
||||
|
||||
fs << "frameCount" << 5;
|
||||
time_t rawtime; time(&rawtime);
|
||||
fs << "calibrationDate" << asctime(localtime(&rawtime));
|
||||
Mat cameraMatrix = (Mat_<double>(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
|
||||
Mat distCoeffs = (Mat_<double>(5,1) << 0.1, 0.01, -0.001, 0, 0);
|
||||
fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;
|
||||
fs << "features" << "[";
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
int x = rand() % 640;
|
||||
int y = rand() % 480;
|
||||
uchar lbp = rand() % 256;
|
||||
|
||||
fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
|
||||
for( int j = 0; j < 8; j++ )
|
||||
fs << ((lbp >> j) & 1);
|
||||
fs << "]" << "}";
|
||||
}
|
||||
fs << "]";
|
||||
fs.release();
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
The sample above stores to XML and integer, text string (calibration date), 2 matrices, and a custom
|
||||
structure "feature", which includes feature coordinates and LBP (local binary pattern) value. Here
|
||||
is output of the sample:
|
||||
@code{.yaml}
|
||||
%YAML:1.0
|
||||
frameCount: 5
|
||||
calibrationDate: "Fri Jun 17 14:09:29 2011\n"
|
||||
cameraMatrix: !!opencv-matrix
|
||||
rows: 3
|
||||
cols: 3
|
||||
dt: d
|
||||
data: [ 1000., 0., 320., 0., 1000., 240., 0., 0., 1. ]
|
||||
distCoeffs: !!opencv-matrix
|
||||
rows: 5
|
||||
cols: 1
|
||||
dt: d
|
||||
data: [ 1.0000000000000001e-01, 1.0000000000000000e-02,
|
||||
-1.0000000000000000e-03, 0., 0. ]
|
||||
features:
|
||||
- { x:167, y:49, lbp:[ 1, 0, 0, 1, 1, 0, 1, 1 ] }
|
||||
- { x:298, y:130, lbp:[ 0, 0, 0, 1, 0, 0, 1, 1 ] }
|
||||
- { x:344, y:158, lbp:[ 1, 1, 0, 0, 0, 0, 1, 0 ] }
|
||||
@endcode
|
||||
|
||||
As an exercise, you can replace ".yml" with ".xml" in the sample above and see, how the
|
||||
corresponding XML file will look like.
|
||||
|
||||
Several things can be noted by looking at the sample code and the output:
|
||||
|
||||
- The produced YAML (and XML) consists of heterogeneous collections that can be nested. There are 2
|
||||
types of collections: named collections (mappings) and unnamed collections (sequences). In mappings
|
||||
each element has a name and is accessed by name. This is similar to structures and std::map in
|
||||
C/C++ and dictionaries in Python. In sequences elements do not have names, they are accessed by
|
||||
indices. This is similar to arrays and std::vector in C/C++ and lists, tuples in Python.
|
||||
"Heterogeneous" means that elements of each single collection can have different types.
|
||||
|
||||
Top-level collection in YAML/XML is a mapping. Each matrix is stored as a mapping, and the matrix
|
||||
elements are stored as a sequence. Then, there is a sequence of features, where each feature is
|
||||
represented a mapping, and lbp value in a nested sequence.
|
||||
|
||||
- When you write to a mapping (a structure), you write element name followed by its value. When you
|
||||
write to a sequence, you simply write the elements one by one. OpenCV data structures (such as
|
||||
cv::Mat) are written in absolutely the same way as simple C data structures - using `<<`
|
||||
operator.
|
||||
|
||||
- To write a mapping, you first write the special string `{` to the storage, then write the
|
||||
elements as pairs (`fs << <element_name> << <element_value>`) and then write the closing
|
||||
`}`.
|
||||
|
||||
- To write a sequence, you first write the special string `[`, then write the elements, then
|
||||
write the closing `]`.
|
||||
|
||||
- In YAML (but not XML), mappings and sequences can be written in a compact Python-like inline
|
||||
form. In the sample above matrix elements, as well as each feature, including its lbp value, is
|
||||
stored in such inline form. To store a mapping/sequence in a compact form, put `:` after the
|
||||
opening character, e.g. use `{:` instead of `{` and `[:` instead of `[`. When the
|
||||
data is written to XML, those extra `:` are ignored.
|
||||
|
||||
Reading data from a file storage.
|
||||
---------------------------------
|
||||
To read the previously written XML or YAML file, do the following:
|
||||
-# Open the file storage using FileStorage::FileStorage constructor or FileStorage::open method.
|
||||
In the current implementation the whole file is parsed and the whole representation of file
|
||||
storage is built in memory as a hierarchy of file nodes (see FileNode)
|
||||
|
||||
-# Read the data you are interested in. Use FileStorage::operator [], FileNode::operator []
|
||||
and/or FileNodeIterator.
|
||||
|
||||
-# Close the storage using FileStorage::release.
|
||||
|
||||
Here is how to read the file created by the code sample above:
|
||||
@code
|
||||
FileStorage fs2("test.yml", FileStorage::READ);
|
||||
|
||||
// first method: use (type) operator on FileNode.
|
||||
int frameCount = (int)fs2["frameCount"];
|
||||
|
||||
String date;
|
||||
// second method: use FileNode::operator >>
|
||||
fs2["calibrationDate"] >> date;
|
||||
|
||||
Mat cameraMatrix2, distCoeffs2;
|
||||
fs2["cameraMatrix"] >> cameraMatrix2;
|
||||
fs2["distCoeffs"] >> distCoeffs2;
|
||||
|
||||
cout << "frameCount: " << frameCount << endl
|
||||
<< "calibration date: " << date << endl
|
||||
<< "camera matrix: " << cameraMatrix2 << endl
|
||||
<< "distortion coeffs: " << distCoeffs2 << endl;
|
||||
|
||||
FileNode features = fs2["features"];
|
||||
FileNodeIterator it = features.begin(), it_end = features.end();
|
||||
int idx = 0;
|
||||
std::vector<uchar> lbpval;
|
||||
|
||||
// iterate through a sequence using FileNodeIterator
|
||||
for( ; it != it_end; ++it, idx++ )
|
||||
{
|
||||
cout << "feature #" << idx << ": ";
|
||||
cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
|
||||
// you can also easily read numerical arrays using FileNode >> std::vector operator.
|
||||
(*it)["lbp"] >> lbpval;
|
||||
for( int i = 0; i < (int)lbpval.size(); i++ )
|
||||
cout << " " << (int)lbpval[i];
|
||||
cout << ")" << endl;
|
||||
}
|
||||
fs.release();
|
||||
@endcode
|
||||
|
||||
Format specification {#format_spec}
|
||||
--------------------
|
||||
`([count]{u|c|w|s|i|f|d})`... where the characters correspond to fundamental C++ types:
|
||||
- `u` 8-bit unsigned number
|
||||
- `c` 8-bit signed number
|
||||
- `w` 16-bit unsigned number
|
||||
- `s` 16-bit signed number
|
||||
- `i` 32-bit signed number
|
||||
- `f` single precision floating-point number
|
||||
- `d` double precision floating-point number
|
||||
- `r` pointer, 32 lower bits of which are written as a signed integer. The type can be used to
|
||||
store structures with links between the elements.
|
||||
|
||||
`count` is the optional counter of values of a given type. For example, `2if` means that each array
|
||||
element is a structure of 2 integers, followed by a single-precision floating-point number. The
|
||||
equivalent notations of the above specification are `iif`, `2i1f` and so forth. Other examples: `u`
|
||||
means that the array consists of bytes, and `2d` means the array consists of pairs of doubles.
|
||||
|
||||
@see @ref filestorage.cpp
|
||||
*/
|
||||
|
||||
//! @{
|
||||
|
||||
/** @example filestorage.cpp
|
||||
A complete example using the FileStorage interface
|
||||
*/
|
||||
|
||||
////////////////////////// XML & YAML I/O //////////////////////////
|
||||
|
||||
class CV_EXPORTS FileNode;
|
||||
class CV_EXPORTS FileNodeIterator;
|
||||
|
||||
/*!
|
||||
XML/YAML File Storage Class.
|
||||
|
||||
The class describes an object associated with XML or YAML file.
|
||||
It can be used to store data to such a file or read and decode the data.
|
||||
|
||||
The storage is organized as a tree of nested sequences (or lists) and mappings.
|
||||
Sequence is a heterogenious array, which elements are accessed by indices or sequentially using an iterator.
|
||||
Mapping is analogue of std::map or C structure, which elements are accessed by names.
|
||||
The most top level structure is a mapping.
|
||||
Leaves of the file storage tree are integers, floating-point numbers and text strings.
|
||||
|
||||
For example, the following code:
|
||||
|
||||
\code
|
||||
// open file storage for writing. Type of the file is determined from the extension
|
||||
FileStorage fs("test.yml", FileStorage::WRITE);
|
||||
fs << "test_int" << 5 << "test_real" << 3.1 << "test_string" << "ABCDEFGH";
|
||||
fs << "test_mat" << Mat::eye(3,3,CV_32F);
|
||||
|
||||
fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" <<
|
||||
"{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]";
|
||||
fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
|
||||
|
||||
const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
|
||||
fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
|
||||
|
||||
fs << "]" << "}";
|
||||
\endcode
|
||||
|
||||
will produce the following file:
|
||||
|
||||
\verbatim
|
||||
%YAML:1.0
|
||||
test_int: 5
|
||||
test_real: 3.1000000000000001e+00
|
||||
test_string: ABCDEFGH
|
||||
test_mat: !!opencv-matrix
|
||||
rows: 3
|
||||
cols: 3
|
||||
dt: f
|
||||
data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1. ]
|
||||
test_list:
|
||||
- 1.0000000000000000e-13
|
||||
- 2
|
||||
- 3.1415926535897931e+00
|
||||
- -3435345
|
||||
- "2-502 2-029 3egegeg"
|
||||
- { month:12, day:31, year:1969 }
|
||||
test_map:
|
||||
x: 1
|
||||
y: 2
|
||||
width: 100
|
||||
height: 200
|
||||
lbp: [ 0, 1, 1, 0, 1, 1, 0, 1 ]
|
||||
\endverbatim
|
||||
|
||||
and to read the file above, the following code can be used:
|
||||
|
||||
\code
|
||||
// open file storage for reading.
|
||||
// Type of the file is determined from the content, not the extension
|
||||
FileStorage fs("test.yml", FileStorage::READ);
|
||||
int test_int = (int)fs["test_int"];
|
||||
double test_real = (double)fs["test_real"];
|
||||
String test_string = (String)fs["test_string"];
|
||||
|
||||
Mat M;
|
||||
fs["test_mat"] >> M;
|
||||
|
||||
FileNode tl = fs["test_list"];
|
||||
CV_Assert(tl.type() == FileNode::SEQ && tl.size() == 6);
|
||||
double tl0 = (double)tl[0];
|
||||
int tl1 = (int)tl[1];
|
||||
double tl2 = (double)tl[2];
|
||||
int tl3 = (int)tl[3];
|
||||
String tl4 = (String)tl[4];
|
||||
CV_Assert(tl[5].type() == FileNode::MAP && tl[5].size() == 3);
|
||||
|
||||
int month = (int)tl[5]["month"];
|
||||
int day = (int)tl[5]["day"];
|
||||
int year = (int)tl[5]["year"];
|
||||
|
||||
FileNode tm = fs["test_map"];
|
||||
|
||||
int x = (int)tm["x"];
|
||||
int y = (int)tm["y"];
|
||||
int width = (int)tm["width"];
|
||||
int height = (int)tm["height"];
|
||||
|
||||
int lbp_val = 0;
|
||||
FileNodeIterator it = tm["lbp"].begin();
|
||||
|
||||
for(int k = 0; k < 8; k++, ++it)
|
||||
lbp_val |= ((int)*it) << k;
|
||||
\endcode
|
||||
*/
|
||||
/** @brief XML/YAML file storage class that encapsulates all the information necessary for writing or reading
|
||||
data to/from a file.
|
||||
*/
|
||||
class CV_EXPORTS_W FileStorage
|
||||
{
|
||||
public:
|
||||
//! file storage mode
|
||||
enum
|
||||
enum Mode
|
||||
{
|
||||
READ = 0, //! read mode
|
||||
WRITE = 1, //! write mode
|
||||
APPEND = 2, //! append mode
|
||||
MEMORY = 4,
|
||||
FORMAT_MASK = (7<<3),
|
||||
FORMAT_AUTO = 0,
|
||||
FORMAT_XML = (1<<3),
|
||||
FORMAT_YAML = (2<<3)
|
||||
READ = 0, //!< value, open the file for reading
|
||||
WRITE = 1, //!< value, open the file for writing
|
||||
APPEND = 2, //!< value, open the file for appending
|
||||
MEMORY = 4, //!< flag, read data from source or write data to the internal buffer (which is
|
||||
//!< returned by FileStorage::release)
|
||||
FORMAT_MASK = (7<<3), //!< mask for format flags
|
||||
FORMAT_AUTO = 0, //!< flag, auto format
|
||||
FORMAT_XML = (1<<3), //!< flag, XML format
|
||||
FORMAT_YAML = (2<<3) //!< flag, YAML format
|
||||
};
|
||||
enum
|
||||
{
|
||||
@ -181,43 +318,117 @@ public:
|
||||
NAME_EXPECTED = 2,
|
||||
INSIDE_MAP = 4
|
||||
};
|
||||
//! the default constructor
|
||||
|
||||
/** @brief The constructors.
|
||||
|
||||
The full constructor opens the file. Alternatively you can use the default constructor and then
|
||||
call FileStorage::open.
|
||||
*/
|
||||
CV_WRAP FileStorage();
|
||||
//! the full constructor that opens file storage for reading or writing
|
||||
|
||||
/** @overload
|
||||
@param source Name of the file to open or the text string to read the data from. Extension of the
|
||||
file (.xml or .yml/.yaml) determines its format (XML or YAML respectively). Also you can append .gz
|
||||
to work with compressed files, for example myHugeMatrix.xml.gz. If both FileStorage::WRITE and
|
||||
FileStorage::MEMORY flags are specified, source is used just to specify the output file format (e.g.
|
||||
mydata.xml, .yml etc.).
|
||||
@param flags Mode of operation. See FileStorage::Mode
|
||||
@param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
|
||||
you should use 8-bit encoding instead of it.
|
||||
*/
|
||||
CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String());
|
||||
//! the constructor that takes pointer to the C FileStorage structure
|
||||
|
||||
/** @overload */
|
||||
FileStorage(CvFileStorage* fs, bool owning=true);
|
||||
|
||||
//! the destructor. calls release()
|
||||
virtual ~FileStorage();
|
||||
|
||||
//! opens file storage for reading or writing. The previous storage is closed with release()
|
||||
/** @brief Opens a file.
|
||||
|
||||
See description of parameters in FileStorage::FileStorage. The method calls FileStorage::release
|
||||
before opening the file.
|
||||
@param filename Name of the file to open or the text string to read the data from.
|
||||
Extension of the file (.xml or .yml/.yaml) determines its format (XML or YAML respectively).
|
||||
Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both
|
||||
FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
|
||||
the output file format (e.g. mydata.xml, .yml etc.).
|
||||
@param flags Mode of operation. One of FileStorage::Mode
|
||||
@param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
|
||||
you should use 8-bit encoding instead of it.
|
||||
*/
|
||||
CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String());
|
||||
//! returns true if the object is associated with currently opened file.
|
||||
|
||||
/** @brief Checks whether the file is opened.
|
||||
|
||||
@returns true if the object is associated with the current file and false otherwise. It is a
|
||||
good practice to call this method after you tried to open a file.
|
||||
*/
|
||||
CV_WRAP virtual bool isOpened() const;
|
||||
//! closes the file and releases all the memory buffers
|
||||
|
||||
/** @brief Closes the file and releases all the memory buffers.
|
||||
|
||||
Call this method after all I/O operations with the storage are finished.
|
||||
*/
|
||||
CV_WRAP virtual void release();
|
||||
//! closes the file, releases all the memory buffers and returns the text string
|
||||
|
||||
/** @brief Closes the file and releases all the memory buffers.
|
||||
|
||||
Call this method after all I/O operations with the storage are finished. If the storage was
|
||||
opened for writing data and FileStorage::WRITE was specified
|
||||
*/
|
||||
CV_WRAP virtual String releaseAndGetString();
|
||||
|
||||
//! returns the first element of the top-level mapping
|
||||
/** @brief Returns the first element of the top-level mapping.
|
||||
@returns The first element of the top-level mapping.
|
||||
*/
|
||||
CV_WRAP FileNode getFirstTopLevelNode() const;
|
||||
//! returns the top-level mapping. YAML supports multiple streams
|
||||
|
||||
/** @brief Returns the top-level mapping
|
||||
@param streamidx Zero-based index of the stream. In most cases there is only one stream in the file.
|
||||
However, YAML supports multiple streams and so there can be several.
|
||||
@returns The top-level mapping.
|
||||
*/
|
||||
CV_WRAP FileNode root(int streamidx=0) const;
|
||||
//! returns the specified element of the top-level mapping
|
||||
|
||||
/** @brief Returns the specified element of the top-level mapping.
|
||||
@param nodename Name of the file node.
|
||||
@returns Node with the given name.
|
||||
*/
|
||||
FileNode operator[](const String& nodename) const;
|
||||
//! returns the specified element of the top-level mapping
|
||||
|
||||
/** @overload */
|
||||
CV_WRAP FileNode operator[](const char* nodename) const;
|
||||
|
||||
//! returns pointer to the underlying C FileStorage structure
|
||||
/** @brief Returns the obsolete C FileStorage structure.
|
||||
@returns Pointer to the underlying C FileStorage structure
|
||||
*/
|
||||
CvFileStorage* operator *() { return fs.get(); }
|
||||
//! returns pointer to the underlying C FileStorage structure
|
||||
|
||||
/** @overload */
|
||||
const CvFileStorage* operator *() const { return fs.get(); }
|
||||
//! writes one or more numbers of the specified format to the currently written structure
|
||||
|
||||
/** @brief Writes multiple numbers.
|
||||
|
||||
Writes one or more numbers of the specified format to the currently written structure. Usually it is
|
||||
more convenient to use operator `<<` instead of this method.
|
||||
@param fmt Specification of each array element, see @ref format_spec "format specification"
|
||||
@param vec Pointer to the written array.
|
||||
@param len Number of the uchar elements to write.
|
||||
*/
|
||||
void writeRaw( const String& fmt, const uchar* vec, size_t len );
|
||||
//! writes the registered C structure (CvMat, CvMatND, CvSeq). See cvWrite()
|
||||
|
||||
/** @brief Writes the registered C structure (CvMat, CvMatND, CvSeq).
|
||||
@param name Name of the written object.
|
||||
@param obj Pointer to the object.
|
||||
@see ocvWrite for details.
|
||||
*/
|
||||
void writeObj( const String& name, const void* obj );
|
||||
|
||||
//! returns the normalized object name for the specified file name
|
||||
/** @brief Returns the normalized object name for the specified name of a file.
|
||||
@param filename Name of a file
|
||||
@returns The normalized object name.
|
||||
*/
|
||||
static String getDefaultObjectName(const String& filename);
|
||||
|
||||
Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure
|
||||
@ -228,21 +439,23 @@ public:
|
||||
|
||||
template<> CV_EXPORTS void DefaultDeleter<CvFileStorage>::operator ()(CvFileStorage* obj) const;
|
||||
|
||||
/*!
|
||||
File Storage Node class
|
||||
/** @brief File Storage Node class.
|
||||
|
||||
The node is used to store each and every element of the file storage opened for reading -
|
||||
from the primitive objects, such as numbers and text strings, to the complex nodes:
|
||||
sequences, mappings and the registered objects.
|
||||
The node is used to store each and every element of the file storage opened for reading. When
|
||||
XML/YAML file is read, it is first parsed and stored in the memory as a hierarchical collection of
|
||||
nodes. Each node can be a “leaf” that is contain a single number or a string, or be a collection of
|
||||
other nodes. There can be named collections (mappings) where each element has a name and it is
|
||||
accessed by a name, and ordered collections (sequences) where elements do not have names but rather
|
||||
accessed by index. Type of the file node can be determined using FileNode::type method.
|
||||
|
||||
Note that file nodes are only used for navigating file storages opened for reading.
|
||||
When a file storage is opened for writing, no data is stored in memory after it is written.
|
||||
*/
|
||||
Note that file nodes are only used for navigating file storages opened for reading. When a file
|
||||
storage is opened for writing, no data is stored in memory after it is written.
|
||||
*/
|
||||
class CV_EXPORTS_W_SIMPLE FileNode
|
||||
{
|
||||
public:
|
||||
//! type of the file storage node
|
||||
enum
|
||||
enum Type
|
||||
{
|
||||
NONE = 0, //!< empty node
|
||||
INT = 1, //!< an integer
|
||||
@ -259,19 +472,43 @@ public:
|
||||
EMPTY = 32, //!< empty structure (sequence or mapping)
|
||||
NAMED = 64 //!< the node has a name (i.e. it is element of a mapping)
|
||||
};
|
||||
//! the default constructor
|
||||
/** @brief The constructors.
|
||||
|
||||
These constructors are used to create a default file node, construct it from obsolete structures or
|
||||
from the another file node.
|
||||
*/
|
||||
CV_WRAP FileNode();
|
||||
//! the full constructor wrapping CvFileNode structure.
|
||||
|
||||
/** @overload
|
||||
@param fs Pointer to the obsolete file storage structure.
|
||||
@param node File node to be used as initialization for the created file node.
|
||||
*/
|
||||
FileNode(const CvFileStorage* fs, const CvFileNode* node);
|
||||
//! the copy constructor
|
||||
|
||||
/** @overload
|
||||
@param node File node to be used as initialization for the created file node.
|
||||
*/
|
||||
FileNode(const FileNode& node);
|
||||
//! returns element of a mapping node
|
||||
|
||||
/** @brief Returns element of a mapping node or a sequence node.
|
||||
@param nodename Name of an element in the mapping node.
|
||||
@returns Returns the element with the given identifier.
|
||||
*/
|
||||
FileNode operator[](const String& nodename) const;
|
||||
//! returns element of a mapping node
|
||||
|
||||
/** @overload
|
||||
@param nodename Name of an element in the mapping node.
|
||||
*/
|
||||
CV_WRAP FileNode operator[](const char* nodename) const;
|
||||
//! returns element of a sequence node
|
||||
|
||||
/** @overload
|
||||
@param i Index of an element in the sequence node.
|
||||
*/
|
||||
CV_WRAP FileNode operator[](int i) const;
|
||||
//! returns type of the node
|
||||
|
||||
/** @brief Returns type of the node.
|
||||
@returns Type of the node. See FileNode::Type
|
||||
*/
|
||||
CV_WRAP int type() const;
|
||||
|
||||
//! returns true if the node is empty
|
||||
@ -316,8 +553,16 @@ public:
|
||||
//! returns iterator pointing to the element following the last node element
|
||||
FileNodeIterator end() const;
|
||||
|
||||
//! reads node elements to the buffer with the specified format
|
||||
/** @brief Reads node elements to the buffer with the specified format.
|
||||
|
||||
Usually it is more convenient to use operator `>>` instead of this method.
|
||||
@param fmt Specification of each array element. See @ref format_spec "format specification"
|
||||
@param vec Pointer to the destination array.
|
||||
@param len Number of elements to read. If it is greater than number of remaining elements then all
|
||||
of them will be read.
|
||||
*/
|
||||
void readRaw( const String& fmt, uchar* vec, size_t len ) const;
|
||||
|
||||
//! reads the registered object and returns pointer to it
|
||||
void* readObj() const;
|
||||
|
||||
@ -327,20 +572,33 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
File Node Iterator
|
||||
/** @brief used to iterate through sequences and mappings.
|
||||
|
||||
The class is used for iterating sequences (usually) and mappings.
|
||||
A standard STL notation, with node.begin(), node.end() denoting the beginning and the end of a
|
||||
sequence, stored in node. See the data reading sample in the beginning of the section.
|
||||
*/
|
||||
class CV_EXPORTS FileNodeIterator
|
||||
{
|
||||
public:
|
||||
//! the default constructor
|
||||
/** @brief The constructors.
|
||||
|
||||
These constructors are used to create a default iterator, set it to specific element in a file node
|
||||
or construct it from another iterator.
|
||||
*/
|
||||
FileNodeIterator();
|
||||
//! the full constructor set to the ofs-th element of the node
|
||||
|
||||
/** @overload
|
||||
@param fs File storage for the iterator.
|
||||
@param node File node for the iterator.
|
||||
@param ofs Index of the element in the node. The created iterator will point to this element.
|
||||
*/
|
||||
FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
|
||||
//! the copy constructor
|
||||
|
||||
/** @overload
|
||||
@param it Iterator to be used as initialization for the created iterator.
|
||||
*/
|
||||
FileNodeIterator(const FileNodeIterator& it);
|
||||
|
||||
//! returns the currently observed element
|
||||
FileNode operator *() const;
|
||||
//! accesses the currently observed element methods
|
||||
@ -359,7 +617,14 @@ public:
|
||||
//! moves iterator backward by the specified offset (possibly negative)
|
||||
FileNodeIterator& operator -= (int ofs);
|
||||
|
||||
//! reads the next maxCount elements (or less, if the sequence/mapping last element occurs earlier) to the buffer with the specified format
|
||||
/** @brief Reads node elements to the buffer with the specified format.
|
||||
|
||||
Usually it is more convenient to use operator `>>` instead of this method.
|
||||
@param fmt Specification of each array element. See @ref format_spec "format specification"
|
||||
@param vec Pointer to the destination array.
|
||||
@param maxCount Number of elements to read. If it is greater than number of remaining elements then
|
||||
all of them will be read.
|
||||
*/
|
||||
FileNodeIterator& readRaw( const String& fmt, uchar* vec,
|
||||
size_t maxCount=(size_t)INT_MAX );
|
||||
|
||||
@ -381,10 +646,13 @@ public:
|
||||
size_t remaining;
|
||||
};
|
||||
|
||||
|
||||
//! @} core_xml
|
||||
|
||||
/////////////////// XML & YAML I/O implementation //////////////////
|
||||
|
||||
//! @relates cv::FileStorage
|
||||
//! @{
|
||||
|
||||
CV_EXPORTS void write( FileStorage& fs, const String& name, int value );
|
||||
CV_EXPORTS void write( FileStorage& fs, const String& name, float value );
|
||||
CV_EXPORTS void write( FileStorage& fs, const String& name, double value );
|
||||
@ -398,6 +666,11 @@ CV_EXPORTS void writeScalar( FileStorage& fs, float value );
|
||||
CV_EXPORTS void writeScalar( FileStorage& fs, double value );
|
||||
CV_EXPORTS void writeScalar( FileStorage& fs, const String& value );
|
||||
|
||||
//! @}
|
||||
|
||||
//! @relates cv::FileNode
|
||||
//! @{
|
||||
|
||||
CV_EXPORTS void read(const FileNode& node, int& value, int default_value);
|
||||
CV_EXPORTS void read(const FileNode& node, float& value, float default_value);
|
||||
CV_EXPORTS void read(const FileNode& node, double& value, double default_value);
|
||||
@ -458,9 +731,14 @@ static inline void read(const FileNode& node, Range& value, const Range& default
|
||||
value.start = temp.x; value.end = temp.y;
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
||||
/** @brief Writes string to a file storage.
|
||||
@relates cv::FileStorage
|
||||
*/
|
||||
CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str);
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace internal
|
||||
{
|
||||
@ -537,7 +815,10 @@ namespace internal
|
||||
|
||||
} // internal
|
||||
|
||||
//! @endcond
|
||||
|
||||
//! @relates cv::FileStorage
|
||||
//! @{
|
||||
|
||||
template<typename _Tp> static inline
|
||||
void write(FileStorage& fs, const _Tp& value)
|
||||
@ -701,6 +982,10 @@ void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec )
|
||||
write(fs, vec);
|
||||
}
|
||||
|
||||
//! @} FileStorage
|
||||
|
||||
//! @relates cv::FileNode
|
||||
//! @{
|
||||
|
||||
static inline
|
||||
void read(const FileNode& node, bool& value, bool default_value)
|
||||
@ -761,7 +1046,13 @@ void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>&
|
||||
}
|
||||
}
|
||||
|
||||
//! @} FileNode
|
||||
|
||||
//! @relates cv::FileStorage
|
||||
//! @{
|
||||
|
||||
/** @brief Writes data to a file storage.
|
||||
*/
|
||||
template<typename _Tp> static inline
|
||||
FileStorage& operator << (FileStorage& fs, const _Tp& value)
|
||||
{
|
||||
@ -775,18 +1066,29 @@ FileStorage& operator << (FileStorage& fs, const _Tp& value)
|
||||
return fs;
|
||||
}
|
||||
|
||||
/** @brief Writes data to a file storage.
|
||||
*/
|
||||
static inline
|
||||
FileStorage& operator << (FileStorage& fs, const char* str)
|
||||
{
|
||||
return (fs << String(str));
|
||||
}
|
||||
|
||||
/** @brief Writes data to a file storage.
|
||||
*/
|
||||
static inline
|
||||
FileStorage& operator << (FileStorage& fs, char* value)
|
||||
{
|
||||
return (fs << String(value));
|
||||
}
|
||||
|
||||
//! @} FileStorage
|
||||
|
||||
//! @relates cv::FileNodeIterator
|
||||
//! @{
|
||||
|
||||
/** @brief Reads data from a file storage.
|
||||
*/
|
||||
template<typename _Tp> static inline
|
||||
FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
|
||||
{
|
||||
@ -794,6 +1096,8 @@ FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
|
||||
return ++it;
|
||||
}
|
||||
|
||||
/** @brief Reads data from a file storage.
|
||||
*/
|
||||
template<typename _Tp> static inline
|
||||
FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec)
|
||||
{
|
||||
@ -802,12 +1106,21 @@ FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec)
|
||||
return it;
|
||||
}
|
||||
|
||||
//! @} FileNodeIterator
|
||||
|
||||
//! @relates cv::FileNode
|
||||
//! @{
|
||||
|
||||
/** @brief Reads data from a file storage.
|
||||
*/
|
||||
template<typename _Tp> static inline
|
||||
void operator >> (const FileNode& n, _Tp& value)
|
||||
{
|
||||
read( n, value, _Tp());
|
||||
}
|
||||
|
||||
/** @brief Reads data from a file storage.
|
||||
*/
|
||||
template<typename _Tp> static inline
|
||||
void operator >> (const FileNode& n, std::vector<_Tp>& vec)
|
||||
{
|
||||
@ -815,6 +1128,10 @@ void operator >> (const FileNode& n, std::vector<_Tp>& vec)
|
||||
it >> vec;
|
||||
}
|
||||
|
||||
//! @} FileNode
|
||||
|
||||
//! @relates cv::FileNodeIterator
|
||||
//! @{
|
||||
|
||||
static inline
|
||||
bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
|
||||
@ -841,6 +1158,10 @@ bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
|
||||
return it1.remaining > it2.remaining;
|
||||
}
|
||||
|
||||
//! @} FileNodeIterator
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
inline FileNode FileStorage::getFirstTopLevelNode() const { FileNode r = root(); FileNodeIterator it = r.begin(); return it != r.end() ? *it : FileNode(); }
|
||||
inline FileNode::FileNode() : fs(0), node(0) {}
|
||||
inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) : fs(_fs), node(_node) {}
|
||||
@ -865,6 +1186,8 @@ inline FileNode FileNodeIterator::operator *() const { return FileNode(fs, (con
|
||||
inline FileNode FileNodeIterator::operator ->() const { return FileNode(fs, (const CvFileNode*)(const void*)reader.ptr); }
|
||||
inline String::String(const FileNode& fn): cstr_(0), len_(0) { read(fn, *this, *this); }
|
||||
|
||||
//! @endcond
|
||||
|
||||
} // cv
|
||||
|
||||
#endif // __OPENCV_CORE_PERSISTENCE_HPP__
|
||||
|
@ -75,6 +75,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv { namespace cuda {
|
||||
CV_EXPORTS cv::String getNppErrorMessage(int code);
|
||||
CV_EXPORTS cv::String getCudaDriverApiErrorMessage(int code);
|
||||
@ -167,4 +169,6 @@ namespace cv { namespace cuda
|
||||
|
||||
#endif // HAVE_CUDA
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CORE_CUDA_PRIVATE_HPP__
|
||||
|
@ -71,6 +71,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv
|
||||
{
|
||||
#ifdef HAVE_TBB
|
||||
@ -301,111 +303,6 @@ typedef enum CvStatus
|
||||
}
|
||||
CvStatus;
|
||||
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
* Auxiliary algorithms *
|
||||
\****************************************************************************************/
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
// This function splits the input sequence or set into one or more equivalence classes and
|
||||
// returns the vector of labels - 0-based class indexes for each element.
|
||||
// predicate(a,b) returns true if the two sequence elements certainly belong to the same class.
|
||||
//
|
||||
// The algorithm is described in "Introduction to Algorithms"
|
||||
// by Cormen, Leiserson and Rivest, the chapter "Data structures for disjoint sets"
|
||||
template<typename _Tp, class _EqPredicate> int
|
||||
partition( const std::vector<_Tp>& _vec, std::vector<int>& labels,
|
||||
_EqPredicate predicate=_EqPredicate())
|
||||
{
|
||||
int i, j, N = (int)_vec.size();
|
||||
const _Tp* vec = &_vec[0];
|
||||
|
||||
const int PARENT=0;
|
||||
const int RANK=1;
|
||||
|
||||
std::vector<int> _nodes(N*2);
|
||||
int (*nodes)[2] = (int(*)[2])&_nodes[0];
|
||||
|
||||
// The first O(N) pass: create N single-vertex trees
|
||||
for(i = 0; i < N; i++)
|
||||
{
|
||||
nodes[i][PARENT]=-1;
|
||||
nodes[i][RANK] = 0;
|
||||
}
|
||||
|
||||
// The main O(N^2) pass: merge connected components
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
int root = i;
|
||||
|
||||
// find root
|
||||
while( nodes[root][PARENT] >= 0 )
|
||||
root = nodes[root][PARENT];
|
||||
|
||||
for( j = 0; j < N; j++ )
|
||||
{
|
||||
if( i == j || !predicate(vec[i], vec[j]))
|
||||
continue;
|
||||
int root2 = j;
|
||||
|
||||
while( nodes[root2][PARENT] >= 0 )
|
||||
root2 = nodes[root2][PARENT];
|
||||
|
||||
if( root2 != root )
|
||||
{
|
||||
// unite both trees
|
||||
int rank = nodes[root][RANK], rank2 = nodes[root2][RANK];
|
||||
if( rank > rank2 )
|
||||
nodes[root2][PARENT] = root;
|
||||
else
|
||||
{
|
||||
nodes[root][PARENT] = root2;
|
||||
nodes[root2][RANK] += rank == rank2;
|
||||
root = root2;
|
||||
}
|
||||
CV_Assert( nodes[root][PARENT] < 0 );
|
||||
|
||||
int k = j, parent;
|
||||
|
||||
// compress the path from node2 to root
|
||||
while( (parent = nodes[k][PARENT]) >= 0 )
|
||||
{
|
||||
nodes[k][PARENT] = root;
|
||||
k = parent;
|
||||
}
|
||||
|
||||
// compress the path from node to root
|
||||
k = i;
|
||||
while( (parent = nodes[k][PARENT]) >= 0 )
|
||||
{
|
||||
nodes[k][PARENT] = root;
|
||||
k = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Final O(N) pass: enumerate classes
|
||||
labels.resize(N);
|
||||
int nclasses = 0;
|
||||
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
int root = i;
|
||||
while( nodes[root][PARENT] >= 0 )
|
||||
root = nodes[root][PARENT];
|
||||
// re-use the rank as the class label
|
||||
if( nodes[root][RANK] >= 0 )
|
||||
nodes[root][RANK] = ~nclasses++;
|
||||
labels[i] = ~nodes[root][RANK];
|
||||
}
|
||||
|
||||
return nclasses;
|
||||
}
|
||||
|
||||
} // namespace cv
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CORE_PRIVATE_HPP__
|
||||
|
@ -44,6 +44,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
namespace cv {
|
||||
|
||||
template<typename Y>
|
||||
@ -335,4 +337,6 @@ Ptr<T> makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5&
|
||||
|
||||
} // namespace cv
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // __OPENCV_CORE_PTR_INL_HPP__
|
||||
|
@ -49,16 +49,59 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
/*!
|
||||
Informative template class for OpenCV "scalars".
|
||||
//! @addtogroup core_basic
|
||||
//! @{
|
||||
|
||||
The class is specialized for each primitive numerical type supported by OpenCV (such as unsigned char or float),
|
||||
as well as for more complex types, like cv::Complex<>, std::complex<>, cv::Vec<> etc.
|
||||
The common property of all such types (called "scalars", do not confuse it with cv::Scalar_)
|
||||
is that each of them is basically a tuple of numbers of the same type. Each "scalar" can be represented
|
||||
by the depth id (CV_8U ... CV_64F) and the number of channels.
|
||||
OpenCV matrices, 2D or nD, dense or sparse, can store "scalars",
|
||||
as long as the number of channels does not exceed CV_CN_MAX.
|
||||
/** @brief Template "trait" class for OpenCV primitive data types.
|
||||
|
||||
A primitive OpenCV data type is one of unsigned char, bool, signed char, unsigned short, signed
|
||||
short, int, float, double, or a tuple of values of one of these types, where all the values in the
|
||||
tuple have the same type. Any primitive type from the list can be defined by an identifier in the
|
||||
form CV_\<bit-depth\>{U|S|F}C(\<number_of_channels\>), for example: uchar \~ CV_8UC1, 3-element
|
||||
floating-point tuple \~ CV_32FC3, and so on. A universal OpenCV structure that is able to store a
|
||||
single instance of such a primitive data type is Vec. Multiple instances of such a type can be
|
||||
stored in a std::vector, Mat, Mat_, SparseMat, SparseMat_, or any other container that is able to
|
||||
store Vec instances.
|
||||
|
||||
The DataType class is basically used to provide a description of such primitive data types without
|
||||
adding any fields or methods to the corresponding classes (and it is actually impossible to add
|
||||
anything to primitive C/C++ data types). This technique is known in C++ as class traits. It is not
|
||||
DataType itself that is used but its specialized versions, such as:
|
||||
@code
|
||||
template<> class DataType<uchar>
|
||||
{
|
||||
typedef uchar value_type;
|
||||
typedef int work_type;
|
||||
typedef uchar channel_type;
|
||||
enum { channel_type = CV_8U, channels = 1, fmt='u', type = CV_8U };
|
||||
};
|
||||
...
|
||||
template<typename _Tp> DataType<std::complex<_Tp> >
|
||||
{
|
||||
typedef std::complex<_Tp> value_type;
|
||||
typedef std::complex<_Tp> work_type;
|
||||
typedef _Tp channel_type;
|
||||
// DataDepth is another helper trait class
|
||||
enum { depth = DataDepth<_Tp>::value, channels=2,
|
||||
fmt=(channels-1)*256+DataDepth<_Tp>::fmt,
|
||||
type=CV_MAKETYPE(depth, channels) };
|
||||
};
|
||||
...
|
||||
@endcode
|
||||
The main purpose of this class is to convert compilation-time type information to an
|
||||
OpenCV-compatible data type identifier, for example:
|
||||
@code
|
||||
// allocates a 30x40 floating-point matrix
|
||||
Mat A(30, 40, DataType<float>::type);
|
||||
|
||||
Mat B = Mat_<std::complex<double> >(3, 3);
|
||||
// the statement below will print 6, 2 , that is depth == CV_64F, channels == 2
|
||||
cout << B.depth() << ", " << B.channels() << endl;
|
||||
@endcode
|
||||
So, such traits are used to tell OpenCV which data type you are working with, even if such a type is
|
||||
not native to OpenCV. For example, the matrix B initialization above is compiled because OpenCV
|
||||
defines the proper specialized template class DataType\<complex\<_Tp\> \> . This mechanism is also
|
||||
useful (and used in OpenCV this way) for generic algorithms implementations.
|
||||
*/
|
||||
template<typename _Tp> class DataType
|
||||
{
|
||||
@ -211,11 +254,10 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
A helper class for cv::DataType
|
||||
/** @brief A helper class for cv::DataType
|
||||
|
||||
The class is specialized for each fundamental numerical data type supported by OpenCV.
|
||||
It provides DataDepth<T>::value constant.
|
||||
The class is specialized for each fundamental numerical data type supported by OpenCV. It provides
|
||||
DataDepth<T>::value constant.
|
||||
*/
|
||||
template<typename _Tp> class DataDepth
|
||||
{
|
||||
@ -277,6 +319,8 @@ template<> class TypeDepth<CV_64F>
|
||||
typedef double value_type;
|
||||
};
|
||||
|
||||
//! @}
|
||||
|
||||
} // cv
|
||||
|
||||
#endif // __OPENCV_CORE_TRAITS_HPP__
|
||||
|
@ -59,10 +59,12 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @addtogroup core_basic
|
||||
//! @{
|
||||
|
||||
//////////////////////////////// Complex //////////////////////////////
|
||||
|
||||
/*!
|
||||
A complex number class.
|
||||
/** @brief A complex number class.
|
||||
|
||||
The template class is similar and compatible with std::complex, however it provides slightly
|
||||
more convenient access to the real and imaginary parts using through the simple field access, as opposite
|
||||
@ -107,12 +109,40 @@ public:
|
||||
|
||||
//////////////////////////////// Point_ ////////////////////////////////
|
||||
|
||||
/*!
|
||||
template 2D point class.
|
||||
/** @brief Template class for 2D points specified by its coordinates `x` and `y`.
|
||||
|
||||
The class defines a point in 2D space. Data type of the point coordinates is specified
|
||||
as a template parameter. There are a few shorter aliases available for user convenience.
|
||||
See cv::Point, cv::Point2i, cv::Point2f and cv::Point2d.
|
||||
An instance of the class is interchangeable with C structures, CvPoint and CvPoint2D32f . There is
|
||||
also a cast operator to convert point coordinates to the specified type. The conversion from
|
||||
floating-point coordinates to integer coordinates is done by rounding. Commonly, the conversion
|
||||
uses this operation for each of the coordinates. Besides the class members listed in the
|
||||
declaration above, the following operations on points are implemented:
|
||||
@code
|
||||
pt1 = pt2 + pt3;
|
||||
pt1 = pt2 - pt3;
|
||||
pt1 = pt2 * a;
|
||||
pt1 = a * pt2;
|
||||
pt1 = pt2 / a;
|
||||
pt1 += pt2;
|
||||
pt1 -= pt2;
|
||||
pt1 *= a;
|
||||
pt1 /= a;
|
||||
double value = norm(pt); // L2 norm
|
||||
pt1 == pt2;
|
||||
pt1 != pt2;
|
||||
@endcode
|
||||
For your convenience, the following type aliases are defined:
|
||||
@code
|
||||
typedef Point_<int> Point2i;
|
||||
typedef Point2i Point;
|
||||
typedef Point_<float> Point2f;
|
||||
typedef Point_<double> Point2d;
|
||||
@endcode
|
||||
Example:
|
||||
@code
|
||||
Point2f a(0.3f, 0.f), b(0.f, 0.4f);
|
||||
Point pt = (a + b)*10.f;
|
||||
cout << pt.x << ", " << pt.y << endl;
|
||||
@endcode
|
||||
*/
|
||||
template<typename _Tp> class Point_
|
||||
{
|
||||
@ -171,13 +201,19 @@ public:
|
||||
|
||||
//////////////////////////////// Point3_ ////////////////////////////////
|
||||
|
||||
/*!
|
||||
template 3D point class.
|
||||
/** @brief Template class for 3D points specified by its coordinates `x`, `y` and `z`.
|
||||
|
||||
The class defines a point in 3D space. Data type of the point coordinates is specified
|
||||
as a template parameter.
|
||||
An instance of the class is interchangeable with the C structure CvPoint2D32f . Similarly to
|
||||
Point_ , the coordinates of 3D points can be converted to another type. The vector arithmetic and
|
||||
comparison operations are also supported.
|
||||
|
||||
\see cv::Point3i, cv::Point3f and cv::Point3d
|
||||
The following Point3_\<\> aliases are available:
|
||||
@code
|
||||
typedef Point3_<int> Point3i;
|
||||
typedef Point3_<float> Point3f;
|
||||
typedef Point3_<double> Point3d;
|
||||
@endcode
|
||||
@see cv::Point3i, cv::Point3f and cv::Point3d
|
||||
*/
|
||||
template<typename _Tp> class Point3_
|
||||
{
|
||||
@ -232,11 +268,18 @@ public:
|
||||
|
||||
//////////////////////////////// Size_ ////////////////////////////////
|
||||
|
||||
/*!
|
||||
The 2D size class
|
||||
/** @brief Template class for specifying the size of an image or rectangle.
|
||||
|
||||
The class represents the size of a 2D rectangle, image size, matrix size etc.
|
||||
Normally, cv::Size ~ cv::Size_<int> is used.
|
||||
The class includes two members called width and height. The structure can be converted to and from
|
||||
the old OpenCV structures CvSize and CvSize2D32f . The same set of arithmetic and comparison
|
||||
operations as for Point_ is available.
|
||||
|
||||
OpenCV defines the following Size_\<\> aliases:
|
||||
@code
|
||||
typedef Size_<int> Size2i;
|
||||
typedef Size2i Size;
|
||||
typedef Size_<float> Size2f;
|
||||
@endcode
|
||||
*/
|
||||
template<typename _Tp> class Size_
|
||||
{
|
||||
@ -285,11 +328,48 @@ public:
|
||||
|
||||
//////////////////////////////// Rect_ ////////////////////////////////
|
||||
|
||||
/*!
|
||||
The 2D up-right rectangle class
|
||||
/** @brief Template class for 2D rectangles
|
||||
|
||||
The class represents a 2D rectangle with coordinates of the specified data type.
|
||||
Normally, cv::Rect ~ cv::Rect_<int> is used.
|
||||
described by the following parameters:
|
||||
- Coordinates of the top-left corner. This is a default interpretation of Rect_::x and Rect_::y
|
||||
in OpenCV. Though, in your algorithms you may count x and y from the bottom-left corner.
|
||||
- Rectangle width and height.
|
||||
|
||||
OpenCV typically assumes that the top and left boundary of the rectangle are inclusive, while the
|
||||
right and bottom boundaries are not. For example, the method Rect_::contains returns true if
|
||||
|
||||
\f[x \leq pt.x < x+width,
|
||||
y \leq pt.y < y+height\f]
|
||||
|
||||
Virtually every loop over an image ROI in OpenCV (where ROI is specified by Rect_\<int\> ) is
|
||||
implemented as:
|
||||
@code
|
||||
for(int y = roi.y; y < roi.y + roi.height; y++)
|
||||
for(int x = roi.x; x < roi.x + roi.width; x++)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
@endcode
|
||||
In addition to the class members, the following operations on rectangles are implemented:
|
||||
- \f$\texttt{rect} = \texttt{rect} \pm \texttt{point}\f$ (shifting a rectangle by a certain offset)
|
||||
- \f$\texttt{rect} = \texttt{rect} \pm \texttt{size}\f$ (expanding or shrinking a rectangle by a
|
||||
certain amount)
|
||||
- rect += point, rect -= point, rect += size, rect -= size (augmenting operations)
|
||||
- rect = rect1 & rect2 (rectangle intersection)
|
||||
- rect = rect1 | rect2 (minimum area rectangle containing rect2 and rect3 )
|
||||
- rect &= rect1, rect |= rect1 (and the corresponding augmenting operations)
|
||||
- rect == rect1, rect != rect1 (rectangle comparison)
|
||||
|
||||
This is an example how the partial ordering on rectangles can be established (rect1 \f$\subseteq\f$
|
||||
rect2):
|
||||
@code
|
||||
template<typename _Tp> inline bool
|
||||
operator <= (const Rect_<_Tp>& r1, const Rect_<_Tp>& r2)
|
||||
{
|
||||
return (r1 & r2) == r1;
|
||||
}
|
||||
@endcode
|
||||
For your convenience, the Rect_\<\> alias is available: cv::Rect
|
||||
*/
|
||||
template<typename _Tp> class Rect_
|
||||
{
|
||||
@ -349,22 +429,52 @@ public:
|
||||
|
||||
///////////////////////////// RotatedRect /////////////////////////////
|
||||
|
||||
/*!
|
||||
The rotated 2D rectangle.
|
||||
/** @brief The class represents rotated (i.e. not up-right) rectangles on a plane.
|
||||
|
||||
The class represents rotated (i.e. not up-right) rectangles on a plane.
|
||||
Each rectangle is described by the center point (mass center), length of each side
|
||||
(represented by cv::Size2f structure) and the rotation angle in degrees.
|
||||
Each rectangle is specified by the center point (mass center), length of each side (represented by
|
||||
cv::Size2f structure) and the rotation angle in degrees.
|
||||
|
||||
The sample below demonstrates how to use RotatedRect:
|
||||
@code
|
||||
Mat image(200, 200, CV_8UC3, Scalar(0));
|
||||
RotatedRect rRect = RotatedRect(Point2f(100,100), Size2f(100,50), 30);
|
||||
|
||||
Point2f vertices[4];
|
||||
rRect.points(vertices);
|
||||
for (int i = 0; i < 4; i++)
|
||||
line(image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0));
|
||||
|
||||
Rect brect = rRect.boundingRect();
|
||||
rectangle(image, brect, Scalar(255,0,0));
|
||||
|
||||
imshow("rectangles", image);
|
||||
waitKey(0);
|
||||
@endcode
|
||||

|
||||
|
||||
@sa CamShift, fitEllipse, minAreaRect, CvBox2D
|
||||
*/
|
||||
class CV_EXPORTS RotatedRect
|
||||
{
|
||||
public:
|
||||
//! various constructors
|
||||
RotatedRect();
|
||||
/**
|
||||
@param center The rectangle mass center.
|
||||
@param size Width and height of the rectangle.
|
||||
@param angle The rotation angle in a clockwise direction. When the angle is 0, 90, 180, 270 etc.,
|
||||
the rectangle becomes an up-right rectangle.
|
||||
*/
|
||||
RotatedRect(const Point2f& center, const Size2f& size, float angle);
|
||||
/**
|
||||
Any 3 end points of the RotatedRect. They must be given in order (either clockwise or
|
||||
anticlockwise).
|
||||
*/
|
||||
RotatedRect(const Point2f& point1, const Point2f& point2, const Point2f& point3);
|
||||
|
||||
//! returns 4 vertices of the rectangle
|
||||
/** returns 4 vertices of the rectangle
|
||||
@param pts The points array for storing rectangle vertices.
|
||||
*/
|
||||
void points(Point2f pts[]) const;
|
||||
//! returns the minimal up-right rectangle containing the rotated rectangle
|
||||
Rect boundingRect() const;
|
||||
@ -395,10 +505,28 @@ public:
|
||||
|
||||
//////////////////////////////// Range /////////////////////////////////
|
||||
|
||||
/*!
|
||||
The 2D range class
|
||||
/** @brief Template class specifying a continuous subsequence (slice) of a sequence.
|
||||
|
||||
This is the class used to specify a continuous subsequence, i.e. part of a contour, or a column span in a matrix.
|
||||
The class is used to specify a row or a column span in a matrix ( Mat ) and for many other purposes.
|
||||
Range(a,b) is basically the same as a:b in Matlab or a..b in Python. As in Python, start is an
|
||||
inclusive left boundary of the range and end is an exclusive right boundary of the range. Such a
|
||||
half-opened interval is usually denoted as \f$[start,end)\f$ .
|
||||
|
||||
The static method Range::all() returns a special variable that means "the whole sequence" or "the
|
||||
whole range", just like " : " in Matlab or " ... " in Python. All the methods and functions in
|
||||
OpenCV that take Range support this special Range::all() value. But, of course, in case of your own
|
||||
custom processing, you will probably have to check and handle it explicitly:
|
||||
@code
|
||||
void my_function(..., const Range& r, ....)
|
||||
{
|
||||
if(r == Range::all()) {
|
||||
// process all the data
|
||||
}
|
||||
else {
|
||||
// process [r.start, r.end)
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
class CV_EXPORTS Range
|
||||
{
|
||||
@ -433,11 +561,11 @@ public:
|
||||
|
||||
//////////////////////////////// Scalar_ ///////////////////////////////
|
||||
|
||||
/*!
|
||||
The template scalar class.
|
||||
/** @brief Template class for a 4-element vector derived from Vec.
|
||||
|
||||
This is partially specialized cv::Vec class with the number of elements = 4, i.e. a short vector of four elements.
|
||||
Normally, cv::Scalar ~ cv::Scalar_<double> is used.
|
||||
Being derived from Vec\<_Tp, 4\> , Scalar_ and Scalar can be used just as typical 4-element
|
||||
vectors. In addition, they can be converted to/from CvScalar . The type Scalar is widely used in
|
||||
OpenCV to pass pixel values.
|
||||
*/
|
||||
template<typename _Tp> class Scalar_ : public Vec<_Tp, 4>
|
||||
{
|
||||
@ -489,42 +617,76 @@ public:
|
||||
|
||||
/////////////////////////////// KeyPoint ////////////////////////////////
|
||||
|
||||
/*!
|
||||
The Keypoint Class
|
||||
/** @brief Data structure for salient point detectors.
|
||||
|
||||
The class instance stores a keypoint, i.e. a point feature found by one of many available keypoint detectors, such as
|
||||
Harris corner detector, cv::FAST, cv::StarDetector, cv::SURF, cv::SIFT, cv::LDetector etc.
|
||||
The class instance stores a keypoint, i.e. a point feature found by one of many available keypoint
|
||||
detectors, such as Harris corner detector, cv::FAST, cv::StarDetector, cv::SURF, cv::SIFT,
|
||||
cv::LDetector etc.
|
||||
|
||||
The keypoint is characterized by the 2D position, scale
|
||||
(proportional to the diameter of the neighborhood that needs to be taken into account),
|
||||
orientation and some other parameters. The keypoint neighborhood is then analyzed by another algorithm that builds a descriptor
|
||||
(usually represented as a feature vector). The keypoints representing the same object in different images can then be matched using
|
||||
cv::KDTree or another method.
|
||||
The keypoint is characterized by the 2D position, scale (proportional to the diameter of the
|
||||
neighborhood that needs to be taken into account), orientation and some other parameters. The
|
||||
keypoint neighborhood is then analyzed by another algorithm that builds a descriptor (usually
|
||||
represented as a feature vector). The keypoints representing the same object in different images
|
||||
can then be matched using cv::KDTree or another method.
|
||||
*/
|
||||
class CV_EXPORTS_W_SIMPLE KeyPoint
|
||||
{
|
||||
public:
|
||||
//! the default constructor
|
||||
CV_WRAP KeyPoint();
|
||||
//! the full constructor
|
||||
/**
|
||||
@param _pt x & y coordinates of the keypoint
|
||||
@param _size keypoint diameter
|
||||
@param _angle keypoint orientation
|
||||
@param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
||||
@param _octave pyramid octave in which the keypoint has been detected
|
||||
@param _class_id object id
|
||||
*/
|
||||
KeyPoint(Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
|
||||
//! another form of the full constructor
|
||||
/**
|
||||
@param x x-coordinate of the keypoint
|
||||
@param y y-coordinate of the keypoint
|
||||
@param _size keypoint diameter
|
||||
@param _angle keypoint orientation
|
||||
@param _response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
||||
@param _octave pyramid octave in which the keypoint has been detected
|
||||
@param _class_id object id
|
||||
*/
|
||||
CV_WRAP KeyPoint(float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1);
|
||||
|
||||
size_t hash() const;
|
||||
|
||||
//! converts vector of keypoints to vector of points
|
||||
/**
|
||||
This method converts vector of keypoints to vector of points or the reverse, where each keypoint is
|
||||
assigned the same size and the same orientation.
|
||||
|
||||
@param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
|
||||
@param points2f Array of (x,y) coordinates of each keypoint
|
||||
@param keypointIndexes Array of indexes of keypoints to be converted to points. (Acts like a mask to
|
||||
convert only specified keypoints)
|
||||
*/
|
||||
CV_WRAP static void convert(const std::vector<KeyPoint>& keypoints,
|
||||
CV_OUT std::vector<Point2f>& points2f,
|
||||
const std::vector<int>& keypointIndexes=std::vector<int>());
|
||||
//! converts vector of points to the vector of keypoints, where each keypoint is assigned the same size and the same orientation
|
||||
/** @overload
|
||||
@param points2f Array of (x,y) coordinates of each keypoint
|
||||
@param keypoints Keypoints obtained from any feature detection algorithm like SIFT/SURF/ORB
|
||||
@param size keypoint diameter
|
||||
@param response keypoint detector response on the keypoint (that is, strength of the keypoint)
|
||||
@param octave pyramid octave in which the keypoint has been detected
|
||||
@param class_id object id
|
||||
*/
|
||||
CV_WRAP static void convert(const std::vector<Point2f>& points2f,
|
||||
CV_OUT std::vector<KeyPoint>& keypoints,
|
||||
float size=1, float response=1, int octave=0, int class_id=-1);
|
||||
|
||||
//! computes overlap for pair of keypoints;
|
||||
//! overlap is a ratio between area of keypoint regions intersection and
|
||||
//! area of keypoint regions union (now keypoint region is circle)
|
||||
/**
|
||||
This method computes overlap for pair of keypoints. Overlap is the ratio between area of keypoint
|
||||
regions' intersection and area of keypoint regions' union (considering keypoint region as circle).
|
||||
If they don't overlap, we get zero. If they coincide at same location with same size, we get 1.
|
||||
@param kp1 First keypoint
|
||||
@param kp2 Second keypoint
|
||||
*/
|
||||
CV_WRAP static float overlap(const KeyPoint& kp1, const KeyPoint& kp2);
|
||||
|
||||
CV_PROP_RW Point2f pt; //!< coordinates of the keypoints
|
||||
@ -558,9 +720,11 @@ public:
|
||||
|
||||
//////////////////////////////// DMatch /////////////////////////////////
|
||||
|
||||
/*
|
||||
* Struct for matching: query descriptor index, train descriptor index, train image index and distance between descriptors.
|
||||
*/
|
||||
/** @brief Class for matching keypoint descriptors
|
||||
|
||||
query descriptor index, train descriptor index, train image index, and distance between
|
||||
descriptors.
|
||||
*/
|
||||
class CV_EXPORTS_W_SIMPLE DMatch
|
||||
{
|
||||
public:
|
||||
@ -599,13 +763,18 @@ public:
|
||||
|
||||
///////////////////////////// TermCriteria //////////////////////////////
|
||||
|
||||
/*!
|
||||
Termination criteria in iterative algorithms
|
||||
*/
|
||||
/** @brief The class defining termination criteria for iterative algorithms.
|
||||
|
||||
You can initialize it by default constructor and then override any parameters, or the structure may
|
||||
be fully initialized using the advanced variant of the constructor.
|
||||
*/
|
||||
class CV_EXPORTS TermCriteria
|
||||
{
|
||||
public:
|
||||
enum
|
||||
/**
|
||||
Criteria type, can be one of: COUNT, EPS or COUNT + EPS
|
||||
*/
|
||||
enum Type
|
||||
{
|
||||
COUNT=1, //!< the maximum number of iterations or elements to compute
|
||||
MAX_ITER=COUNT, //!< ditto
|
||||
@ -614,7 +783,11 @@ public:
|
||||
|
||||
//! default constructor
|
||||
TermCriteria();
|
||||
//! full constructor
|
||||
/**
|
||||
@param type The type of termination criteria, one of TermCriteria::Type
|
||||
@param maxCount The maximum number of iterations or elements to compute.
|
||||
@param epsilon The desired accuracy or change in parameters at which the iterative algorithm stops.
|
||||
*/
|
||||
TermCriteria(int type, int maxCount, double epsilon);
|
||||
|
||||
int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS
|
||||
@ -623,9 +796,15 @@ public:
|
||||
};
|
||||
|
||||
|
||||
//! @} core_basic
|
||||
|
||||
///////////////////////// raster image moments //////////////////////////
|
||||
|
||||
//! @addtogroup imgproc_shape
|
||||
//! @{
|
||||
|
||||
/** @brief struct returned by cv::moments
|
||||
*/
|
||||
class CV_EXPORTS_W_MAP Moments
|
||||
{
|
||||
public:
|
||||
@ -639,12 +818,20 @@ public:
|
||||
////! the conversion to CvMoments
|
||||
//operator CvMoments() const;
|
||||
|
||||
//! spatial moments
|
||||
//! @name spatial moments
|
||||
//! @{
|
||||
CV_PROP_RW double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
|
||||
//! central moments
|
||||
//! @}
|
||||
|
||||
//! @name central moments
|
||||
//! @{
|
||||
CV_PROP_RW double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
|
||||
//! central normalized moments
|
||||
//! @}
|
||||
|
||||
//! @name central normalized moments
|
||||
//! @{
|
||||
CV_PROP_RW double nu20, nu11, nu02, nu30, nu21, nu12, nu03;
|
||||
//! @}
|
||||
};
|
||||
|
||||
template<> class DataType<Moments>
|
||||
@ -664,7 +851,9 @@ public:
|
||||
typedef Vec<channel_type, channels> vec_type;
|
||||
};
|
||||
|
||||
//! @} imgproc_shape
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////// Implementation ////////////////////////////
|
||||
@ -2002,6 +2191,8 @@ inline
|
||||
TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
|
||||
: type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
|
||||
|
||||
//! @endcond
|
||||
|
||||
} // cv
|
||||
|
||||
#endif //__OPENCV_CORE_TYPES_HPP__
|
||||
|
@ -101,10 +101,15 @@
|
||||
# include "opencv2/core.hpp"
|
||||
#endif
|
||||
|
||||
/* CvArr* is used to pass arbitrary
|
||||
* array-like data structures
|
||||
* into functions where the particular
|
||||
* array type is recognized at runtime:
|
||||
/** @addtogroup core_c
|
||||
@{
|
||||
*/
|
||||
|
||||
/** @brief This is the "metatype" used *only* as a function parameter.
|
||||
|
||||
It denotes that the function accepts arrays of multiple types, such as IplImage*, CvMat* or even
|
||||
CvSeq* sometimes. The particular array type is determined at runtime by analyzing the first 4
|
||||
bytes of the header. In C++ interface the role of CvArr is played by InputArray and OutputArray.
|
||||
*/
|
||||
typedef void CvArr;
|
||||
|
||||
@ -126,19 +131,20 @@ Cv64suf;
|
||||
|
||||
typedef int CVStatus;
|
||||
|
||||
/** @see cv::Error::Code */
|
||||
enum {
|
||||
CV_StsOk= 0, /* everithing is ok */
|
||||
CV_StsBackTrace= -1, /* pseudo error for back trace */
|
||||
CV_StsError= -2, /* unknown /unspecified error */
|
||||
CV_StsInternal= -3, /* internal error (bad state) */
|
||||
CV_StsNoMem= -4, /* insufficient memory */
|
||||
CV_StsBadArg= -5, /* function arg/param is bad */
|
||||
CV_StsBadFunc= -6, /* unsupported function */
|
||||
CV_StsNoConv= -7, /* iter. didn't converge */
|
||||
CV_StsAutoTrace= -8, /* tracing */
|
||||
CV_HeaderIsNull= -9, /* image header is NULL */
|
||||
CV_BadImageSize= -10, /* image size is invalid */
|
||||
CV_BadOffset= -11, /* offset is invalid */
|
||||
CV_StsOk= 0, /**< everithing is ok */
|
||||
CV_StsBackTrace= -1, /**< pseudo error for back trace */
|
||||
CV_StsError= -2, /**< unknown /unspecified error */
|
||||
CV_StsInternal= -3, /**< internal error (bad state) */
|
||||
CV_StsNoMem= -4, /**< insufficient memory */
|
||||
CV_StsBadArg= -5, /**< function arg/param is bad */
|
||||
CV_StsBadFunc= -6, /**< unsupported function */
|
||||
CV_StsNoConv= -7, /**< iter. didn't converge */
|
||||
CV_StsAutoTrace= -8, /**< tracing */
|
||||
CV_HeaderIsNull= -9, /**< image header is NULL */
|
||||
CV_BadImageSize= -10, /**< image size is invalid */
|
||||
CV_BadOffset= -11, /**< offset is invalid */
|
||||
CV_BadDataPtr= -12, /**/
|
||||
CV_BadStep= -13, /**/
|
||||
CV_BadModelOrChSeq= -14, /**/
|
||||
@ -154,26 +160,26 @@ enum {
|
||||
CV_BadCOI= -24, /**/
|
||||
CV_BadROISize= -25, /**/
|
||||
CV_MaskIsTiled= -26, /**/
|
||||
CV_StsNullPtr= -27, /* null pointer */
|
||||
CV_StsVecLengthErr= -28, /* incorrect vector length */
|
||||
CV_StsFilterStructContentErr= -29, /* incorr. filter structure content */
|
||||
CV_StsKernelStructContentErr= -30, /* incorr. transform kernel content */
|
||||
CV_StsFilterOffsetErr= -31, /* incorrect filter offset value */
|
||||
CV_StsBadSize= -201, /* the input/output structure size is incorrect */
|
||||
CV_StsDivByZero= -202, /* division by zero */
|
||||
CV_StsInplaceNotSupported= -203, /* in-place operation is not supported */
|
||||
CV_StsObjectNotFound= -204, /* request can't be completed */
|
||||
CV_StsUnmatchedFormats= -205, /* formats of input/output arrays differ */
|
||||
CV_StsBadFlag= -206, /* flag is wrong or not supported */
|
||||
CV_StsBadPoint= -207, /* bad CvPoint */
|
||||
CV_StsBadMask= -208, /* bad format of mask (neither 8uC1 nor 8sC1)*/
|
||||
CV_StsUnmatchedSizes= -209, /* sizes of input/output structures do not match */
|
||||
CV_StsUnsupportedFormat= -210, /* the data format/type is not supported by the function*/
|
||||
CV_StsOutOfRange= -211, /* some of parameters are out of range */
|
||||
CV_StsParseError= -212, /* invalid syntax/structure of the parsed file */
|
||||
CV_StsNotImplemented= -213, /* the requested function/feature is not implemented */
|
||||
CV_StsBadMemBlock= -214, /* an allocated block has been corrupted */
|
||||
CV_StsAssert= -215, /* assertion failed */
|
||||
CV_StsNullPtr= -27, /**< null pointer */
|
||||
CV_StsVecLengthErr= -28, /**< incorrect vector length */
|
||||
CV_StsFilterStructContentErr= -29, /**< incorr. filter structure content */
|
||||
CV_StsKernelStructContentErr= -30, /**< incorr. transform kernel content */
|
||||
CV_StsFilterOffsetErr= -31, /**< incorrect filter offset value */
|
||||
CV_StsBadSize= -201, /**< the input/output structure size is incorrect */
|
||||
CV_StsDivByZero= -202, /**< division by zero */
|
||||
CV_StsInplaceNotSupported= -203, /**< in-place operation is not supported */
|
||||
CV_StsObjectNotFound= -204, /**< request can't be completed */
|
||||
CV_StsUnmatchedFormats= -205, /**< formats of input/output arrays differ */
|
||||
CV_StsBadFlag= -206, /**< flag is wrong or not supported */
|
||||
CV_StsBadPoint= -207, /**< bad CvPoint */
|
||||
CV_StsBadMask= -208, /**< bad format of mask (neither 8uC1 nor 8sC1)*/
|
||||
CV_StsUnmatchedSizes= -209, /**< sizes of input/output structures do not match */
|
||||
CV_StsUnsupportedFormat= -210, /**< the data format/type is not supported by the function*/
|
||||
CV_StsOutOfRange= -211, /**< some of parameters are out of range */
|
||||
CV_StsParseError= -212, /**< invalid syntax/structure of the parsed file */
|
||||
CV_StsNotImplemented= -213, /**< the requested function/feature is not implemented */
|
||||
CV_StsBadMemBlock= -214, /**< an allocated block has been corrupted */
|
||||
CV_StsAssert= -215, /**< assertion failed */
|
||||
CV_GpuNotSupported= -216,
|
||||
CV_GpuApiCallError= -217,
|
||||
CV_OpenGlNotSupported= -218,
|
||||
@ -190,12 +196,12 @@ enum {
|
||||
|
||||
#define CV_SWAP(a,b,t) ((t) = (a), (a) = (b), (b) = (t))
|
||||
|
||||
/* min & max without jumps */
|
||||
/** min & max without jumps */
|
||||
#define CV_IMIN(a, b) ((a) ^ (((a)^(b)) & (((a) < (b)) - 1)))
|
||||
|
||||
#define CV_IMAX(a, b) ((a) ^ (((a)^(b)) & (((a) > (b)) - 1)))
|
||||
|
||||
/* absolute value without jumps */
|
||||
/** absolute value without jumps */
|
||||
#ifndef __cplusplus
|
||||
# define CV_IABS(a) (((a) ^ ((a) < 0 ? -1 : 0)) - ((a) < 0 ? -1 : 0))
|
||||
#else
|
||||
@ -214,13 +220,27 @@ typedef uint64 CvRNG;
|
||||
|
||||
#define CV_RNG_COEFF 4164903690U
|
||||
|
||||
/** @brief Initializes a random number generator state.
|
||||
|
||||
The function initializes a random number generator and returns the state. The pointer to the state
|
||||
can be then passed to the cvRandInt, cvRandReal and cvRandArr functions. In the current
|
||||
implementation a multiply-with-carry generator is used.
|
||||
@param seed 64-bit value used to initiate a random sequence
|
||||
@sa the C++ class RNG replaced CvRNG.
|
||||
*/
|
||||
CV_INLINE CvRNG cvRNG( int64 seed CV_DEFAULT(-1))
|
||||
{
|
||||
CvRNG rng = seed ? (uint64)seed : (uint64)(int64)-1;
|
||||
return rng;
|
||||
}
|
||||
|
||||
/* Return random 32-bit unsigned integer: */
|
||||
/** @brief Returns a 32-bit unsigned integer and updates RNG.
|
||||
|
||||
The function returns a uniformly-distributed random 32-bit unsigned integer and updates the RNG
|
||||
state. It is similar to the rand() function from the C runtime library, except that OpenCV functions
|
||||
always generates a 32-bit random number, regardless of the platform.
|
||||
@param rng CvRNG state initialized by cvRNG.
|
||||
*/
|
||||
CV_INLINE unsigned cvRandInt( CvRNG* rng )
|
||||
{
|
||||
uint64 temp = *rng;
|
||||
@ -229,7 +249,12 @@ CV_INLINE unsigned cvRandInt( CvRNG* rng )
|
||||
return (unsigned)temp;
|
||||
}
|
||||
|
||||
/* Returns random floating-point number between 0 and 1: */
|
||||
/** @brief Returns a floating-point random number and updates RNG.
|
||||
|
||||
The function returns a uniformly-distributed random floating-point number between 0 and 1 (1 is not
|
||||
included).
|
||||
@param rng RNG state initialized by cvRNG
|
||||
*/
|
||||
CV_INLINE double cvRandReal( CvRNG* rng )
|
||||
{
|
||||
return cvRandInt(rng)*2.3283064365386962890625e-10 /* 2^-32 */;
|
||||
@ -276,40 +301,48 @@ CV_INLINE double cvRandReal( CvRNG* rng )
|
||||
#define IPL_BORDER_REFLECT 2
|
||||
#define IPL_BORDER_WRAP 3
|
||||
|
||||
/** The IplImage is taken from the Intel Image Processing Library, in which the format is native. OpenCV
|
||||
only supports a subset of possible IplImage formats, as outlined in the parameter list above.
|
||||
|
||||
In addition to the above restrictions, OpenCV handles ROIs differently. OpenCV functions require
|
||||
that the image size or ROI size of all source and destination images match exactly. On the other
|
||||
hand, the Intel Image Processing Library processes the area of intersection between the source and
|
||||
destination images (or ROIs), allowing them to vary independently.
|
||||
*/
|
||||
typedef struct
|
||||
#ifdef __cplusplus
|
||||
CV_EXPORTS
|
||||
#endif
|
||||
_IplImage
|
||||
{
|
||||
int nSize; /* sizeof(IplImage) */
|
||||
int ID; /* version (=0)*/
|
||||
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
|
||||
int alphaChannel; /* Ignored by OpenCV */
|
||||
int depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
|
||||
int nSize; /**< sizeof(IplImage) */
|
||||
int ID; /**< version (=0)*/
|
||||
int nChannels; /**< Most of OpenCV functions support 1,2,3 or 4 channels */
|
||||
int alphaChannel; /**< Ignored by OpenCV */
|
||||
int depth; /**< Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
|
||||
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */
|
||||
char colorModel[4]; /* Ignored by OpenCV */
|
||||
char channelSeq[4]; /* ditto */
|
||||
int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels.
|
||||
char colorModel[4]; /**< Ignored by OpenCV */
|
||||
char channelSeq[4]; /**< ditto */
|
||||
int dataOrder; /**< 0 - interleaved color channels, 1 - separate color channels.
|
||||
cvCreateImage can only create interleaved images */
|
||||
int origin; /* 0 - top-left origin,
|
||||
int origin; /**< 0 - top-left origin,
|
||||
1 - bottom-left origin (Windows bitmaps style). */
|
||||
int align; /* Alignment of image rows (4 or 8).
|
||||
int align; /**< Alignment of image rows (4 or 8).
|
||||
OpenCV ignores it and uses widthStep instead. */
|
||||
int width; /* Image width in pixels. */
|
||||
int height; /* Image height in pixels. */
|
||||
struct _IplROI *roi; /* Image ROI. If NULL, the whole image is selected. */
|
||||
struct _IplImage *maskROI; /* Must be NULL. */
|
||||
void *imageId; /* " " */
|
||||
struct _IplTileInfo *tileInfo; /* " " */
|
||||
int imageSize; /* Image data size in bytes
|
||||
int width; /**< Image width in pixels. */
|
||||
int height; /**< Image height in pixels. */
|
||||
struct _IplROI *roi; /**< Image ROI. If NULL, the whole image is selected. */
|
||||
struct _IplImage *maskROI; /**< Must be NULL. */
|
||||
void *imageId; /**< " " */
|
||||
struct _IplTileInfo *tileInfo; /**< " " */
|
||||
int imageSize; /**< Image data size in bytes
|
||||
(==image->height*image->widthStep
|
||||
in case of interleaved data)*/
|
||||
char *imageData; /* Pointer to aligned image data. */
|
||||
int widthStep; /* Size of aligned image row in bytes. */
|
||||
int BorderMode[4]; /* Ignored by OpenCV. */
|
||||
int BorderConst[4]; /* Ditto. */
|
||||
char *imageDataOrigin; /* Pointer to very origin of image data
|
||||
char *imageData; /**< Pointer to aligned image data. */
|
||||
int widthStep; /**< Size of aligned image row in bytes. */
|
||||
int BorderMode[4]; /**< Ignored by OpenCV. */
|
||||
int BorderConst[4]; /**< Ditto. */
|
||||
char *imageDataOrigin; /**< Pointer to very origin of image data
|
||||
(not necessarily aligned) -
|
||||
needed for correct deallocation */
|
||||
|
||||
@ -324,7 +357,7 @@ typedef struct _IplTileInfo IplTileInfo;
|
||||
|
||||
typedef struct _IplROI
|
||||
{
|
||||
int coi; /* 0 - no COI (all channels are selected), 1 - 0th channel is selected ...*/
|
||||
int coi; /**< 0 - no COI (all channels are selected), 1 - 0th channel is selected ...*/
|
||||
int xOffset;
|
||||
int yOffset;
|
||||
int width;
|
||||
@ -359,7 +392,7 @@ IplConvKernelFP;
|
||||
|
||||
#endif/*HAVE_IPL*/
|
||||
|
||||
/* extra border mode */
|
||||
/** extra border mode */
|
||||
#define IPL_BORDER_REFLECT_101 4
|
||||
#define IPL_BORDER_TRANSPARENT 5
|
||||
|
||||
@ -372,11 +405,11 @@ IplConvKernelFP;
|
||||
#define CV_IS_IMAGE(img) \
|
||||
(CV_IS_IMAGE_HDR(img) && ((IplImage*)img)->imageData != NULL)
|
||||
|
||||
/* for storing double-precision
|
||||
/** for storing double-precision
|
||||
floating point data in IplImage's */
|
||||
#define IPL_DEPTH_64F 64
|
||||
|
||||
/* get reference to pixel at (col,row),
|
||||
/** get reference to pixel at (col,row),
|
||||
for multi-channel images (col) should be multiplied by number of channels */
|
||||
#define CV_IMAGE_ELEM( image, elemtype, row, col ) \
|
||||
(((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)])
|
||||
@ -392,6 +425,17 @@ IplConvKernelFP;
|
||||
#define CV_MAT_MAGIC_VAL 0x42420000
|
||||
#define CV_TYPE_NAME_MAT "opencv-matrix"
|
||||
|
||||
/** Matrix elements are stored row by row. Element (i, j) (i - 0-based row index, j - 0-based column
|
||||
index) of a matrix can be retrieved or modified using CV_MAT_ELEM macro:
|
||||
|
||||
uchar pixval = CV_MAT_ELEM(grayimg, uchar, i, j)
|
||||
CV_MAT_ELEM(cameraMatrix, float, 0, 2) = image.width*0.5f;
|
||||
|
||||
To access multiple-channel matrices, you can use
|
||||
CV_MAT_ELEM(matrix, type, i, j\*nchannels + channel_idx).
|
||||
|
||||
@deprecated CvMat is now obsolete; consider using Mat instead.
|
||||
*/
|
||||
typedef struct CvMat
|
||||
{
|
||||
int type;
|
||||
@ -474,7 +518,7 @@ CvMat;
|
||||
(CV_16S<<24)+(CV_32S<<28)) >> ((((depth) & 0xF0) >> 2) + \
|
||||
(((depth) & IPL_DEPTH_SIGN) ? 20 : 0))) & 15)
|
||||
|
||||
/* Inline constructor. No data is allocated internally!!!
|
||||
/** Inline constructor. No data is allocated internally!!!
|
||||
* (Use together with cvCreateData, or use cvCreateMat instead to
|
||||
* get a matrix with allocated data):
|
||||
*/
|
||||
@ -517,7 +561,15 @@ inline CvMat::CvMat(const cv::Mat& m)
|
||||
#define CV_MAT_ELEM( mat, elemtype, row, col ) \
|
||||
(*(elemtype*)CV_MAT_ELEM_PTR_FAST( mat, row, col, sizeof(elemtype)))
|
||||
|
||||
/** @brief Returns the particular element of single-channel floating-point matrix.
|
||||
|
||||
The function is a fast replacement for cvGetReal2D in the case of single-channel floating-point
|
||||
matrices. It is faster because it is inline, it does fewer checks for array type and array element
|
||||
type, and it checks for the row and column ranges only in debug mode.
|
||||
@param mat Input matrix
|
||||
@param row The zero-based index of row
|
||||
@param col The zero-based index of column
|
||||
*/
|
||||
CV_INLINE double cvmGet( const CvMat* mat, int row, int col )
|
||||
{
|
||||
int type;
|
||||
@ -535,7 +587,16 @@ CV_INLINE double cvmGet( const CvMat* mat, int row, int col )
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Sets a specific element of a single-channel floating-point matrix.
|
||||
|
||||
The function is a fast replacement for cvSetReal2D in the case of single-channel floating-point
|
||||
matrices. It is faster because it is inline, it does fewer checks for array type and array element
|
||||
type, and it checks for the row and column ranges only in debug mode.
|
||||
@param mat The matrix
|
||||
@param row The zero-based index of row
|
||||
@param col The zero-based index of column
|
||||
@param value The new value of the matrix element
|
||||
*/
|
||||
CV_INLINE void cvmSet( CvMat* mat, int row, int col, double value )
|
||||
{
|
||||
int type;
|
||||
@ -571,6 +632,9 @@ CV_INLINE int cvIplDepth( int type )
|
||||
#define CV_MAX_DIM 32
|
||||
#define CV_MAX_DIM_HEAP 1024
|
||||
|
||||
/**
|
||||
@deprecated consider using cv::Mat instead
|
||||
*/
|
||||
typedef struct
|
||||
#ifdef __cplusplus
|
||||
CV_EXPORTS
|
||||
@ -686,14 +750,14 @@ typedef int CvHistType;
|
||||
#define CV_HIST_MAGIC_VAL 0x42450000
|
||||
#define CV_HIST_UNIFORM_FLAG (1 << 10)
|
||||
|
||||
/* indicates whether bin ranges are set already or not */
|
||||
/** indicates whether bin ranges are set already or not */
|
||||
#define CV_HIST_RANGES_FLAG (1 << 11)
|
||||
|
||||
#define CV_HIST_ARRAY 0
|
||||
#define CV_HIST_SPARSE 1
|
||||
#define CV_HIST_TREE CV_HIST_SPARSE
|
||||
|
||||
/* should be used as a parameter only,
|
||||
/** should be used as a parameter only,
|
||||
it turns to CV_HIST_UNIFORM_FLAG of hist->type */
|
||||
#define CV_HIST_UNIFORM 1
|
||||
|
||||
@ -701,9 +765,9 @@ typedef struct CvHistogram
|
||||
{
|
||||
int type;
|
||||
CvArr* bins;
|
||||
float thresh[CV_MAX_DIM][2]; /* For uniform histograms. */
|
||||
float** thresh2; /* For non-uniform histograms. */
|
||||
CvMatND mat; /* Embedded matrix header for array histograms. */
|
||||
float thresh[CV_MAX_DIM][2]; /**< For uniform histograms. */
|
||||
float** thresh2; /**< For non-uniform histograms. */
|
||||
CvMatND mat; /**< Embedded matrix header for array histograms. */
|
||||
}
|
||||
CvHistogram;
|
||||
|
||||
@ -726,7 +790,7 @@ CvHistogram;
|
||||
\****************************************************************************************/
|
||||
|
||||
/*************************************** CvRect *****************************************/
|
||||
|
||||
/** @sa Rect_ */
|
||||
typedef struct CvRect
|
||||
{
|
||||
int x;
|
||||
@ -744,6 +808,7 @@ typedef struct CvRect
|
||||
}
|
||||
CvRect;
|
||||
|
||||
/** constructs CvRect structure. */
|
||||
CV_INLINE CvRect cvRect( int x, int y, int width, int height )
|
||||
{
|
||||
CvRect r;
|
||||
@ -781,9 +846,11 @@ CV_INLINE CvRect cvROIToRect( IplROI roi )
|
||||
#define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER
|
||||
#define CV_TERMCRIT_EPS 2
|
||||
|
||||
/** @sa TermCriteria
|
||||
*/
|
||||
typedef struct CvTermCriteria
|
||||
{
|
||||
int type; /* may be combination of
|
||||
int type; /**< may be combination of
|
||||
CV_TERMCRIT_ITER
|
||||
CV_TERMCRIT_EPS */
|
||||
int max_iter;
|
||||
@ -827,7 +894,7 @@ typedef struct CvPoint
|
||||
}
|
||||
CvPoint;
|
||||
|
||||
|
||||
/** constructs CvPoint structure. */
|
||||
CV_INLINE CvPoint cvPoint( int x, int y )
|
||||
{
|
||||
CvPoint p;
|
||||
@ -854,7 +921,7 @@ typedef struct CvPoint2D32f
|
||||
}
|
||||
CvPoint2D32f;
|
||||
|
||||
|
||||
/** constructs CvPoint2D32f structure. */
|
||||
CV_INLINE CvPoint2D32f cvPoint2D32f( double x, double y )
|
||||
{
|
||||
CvPoint2D32f p;
|
||||
@ -865,13 +932,13 @@ CV_INLINE CvPoint2D32f cvPoint2D32f( double x, double y )
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/** converts CvPoint to CvPoint2D32f. */
|
||||
CV_INLINE CvPoint2D32f cvPointTo32f( CvPoint point )
|
||||
{
|
||||
return cvPoint2D32f( (float)point.x, (float)point.y );
|
||||
}
|
||||
|
||||
|
||||
/** converts CvPoint2D32f to CvPoint. */
|
||||
CV_INLINE CvPoint cvPointFrom32f( CvPoint2D32f point )
|
||||
{
|
||||
CvPoint ipt;
|
||||
@ -898,7 +965,7 @@ typedef struct CvPoint3D32f
|
||||
}
|
||||
CvPoint3D32f;
|
||||
|
||||
|
||||
/** constructs CvPoint3D32f structure. */
|
||||
CV_INLINE CvPoint3D32f cvPoint3D32f( double x, double y, double z )
|
||||
{
|
||||
CvPoint3D32f p;
|
||||
@ -918,7 +985,7 @@ typedef struct CvPoint2D64f
|
||||
}
|
||||
CvPoint2D64f;
|
||||
|
||||
|
||||
/** constructs CvPoint2D64f structure.*/
|
||||
CV_INLINE CvPoint2D64f cvPoint2D64f( double x, double y )
|
||||
{
|
||||
CvPoint2D64f p;
|
||||
@ -938,7 +1005,7 @@ typedef struct CvPoint3D64f
|
||||
}
|
||||
CvPoint3D64f;
|
||||
|
||||
|
||||
/** constructs CvPoint3D64f structure. */
|
||||
CV_INLINE CvPoint3D64f cvPoint3D64f( double x, double y, double z )
|
||||
{
|
||||
CvPoint3D64f p;
|
||||
@ -968,6 +1035,7 @@ typedef struct CvSize
|
||||
}
|
||||
CvSize;
|
||||
|
||||
/** constructs CvSize structure. */
|
||||
CV_INLINE CvSize cvSize( int width, int height )
|
||||
{
|
||||
CvSize s;
|
||||
@ -993,7 +1061,7 @@ typedef struct CvSize2D32f
|
||||
}
|
||||
CvSize2D32f;
|
||||
|
||||
|
||||
/** constructs CvSize2D32f structure. */
|
||||
CV_INLINE CvSize2D32f cvSize2D32f( double width, double height )
|
||||
{
|
||||
CvSize2D32f s;
|
||||
@ -1004,12 +1072,14 @@ CV_INLINE CvSize2D32f cvSize2D32f( double width, double height )
|
||||
return s;
|
||||
}
|
||||
|
||||
/** @sa RotatedRect
|
||||
*/
|
||||
typedef struct CvBox2D
|
||||
{
|
||||
CvPoint2D32f center; /* Center of the box. */
|
||||
CvSize2D32f size; /* Box width and length. */
|
||||
float angle; /* Angle between the horizontal axis */
|
||||
/* and the first side (i.e. length) in degrees */
|
||||
CvPoint2D32f center; /**< Center of the box. */
|
||||
CvSize2D32f size; /**< Box width and length. */
|
||||
float angle; /**< Angle between the horizontal axis */
|
||||
/**< and the first side (i.e. length) in degrees */
|
||||
|
||||
#ifdef __cplusplus
|
||||
CvBox2D(CvPoint2D32f c = CvPoint2D32f(), CvSize2D32f s = CvSize2D32f(), float a = 0) : center(c), size(s), angle(a) {}
|
||||
@ -1020,10 +1090,10 @@ typedef struct CvBox2D
|
||||
CvBox2D;
|
||||
|
||||
|
||||
/* Line iterator state: */
|
||||
/** Line iterator state: */
|
||||
typedef struct CvLineIterator
|
||||
{
|
||||
/* Pointer to the current point: */
|
||||
/** Pointer to the current point: */
|
||||
uchar* ptr;
|
||||
|
||||
/* Bresenham algorithm state: */
|
||||
@ -1065,7 +1135,8 @@ CV_INLINE CvSlice cvSlice( int start, int end )
|
||||
|
||||
|
||||
/************************************* CvScalar *****************************************/
|
||||
|
||||
/** @sa Scalar_
|
||||
*/
|
||||
typedef struct CvScalar
|
||||
{
|
||||
double val[4];
|
||||
@ -1134,11 +1205,11 @@ CvMemBlock;
|
||||
typedef struct CvMemStorage
|
||||
{
|
||||
int signature;
|
||||
CvMemBlock* bottom; /* First allocated block. */
|
||||
CvMemBlock* top; /* Current memory block - top of the stack. */
|
||||
struct CvMemStorage* parent; /* We get new blocks from parent as needed. */
|
||||
int block_size; /* Block size. */
|
||||
int free_space; /* Remaining free space in current block. */
|
||||
CvMemBlock* bottom; /**< First allocated block. */
|
||||
CvMemBlock* top; /**< Current memory block - top of the stack. */
|
||||
struct CvMemStorage* parent; /**< We get new blocks from parent as needed. */
|
||||
int block_size; /**< Block size. */
|
||||
int free_space; /**< Remaining free space in current block. */
|
||||
}
|
||||
CvMemStorage;
|
||||
|
||||
@ -1159,38 +1230,38 @@ CvMemStoragePos;
|
||||
|
||||
typedef struct CvSeqBlock
|
||||
{
|
||||
struct CvSeqBlock* prev; /* Previous sequence block. */
|
||||
struct CvSeqBlock* next; /* Next sequence block. */
|
||||
int start_index; /* Index of the first element in the block + */
|
||||
/* sequence->first->start_index. */
|
||||
int count; /* Number of elements in the block. */
|
||||
schar* data; /* Pointer to the first element of the block. */
|
||||
struct CvSeqBlock* prev; /**< Previous sequence block. */
|
||||
struct CvSeqBlock* next; /**< Next sequence block. */
|
||||
int start_index; /**< Index of the first element in the block + */
|
||||
/**< sequence->first->start_index. */
|
||||
int count; /**< Number of elements in the block. */
|
||||
schar* data; /**< Pointer to the first element of the block. */
|
||||
}
|
||||
CvSeqBlock;
|
||||
|
||||
|
||||
#define CV_TREE_NODE_FIELDS(node_type) \
|
||||
int flags; /* Miscellaneous flags. */ \
|
||||
int header_size; /* Size of sequence header. */ \
|
||||
struct node_type* h_prev; /* Previous sequence. */ \
|
||||
struct node_type* h_next; /* Next sequence. */ \
|
||||
struct node_type* v_prev; /* 2nd previous sequence. */ \
|
||||
struct node_type* v_next /* 2nd next sequence. */
|
||||
int flags; /**< Miscellaneous flags. */ \
|
||||
int header_size; /**< Size of sequence header. */ \
|
||||
struct node_type* h_prev; /**< Previous sequence. */ \
|
||||
struct node_type* h_next; /**< Next sequence. */ \
|
||||
struct node_type* v_prev; /**< 2nd previous sequence. */ \
|
||||
struct node_type* v_next /**< 2nd next sequence. */
|
||||
|
||||
/*
|
||||
/**
|
||||
Read/Write sequence.
|
||||
Elements can be dynamically inserted to or deleted from the sequence.
|
||||
*/
|
||||
#define CV_SEQUENCE_FIELDS() \
|
||||
CV_TREE_NODE_FIELDS(CvSeq); \
|
||||
int total; /* Total number of elements. */ \
|
||||
int elem_size; /* Size of sequence element in bytes. */ \
|
||||
schar* block_max; /* Maximal bound of the last block. */ \
|
||||
schar* ptr; /* Current write pointer. */ \
|
||||
int delta_elems; /* Grow seq this many at a time. */ \
|
||||
CvMemStorage* storage; /* Where the seq is stored. */ \
|
||||
CvSeqBlock* free_blocks; /* Free blocks list. */ \
|
||||
CvSeqBlock* first; /* Pointer to the first sequence block. */
|
||||
int total; /**< Total number of elements. */ \
|
||||
int elem_size; /**< Size of sequence element in bytes. */ \
|
||||
schar* block_max; /**< Maximal bound of the last block. */ \
|
||||
schar* ptr; /**< Current write pointer. */ \
|
||||
int delta_elems; /**< Grow seq this many at a time. */ \
|
||||
CvMemStorage* storage; /**< Where the seq is stored. */ \
|
||||
CvSeqBlock* free_blocks; /**< Free blocks list. */ \
|
||||
CvSeqBlock* first; /**< Pointer to the first sequence block. */
|
||||
|
||||
typedef struct CvSeq
|
||||
{
|
||||
@ -1202,8 +1273,7 @@ CvSeq;
|
||||
#define CV_TYPE_NAME_SEQ_TREE "opencv-sequence-tree"
|
||||
|
||||
/*************************************** Set ********************************************/
|
||||
/*
|
||||
Set.
|
||||
/** @brief Set
|
||||
Order is not preserved. There can be gaps between sequence elements.
|
||||
After the element has been inserted it stays in the same place all the time.
|
||||
The MSB(most-significant or sign bit) of the first field (flags) is 0 iff the element exists.
|
||||
@ -1233,28 +1303,30 @@ CvSet;
|
||||
#define CV_SET_ELEM_IDX_MASK ((1 << 26) - 1)
|
||||
#define CV_SET_ELEM_FREE_FLAG (1 << (sizeof(int)*8-1))
|
||||
|
||||
/* Checks whether the element pointed by ptr belongs to a set or not */
|
||||
/** Checks whether the element pointed by ptr belongs to a set or not */
|
||||
#define CV_IS_SET_ELEM( ptr ) (((CvSetElem*)(ptr))->flags >= 0)
|
||||
|
||||
/************************************* Graph ********************************************/
|
||||
|
||||
/*
|
||||
We represent a graph as a set of vertices.
|
||||
Vertices contain their adjacency lists (more exactly, pointers to first incoming or
|
||||
outcoming edge (or 0 if isolated vertex)). Edges are stored in another set.
|
||||
There is a singly-linked list of incoming/outcoming edges for each vertex.
|
||||
/** @name Graph
|
||||
|
||||
Each edge consists of
|
||||
We represent a graph as a set of vertices. Vertices contain their adjacency lists (more exactly,
|
||||
pointers to first incoming or outcoming edge (or 0 if isolated vertex)). Edges are stored in
|
||||
another set. There is a singly-linked list of incoming/outcoming edges for each vertex.
|
||||
|
||||
o Two pointers to the starting and ending vertices
|
||||
(vtx[0] and vtx[1] respectively).
|
||||
Each edge consists of:
|
||||
|
||||
A graph may be oriented or not. In the latter case, edges between
|
||||
vertex i to vertex j are not distinguished during search operations.
|
||||
- Two pointers to the starting and ending vertices (vtx[0] and vtx[1] respectively).
|
||||
|
||||
o Two pointers to next edges for the starting and ending vertices, where
|
||||
next[0] points to the next edge in the vtx[0] adjacency list and
|
||||
next[1] points to the next edge in the vtx[1] adjacency list.
|
||||
A graph may be oriented or not. In the latter case, edges between vertex i to vertex j are not
|
||||
distinguished during search operations.
|
||||
|
||||
- Two pointers to next edges for the starting and ending vertices, where next[0] points to the
|
||||
next edge in the vtx[0] adjacency list and next[1] points to the next edge in the vtx[1]
|
||||
adjacency list.
|
||||
|
||||
@see CvGraphEdge, CvGraphVtx, CvGraphVtx2D, CvGraph
|
||||
@{
|
||||
*/
|
||||
#define CV_GRAPH_EDGE_FIELDS() \
|
||||
int flags; \
|
||||
@ -1287,7 +1359,7 @@ typedef struct CvGraphVtx2D
|
||||
}
|
||||
CvGraphVtx2D;
|
||||
|
||||
/*
|
||||
/**
|
||||
Graph is "derived" from the set (this is set a of vertices)
|
||||
and includes another set (edges)
|
||||
*/
|
||||
@ -1303,6 +1375,8 @@ CvGraph;
|
||||
|
||||
#define CV_TYPE_NAME_GRAPH "opencv-graph"
|
||||
|
||||
/** @} */
|
||||
|
||||
/*********************************** Chain/Countour *************************************/
|
||||
|
||||
typedef struct CvChain
|
||||
@ -1342,45 +1416,45 @@ typedef CvContour CvPoint2DSeq;
|
||||
#define CV_SEQ_ELTYPE_BITS 12
|
||||
#define CV_SEQ_ELTYPE_MASK ((1 << CV_SEQ_ELTYPE_BITS) - 1)
|
||||
|
||||
#define CV_SEQ_ELTYPE_POINT CV_32SC2 /* (x,y) */
|
||||
#define CV_SEQ_ELTYPE_CODE CV_8UC1 /* freeman code: 0..7 */
|
||||
#define CV_SEQ_ELTYPE_POINT CV_32SC2 /**< (x,y) */
|
||||
#define CV_SEQ_ELTYPE_CODE CV_8UC1 /**< freeman code: 0..7 */
|
||||
#define CV_SEQ_ELTYPE_GENERIC 0
|
||||
#define CV_SEQ_ELTYPE_PTR CV_USRTYPE1
|
||||
#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /* &(x,y) */
|
||||
#define CV_SEQ_ELTYPE_INDEX CV_32SC1 /* #(x,y) */
|
||||
#define CV_SEQ_ELTYPE_GRAPH_EDGE 0 /* &next_o, &next_d, &vtx_o, &vtx_d */
|
||||
#define CV_SEQ_ELTYPE_GRAPH_VERTEX 0 /* first_edge, &(x,y) */
|
||||
#define CV_SEQ_ELTYPE_TRIAN_ATR 0 /* vertex of the binary tree */
|
||||
#define CV_SEQ_ELTYPE_CONNECTED_COMP 0 /* connected component */
|
||||
#define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /* (x,y,z) */
|
||||
#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /**< &(x,y) */
|
||||
#define CV_SEQ_ELTYPE_INDEX CV_32SC1 /**< #(x,y) */
|
||||
#define CV_SEQ_ELTYPE_GRAPH_EDGE 0 /**< &next_o, &next_d, &vtx_o, &vtx_d */
|
||||
#define CV_SEQ_ELTYPE_GRAPH_VERTEX 0 /**< first_edge, &(x,y) */
|
||||
#define CV_SEQ_ELTYPE_TRIAN_ATR 0 /**< vertex of the binary tree */
|
||||
#define CV_SEQ_ELTYPE_CONNECTED_COMP 0 /**< connected component */
|
||||
#define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /**< (x,y,z) */
|
||||
|
||||
#define CV_SEQ_KIND_BITS 2
|
||||
#define CV_SEQ_KIND_MASK (((1 << CV_SEQ_KIND_BITS) - 1)<<CV_SEQ_ELTYPE_BITS)
|
||||
|
||||
/* types of sequences */
|
||||
/** types of sequences */
|
||||
#define CV_SEQ_KIND_GENERIC (0 << CV_SEQ_ELTYPE_BITS)
|
||||
#define CV_SEQ_KIND_CURVE (1 << CV_SEQ_ELTYPE_BITS)
|
||||
#define CV_SEQ_KIND_BIN_TREE (2 << CV_SEQ_ELTYPE_BITS)
|
||||
|
||||
/* types of sparse sequences (sets) */
|
||||
/** types of sparse sequences (sets) */
|
||||
#define CV_SEQ_KIND_GRAPH (1 << CV_SEQ_ELTYPE_BITS)
|
||||
#define CV_SEQ_KIND_SUBDIV2D (2 << CV_SEQ_ELTYPE_BITS)
|
||||
|
||||
#define CV_SEQ_FLAG_SHIFT (CV_SEQ_KIND_BITS + CV_SEQ_ELTYPE_BITS)
|
||||
|
||||
/* flags for curves */
|
||||
/** flags for curves */
|
||||
#define CV_SEQ_FLAG_CLOSED (1 << CV_SEQ_FLAG_SHIFT)
|
||||
#define CV_SEQ_FLAG_SIMPLE (0 << CV_SEQ_FLAG_SHIFT)
|
||||
#define CV_SEQ_FLAG_CONVEX (0 << CV_SEQ_FLAG_SHIFT)
|
||||
#define CV_SEQ_FLAG_HOLE (2 << CV_SEQ_FLAG_SHIFT)
|
||||
|
||||
/* flags for graphs */
|
||||
/** flags for graphs */
|
||||
#define CV_GRAPH_FLAG_ORIENTED (1 << CV_SEQ_FLAG_SHIFT)
|
||||
|
||||
#define CV_GRAPH CV_SEQ_KIND_GRAPH
|
||||
#define CV_ORIENTED_GRAPH (CV_SEQ_KIND_GRAPH|CV_GRAPH_FLAG_ORIENTED)
|
||||
|
||||
/* point sets */
|
||||
/** point sets */
|
||||
#define CV_SEQ_POINT_SET (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT)
|
||||
#define CV_SEQ_POINT3D_SET (CV_SEQ_KIND_GENERIC| CV_SEQ_ELTYPE_POINT3D)
|
||||
#define CV_SEQ_POLYLINE (CV_SEQ_KIND_CURVE | CV_SEQ_ELTYPE_POINT)
|
||||
@ -1388,23 +1462,23 @@ typedef CvContour CvPoint2DSeq;
|
||||
#define CV_SEQ_CONTOUR CV_SEQ_POLYGON
|
||||
#define CV_SEQ_SIMPLE_POLYGON (CV_SEQ_FLAG_SIMPLE | CV_SEQ_POLYGON )
|
||||
|
||||
/* chain-coded curves */
|
||||
/** chain-coded curves */
|
||||
#define CV_SEQ_CHAIN (CV_SEQ_KIND_CURVE | CV_SEQ_ELTYPE_CODE)
|
||||
#define CV_SEQ_CHAIN_CONTOUR (CV_SEQ_FLAG_CLOSED | CV_SEQ_CHAIN)
|
||||
|
||||
/* binary tree for the contour */
|
||||
/** binary tree for the contour */
|
||||
#define CV_SEQ_POLYGON_TREE (CV_SEQ_KIND_BIN_TREE | CV_SEQ_ELTYPE_TRIAN_ATR)
|
||||
|
||||
/* sequence of the connected components */
|
||||
/** sequence of the connected components */
|
||||
#define CV_SEQ_CONNECTED_COMP (CV_SEQ_KIND_GENERIC | CV_SEQ_ELTYPE_CONNECTED_COMP)
|
||||
|
||||
/* sequence of the integer numbers */
|
||||
/** sequence of the integer numbers */
|
||||
#define CV_SEQ_INDEX (CV_SEQ_KIND_GENERIC | CV_SEQ_ELTYPE_INDEX)
|
||||
|
||||
#define CV_SEQ_ELTYPE( seq ) ((seq)->flags & CV_SEQ_ELTYPE_MASK)
|
||||
#define CV_SEQ_KIND( seq ) ((seq)->flags & CV_SEQ_KIND_MASK )
|
||||
|
||||
/* flag checking */
|
||||
/** flag checking */
|
||||
#define CV_IS_SEQ_INDEX( seq ) ((CV_SEQ_ELTYPE(seq) == CV_SEQ_ELTYPE_INDEX) && \
|
||||
(CV_SEQ_KIND(seq) == CV_SEQ_KIND_GENERIC))
|
||||
|
||||
@ -1414,7 +1488,7 @@ typedef CvContour CvPoint2DSeq;
|
||||
#define CV_IS_SEQ_HOLE( seq ) (((seq)->flags & CV_SEQ_FLAG_HOLE) != 0)
|
||||
#define CV_IS_SEQ_SIMPLE( seq ) 1
|
||||
|
||||
/* type checking macros */
|
||||
/** type checking macros */
|
||||
#define CV_IS_SEQ_POINT_SET( seq ) \
|
||||
((CV_SEQ_ELTYPE(seq) == CV_32SC2 || CV_SEQ_ELTYPE(seq) == CV_32FC2))
|
||||
|
||||
@ -1455,11 +1529,11 @@ typedef CvContour CvPoint2DSeq;
|
||||
|
||||
#define CV_SEQ_WRITER_FIELDS() \
|
||||
int header_size; \
|
||||
CvSeq* seq; /* the sequence written */ \
|
||||
CvSeqBlock* block; /* current block */ \
|
||||
schar* ptr; /* pointer to free space */ \
|
||||
schar* block_min; /* pointer to the beginning of block*/\
|
||||
schar* block_max; /* pointer to the end of block */
|
||||
CvSeq* seq; /**< the sequence written */ \
|
||||
CvSeqBlock* block; /**< current block */ \
|
||||
schar* ptr; /**< pointer to free space */ \
|
||||
schar* block_min; /**< pointer to the beginning of block*/\
|
||||
schar* block_max; /**< pointer to the end of block */
|
||||
|
||||
typedef struct CvSeqWriter
|
||||
{
|
||||
@ -1470,13 +1544,13 @@ CvSeqWriter;
|
||||
|
||||
#define CV_SEQ_READER_FIELDS() \
|
||||
int header_size; \
|
||||
CvSeq* seq; /* sequence, beign read */ \
|
||||
CvSeqBlock* block; /* current block */ \
|
||||
schar* ptr; /* pointer to element be read next */ \
|
||||
schar* block_min; /* pointer to the beginning of block */\
|
||||
schar* block_max; /* pointer to the end of block */ \
|
||||
int delta_index;/* = seq->first->start_index */ \
|
||||
schar* prev_elem; /* pointer to previous element */
|
||||
CvSeq* seq; /**< sequence, beign read */ \
|
||||
CvSeqBlock* block; /**< current block */ \
|
||||
schar* ptr; /**< pointer to element be read next */ \
|
||||
schar* block_min; /**< pointer to the beginning of block */\
|
||||
schar* block_max; /**< pointer to the end of block */ \
|
||||
int delta_index;/**< = seq->first->start_index */ \
|
||||
schar* prev_elem; /**< pointer to previous element */
|
||||
|
||||
typedef struct CvSeqReader
|
||||
{
|
||||
@ -1489,7 +1563,7 @@ CvSeqReader;
|
||||
/****************************************************************************************/
|
||||
|
||||
#define CV_SEQ_ELEM( seq, elem_type, index ) \
|
||||
/* assert gives some guarantee that <seq> parameter is valid */ \
|
||||
/** assert gives some guarantee that <seq> parameter is valid */ \
|
||||
( assert(sizeof((seq)->first[0]) == sizeof(CvSeqBlock) && \
|
||||
(seq)->elem_size == sizeof(elem_type)), \
|
||||
(elem_type*)((seq)->first && (unsigned)index < \
|
||||
@ -1498,7 +1572,7 @@ CvSeqReader;
|
||||
cvGetSeqElem( (CvSeq*)(seq), (index) )))
|
||||
#define CV_GET_SEQ_ELEM( elem_type, seq, index ) CV_SEQ_ELEM( (seq), elem_type, (index) )
|
||||
|
||||
/* Add element to sequence: */
|
||||
/** Add element to sequence: */
|
||||
#define CV_WRITE_SEQ_ELEM_VAR( elem_ptr, writer ) \
|
||||
{ \
|
||||
if( (writer).ptr >= (writer).block_max ) \
|
||||
@ -1522,7 +1596,7 @@ CvSeqReader;
|
||||
}
|
||||
|
||||
|
||||
/* Move reader position forward: */
|
||||
/** Move reader position forward: */
|
||||
#define CV_NEXT_SEQ_ELEM( elem_size, reader ) \
|
||||
{ \
|
||||
if( ((reader).ptr += (elem_size)) >= (reader).block_max ) \
|
||||
@ -1532,7 +1606,7 @@ CvSeqReader;
|
||||
}
|
||||
|
||||
|
||||
/* Move reader position backward: */
|
||||
/** Move reader position backward: */
|
||||
#define CV_PREV_SEQ_ELEM( elem_size, reader ) \
|
||||
{ \
|
||||
if( ((reader).ptr -= (elem_size)) < (reader).block_min ) \
|
||||
@ -1541,7 +1615,7 @@ CvSeqReader;
|
||||
} \
|
||||
}
|
||||
|
||||
/* Read element and move read position forward: */
|
||||
/** Read element and move read position forward: */
|
||||
#define CV_READ_SEQ_ELEM( elem, reader ) \
|
||||
{ \
|
||||
assert( (reader).seq->elem_size == sizeof(elem)); \
|
||||
@ -1549,7 +1623,7 @@ CvSeqReader;
|
||||
CV_NEXT_SEQ_ELEM( sizeof(elem), reader ) \
|
||||
}
|
||||
|
||||
/* Read element and move read position backward: */
|
||||
/** Read element and move read position backward: */
|
||||
#define CV_REV_READ_SEQ_ELEM( elem, reader ) \
|
||||
{ \
|
||||
assert( (reader).seq->elem_size == sizeof(elem)); \
|
||||
@ -1586,7 +1660,7 @@ CvSeqReader;
|
||||
|
||||
/************ Graph macros ************/
|
||||
|
||||
/* Return next graph edge for given vertex: */
|
||||
/** Return next graph edge for given vertex: */
|
||||
#define CV_NEXT_GRAPH_EDGE( edge, vertex ) \
|
||||
(assert((edge)->vtx[0] == (vertex) || (edge)->vtx[1] == (vertex)), \
|
||||
(edge)->next[(edge)->vtx[1] == (vertex)])
|
||||
@ -1597,10 +1671,10 @@ CvSeqReader;
|
||||
* Data structures for persistence (a.k.a serialization) functionality *
|
||||
\****************************************************************************************/
|
||||
|
||||
/* "black box" file storage */
|
||||
/** "black box" file storage */
|
||||
typedef struct CvFileStorage CvFileStorage;
|
||||
|
||||
/* Storage flags: */
|
||||
/** Storage flags: */
|
||||
#define CV_STORAGE_READ 0
|
||||
#define CV_STORAGE_WRITE 1
|
||||
#define CV_STORAGE_WRITE_TEXT CV_STORAGE_WRITE
|
||||
@ -1612,14 +1686,21 @@ typedef struct CvFileStorage CvFileStorage;
|
||||
#define CV_STORAGE_FORMAT_XML 8
|
||||
#define CV_STORAGE_FORMAT_YAML 16
|
||||
|
||||
/* List of attributes: */
|
||||
/** @brief List of attributes. :
|
||||
|
||||
In the current implementation, attributes are used to pass extra parameters when writing user
|
||||
objects (see cvWrite). XML attributes inside tags are not supported, aside from the object type
|
||||
specification (type_id attribute).
|
||||
@see cvAttrList, cvAttrValue
|
||||
*/
|
||||
typedef struct CvAttrList
|
||||
{
|
||||
const char** attr; /* NULL-terminated array of (attribute_name,attribute_value) pairs. */
|
||||
struct CvAttrList* next; /* Pointer to next chunk of the attributes list. */
|
||||
const char** attr; /**< NULL-terminated array of (attribute_name,attribute_value) pairs. */
|
||||
struct CvAttrList* next; /**< Pointer to next chunk of the attributes list. */
|
||||
}
|
||||
CvAttrList;
|
||||
|
||||
/** initializes CvAttrList structure */
|
||||
CV_INLINE CvAttrList cvAttrList( const char** attr CV_DEFAULT(NULL),
|
||||
CvAttrList* next CV_DEFAULT(NULL) )
|
||||
{
|
||||
@ -1639,15 +1720,15 @@ struct CvTypeInfo;
|
||||
#define CV_NODE_FLOAT CV_NODE_REAL
|
||||
#define CV_NODE_STR 3
|
||||
#define CV_NODE_STRING CV_NODE_STR
|
||||
#define CV_NODE_REF 4 /* not used */
|
||||
#define CV_NODE_REF 4 /**< not used */
|
||||
#define CV_NODE_SEQ 5
|
||||
#define CV_NODE_MAP 6
|
||||
#define CV_NODE_TYPE_MASK 7
|
||||
|
||||
#define CV_NODE_TYPE(flags) ((flags) & CV_NODE_TYPE_MASK)
|
||||
|
||||
/* file node flags */
|
||||
#define CV_NODE_FLOW 8 /* Used only for writing structures in YAML format. */
|
||||
/** file node flags */
|
||||
#define CV_NODE_FLOW 8 /**<Used only for writing structures in YAML format. */
|
||||
#define CV_NODE_USER 16
|
||||
#define CV_NODE_EMPTY 32
|
||||
#define CV_NODE_NAMED 64
|
||||
@ -1673,7 +1754,7 @@ typedef struct CvString
|
||||
}
|
||||
CvString;
|
||||
|
||||
/* All the keys (names) of elements in the readed file storage
|
||||
/** All the keys (names) of elements in the readed file storage
|
||||
are stored in the hash to speed up the lookup operations: */
|
||||
typedef struct CvStringHashNode
|
||||
{
|
||||
@ -1685,19 +1766,19 @@ CvStringHashNode;
|
||||
|
||||
typedef struct CvGenericHash CvFileNodeHash;
|
||||
|
||||
/* Basic element of the file storage - scalar or collection: */
|
||||
/** Basic element of the file storage - scalar or collection: */
|
||||
typedef struct CvFileNode
|
||||
{
|
||||
int tag;
|
||||
struct CvTypeInfo* info; /* type information
|
||||
struct CvTypeInfo* info; /**< type information
|
||||
(only for user-defined object, for others it is 0) */
|
||||
union
|
||||
{
|
||||
double f; /* scalar floating-point number */
|
||||
int i; /* scalar integer number */
|
||||
CvString str; /* text string */
|
||||
CvSeq* seq; /* sequence (ordered collection of file nodes) */
|
||||
CvFileNodeHash* map; /* map (collection of named file nodes) */
|
||||
double f; /**< scalar floating-point number */
|
||||
int i; /**< scalar integer number */
|
||||
CvString str; /**< text string */
|
||||
CvSeq* seq; /**< sequence (ordered collection of file nodes) */
|
||||
CvFileNodeHash* map; /**< map (collection of named file nodes) */
|
||||
} data;
|
||||
}
|
||||
CvFileNode;
|
||||
@ -1715,18 +1796,28 @@ typedef void* (CV_CDECL *CvCloneFunc)( const void* struct_ptr );
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief Type information
|
||||
|
||||
The structure contains information about one of the standard or user-defined types. Instances of the
|
||||
type may or may not contain a pointer to the corresponding CvTypeInfo structure. In any case, there
|
||||
is a way to find the type info structure for a given object using the cvTypeOf function.
|
||||
Alternatively, type info can be found by type name using cvFindType, which is used when an object
|
||||
is read from file storage. The user can register a new type with cvRegisterType that adds the type
|
||||
information structure into the beginning of the type list. Thus, it is possible to create
|
||||
specialized types from generic standard types and override the basic methods.
|
||||
*/
|
||||
typedef struct CvTypeInfo
|
||||
{
|
||||
int flags;
|
||||
int header_size;
|
||||
struct CvTypeInfo* prev;
|
||||
struct CvTypeInfo* next;
|
||||
const char* type_name;
|
||||
CvIsInstanceFunc is_instance;
|
||||
CvReleaseFunc release;
|
||||
CvReadFunc read;
|
||||
CvWriteFunc write;
|
||||
CvCloneFunc clone;
|
||||
int flags; /**< not used */
|
||||
int header_size; /**< sizeof(CvTypeInfo) */
|
||||
struct CvTypeInfo* prev; /**< previous registered type in the list */
|
||||
struct CvTypeInfo* next; /**< next registered type in the list */
|
||||
const char* type_name; /**< type name, written to file storage */
|
||||
CvIsInstanceFunc is_instance; /**< checks if the passed object belongs to the type */
|
||||
CvReleaseFunc release; /**< releases object (memory etc.) */
|
||||
CvReadFunc read; /**< reads object from file storage */
|
||||
CvWriteFunc write; /**< writes object to file storage */
|
||||
CvCloneFunc clone; /**< creates a copy of the object */
|
||||
}
|
||||
CvTypeInfo;
|
||||
|
||||
@ -1752,6 +1843,8 @@ typedef struct CvModuleInfo
|
||||
}
|
||||
CvModuleInfo;
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /*__OPENCV_CORE_TYPES_H__*/
|
||||
|
||||
/* End of file. */
|
||||
|
@ -77,8 +77,10 @@ CV_EXPORTS void setUseCollection(bool flag); // set implementation collection st
|
||||
#define CV_IMPL_ADD(impl)
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Automatically Allocated Buffer Class
|
||||
//! @addtogroup core_utils
|
||||
//! @{
|
||||
|
||||
/** @brief Automatically Allocated Buffer Class
|
||||
|
||||
The class is used for temporary buffers in functions and methods.
|
||||
If a temporary buffer is usually small (a few K's of memory),
|
||||
@ -144,13 +146,12 @@ protected:
|
||||
_Tp buf[(fixed_size > 0) ? fixed_size : 1];
|
||||
};
|
||||
|
||||
//! Sets/resets the break-on-error mode.
|
||||
/** @brief Sets/resets the break-on-error mode.
|
||||
|
||||
/*!
|
||||
When the break-on-error mode is set, the default error handler
|
||||
issues a hardware exception, which can make debugging more convenient.
|
||||
When the break-on-error mode is set, the default error handler issues a hardware exception, which
|
||||
can make debugging more convenient.
|
||||
|
||||
\return the previous state
|
||||
\return the previous state
|
||||
*/
|
||||
CV_EXPORTS bool setBreakOnError(bool flag);
|
||||
|
||||
@ -158,9 +159,9 @@ extern "C" typedef int (*ErrorCallback)( int status, const char* func_name,
|
||||
const char* err_msg, const char* file_name,
|
||||
int line, void* userdata );
|
||||
|
||||
//! Sets the new error handler and the optional user data.
|
||||
|
||||
/*!
|
||||
/** @brief Sets the new error handler and the optional user data.
|
||||
|
||||
The function sets the new error handler, called from cv::error().
|
||||
|
||||
\param errCallback the new error handler. If NULL, the default error handler is used.
|
||||
@ -171,124 +172,194 @@ extern "C" typedef int (*ErrorCallback)( int status, const char* func_name,
|
||||
*/
|
||||
CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback, void* userdata=0, void** prevUserdata=0);
|
||||
|
||||
/** @brief Returns a text string formatted using the printf-like expression.
|
||||
|
||||
The function acts like sprintf but forms and returns an STL string. It can be used to form an error
|
||||
message in the Exception constructor.
|
||||
@param fmt printf-compatible formatting specifiers.
|
||||
*/
|
||||
CV_EXPORTS String format( const char* fmt, ... );
|
||||
CV_EXPORTS String tempfile( const char* suffix = 0);
|
||||
CV_EXPORTS void glob(String pattern, std::vector<String>& result, bool recursive = false);
|
||||
|
||||
/** @brief OpenCV will try to set the number of threads for the next parallel region.
|
||||
|
||||
If threads == 0, OpenCV will disable threading optimizations and run all it's functions
|
||||
sequentially. Passing threads \< 0 will reset threads number to system default. This function must
|
||||
be called outside of parallel region.
|
||||
|
||||
OpenCV will try to run it's functions with specified threads number, but some behaviour differs from
|
||||
framework:
|
||||
- `TBB` – User-defined parallel constructions will run with the same threads number, if
|
||||
another does not specified. If late on user creates own scheduler, OpenCV will be use it.
|
||||
- `OpenMP` – No special defined behaviour.
|
||||
- `Concurrency` – If threads == 1, OpenCV will disable threading optimizations and run it's
|
||||
functions sequentially.
|
||||
- `GCD` – Supports only values \<= 0.
|
||||
- `C=` – No special defined behaviour.
|
||||
@param nthreads Number of threads used by OpenCV.
|
||||
@sa getNumThreads, getThreadNum
|
||||
*/
|
||||
CV_EXPORTS void setNumThreads(int nthreads);
|
||||
|
||||
/** @brief Returns the number of threads used by OpenCV for parallel regions.
|
||||
|
||||
Always returns 1 if OpenCV is built without threading support.
|
||||
|
||||
The exact meaning of return value depends on the threading framework used by OpenCV library:
|
||||
- `TBB` – The number of threads, that OpenCV will try to use for parallel regions. If there is
|
||||
any tbb::thread_scheduler_init in user code conflicting with OpenCV, then function returns
|
||||
default number of threads used by TBB library.
|
||||
- `OpenMP` – An upper bound on the number of threads that could be used to form a new team.
|
||||
- `Concurrency` – The number of threads, that OpenCV will try to use for parallel regions.
|
||||
- `GCD` – Unsupported; returns the GCD thread pool limit (512) for compatibility.
|
||||
- `C=` – The number of threads, that OpenCV will try to use for parallel regions, if before
|
||||
called setNumThreads with threads \> 0, otherwise returns the number of logical CPUs,
|
||||
available for the process.
|
||||
@sa setNumThreads, getThreadNum
|
||||
*/
|
||||
CV_EXPORTS int getNumThreads();
|
||||
|
||||
/** @brief Returns the index of the currently executed thread within the current parallel region. Always
|
||||
returns 0 if called outside of parallel region.
|
||||
|
||||
The exact meaning of return value depends on the threading framework used by OpenCV library:
|
||||
- `TBB` – Unsupported with current 4.1 TBB release. May be will be supported in future.
|
||||
- `OpenMP` – The thread number, within the current team, of the calling thread.
|
||||
- `Concurrency` – An ID for the virtual processor that the current context is executing on (0
|
||||
for master thread and unique number for others, but not necessary 1,2,3,...).
|
||||
- `GCD` – System calling thread's ID. Never returns 0 inside parallel region.
|
||||
- `C=` – The index of the current parallel task.
|
||||
@sa setNumThreads, getNumThreads
|
||||
*/
|
||||
CV_EXPORTS int getThreadNum();
|
||||
|
||||
/** @brief Returns full configuration time cmake output.
|
||||
|
||||
Returned value is raw cmake output including version control system revision, compiler version,
|
||||
compiler flags, enabled modules and third party libraries, etc. Output format depends on target
|
||||
architecture.
|
||||
*/
|
||||
CV_EXPORTS_W const String& getBuildInformation();
|
||||
|
||||
//! Returns the number of ticks.
|
||||
/** @brief Returns the number of ticks.
|
||||
|
||||
/*!
|
||||
The function returns the number of ticks since the certain event (e.g. when the machine was turned on).
|
||||
It can be used to initialize cv::RNG or to measure a function execution time by reading the tick count
|
||||
before and after the function call. The granularity of ticks depends on the hardware and OS used. Use
|
||||
cv::getTickFrequency() to convert ticks to seconds.
|
||||
*/
|
||||
The function returns the number of ticks after the certain event (for example, when the machine was
|
||||
turned on). It can be used to initialize RNG or to measure a function execution time by reading the
|
||||
tick count before and after the function call. See also the tick frequency.
|
||||
*/
|
||||
CV_EXPORTS_W int64 getTickCount();
|
||||
|
||||
/*!
|
||||
Returns the number of ticks per seconds.
|
||||
/** @brief Returns the number of ticks per second.
|
||||
|
||||
The function returns the number of ticks (as returned by cv::getTickCount()) per second.
|
||||
The following code computes the execution time in milliseconds:
|
||||
|
||||
\code
|
||||
double exec_time = (double)getTickCount();
|
||||
// do something ...
|
||||
exec_time = ((double)getTickCount() - exec_time)*1000./getTickFrequency();
|
||||
\endcode
|
||||
*/
|
||||
The function returns the number of ticks per second. That is, the following code computes the
|
||||
execution time in seconds:
|
||||
@code
|
||||
double t = (double)getTickCount();
|
||||
// do something ...
|
||||
t = ((double)getTickCount() - t)/getTickFrequency();
|
||||
@endcode
|
||||
*/
|
||||
CV_EXPORTS_W double getTickFrequency();
|
||||
|
||||
/*!
|
||||
Returns the number of CPU ticks.
|
||||
/** @brief Returns the number of CPU ticks.
|
||||
|
||||
On platforms where the feature is available, the function returns the number of CPU ticks
|
||||
since the certain event (normally, the system power-on moment). Using this function
|
||||
one can accurately measure the execution time of very small code fragments,
|
||||
for which cv::getTickCount() granularity is not enough.
|
||||
*/
|
||||
The function returns the current number of CPU ticks on some architectures (such as x86, x64,
|
||||
PowerPC). On other platforms the function is equivalent to getTickCount. It can also be used for
|
||||
very accurate time measurements, as well as for RNG initialization. Note that in case of multi-CPU
|
||||
systems a thread, from which getCPUTickCount is called, can be suspended and resumed at another CPU
|
||||
with its own counter. So, theoretically (and practically) the subsequent calls to the function do
|
||||
not necessary return the monotonously increasing values. Also, since a modern CPU varies the CPU
|
||||
frequency depending on the load, the number of CPU clocks spent in some code cannot be directly
|
||||
converted to time units. Therefore, getTickCount is generally a preferable solution for measuring
|
||||
execution time.
|
||||
*/
|
||||
CV_EXPORTS_W int64 getCPUTickCount();
|
||||
|
||||
//! Available CPU features. Currently, the following features are recognized:
|
||||
enum {
|
||||
CPU_MMX = 1,
|
||||
CPU_SSE = 2,
|
||||
CPU_SSE2 = 3,
|
||||
CPU_SSE3 = 4,
|
||||
CPU_SSSE3 = 5,
|
||||
CPU_SSE4_1 = 6,
|
||||
CPU_SSE4_2 = 7,
|
||||
CPU_POPCNT = 8,
|
||||
CPU_AVX = 10,
|
||||
CPU_NEON = 11
|
||||
};
|
||||
// remember to keep this list identical to the one in cvdef.h
|
||||
/** @brief Available CPU features.
|
||||
|
||||
/*!
|
||||
Returns SSE etc. support status
|
||||
|
||||
The function returns true if certain hardware features are available.
|
||||
|
||||
\note {Note that the function output is not static. Once you called cv::useOptimized(false),
|
||||
most of the hardware acceleration is disabled and thus the function will returns false,
|
||||
until you call cv::useOptimized(true)}
|
||||
remember to keep this list identical to the one in cvdef.h
|
||||
*/
|
||||
enum CpuFeatures {
|
||||
CPU_MMX = 1,
|
||||
CPU_SSE = 2,
|
||||
CPU_SSE2 = 3,
|
||||
CPU_SSE3 = 4,
|
||||
CPU_SSSE3 = 5,
|
||||
CPU_SSE4_1 = 6,
|
||||
CPU_SSE4_2 = 7,
|
||||
CPU_POPCNT = 8,
|
||||
CPU_AVX = 10,
|
||||
CPU_NEON = 11
|
||||
};
|
||||
|
||||
/** @brief Returns true if the specified feature is supported by the host hardware.
|
||||
|
||||
The function returns true if the host hardware supports the specified feature. When user calls
|
||||
setUseOptimized(false), the subsequent calls to checkHardwareSupport() will return false until
|
||||
setUseOptimized(true) is called. This way user can dynamically switch on and off the optimized code
|
||||
in OpenCV.
|
||||
@param feature The feature of interest, one of cv::CpuFeatures
|
||||
*/
|
||||
CV_EXPORTS_W bool checkHardwareSupport(int feature);
|
||||
|
||||
//! returns the number of CPUs (including hyper-threading)
|
||||
/** @brief Returns the number of logical CPUs available for the process.
|
||||
*/
|
||||
CV_EXPORTS_W int getNumberOfCPUs();
|
||||
|
||||
|
||||
/*!
|
||||
Aligns pointer by the certain number of bytes
|
||||
/** @brief Aligns a pointer to the specified number of bytes.
|
||||
|
||||
This small inline function aligns the pointer by the certian number of bytes by shifting
|
||||
it forward by 0 or a positive offset.
|
||||
*/
|
||||
The function returns the aligned pointer of the same type as the input pointer:
|
||||
\f[\texttt{(\_Tp*)(((size\_t)ptr + n-1) \& -n)}\f]
|
||||
@param ptr Aligned pointer.
|
||||
@param n Alignment size that must be a power of two.
|
||||
*/
|
||||
template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
|
||||
{
|
||||
return (_Tp*)(((size_t)ptr + n-1) & -n);
|
||||
}
|
||||
|
||||
/*!
|
||||
Aligns buffer size by the certain number of bytes
|
||||
/** @brief Aligns a buffer size to the specified number of bytes.
|
||||
|
||||
This small inline function aligns a buffer size by the certian number of bytes by enlarging it.
|
||||
*/
|
||||
The function returns the minimum number that is greater or equal to sz and is divisible by n :
|
||||
\f[\texttt{(sz + n-1) \& -n}\f]
|
||||
@param sz Buffer size to align.
|
||||
@param n Alignment size that must be a power of two.
|
||||
*/
|
||||
static inline size_t alignSize(size_t sz, int n)
|
||||
{
|
||||
CV_DbgAssert((n & (n - 1)) == 0); // n is a power of 2
|
||||
return (sz + n-1) & -n;
|
||||
}
|
||||
|
||||
/*!
|
||||
Turns on/off available optimization
|
||||
/** @brief Enables or disables the optimized code.
|
||||
|
||||
The function turns on or off the optimized code in OpenCV. Some optimization can not be enabled
|
||||
or disabled, but, for example, most of SSE code in OpenCV can be temporarily turned on or off this way.
|
||||
The function can be used to dynamically turn on and off optimized code (code that uses SSE2, AVX,
|
||||
and other instructions on the platforms that support it). It sets a global flag that is further
|
||||
checked by OpenCV functions. Since the flag is not checked in the inner OpenCV loops, it is only
|
||||
safe to call the function on the very top level in your application where you can be sure that no
|
||||
other OpenCV function is currently executed.
|
||||
|
||||
\note{Since optimization may imply using special data structures, it may be unsafe
|
||||
to call this function anywhere in the code. Instead, call it somewhere at the top level.}
|
||||
*/
|
||||
By default, the optimized code is enabled unless you disable it in CMake. The current status can be
|
||||
retrieved using useOptimized.
|
||||
@param onoff The boolean flag specifying whether the optimized code should be used (onoff=true)
|
||||
or not (onoff=false).
|
||||
*/
|
||||
CV_EXPORTS_W void setUseOptimized(bool onoff);
|
||||
|
||||
/*!
|
||||
Returns the current optimization status
|
||||
/** @brief Returns the status of optimized code usage.
|
||||
|
||||
The function returns the current optimization status, which is controlled by cv::setUseOptimized().
|
||||
*/
|
||||
The function returns true if the optimized code is enabled. Otherwise, it returns false.
|
||||
*/
|
||||
CV_EXPORTS_W bool useOptimized();
|
||||
|
||||
static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); }
|
||||
|
||||
/////////////////////////////// Parallel Primitives //////////////////////////////////
|
||||
|
||||
// a base body class
|
||||
/** @brief Base class for parallel data processors
|
||||
*/
|
||||
class CV_EXPORTS ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
@ -296,6 +367,8 @@ public:
|
||||
virtual void operator() (const Range& range) const = 0;
|
||||
};
|
||||
|
||||
/** @brief Parallel data processor
|
||||
*/
|
||||
CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
|
||||
|
||||
/////////////////////////////// forEach method of cv::Mat ////////////////////////////
|
||||
@ -451,8 +524,58 @@ private:
|
||||
virtual void deleteDataInstance(void* data) const { delete (T*)data; }
|
||||
};
|
||||
|
||||
// The CommandLineParser class is designed for command line arguments parsing
|
||||
/** @brief designed for command line arguments parsing
|
||||
|
||||
The sample below demonstrates how to use CommandLineParser:
|
||||
@code
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
parser.about("Application name v1.0.0");
|
||||
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int N = parser.get<int>("N");
|
||||
double fps = parser.get<double>("fps");
|
||||
String path = parser.get<String>("path");
|
||||
|
||||
use_time_stamp = parser.has("timestamp");
|
||||
|
||||
String img1 = parser.get<String>(0);
|
||||
String img2 = parser.get<String>(1);
|
||||
|
||||
int repeat = parser.get<int>(2);
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return 0;
|
||||
}
|
||||
@endcode
|
||||
Syntax:
|
||||
@code
|
||||
const String keys =
|
||||
"{help h usage ? | | print this message }"
|
||||
"{@image1 | | image1 for compare }"
|
||||
"{@image2 | | image2 for compare }"
|
||||
"{@repeat |1 | number }"
|
||||
"{path |. | path to file }"
|
||||
"{fps | -1.0 | fps for output video }"
|
||||
"{N count |100 | count of objects }"
|
||||
"{ts timestamp | | use time stamp }"
|
||||
;
|
||||
@endcode
|
||||
Use:
|
||||
@code
|
||||
# ./app -N=200 1.png 2.jpg 19 -ts
|
||||
|
||||
# ./app -fps=aaa
|
||||
ERRORS:
|
||||
Exception: can not convert: [aaa] to [double]
|
||||
@endcode
|
||||
*/
|
||||
class CV_EXPORTS CommandLineParser
|
||||
{
|
||||
public:
|
||||
@ -497,6 +620,10 @@ protected:
|
||||
Impl* impl;
|
||||
};
|
||||
|
||||
//! @} core_utils
|
||||
|
||||
//! @cond IGNORED
|
||||
|
||||
/////////////////////////////// AutoBuffer implementation ////////////////////////////////////////
|
||||
|
||||
template<typename _Tp, size_t fixed_size> inline
|
||||
@ -615,6 +742,8 @@ template<> inline std::string CommandLineParser::get<std::string>(const String&
|
||||
}
|
||||
#endif // OPENCV_NOSTL
|
||||
|
||||
//! @endcond
|
||||
|
||||
} //namespace cv
|
||||
|
||||
#endif //__OPENCV_CORE_UTILITY_H__
|
||||
|
@ -1,4 +1,4 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/*M//////////////////////////////////////////////////////////////////////////////
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to
|
||||
@ -36,67 +36,9 @@
|
||||
// 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.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Image class which provides a thin layer around an IplImage. The goals
|
||||
// of the class design are:
|
||||
// 1. All the data has explicit ownership to avoid memory leaks
|
||||
// 2. No hidden allocations or copies for performance.
|
||||
// 3. Easy access to OpenCV methods (which will access IPP if available)
|
||||
// 4. Can easily treat external data as an image
|
||||
// 5. Easy to create images which are subsets of other images
|
||||
// 6. Fast pixel access which can take advantage of number of channels
|
||||
// if known at compile time.
|
||||
//
|
||||
// The WImage class is the image class which provides the data accessors.
|
||||
// The 'W' comes from the fact that it is also a wrapper around the popular
|
||||
// but inconvenient IplImage class. A WImage can be constructed either using a
|
||||
// WImageBuffer class which allocates and frees the data,
|
||||
// or using a WImageView class which constructs a subimage or a view into
|
||||
// external data. The view class does no memory management. Each class
|
||||
// actually has two versions, one when the number of channels is known at
|
||||
// compile time and one when it isn't. Using the one with the number of
|
||||
// channels specified can provide some compile time optimizations by using the
|
||||
// fact that the number of channels is a constant.
|
||||
//
|
||||
// We use the convention (c,r) to refer to column c and row r with (0,0) being
|
||||
// the upper left corner. This is similar to standard Euclidean coordinates
|
||||
// with the first coordinate varying in the horizontal direction and the second
|
||||
// coordinate varying in the vertical direction.
|
||||
// Thus (c,r) is usually in the domain [0, width) X [0, height)
|
||||
//
|
||||
// Example usage:
|
||||
// WImageBuffer3_b im(5,7); // Make a 5X7 3 channel image of type uchar
|
||||
// WImageView3_b sub_im(im, 2,2, 3,3); // 3X3 submatrix
|
||||
// vector<float> vec(10, 3.0f);
|
||||
// WImageView1_f user_im(&vec[0], 2, 5); // 2X5 image w/ supplied data
|
||||
//
|
||||
// im.SetZero(); // same as cvSetZero(im.Ipl())
|
||||
// *im(2, 3) = 15; // Modify the element at column 2, row 3
|
||||
// MySetRand(&sub_im);
|
||||
//
|
||||
// // Copy the second row into the first. This can be done with no memory
|
||||
// // allocation and will use SSE if IPP is available.
|
||||
// int w = im.Width();
|
||||
// im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1));
|
||||
//
|
||||
// // Doesn't care about source of data since using WImage
|
||||
// void MySetRand(WImage_b* im) { // Works with any number of channels
|
||||
// for (int r = 0; r < im->Height(); ++r) {
|
||||
// float* row = im->Row(r);
|
||||
// for (int c = 0; c < im->Width(); ++c) {
|
||||
// for (int ch = 0; ch < im->Channels(); ++ch, ++row) {
|
||||
// *row = uchar(rand() & 255);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Functions that are not part of the basic image allocation, viewing, and
|
||||
// access should come from OpenCV, except some useful functions that are not
|
||||
// part of OpenCV can be found in wimage_util.h
|
||||
//M*/
|
||||
|
||||
#ifndef __OPENCV_CORE_WIMAGE_HPP__
|
||||
#define __OPENCV_CORE_WIMAGE_HPP__
|
||||
|
||||
@ -106,6 +48,9 @@
|
||||
|
||||
namespace cv {
|
||||
|
||||
//! @addtogroup core
|
||||
//! @{
|
||||
|
||||
template <typename T> class WImage;
|
||||
template <typename T> class WImageBuffer;
|
||||
template <typename T> class WImageView;
|
||||
@ -165,12 +110,63 @@ typedef WImageC<ushort, 3> WImage3_16u;
|
||||
typedef WImageViewC<ushort, 3> WImageView3_16u;
|
||||
typedef WImageBufferC<ushort, 3> WImageBuffer3_16u;
|
||||
|
||||
//
|
||||
// WImage definitions
|
||||
//
|
||||
// This WImage class gives access to the data it refers to. It can be
|
||||
// constructed either by allocating the data with a WImageBuffer class or
|
||||
// using the WImageView class to refer to a subimage or outside data.
|
||||
/** @brief Image class which provides a thin layer around an IplImage.
|
||||
|
||||
The goals of the class design are:
|
||||
|
||||
-# All the data has explicit ownership to avoid memory leaks
|
||||
-# No hidden allocations or copies for performance.
|
||||
-# Easy access to OpenCV methods (which will access IPP if available)
|
||||
-# Can easily treat external data as an image
|
||||
-# Easy to create images which are subsets of other images
|
||||
-# Fast pixel access which can take advantage of number of channels if known at compile time.
|
||||
|
||||
The WImage class is the image class which provides the data accessors. The 'W' comes from the fact
|
||||
that it is also a wrapper around the popular but inconvenient IplImage class. A WImage can be
|
||||
constructed either using a WImageBuffer class which allocates and frees the data, or using a
|
||||
WImageView class which constructs a subimage or a view into external data. The view class does no
|
||||
memory management. Each class actually has two versions, one when the number of channels is known
|
||||
at compile time and one when it isn't. Using the one with the number of channels specified can
|
||||
provide some compile time optimizations by using the fact that the number of channels is a
|
||||
constant.
|
||||
|
||||
We use the convention (c,r) to refer to column c and row r with (0,0) being the upper left corner.
|
||||
This is similar to standard Euclidean coordinates with the first coordinate varying in the
|
||||
horizontal direction and the second coordinate varying in the vertical direction. Thus (c,r) is
|
||||
usually in the domain [0, width) X [0, height)
|
||||
|
||||
Example usage:
|
||||
@code
|
||||
WImageBuffer3_b im(5,7); // Make a 5X7 3 channel image of type uchar
|
||||
WImageView3_b sub_im(im, 2,2, 3,3); // 3X3 submatrix
|
||||
vector<float> vec(10, 3.0f);
|
||||
WImageView1_f user_im(&vec[0], 2, 5); // 2X5 image w/ supplied data
|
||||
|
||||
im.SetZero(); // same as cvSetZero(im.Ipl())
|
||||
*im(2, 3) = 15; // Modify the element at column 2, row 3
|
||||
MySetRand(&sub_im);
|
||||
|
||||
// Copy the second row into the first. This can be done with no memory
|
||||
// allocation and will use SSE if IPP is available.
|
||||
int w = im.Width();
|
||||
im.View(0,0, w,1).CopyFrom(im.View(0,1, w,1));
|
||||
|
||||
// Doesn't care about source of data since using WImage
|
||||
void MySetRand(WImage_b* im) { // Works with any number of channels
|
||||
for (int r = 0; r < im->Height(); ++r) {
|
||||
float* row = im->Row(r);
|
||||
for (int c = 0; c < im->Width(); ++c) {
|
||||
for (int ch = 0; ch < im->Channels(); ++ch, ++row) {
|
||||
*row = uchar(rand() & 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
Functions that are not part of the basic image allocation, viewing, and access should come from
|
||||
OpenCV, except some useful functions that are not part of OpenCV can be found in wimage_util.h
|
||||
*/
|
||||
template<typename T>
|
||||
class WImage
|
||||
{
|
||||
@ -252,10 +248,10 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Image class when both the pixel type and number of channels
|
||||
// are known at compile time. This wrapper will speed up some of the operations
|
||||
// like accessing individual pixels using the () operator.
|
||||
/** Image class when both the pixel type and number of channels
|
||||
are known at compile time. This wrapper will speed up some of the operations
|
||||
like accessing individual pixels using the () operator.
|
||||
*/
|
||||
template<typename T, int C>
|
||||
class WImageC : public WImage<T>
|
||||
{
|
||||
@ -292,12 +288,9 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// WImageBuffer definitions
|
||||
//
|
||||
// Image class which owns the data, so it can be allocated and is always
|
||||
// freed. It cannot be copied but can be explicity cloned.
|
||||
//
|
||||
/** Image class which owns the data, so it can be allocated and is always
|
||||
freed. It cannot be copied but can be explicity cloned.
|
||||
*/
|
||||
template<typename T>
|
||||
class WImageBuffer : public WImage<T>
|
||||
{
|
||||
@ -352,8 +345,8 @@ private:
|
||||
void operator=(const WImageBuffer&);
|
||||
};
|
||||
|
||||
// Like a WImageBuffer class but when the number of channels is known
|
||||
// at compile time.
|
||||
/** Like a WImageBuffer class but when the number of channels is known at compile time.
|
||||
*/
|
||||
template<typename T, int C>
|
||||
class WImageBufferC : public WImageC<T, C>
|
||||
{
|
||||
@ -409,14 +402,10 @@ private:
|
||||
void operator=(const WImageBufferC&);
|
||||
};
|
||||
|
||||
//
|
||||
// WImageView definitions
|
||||
//
|
||||
// View into an image class which allows treating a subimage as an image
|
||||
// or treating external data as an image
|
||||
//
|
||||
template<typename T>
|
||||
class WImageView : public WImage<T>
|
||||
/** View into an image class which allows treating a subimage as an image or treating external data
|
||||
as an image
|
||||
*/
|
||||
template<typename T> class WImageView : public WImage<T>
|
||||
{
|
||||
public:
|
||||
typedef typename WImage<T>::BaseType BaseType;
|
||||
@ -518,15 +507,9 @@ inline int WImage<float>::Depth() const {return IPL_DEPTH_32F; }
|
||||
template<>
|
||||
inline int WImage<double>::Depth() const {return IPL_DEPTH_64F; }
|
||||
|
||||
//
|
||||
// Pure virtual destructors still need to be defined.
|
||||
//
|
||||
template<typename T> inline WImage<T>::~WImage() {}
|
||||
template<typename T, int C> inline WImageC<T, C>::~WImageC() {}
|
||||
|
||||
//
|
||||
// Allocate ImageData
|
||||
//
|
||||
template<typename T>
|
||||
inline void WImageBuffer<T>::Allocate(int width, int height, int nchannels)
|
||||
{
|
||||
@ -547,9 +530,6 @@ inline void WImageBufferC<T, C>::Allocate(int width, int height)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ImageView methods
|
||||
//
|
||||
template<typename T>
|
||||
WImageView<T>::WImageView(WImage<T>* img, int c, int r, int width, int height)
|
||||
: WImage<T>(0)
|
||||
@ -614,6 +594,8 @@ WImageViewC<T, C> WImageC<T, C>::View(int c, int r, int width, int height) {
|
||||
return WImageViewC<T, C>(this, c, r, width, height);
|
||||
}
|
||||
|
||||
//! @} core
|
||||
|
||||
} // end of namespace
|
||||
|
||||
#endif // __cplusplus
|
||||
|
@ -168,6 +168,31 @@ static void FastAtan2_32f(const float *Y, const float *X, float *angle, int len,
|
||||
_mm_storeu_ps(angle + i, a);
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
float32x4_t eps = vdupq_n_f32((float)DBL_EPSILON);
|
||||
float32x4_t _90 = vdupq_n_f32(90.f), _180 = vdupq_n_f32(180.f), _360 = vdupq_n_f32(360.f);
|
||||
float32x4_t z = vdupq_n_f32(0.0f), scale4 = vdupq_n_f32(scale);
|
||||
float32x4_t p1 = vdupq_n_f32(atan2_p1), p3 = vdupq_n_f32(atan2_p3);
|
||||
float32x4_t p5 = vdupq_n_f32(atan2_p5), p7 = vdupq_n_f32(atan2_p7);
|
||||
|
||||
for( ; i <= len - 4; i += 4 )
|
||||
{
|
||||
float32x4_t x = vld1q_f32(X + i), y = vld1q_f32(Y + i);
|
||||
float32x4_t ax = vabsq_f32(x), ay = vabsq_f32(y);
|
||||
float32x4_t tmin = vminq_f32(ax, ay), tmax = vmaxq_f32(ax, ay);
|
||||
float32x4_t c = vmulq_f32(tmin, cv_vrecpq_f32(vaddq_f32(tmax, eps)));
|
||||
float32x4_t c2 = vmulq_f32(c, c);
|
||||
float32x4_t a = vmulq_f32(c2, p7);
|
||||
a = vmulq_f32(vaddq_f32(a, p5), c2);
|
||||
a = vmulq_f32(vaddq_f32(a, p3), c2);
|
||||
a = vmulq_f32(vaddq_f32(a, p1), c);
|
||||
|
||||
a = vbslq_f32(vcgeq_f32(ax, ay), a, vsubq_f32(_90, a));
|
||||
a = vbslq_f32(vcltq_f32(x, z), vsubq_f32(_180, a), a);
|
||||
a = vbslq_f32(vcltq_f32(y, z), vsubq_f32(_360, a), a);
|
||||
|
||||
vst1q_f32(angle + i, vmulq_f32(a, scale4));
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; i < len; i++ )
|
||||
@ -268,17 +293,15 @@ static void Magnitude_32f(const float* x, const float* y, float* mag, int len)
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
float CV_DECL_ALIGNED(16) m[4];
|
||||
|
||||
for( ; i <= len - 4; i += 4 )
|
||||
{
|
||||
float32x4_t v_x = vld1q_f32(x + i), v_y = vld1q_f32(y + i);
|
||||
vst1q_f32(m, vaddq_f32(vmulq_f32(v_x, v_x), vmulq_f32(v_y, v_y)));
|
||||
|
||||
mag[i] = std::sqrt(m[0]);
|
||||
mag[i+1] = std::sqrt(m[1]);
|
||||
mag[i+2] = std::sqrt(m[2]);
|
||||
mag[i+3] = std::sqrt(m[3]);
|
||||
vst1q_f32(mag + i, cv_vsqrtq_f32(vmlaq_f32(vmulq_f32(v_x, v_x), v_y, v_y)));
|
||||
}
|
||||
for( ; i <= len - 2; i += 2 )
|
||||
{
|
||||
float32x2_t v_x = vld1_f32(x + i), v_y = vld1_f32(y + i);
|
||||
vst1_f32(mag + i, cv_vsqrt_f32(vmla_f32(vmul_f32(v_x, v_x), v_y, v_y)));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -370,6 +393,12 @@ static void InvSqrt_32f(const float* src, float* dst, int len)
|
||||
_mm_storeu_ps(dst + i, t0); _mm_storeu_ps(dst + i + 4, t1);
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
{
|
||||
vst1q_f32(dst + i, cv_vrsqrtq_f32(vld1q_f32(src + i)));
|
||||
vst1q_f32(dst + i + 4, cv_vrsqrtq_f32(vld1q_f32(src + i + 4)));
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; i < len; i++ )
|
||||
@ -428,6 +457,12 @@ static void Sqrt_32f(const float* src, float* dst, int len)
|
||||
_mm_storeu_ps(dst + i, t0); _mm_storeu_ps(dst + i + 4, t1);
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
{
|
||||
vst1q_f32(dst + i, cv_vsqrtq_f32(vld1q_f32(src + i)));
|
||||
vst1q_f32(dst + i + 4, cv_vsqrtq_f32(vld1q_f32(src + i + 4)));
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; i < len; i++ )
|
||||
@ -869,11 +904,24 @@ void polarToCart( InputArray src1, InputArray src2,
|
||||
|
||||
SinCos_32f( angle, y, x, len, angleInDegrees );
|
||||
if( mag )
|
||||
for( k = 0; k < len; k++ )
|
||||
{
|
||||
k = 0;
|
||||
|
||||
#if CV_NEON
|
||||
for( ; k <= len - 4; k += 4 )
|
||||
{
|
||||
float32x4_t v_m = vld1q_f32(mag + k);
|
||||
vst1q_f32(x + k, vmulq_f32(vld1q_f32(x + k), v_m));
|
||||
vst1q_f32(y + k, vmulq_f32(vld1q_f32(y + k), v_m));
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; k < len; k++ )
|
||||
{
|
||||
float m = mag[k];
|
||||
x[k] *= m; y[k] *= m;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2121,12 +2169,230 @@ void log( InputArray _src, OutputArray _dst )
|
||||
* P O W E R *
|
||||
\****************************************************************************************/
|
||||
|
||||
template <typename T, typename WT>
|
||||
struct iPow_SIMD
|
||||
{
|
||||
int operator() ( const T *, T *, int, int)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#if CV_NEON
|
||||
|
||||
template <>
|
||||
struct iPow_SIMD<uchar, int>
|
||||
{
|
||||
int operator() ( const uchar * src, uchar * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
uint32x4_t v_1 = vdupq_n_u32(1u);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
{
|
||||
uint32x4_t v_a1 = v_1, v_a2 = v_1;
|
||||
uint16x8_t v_src = vmovl_u8(vld1_u8(src + i));
|
||||
uint32x4_t v_b1 = vmovl_u16(vget_low_u16(v_src)), v_b2 = vmovl_u16(vget_high_u16(v_src));
|
||||
int p = power;
|
||||
|
||||
while( p > 1 )
|
||||
{
|
||||
if (p & 1)
|
||||
{
|
||||
v_a1 = vmulq_u32(v_a1, v_b1);
|
||||
v_a2 = vmulq_u32(v_a2, v_b2);
|
||||
}
|
||||
v_b1 = vmulq_u32(v_b1, v_b1);
|
||||
v_b2 = vmulq_u32(v_b2, v_b2);
|
||||
p >>= 1;
|
||||
}
|
||||
|
||||
v_a1 = vmulq_u32(v_a1, v_b1);
|
||||
v_a2 = vmulq_u32(v_a2, v_b2);
|
||||
vst1_u8(dst + i, vqmovn_u16(vcombine_u16(vqmovn_u32(v_a1), vqmovn_u32(v_a2))));
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iPow_SIMD<schar, int>
|
||||
{
|
||||
int operator() ( const schar * src, schar * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
int32x4_t v_1 = vdupq_n_s32(1);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
{
|
||||
int32x4_t v_a1 = v_1, v_a2 = v_1;
|
||||
int16x8_t v_src = vmovl_s8(vld1_s8(src + i));
|
||||
int32x4_t v_b1 = vmovl_s16(vget_low_s16(v_src)), v_b2 = vmovl_s16(vget_high_s16(v_src));
|
||||
int p = power;
|
||||
|
||||
while( p > 1 )
|
||||
{
|
||||
if (p & 1)
|
||||
{
|
||||
v_a1 = vmulq_s32(v_a1, v_b1);
|
||||
v_a2 = vmulq_s32(v_a2, v_b2);
|
||||
}
|
||||
v_b1 = vmulq_s32(v_b1, v_b1);
|
||||
v_b2 = vmulq_s32(v_b2, v_b2);
|
||||
p >>= 1;
|
||||
}
|
||||
|
||||
v_a1 = vmulq_s32(v_a1, v_b1);
|
||||
v_a2 = vmulq_s32(v_a2, v_b2);
|
||||
vst1_s8(dst + i, vqmovn_s16(vcombine_s16(vqmovn_s32(v_a1), vqmovn_s32(v_a2))));
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iPow_SIMD<ushort, int>
|
||||
{
|
||||
int operator() ( const ushort * src, ushort * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
uint32x4_t v_1 = vdupq_n_u32(1u);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
{
|
||||
uint32x4_t v_a1 = v_1, v_a2 = v_1;
|
||||
uint16x8_t v_src = vld1q_u16(src + i);
|
||||
uint32x4_t v_b1 = vmovl_u16(vget_low_u16(v_src)), v_b2 = vmovl_u16(vget_high_u16(v_src));
|
||||
int p = power;
|
||||
|
||||
while( p > 1 )
|
||||
{
|
||||
if (p & 1)
|
||||
{
|
||||
v_a1 = vmulq_u32(v_a1, v_b1);
|
||||
v_a2 = vmulq_u32(v_a2, v_b2);
|
||||
}
|
||||
v_b1 = vmulq_u32(v_b1, v_b1);
|
||||
v_b2 = vmulq_u32(v_b2, v_b2);
|
||||
p >>= 1;
|
||||
}
|
||||
|
||||
v_a1 = vmulq_u32(v_a1, v_b1);
|
||||
v_a2 = vmulq_u32(v_a2, v_b2);
|
||||
vst1q_u16(dst + i, vcombine_u16(vqmovn_u32(v_a1), vqmovn_u32(v_a2)));
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iPow_SIMD<short, int>
|
||||
{
|
||||
int operator() ( const short * src, short * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
int32x4_t v_1 = vdupq_n_s32(1);
|
||||
|
||||
for ( ; i <= len - 8; i += 8)
|
||||
{
|
||||
int32x4_t v_a1 = v_1, v_a2 = v_1;
|
||||
int16x8_t v_src = vld1q_s16(src + i);
|
||||
int32x4_t v_b1 = vmovl_s16(vget_low_s16(v_src)), v_b2 = vmovl_s16(vget_high_s16(v_src));
|
||||
int p = power;
|
||||
|
||||
while( p > 1 )
|
||||
{
|
||||
if (p & 1)
|
||||
{
|
||||
v_a1 = vmulq_s32(v_a1, v_b1);
|
||||
v_a2 = vmulq_s32(v_a2, v_b2);
|
||||
}
|
||||
v_b1 = vmulq_s32(v_b1, v_b1);
|
||||
v_b2 = vmulq_s32(v_b2, v_b2);
|
||||
p >>= 1;
|
||||
}
|
||||
|
||||
v_a1 = vmulq_s32(v_a1, v_b1);
|
||||
v_a2 = vmulq_s32(v_a2, v_b2);
|
||||
vst1q_s16(dst + i, vcombine_s16(vqmovn_s32(v_a1), vqmovn_s32(v_a2)));
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
struct iPow_SIMD<int, int>
|
||||
{
|
||||
int operator() ( const int * src, int * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
int32x4_t v_1 = vdupq_n_s32(1);
|
||||
|
||||
for ( ; i <= len - 4; i += 4)
|
||||
{
|
||||
int32x4_t v_b = vld1q_s32(src + i), v_a = v_1;
|
||||
int p = power;
|
||||
|
||||
while( p > 1 )
|
||||
{
|
||||
if (p & 1)
|
||||
v_a = vmulq_s32(v_a, v_b);
|
||||
v_b = vmulq_s32(v_b, v_b);
|
||||
p >>= 1;
|
||||
}
|
||||
|
||||
v_a = vmulq_s32(v_a, v_b);
|
||||
vst1q_s32(dst + i, v_a);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iPow_SIMD<float, float>
|
||||
{
|
||||
int operator() ( const float * src, float * dst, int len, int power)
|
||||
{
|
||||
int i = 0;
|
||||
float32x4_t v_1 = vdupq_n_f32(1.0f);
|
||||
|
||||
for ( ; i <= len - 4; i += 4)
|
||||
{
|
||||
float32x4_t v_b = vld1q_f32(src + i), v_a = v_1;
|
||||
int p = power;
|
||||
|
||||
while( p > 1 )
|
||||
{
|
||||
if (p & 1)
|
||||
v_a = vmulq_f32(v_a, v_b);
|
||||
v_b = vmulq_f32(v_b, v_b);
|
||||
p >>= 1;
|
||||
}
|
||||
|
||||
v_a = vmulq_f32(v_a, v_b);
|
||||
vst1q_f32(dst + i, v_a);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<typename T, typename WT>
|
||||
static void
|
||||
iPow_( const T* src, T* dst, int len, int power )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < len; i++ )
|
||||
iPow_SIMD<T, WT> vop;
|
||||
int i = vop(src, dst, len, power);
|
||||
|
||||
for( ; i < len; i++ )
|
||||
{
|
||||
WT a = 1, b = src[i];
|
||||
int p = power;
|
||||
@ -2212,8 +2478,8 @@ static bool ocl_pow(InputArray _src, double power, OutputArray _dst,
|
||||
if (depth == CV_64F && !doubleSupport)
|
||||
return false;
|
||||
|
||||
bool issqrt = std::abs(power - 0.5) < DBL_EPSILON, nonnegative = power >= 0;
|
||||
const char * const op = issqrt ? "OP_SQRT" : is_ipower ? nonnegative ? "OP_POWN" : "OP_ROOTN" : nonnegative ? "OP_POWR" : "OP_POW";
|
||||
bool issqrt = std::abs(power - 0.5) < DBL_EPSILON;
|
||||
const char * const op = issqrt ? "OP_SQRT" : is_ipower ? "OP_POWN" : "OP_POW";
|
||||
|
||||
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
|
||||
format("-D dstT=%s -D depth=%d -D rowsPerWI=%d -D %s -D UNARY_OP%s",
|
||||
|
@ -1453,7 +1453,7 @@ bool useOpenCL()
|
||||
{
|
||||
try
|
||||
{
|
||||
data->useOpenCL = (int)haveOpenCL() && Device::getDefault().ptr() != NULL;
|
||||
data->useOpenCL = (int)haveOpenCL() && Device::getDefault().ptr() && Device::getDefault().available();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -2130,7 +2130,8 @@ const Device& Device::getDefault()
|
||||
{
|
||||
const Context& ctx = Context::getDefault();
|
||||
int idx = coreTlsData.get()->device;
|
||||
return ctx.device(idx);
|
||||
const Device& device = ctx.device(idx);
|
||||
return device;
|
||||
}
|
||||
|
||||
////////////////////////////////////// Context ///////////////////////////////////////////////////
|
||||
@ -2210,7 +2211,10 @@ static cl_device_id selectOpenCLDevice()
|
||||
std::vector<std::string> deviceTypes;
|
||||
|
||||
const char* configuration = getenv("OPENCV_OPENCL_DEVICE");
|
||||
if (configuration && !parseOpenCLDeviceConfiguration(std::string(configuration), platform, deviceTypes, deviceName))
|
||||
if (configuration &&
|
||||
(strcmp(configuration, "disabled") == 0 ||
|
||||
!parseOpenCLDeviceConfiguration(std::string(configuration), platform, deviceTypes, deviceName)
|
||||
))
|
||||
return NULL;
|
||||
|
||||
bool isID = false;
|
||||
@ -2339,14 +2343,16 @@ static cl_device_id selectOpenCLDevice()
|
||||
}
|
||||
|
||||
not_found:
|
||||
std::cerr << "ERROR: Required OpenCL device not found, check configuration: " << (configuration == NULL ? "" : configuration) << std::endl
|
||||
if (!configuration)
|
||||
return NULL; // suppress messages on stderr
|
||||
|
||||
std::cerr << "ERROR: Requested OpenCL device not found, check configuration: " << (configuration == NULL ? "" : configuration) << std::endl
|
||||
<< " Platform: " << (platform.length() == 0 ? "any" : platform) << std::endl
|
||||
<< " Device types: ";
|
||||
for (size_t t = 0; t < deviceTypes.size(); t++)
|
||||
std::cerr << deviceTypes[t] << " ";
|
||||
|
||||
std::cerr << std::endl << " Device name: " << (deviceName.length() == 0 ? "any" : deviceName) << std::endl;
|
||||
CV_Error(CL_INVALID_DEVICE, "Requested OpenCL device is not found");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
@ -277,16 +277,6 @@
|
||||
#elif defined OP_POW
|
||||
#define PROCESS_ELEM storedst(pow(srcelem1, srcelem2))
|
||||
|
||||
#elif defined OP_ROOTN
|
||||
#define PROCESS_ELEM storedst(rootn(srcelem1, srcelem2))
|
||||
|
||||
#elif defined OP_POWR
|
||||
#if depth == 5
|
||||
#define PROCESS_ELEM storedst(native_powr(srcelem1, srcelem2))
|
||||
#else
|
||||
#define PROCESS_ELEM storedst(powr(srcelem1, srcelem2))
|
||||
#endif
|
||||
|
||||
#elif defined OP_POWN
|
||||
#undef workT
|
||||
#define workT int
|
||||
|
@ -3212,7 +3212,9 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m
|
||||
type == CV_16UC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C1R :
|
||||
type == CV_16UC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C3R :
|
||||
type == CV_16UC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C4R :
|
||||
#if !(IPP_VERSION_X100 == 802 && (!defined(IPP_VERSION_UPDATE) || IPP_VERSION_UPDATE <= 1)) // Oct 2014: Accuracy issue with IPP 8.2 / 8.2.1
|
||||
type == CV_16SC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C1R :
|
||||
#endif
|
||||
type == CV_16SC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C3R :
|
||||
type == CV_16SC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C4R :
|
||||
0) :
|
||||
|
@ -130,6 +130,12 @@ TEST_P(UMatBasicTests, swap)
|
||||
|
||||
TEST_P(UMatBasicTests, base)
|
||||
{
|
||||
const int align_mask = 3;
|
||||
roi.x &= ~align_mask;
|
||||
roi.y &= ~align_mask;
|
||||
roi.width = (roi.width + align_mask) & ~align_mask;
|
||||
roi &= Rect(0, 0, ua.cols, ua.rows);
|
||||
|
||||
if(useRoi)
|
||||
{
|
||||
ua = UMat(ua,roi);
|
||||
|
@ -430,7 +430,7 @@ Applies a fixed-level threshold to each array element.
|
||||
|
||||
:param maxval: Maximum value to use with ``THRESH_BINARY`` and ``THRESH_BINARY_INV`` threshold types.
|
||||
|
||||
:param type: Threshold type. For details, see :ocv:func:`threshold` . The ``THRESH_OTSU`` threshold type is not supported.
|
||||
:param type: Threshold type. For details, see :ocv:func:`threshold` . The ``THRESH_OTSU`` and ``THRESH_TRIANGLE`` threshold types are not supported.
|
||||
|
||||
:param stream: Stream for the asynchronous version.
|
||||
|
||||
|
@ -128,12 +128,12 @@ PERF_TEST_P(Image_NFeatures, ORB,
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::ORB orb(nFeatures);
|
||||
cv::Ptr<cv::ORB> orb = cv::ORB::create(nFeatures);
|
||||
|
||||
std::vector<cv::KeyPoint> cpu_keypoints;
|
||||
cv::Mat cpu_descriptors;
|
||||
|
||||
TEST_CYCLE() orb(img, cv::noArray(), cpu_keypoints, cpu_descriptors);
|
||||
TEST_CYCLE() orb->detectAndCompute(img, cv::noArray(), cpu_keypoints, cpu_descriptors);
|
||||
|
||||
SANITY_CHECK_KEYPOINTS(cpu_keypoints);
|
||||
SANITY_CHECK(cpu_descriptors);
|
||||
|
@ -185,11 +185,11 @@ CUDA_TEST_P(ORB, Accuracy)
|
||||
cv::cuda::GpuMat descriptors;
|
||||
orb(loadMat(image), loadMat(mask), keypoints, descriptors);
|
||||
|
||||
cv::ORB orb_gold(nFeatures, scaleFactor, nLevels, edgeThreshold, firstLevel, WTA_K, scoreType, patchSize);
|
||||
cv::Ptr<cv::ORB> orb_gold = cv::ORB::create(nFeatures, scaleFactor, nLevels, edgeThreshold, firstLevel, WTA_K, scoreType, patchSize);
|
||||
|
||||
std::vector<cv::KeyPoint> keypoints_gold;
|
||||
cv::Mat descriptors_gold;
|
||||
orb_gold(image, mask, keypoints_gold, descriptors_gold);
|
||||
orb_gold->detectAndCompute(image, mask, keypoints_gold, descriptors_gold);
|
||||
|
||||
cv::BFMatcher matcher(cv::NORM_HAMMING);
|
||||
std::vector<cv::DMatch> matches;
|
||||
|
@ -79,7 +79,7 @@ PERF_TEST_P(ImagePair, StereoBM,
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::Ptr<cv::StereoBM> bm = cv::createStereoBM(ndisp);
|
||||
cv::Ptr<cv::StereoBM> bm = cv::StereoBM::create(ndisp);
|
||||
|
||||
cv::Mat dst;
|
||||
|
||||
|
@ -268,7 +268,7 @@ The function finds the most prominent corners in the image or in the specified i
|
||||
|
||||
The function can be used to initialize a point-based tracker of an object.
|
||||
|
||||
.. note:: If the function is called with different values ``A`` and ``B`` of the parameter ``qualityLevel`` , and ``A`` > {B}, the vector of returned corners with ``qualityLevel=A`` will be the prefix of the output vector with ``qualityLevel=B`` .
|
||||
.. note:: If the function is called with different values ``A`` and ``B`` of the parameter ``qualityLevel`` , and ``A`` > ``B``, the vector of returned corners with ``qualityLevel=A`` will be the prefix of the output vector with ``qualityLevel=B`` .
|
||||
|
||||
.. seealso::
|
||||
|
||||
|
@ -712,11 +712,11 @@ types of thresholding supported by the function. They are determined by ``type``
|
||||
|
||||
\texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise}
|
||||
|
||||
Also, the special value ``THRESH_OTSU`` may be combined with
|
||||
one of the above values. In this case, the function determines the optimal threshold
|
||||
value using the Otsu's algorithm and uses it instead of the specified ``thresh`` .
|
||||
Also, the special values ``THRESH_OTSU`` or ``THRESH_TRIANGLE`` may be combined with
|
||||
one of the above values. In these cases, the function determines the optimal threshold
|
||||
value using the Otsu's or Triangle algorithm and uses it instead of the specified ``thresh`` .
|
||||
The function returns the computed threshold value.
|
||||
Currently, the Otsu's method is implemented only for 8-bit images.
|
||||
Currently, the Otsu's and Triangle methods are implemented only for 8-bit images.
|
||||
|
||||
|
||||
.. image:: pics/threshold.png
|
||||
|
@ -45,12 +45,23 @@
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
/*! \namespace cv
|
||||
Namespace where all the C++ OpenCV functionality resides
|
||||
*/
|
||||
/**
|
||||
@defgroup imgproc Image processing
|
||||
@{
|
||||
@defgroup imgproc_filter Image filtering
|
||||
@defgroup imgproc_transform Image transformations
|
||||
@defgroup imgproc_drawing Drawing functions
|
||||
@defgroup imgproc_shape Structural Analysis and Shape Descriptors
|
||||
@}
|
||||
*/
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
/** @addtogroup imgproc
|
||||
@{
|
||||
*/
|
||||
|
||||
//! type of morphological operation
|
||||
enum { MORPH_ERODE = 0,
|
||||
MORPH_DILATE = 1,
|
||||
@ -109,7 +120,8 @@ enum { THRESH_BINARY = 0, // value = value > threshold ? max_value : 0
|
||||
THRESH_TOZERO = 3, // value = value > threshold ? value : 0
|
||||
THRESH_TOZERO_INV = 4, // value = value > threshold ? 0 : value
|
||||
THRESH_MASK = 7,
|
||||
THRESH_OTSU = 8 // use Otsu algorithm to choose the optimal threshold value
|
||||
THRESH_OTSU = 8, // use Otsu algorithm to choose the optimal threshold value
|
||||
THRESH_TRIANGLE = 16 // use Triangle algorithm to choose the optimal threshold value
|
||||
};
|
||||
|
||||
//! adaptive threshold algorithm
|
||||
@ -1315,6 +1327,8 @@ CV_EXPORTS_W Size getTextSize(const String& text, int fontFace,
|
||||
double fontScale, int thickness,
|
||||
CV_OUT int* baseLine);
|
||||
|
||||
/** @} */
|
||||
|
||||
} // cv
|
||||
|
||||
#endif
|
||||
|
@ -551,8 +551,11 @@ enum
|
||||
CV_THRESH_TOZERO =3, /* value = value > threshold ? value : 0 */
|
||||
CV_THRESH_TOZERO_INV =4, /* value = value > threshold ? 0 : value */
|
||||
CV_THRESH_MASK =7,
|
||||
CV_THRESH_OTSU =8 /* use Otsu algorithm to choose the optimal threshold value;
|
||||
CV_THRESH_OTSU =8, /* use Otsu algorithm to choose the optimal threshold value;
|
||||
combine the flag with one of the above CV_THRESH_* values */
|
||||
CV_THRESH_TRIANGLE =16 /* use Triangle algorithm to choose the optimal threshold value;
|
||||
combine the flag with one of the above CV_THRESH_* values, but not
|
||||
with CV_THRESH_OTSU */
|
||||
};
|
||||
|
||||
/* Adaptive threshold methods */
|
||||
|
@ -138,10 +138,10 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
|
||||
*/
|
||||
char cvt[40];
|
||||
ocl::Kernel with_sobel("stage1_with_sobel", ocl::imgproc::canny_oclsrc,
|
||||
format("-D WITH_SOBEL -D cn=%d -D TYPE=%s -D convert_intN=%s -D intN=%s -D GRP_SIZEX=%d -D GRP_SIZEY=%d%s",
|
||||
format("-D WITH_SOBEL -D cn=%d -D TYPE=%s -D convert_floatN=%s -D floatN=%s -D GRP_SIZEX=%d -D GRP_SIZEY=%d%s",
|
||||
cn, ocl::memopTypeToStr(_src.depth()),
|
||||
ocl::convertTypeStr(_src.type(), CV_32SC(cn), cn, cvt),
|
||||
ocl::memopTypeToStr(CV_32SC(cn)),
|
||||
ocl::convertTypeStr(_src.depth(), CV_32F, cn, cvt),
|
||||
ocl::typeToStr(CV_MAKE_TYPE(CV_32F, cn)),
|
||||
lSizeX, lSizeY,
|
||||
L2gradient ? " -D L2GRAD" : ""));
|
||||
if (with_sobel.empty())
|
||||
@ -151,7 +151,7 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
|
||||
map.create(size, CV_32S);
|
||||
with_sobel.args(ocl::KernelArg::ReadOnly(src),
|
||||
ocl::KernelArg::WriteOnlyNoSize(map),
|
||||
low, high);
|
||||
(float) low, (float) high);
|
||||
|
||||
size_t globalsize[2] = { size.width, size.height },
|
||||
localsize[2] = { lSizeX, lSizeY };
|
||||
@ -453,7 +453,7 @@ void cv::Canny( InputArray _src, OutputArray _dst,
|
||||
if ((stack_top - stack_bottom) + src.cols > maxsize)
|
||||
{
|
||||
int sz = (int)(stack_top - stack_bottom);
|
||||
maxsize = maxsize * 3/2;
|
||||
maxsize = std::max(maxsize * 3/2, sz + src.cols);
|
||||
stack.resize(maxsize);
|
||||
stack_bottom = &stack[0];
|
||||
stack_top = stack_bottom + sz;
|
||||
|
@ -69,7 +69,7 @@ static void calcMinEigenVal( const Mat& _cov, Mat& _dst )
|
||||
if( simd )
|
||||
{
|
||||
__m128 half = _mm_set1_ps(0.5f);
|
||||
for( ; j <= size.width - 5; j += 4 )
|
||||
for( ; j <= size.width - 4; j += 4 )
|
||||
{
|
||||
__m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x
|
||||
__m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x
|
||||
@ -90,6 +90,19 @@ static void calcMinEigenVal( const Mat& _cov, Mat& _dst )
|
||||
_mm_storeu_ps(dst + j, a);
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
float32x4_t v_half = vdupq_n_f32(0.5f);
|
||||
for( ; j <= size.width - 4; j += 4 )
|
||||
{
|
||||
float32x4x3_t v_src = vld3q_f32(cov + j * 3);
|
||||
float32x4_t v_a = vmulq_f32(v_src.val[0], v_half);
|
||||
float32x4_t v_b = v_src.val[1];
|
||||
float32x4_t v_c = vmulq_f32(v_src.val[2], v_half);
|
||||
|
||||
float32x4_t v_t = vsubq_f32(v_a, v_c);
|
||||
v_t = vmlaq_f32(vmulq_f32(v_t, v_t), v_b, v_b);
|
||||
vst1q_f32(dst + j, vsubq_f32(vaddq_f32(v_a, v_c), cv_vsqrtq_f32(v_t)));
|
||||
}
|
||||
#endif
|
||||
for( ; j < size.width; j++ )
|
||||
{
|
||||
@ -290,8 +303,24 @@ cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
|
||||
float* cov_data = cov.ptr<float>(i);
|
||||
const float* dxdata = Dx.ptr<float>(i);
|
||||
const float* dydata = Dy.ptr<float>(i);
|
||||
j = 0;
|
||||
|
||||
for( j = 0; j < size.width; j++ )
|
||||
#if CV_NEON
|
||||
for( ; j <= size.width - 4; j += 4 )
|
||||
{
|
||||
float32x4_t v_dx = vld1q_f32(dxdata + j);
|
||||
float32x4_t v_dy = vld1q_f32(dydata + j);
|
||||
|
||||
float32x4x3_t v_dst;
|
||||
v_dst.val[0] = vmulq_f32(v_dx, v_dx);
|
||||
v_dst.val[1] = vmulq_f32(v_dx, v_dy);
|
||||
v_dst.val[2] = vmulq_f32(v_dy, v_dy);
|
||||
|
||||
vst3q_f32(cov_data + j * 3, v_dst);
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; j < size.width; j++ )
|
||||
{
|
||||
float dx = dxdata[j];
|
||||
float dy = dydata[j];
|
||||
|
@ -2316,7 +2316,16 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
|
||||
}
|
||||
else if( method == CV_COMP_INTERSECT )
|
||||
{
|
||||
for( j = 0; j < len; j++ )
|
||||
j = 0;
|
||||
#if CV_NEON
|
||||
float32x4_t v_result = vdupq_n_f32(0.0f);
|
||||
for( ; j <= len - 4; j += 4 )
|
||||
v_result = vaddq_f32(v_result, vminq_f32(vld1q_f32(h1 + j), vld1q_f32(h2 + j)));
|
||||
float CV_DECL_ALIGNED(16) ar[4];
|
||||
vst1q_f32(ar, v_result);
|
||||
result += ar[0] + ar[1] + ar[2] + ar[3];
|
||||
#endif
|
||||
for( ; j < len; j++ )
|
||||
result += std::min(h1[j], h2[j]);
|
||||
}
|
||||
else if( method == CV_COMP_BHATTACHARYYA )
|
||||
|
@ -303,7 +303,7 @@ HoughLinesSDiv( const Mat& img,
|
||||
ti1 < halftn; ti1++, phi += theta_it, phi1 += scale_factor )
|
||||
{
|
||||
rv = r0 * std::cos( phi );
|
||||
i = cvFloor( rv ) * tn;
|
||||
i = (int)rv * tn;
|
||||
i += cvFloor( phi1 );
|
||||
assert( i >= 0 );
|
||||
assert( i < rn * tn );
|
||||
|
@ -133,7 +133,7 @@ static uchar NNDeltaTab_i[INTER_TAB_SIZE2][2];
|
||||
static float BilinearTab_f[INTER_TAB_SIZE2][2][2];
|
||||
static short BilinearTab_i[INTER_TAB_SIZE2][2][2];
|
||||
|
||||
#if CV_SSE2
|
||||
#if CV_SSE2 || CV_NEON
|
||||
static short BilinearTab_iC4_buf[INTER_TAB_SIZE2+2][2][8];
|
||||
static short (*BilinearTab_iC4)[2][8] = (short (*)[2][8])alignPtr(BilinearTab_iC4_buf, 16);
|
||||
#endif
|
||||
@ -269,7 +269,7 @@ static const void* initInterTab2D( int method, bool fixpt )
|
||||
}
|
||||
tab -= INTER_TAB_SIZE2*ksize*ksize;
|
||||
itab -= INTER_TAB_SIZE2*ksize*ksize;
|
||||
#if CV_SSE2
|
||||
#if CV_SSE2 || CV_NEON
|
||||
if( method == INTER_LINEAR )
|
||||
{
|
||||
for( i = 0; i < INTER_TAB_SIZE2; i++ )
|
||||
@ -894,9 +894,51 @@ struct VResizeCubicVec_32f
|
||||
}
|
||||
};
|
||||
|
||||
typedef VResizeNoVec VResizeLanczos4Vec_32f16u;
|
||||
typedef VResizeNoVec VResizeLanczos4Vec_32f16s;
|
||||
typedef VResizeNoVec VResizeLanczos4Vec_32f;
|
||||
|
||||
#elif CV_NEON
|
||||
|
||||
typedef VResizeNoVec VResizeLinearVec_32s8u;
|
||||
struct VResizeLinearVec_32s8u
|
||||
{
|
||||
int operator()(const uchar** _src, uchar* dst, const uchar* _beta, int width ) const
|
||||
{
|
||||
const int** src = (const int**)_src, *S0 = src[0], *S1 = src[1];
|
||||
const short* beta = (const short*)_beta;
|
||||
int x = 0;
|
||||
int16x8_t v_b0 = vdupq_n_s16(beta[0]), v_b1 = vdupq_n_s16(beta[1]), v_delta = vdupq_n_s16(2);
|
||||
|
||||
for( ; x <= width - 16; x += 16)
|
||||
{
|
||||
int32x4_t v_src00 = vshrq_n_s32(vld1q_s32(S0 + x), 4), v_src10 = vshrq_n_s32(vld1q_s32(S1 + x), 4);
|
||||
int32x4_t v_src01 = vshrq_n_s32(vld1q_s32(S0 + x + 4), 4), v_src11 = vshrq_n_s32(vld1q_s32(S1 + x + 4), 4);
|
||||
|
||||
int16x8_t v_src0 = vcombine_s16(vmovn_s32(v_src00), vmovn_s32(v_src01));
|
||||
int16x8_t v_src1 = vcombine_s16(vmovn_s32(v_src10), vmovn_s32(v_src11));
|
||||
|
||||
int16x8_t v_dst0 = vaddq_s16(vshrq_n_s16(vqdmulhq_s16(v_src0, v_b0), 1),
|
||||
vshrq_n_s16(vqdmulhq_s16(v_src1, v_b1), 1));
|
||||
v_dst0 = vshrq_n_s16(vaddq_s16(v_dst0, v_delta), 2);
|
||||
|
||||
v_src00 = vshrq_n_s32(vld1q_s32(S0 + x + 8), 4);
|
||||
v_src10 = vshrq_n_s32(vld1q_s32(S1 + x + 8), 4);
|
||||
v_src01 = vshrq_n_s32(vld1q_s32(S0 + x + 12), 4);
|
||||
v_src11 = vshrq_n_s32(vld1q_s32(S1 + x + 12), 4);
|
||||
|
||||
v_src0 = vcombine_s16(vmovn_s32(v_src00), vmovn_s32(v_src01));
|
||||
v_src1 = vcombine_s16(vmovn_s32(v_src10), vmovn_s32(v_src11));
|
||||
|
||||
int16x8_t v_dst1 = vaddq_s16(vshrq_n_s16(vqdmulhq_s16(v_src0, v_b0), 1),
|
||||
vshrq_n_s16(vqdmulhq_s16(v_src1, v_b1), 1));
|
||||
v_dst1 = vshrq_n_s16(vaddq_s16(v_dst1, v_delta), 2);
|
||||
|
||||
vst1q_u8(dst + x, vcombine_u8(vqmovun_s16(v_dst0), vqmovun_s16(v_dst1)));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
struct VResizeLinearVec_32f16u
|
||||
{
|
||||
@ -1071,6 +1113,128 @@ struct VResizeCubicVec_32f
|
||||
}
|
||||
};
|
||||
|
||||
struct VResizeLanczos4Vec_32f16u
|
||||
{
|
||||
int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const
|
||||
{
|
||||
const float** src = (const float**)_src;
|
||||
const float* beta = (const float*)_beta;
|
||||
const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3],
|
||||
*S4 = src[4], *S5 = src[5], *S6 = src[6], *S7 = src[7];
|
||||
ushort * dst = (ushort*)_dst;
|
||||
int x = 0;
|
||||
float32x4_t v_b0 = vdupq_n_f32(beta[0]), v_b1 = vdupq_n_f32(beta[1]),
|
||||
v_b2 = vdupq_n_f32(beta[2]), v_b3 = vdupq_n_f32(beta[3]),
|
||||
v_b4 = vdupq_n_f32(beta[4]), v_b5 = vdupq_n_f32(beta[5]),
|
||||
v_b6 = vdupq_n_f32(beta[6]), v_b7 = vdupq_n_f32(beta[7]);
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
float32x4_t v_dst0 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b0, vld1q_f32(S0 + x)),
|
||||
v_b1, vld1q_f32(S1 + x)),
|
||||
v_b2, vld1q_f32(S2 + x)),
|
||||
v_b3, vld1q_f32(S3 + x));
|
||||
float32x4_t v_dst1 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b4, vld1q_f32(S4 + x)),
|
||||
v_b5, vld1q_f32(S5 + x)),
|
||||
v_b6, vld1q_f32(S6 + x)),
|
||||
v_b7, vld1q_f32(S7 + x));
|
||||
float32x4_t v_dst = vaddq_f32(v_dst0, v_dst1);
|
||||
|
||||
v_dst0 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b0, vld1q_f32(S0 + x + 4)),
|
||||
v_b1, vld1q_f32(S1 + x + 4)),
|
||||
v_b2, vld1q_f32(S2 + x + 4)),
|
||||
v_b3, vld1q_f32(S3 + x + 4));
|
||||
v_dst1 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b4, vld1q_f32(S4 + x + 4)),
|
||||
v_b5, vld1q_f32(S5 + x + 4)),
|
||||
v_b6, vld1q_f32(S6 + x + 4)),
|
||||
v_b7, vld1q_f32(S7 + x + 4));
|
||||
v_dst1 = vaddq_f32(v_dst0, v_dst1);
|
||||
|
||||
vst1q_u16(dst + x, vcombine_u16(vqmovn_u32(cv_vrndq_u32_f32(v_dst)),
|
||||
vqmovn_u32(cv_vrndq_u32_f32(v_dst1))));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
struct VResizeLanczos4Vec_32f16s
|
||||
{
|
||||
int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const
|
||||
{
|
||||
const float** src = (const float**)_src;
|
||||
const float* beta = (const float*)_beta;
|
||||
const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3],
|
||||
*S4 = src[4], *S5 = src[5], *S6 = src[6], *S7 = src[7];
|
||||
short * dst = (short*)_dst;
|
||||
int x = 0;
|
||||
float32x4_t v_b0 = vdupq_n_f32(beta[0]), v_b1 = vdupq_n_f32(beta[1]),
|
||||
v_b2 = vdupq_n_f32(beta[2]), v_b3 = vdupq_n_f32(beta[3]),
|
||||
v_b4 = vdupq_n_f32(beta[4]), v_b5 = vdupq_n_f32(beta[5]),
|
||||
v_b6 = vdupq_n_f32(beta[6]), v_b7 = vdupq_n_f32(beta[7]);
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
float32x4_t v_dst0 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b0, vld1q_f32(S0 + x)),
|
||||
v_b1, vld1q_f32(S1 + x)),
|
||||
v_b2, vld1q_f32(S2 + x)),
|
||||
v_b3, vld1q_f32(S3 + x));
|
||||
float32x4_t v_dst1 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b4, vld1q_f32(S4 + x)),
|
||||
v_b5, vld1q_f32(S5 + x)),
|
||||
v_b6, vld1q_f32(S6 + x)),
|
||||
v_b7, vld1q_f32(S7 + x));
|
||||
float32x4_t v_dst = vaddq_f32(v_dst0, v_dst1);
|
||||
|
||||
v_dst0 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b0, vld1q_f32(S0 + x + 4)),
|
||||
v_b1, vld1q_f32(S1 + x + 4)),
|
||||
v_b2, vld1q_f32(S2 + x + 4)),
|
||||
v_b3, vld1q_f32(S3 + x + 4));
|
||||
v_dst1 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b4, vld1q_f32(S4 + x + 4)),
|
||||
v_b5, vld1q_f32(S5 + x + 4)),
|
||||
v_b6, vld1q_f32(S6 + x + 4)),
|
||||
v_b7, vld1q_f32(S7 + x + 4));
|
||||
v_dst1 = vaddq_f32(v_dst0, v_dst1);
|
||||
|
||||
vst1q_s16(dst + x, vcombine_s16(vqmovn_s32(cv_vrndq_s32_f32(v_dst)),
|
||||
vqmovn_s32(cv_vrndq_s32_f32(v_dst1))));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
struct VResizeLanczos4Vec_32f
|
||||
{
|
||||
int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const
|
||||
{
|
||||
const float** src = (const float**)_src;
|
||||
const float* beta = (const float*)_beta;
|
||||
const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3],
|
||||
*S4 = src[4], *S5 = src[5], *S6 = src[6], *S7 = src[7];
|
||||
float* dst = (float*)_dst;
|
||||
int x = 0;
|
||||
float32x4_t v_b0 = vdupq_n_f32(beta[0]), v_b1 = vdupq_n_f32(beta[1]),
|
||||
v_b2 = vdupq_n_f32(beta[2]), v_b3 = vdupq_n_f32(beta[3]),
|
||||
v_b4 = vdupq_n_f32(beta[4]), v_b5 = vdupq_n_f32(beta[5]),
|
||||
v_b6 = vdupq_n_f32(beta[6]), v_b7 = vdupq_n_f32(beta[7]);
|
||||
|
||||
for( ; x <= width - 4; x += 4 )
|
||||
{
|
||||
float32x4_t v_dst0 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b0, vld1q_f32(S0 + x)),
|
||||
v_b1, vld1q_f32(S1 + x)),
|
||||
v_b2, vld1q_f32(S2 + x)),
|
||||
v_b3, vld1q_f32(S3 + x));
|
||||
float32x4_t v_dst1 = vmlaq_f32(vmlaq_f32(vmlaq_f32(vmulq_f32(v_b4, vld1q_f32(S4 + x)),
|
||||
v_b5, vld1q_f32(S5 + x)),
|
||||
v_b6, vld1q_f32(S6 + x)),
|
||||
v_b7, vld1q_f32(S7 + x));
|
||||
vst1q_f32(dst + x, vaddq_f32(v_dst0, v_dst1));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef VResizeNoVec VResizeLinearVec_32s8u;
|
||||
@ -1083,6 +1247,10 @@ typedef VResizeNoVec VResizeCubicVec_32f16u;
|
||||
typedef VResizeNoVec VResizeCubicVec_32f16s;
|
||||
typedef VResizeNoVec VResizeCubicVec_32f;
|
||||
|
||||
typedef VResizeNoVec VResizeLanczos4Vec_32f16u;
|
||||
typedef VResizeNoVec VResizeLanczos4Vec_32f16s;
|
||||
typedef VResizeNoVec VResizeLanczos4Vec_32f;
|
||||
|
||||
#endif
|
||||
|
||||
typedef HResizeNoVec HResizeLinearVec_8u32s;
|
||||
@ -1611,6 +1779,107 @@ private:
|
||||
int cn, step;
|
||||
};
|
||||
|
||||
class ResizeAreaFastVec_SIMD_16s
|
||||
{
|
||||
public:
|
||||
ResizeAreaFastVec_SIMD_16s(int _cn, int _step) :
|
||||
cn(_cn), step(_step)
|
||||
{
|
||||
}
|
||||
|
||||
int operator() (const short * S, short * D, int w) const
|
||||
{
|
||||
int dx = 0;
|
||||
const short * S0 = S, * S1 = (const short *)((const uchar *)(S0) + step);
|
||||
|
||||
int32x4_t v_2 = vdupq_n_s32(2);
|
||||
|
||||
if (cn == 1)
|
||||
{
|
||||
for ( ; dx <= w - 8; dx += 8, S0 += 16, S1 += 16, D += 8)
|
||||
{
|
||||
int16x8x2_t v_row0 = vld2q_s16(S0), v_row1 = vld2q_s16(S1);
|
||||
|
||||
int32x4_t v_dst0 = vaddl_s16(vget_low_s16(v_row0.val[0]), vget_low_s16(v_row0.val[1]));
|
||||
v_dst0 = vaddq_s32(v_dst0, vaddl_s16(vget_low_s16(v_row1.val[0]), vget_low_s16(v_row1.val[1])));
|
||||
v_dst0 = vshrq_n_s32(vaddq_s32(v_dst0, v_2), 2);
|
||||
|
||||
int32x4_t v_dst1 = vaddl_s16(vget_high_s16(v_row0.val[0]), vget_high_s16(v_row0.val[1]));
|
||||
v_dst1 = vaddq_s32(v_dst1, vaddl_s16(vget_high_s16(v_row1.val[0]), vget_high_s16(v_row1.val[1])));
|
||||
v_dst1 = vshrq_n_s32(vaddq_s32(v_dst1, v_2), 2);
|
||||
|
||||
vst1q_s16(D, vcombine_s16(vmovn_s32(v_dst0), vmovn_s32(v_dst1)));
|
||||
}
|
||||
}
|
||||
else if (cn == 4)
|
||||
{
|
||||
for ( ; dx <= w - 4; dx += 4, S0 += 8, S1 += 8, D += 4)
|
||||
{
|
||||
int16x8_t v_row0 = vld1q_s16(S0), v_row1 = vld1q_s16(S1);
|
||||
int32x4_t v_dst = vaddq_s32(vaddl_s16(vget_low_s16(v_row0), vget_high_s16(v_row0)),
|
||||
vaddl_s16(vget_low_s16(v_row1), vget_high_s16(v_row1)));
|
||||
vst1_s16(D, vmovn_s32(vshrq_n_s32(vaddq_s32(v_dst, v_2), 2)));
|
||||
}
|
||||
}
|
||||
|
||||
return dx;
|
||||
}
|
||||
|
||||
private:
|
||||
int cn, step;
|
||||
};
|
||||
|
||||
struct ResizeAreaFastVec_SIMD_32f
|
||||
{
|
||||
ResizeAreaFastVec_SIMD_32f(int _scale_x, int _scale_y, int _cn, int _step) :
|
||||
scale_x(_scale_x), scale_y(_scale_y), cn(_cn), step(_step)
|
||||
{
|
||||
fast_mode = scale_x == 2 && scale_y == 2 && (cn == 1 || cn == 3 || cn == 4);
|
||||
}
|
||||
|
||||
int operator() (const float * S, float * D, int w) const
|
||||
{
|
||||
if (!fast_mode)
|
||||
return 0;
|
||||
|
||||
const float * S0 = S, * S1 = (const float *)((const uchar *)(S0) + step);
|
||||
int dx = 0;
|
||||
|
||||
float32x4_t v_025 = vdupq_n_f32(0.25f);
|
||||
|
||||
if (cn == 1)
|
||||
{
|
||||
for ( ; dx <= w - 4; dx += 4, S0 += 8, S1 += 8, D += 4)
|
||||
{
|
||||
float32x4x2_t v_row0 = vld2q_f32(S0), v_row1 = vld2q_f32(S1);
|
||||
|
||||
float32x4_t v_dst0 = vaddq_f32(v_row0.val[0], v_row0.val[1]);
|
||||
float32x4_t v_dst1 = vaddq_f32(v_row1.val[0], v_row1.val[1]);
|
||||
|
||||
vst1q_f32(D, vmulq_f32(vaddq_f32(v_dst0, v_dst1), v_025));
|
||||
}
|
||||
}
|
||||
else if (cn == 4)
|
||||
{
|
||||
for ( ; dx <= w - 4; dx += 4, S0 += 8, S1 += 8, D += 4)
|
||||
{
|
||||
float32x4_t v_dst0 = vaddq_f32(vld1q_f32(S0), vld1q_f32(S0 + 4));
|
||||
float32x4_t v_dst1 = vaddq_f32(vld1q_f32(S1), vld1q_f32(S1 + 4));
|
||||
|
||||
vst1q_f32(D, vmulq_f32(vaddq_f32(v_dst0, v_dst1), v_025));
|
||||
}
|
||||
}
|
||||
|
||||
return dx;
|
||||
}
|
||||
|
||||
private:
|
||||
int scale_x, scale_y;
|
||||
int cn;
|
||||
bool fast_mode;
|
||||
int step;
|
||||
};
|
||||
|
||||
#elif CV_SSE2
|
||||
|
||||
class ResizeAreaFastVec_SIMD_8u
|
||||
@ -1800,9 +2069,16 @@ private:
|
||||
bool use_simd;
|
||||
};
|
||||
|
||||
typedef ResizeAreaFastNoVec<short, short> ResizeAreaFastVec_SIMD_16s;
|
||||
typedef ResizeAreaFastNoVec<float, float> ResizeAreaFastVec_SIMD_32f;
|
||||
|
||||
#else
|
||||
|
||||
typedef ResizeAreaFastNoVec<uchar, uchar> ResizeAreaFastVec_SIMD_8u;
|
||||
typedef ResizeAreaFastNoVec<ushort, ushort> ResizeAreaFastVec_SIMD_16u;
|
||||
typedef ResizeAreaFastNoVec<short, short> ResizeAreaFastVec_SIMD_16s;
|
||||
typedef ResizeAreaFastNoVec<float, float> ResizeAreaFastVec_SIMD_32f;
|
||||
|
||||
#endif
|
||||
|
||||
template<typename T, typename SIMDVecOp>
|
||||
@ -2626,14 +2902,14 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
|
||||
0,
|
||||
resizeGeneric_<HResizeLanczos4<ushort, float, float>,
|
||||
VResizeLanczos4<ushort, float, float, Cast<float, ushort>,
|
||||
VResizeNoVec> >,
|
||||
VResizeLanczos4Vec_32f16u> >,
|
||||
resizeGeneric_<HResizeLanczos4<short, float, float>,
|
||||
VResizeLanczos4<short, float, float, Cast<float, short>,
|
||||
VResizeNoVec> >,
|
||||
VResizeLanczos4Vec_32f16s> >,
|
||||
0,
|
||||
resizeGeneric_<HResizeLanczos4<float, float, float>,
|
||||
VResizeLanczos4<float, float, float, Cast<float, float>,
|
||||
VResizeNoVec> >,
|
||||
VResizeLanczos4Vec_32f> >,
|
||||
resizeGeneric_<HResizeLanczos4<double, double, float>,
|
||||
VResizeLanczos4<double, double, float, Cast<double, double>,
|
||||
VResizeNoVec> >,
|
||||
@ -2645,9 +2921,9 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
|
||||
resizeAreaFast_<uchar, int, ResizeAreaFastVec<uchar, ResizeAreaFastVec_SIMD_8u> >,
|
||||
0,
|
||||
resizeAreaFast_<ushort, float, ResizeAreaFastVec<ushort, ResizeAreaFastVec_SIMD_16u> >,
|
||||
resizeAreaFast_<short, float, ResizeAreaFastVec<short, ResizeAreaFastNoVec<short, float> > >,
|
||||
resizeAreaFast_<short, float, ResizeAreaFastVec<short, ResizeAreaFastVec_SIMD_16s> >,
|
||||
0,
|
||||
resizeAreaFast_<float, float, ResizeAreaFastNoVec<float, float> >,
|
||||
resizeAreaFast_<float, float, ResizeAreaFastVec_SIMD_32f>,
|
||||
resizeAreaFast_<double, double, ResizeAreaFastNoVec<double, double> >,
|
||||
0
|
||||
};
|
||||
@ -4281,17 +4557,59 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
float* dst2f = dstmap2.ptr<float>(y);
|
||||
short* dst1 = (short*)dst1f;
|
||||
ushort* dst2 = (ushort*)dst2f;
|
||||
x = 0;
|
||||
|
||||
if( m1type == CV_32FC1 && dstm1type == CV_16SC2 )
|
||||
{
|
||||
if( nninterpolate )
|
||||
for( x = 0; x < size.width; x++ )
|
||||
{
|
||||
#if CV_NEON
|
||||
for( ; x <= size.width - 8; x += 8 )
|
||||
{
|
||||
int16x8x2_t v_dst;
|
||||
v_dst.val[0] = vcombine_s16(vqmovn_s32(cv_vrndq_s32_f32(vld1q_f32(src1f + x))),
|
||||
vqmovn_s32(cv_vrndq_s32_f32(vld1q_f32(src1f + x + 4))));
|
||||
v_dst.val[1] = vcombine_s16(vqmovn_s32(cv_vrndq_s32_f32(vld1q_f32(src2f + x))),
|
||||
vqmovn_s32(cv_vrndq_s32_f32(vld1q_f32(src2f + x + 4))));
|
||||
|
||||
vst2q_s16(dst1 + (x << 1), v_dst);
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
dst1[x*2] = saturate_cast<short>(src1f[x]);
|
||||
dst1[x*2+1] = saturate_cast<short>(src2f[x]);
|
||||
}
|
||||
}
|
||||
else
|
||||
for( x = 0; x < size.width; x++ )
|
||||
{
|
||||
#if CV_NEON
|
||||
float32x4_t v_scale = vdupq_n_f32((float)INTER_TAB_SIZE);
|
||||
int32x4_t v_mask = vdupq_n_s32(INTER_TAB_SIZE - 1);
|
||||
|
||||
for( ; x <= size.width - 8; x += 8 )
|
||||
{
|
||||
int32x4_t v_ix0 = cv_vrndq_s32_f32(vmulq_f32(vld1q_f32(src1f + x), v_scale));
|
||||
int32x4_t v_ix1 = cv_vrndq_s32_f32(vmulq_f32(vld1q_f32(src1f + x + 4), v_scale));
|
||||
int32x4_t v_iy0 = cv_vrndq_s32_f32(vmulq_f32(vld1q_f32(src2f + x), v_scale));
|
||||
int32x4_t v_iy1 = cv_vrndq_s32_f32(vmulq_f32(vld1q_f32(src2f + x + 4), v_scale));
|
||||
|
||||
int16x8x2_t v_dst;
|
||||
v_dst.val[0] = vcombine_s16(vqmovn_s32(vshrq_n_s32(v_ix0, INTER_BITS)),
|
||||
vqmovn_s32(vshrq_n_s32(v_ix1, INTER_BITS)));
|
||||
v_dst.val[1] = vcombine_s16(vqmovn_s32(vshrq_n_s32(v_iy0, INTER_BITS)),
|
||||
vqmovn_s32(vshrq_n_s32(v_iy1, INTER_BITS)));
|
||||
|
||||
vst2q_s16(dst1 + (x << 1), v_dst);
|
||||
|
||||
uint16x4_t v_dst0 = vqmovun_s32(vaddq_s32(vshlq_n_s32(vandq_s32(v_iy0, v_mask), INTER_BITS),
|
||||
vandq_s32(v_ix0, v_mask)));
|
||||
uint16x4_t v_dst1 = vqmovun_s32(vaddq_s32(vshlq_n_s32(vandq_s32(v_iy1, v_mask), INTER_BITS),
|
||||
vandq_s32(v_ix1, v_mask)));
|
||||
vst1q_u16(dst2 + x, vcombine_u16(v_dst0, v_dst1));
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
int ix = saturate_cast<int>(src1f[x]*INTER_TAB_SIZE);
|
||||
int iy = saturate_cast<int>(src2f[x]*INTER_TAB_SIZE);
|
||||
@ -4299,17 +4617,53 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
dst1[x*2+1] = saturate_cast<short>(iy >> INTER_BITS);
|
||||
dst2[x] = (ushort)((iy & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (ix & (INTER_TAB_SIZE-1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( m1type == CV_32FC2 && dstm1type == CV_16SC2 )
|
||||
{
|
||||
if( nninterpolate )
|
||||
for( x = 0; x < size.width; x++ )
|
||||
{
|
||||
#if CV_NEON
|
||||
for( ; x <= (size.width << 1) - 8; x += 8 )
|
||||
vst1q_s16(dst1 + x, vcombine_s16(vqmovn_s32(cv_vrndq_s32_f32(vld1q_f32(src1f + x))),
|
||||
vqmovn_s32(cv_vrndq_s32_f32(vld1q_f32(src1f + x + 4)))));
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
dst1[x*2] = saturate_cast<short>(src1f[x*2]);
|
||||
dst1[x*2+1] = saturate_cast<short>(src1f[x*2+1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
for( x = 0; x < size.width; x++ )
|
||||
{
|
||||
#if CV_NEON
|
||||
float32x4_t v_scale = vdupq_n_f32((float)INTER_TAB_SIZE);
|
||||
int32x4_t v_mask = vdupq_n_s32(INTER_TAB_SIZE - 1);
|
||||
|
||||
for( ; x <= size.width - 8; x += 8 )
|
||||
{
|
||||
float32x4x2_t v_src0 = vld2q_f32(src1f + (x << 1)), v_src1 = vld2q_f32(src1f + (x << 1) + 8);
|
||||
int32x4_t v_ix0 = cv_vrndq_s32_f32(vmulq_f32(v_src0.val[0], v_scale));
|
||||
int32x4_t v_ix1 = cv_vrndq_s32_f32(vmulq_f32(v_src1.val[0], v_scale));
|
||||
int32x4_t v_iy0 = cv_vrndq_s32_f32(vmulq_f32(v_src0.val[1], v_scale));
|
||||
int32x4_t v_iy1 = cv_vrndq_s32_f32(vmulq_f32(v_src1.val[1], v_scale));
|
||||
|
||||
int16x8x2_t v_dst;
|
||||
v_dst.val[0] = vcombine_s16(vqmovn_s32(vshrq_n_s32(v_ix0, INTER_BITS)),
|
||||
vqmovn_s32(vshrq_n_s32(v_ix1, INTER_BITS)));
|
||||
v_dst.val[1] = vcombine_s16(vqmovn_s32(vshrq_n_s32(v_iy0, INTER_BITS)),
|
||||
vqmovn_s32(vshrq_n_s32(v_iy1, INTER_BITS)));
|
||||
|
||||
vst2q_s16(dst1 + (x << 1), v_dst);
|
||||
|
||||
uint16x4_t v_dst0 = vqmovun_s32(vaddq_s32(vshlq_n_s32(vandq_s32(v_iy0, v_mask), INTER_BITS),
|
||||
vandq_s32(v_ix0, v_mask)));
|
||||
uint16x4_t v_dst1 = vqmovun_s32(vaddq_s32(vshlq_n_s32(vandq_s32(v_iy1, v_mask), INTER_BITS),
|
||||
vandq_s32(v_ix1, v_mask)));
|
||||
vst1q_u16(dst2 + x, vcombine_u16(v_dst0, v_dst1));
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
int ix = saturate_cast<int>(src1f[x*2]*INTER_TAB_SIZE);
|
||||
int iy = saturate_cast<int>(src1f[x*2+1]*INTER_TAB_SIZE);
|
||||
@ -4317,10 +4671,44 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
dst1[x*2+1] = saturate_cast<short>(iy >> INTER_BITS);
|
||||
dst2[x] = (ushort)((iy & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (ix & (INTER_TAB_SIZE-1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( m1type == CV_16SC2 && dstm1type == CV_32FC1 )
|
||||
{
|
||||
for( x = 0; x < size.width; x++ )
|
||||
#if CV_NEON
|
||||
uint16x8_t v_mask2 = vdupq_n_u16(INTER_TAB_SIZE2-1);
|
||||
uint32x4_t v_zero = vdupq_n_u32(0u), v_mask = vdupq_n_u32(INTER_TAB_SIZE-1);
|
||||
float32x4_t v_scale = vdupq_n_f32(scale);
|
||||
|
||||
for( ; x <= size.width - 8; x += 8)
|
||||
{
|
||||
uint32x4_t v_fxy1, v_fxy2;
|
||||
if (src2)
|
||||
{
|
||||
uint16x8_t v_src2 = vandq_u16(vld1q_u16(src2 + x), v_mask2);
|
||||
v_fxy1 = vmovl_u16(vget_low_u16(v_src2));
|
||||
v_fxy2 = vmovl_u16(vget_high_u16(v_src2));
|
||||
}
|
||||
else
|
||||
v_fxy1 = v_fxy2 = v_zero;
|
||||
|
||||
int16x8x2_t v_src = vld2q_s16(src1 + (x << 1));
|
||||
float32x4_t v_dst1 = vmlaq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src.val[0]))),
|
||||
v_scale, vcvtq_f32_u32(vandq_u32(v_fxy1, v_mask)));
|
||||
float32x4_t v_dst2 = vmlaq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src.val[1]))),
|
||||
v_scale, vcvtq_f32_u32(vshrq_n_u32(v_fxy1, INTER_BITS)));
|
||||
vst1q_f32(dst1f + x, v_dst1);
|
||||
vst1q_f32(dst2f + x, v_dst2);
|
||||
|
||||
v_dst1 = vmlaq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src.val[0]))),
|
||||
v_scale, vcvtq_f32_u32(vandq_u32(v_fxy2, v_mask)));
|
||||
v_dst2 = vmlaq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src.val[1]))),
|
||||
v_scale, vcvtq_f32_u32(vshrq_n_u32(v_fxy2, INTER_BITS)));
|
||||
vst1q_f32(dst1f + x + 4, v_dst1);
|
||||
vst1q_f32(dst2f + x + 4, v_dst2);
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
int fxy = src2 ? src2[x] & (INTER_TAB_SIZE2-1) : 0;
|
||||
dst1f[x] = src1[x*2] + (fxy & (INTER_TAB_SIZE-1))*scale;
|
||||
@ -4329,7 +4717,39 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
}
|
||||
else if( m1type == CV_16SC2 && dstm1type == CV_32FC2 )
|
||||
{
|
||||
for( x = 0; x < size.width; x++ )
|
||||
#if CV_NEON
|
||||
int16x8_t v_mask2 = vdupq_n_s16(INTER_TAB_SIZE2-1);
|
||||
int32x4_t v_zero = vdupq_n_s32(0), v_mask = vdupq_n_s32(INTER_TAB_SIZE-1);
|
||||
float32x4_t v_scale = vdupq_n_f32(scale);
|
||||
|
||||
for( ; x <= size.width - 8; x += 8)
|
||||
{
|
||||
int32x4_t v_fxy1, v_fxy2;
|
||||
if (src2)
|
||||
{
|
||||
int16x8_t v_src2 = vandq_s16(vld1q_s16((short *)src2 + x), v_mask2);
|
||||
v_fxy1 = vmovl_s16(vget_low_s16(v_src2));
|
||||
v_fxy2 = vmovl_s16(vget_high_s16(v_src2));
|
||||
}
|
||||
else
|
||||
v_fxy1 = v_fxy2 = v_zero;
|
||||
|
||||
int16x8x2_t v_src = vld2q_s16(src1 + (x << 1));
|
||||
float32x4x2_t v_dst;
|
||||
v_dst.val[0] = vmlaq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src.val[0]))),
|
||||
v_scale, vcvtq_f32_s32(vandq_s32(v_fxy1, v_mask)));
|
||||
v_dst.val[1] = vmlaq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_src.val[1]))),
|
||||
v_scale, vcvtq_f32_s32(vshrq_n_s32(v_fxy1, INTER_BITS)));
|
||||
vst2q_f32(dst1f + (x << 1), v_dst);
|
||||
|
||||
v_dst.val[0] = vmlaq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src.val[0]))),
|
||||
v_scale, vcvtq_f32_s32(vandq_s32(v_fxy2, v_mask)));
|
||||
v_dst.val[1] = vmlaq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_src.val[1]))),
|
||||
v_scale, vcvtq_f32_s32(vshrq_n_s32(v_fxy2, INTER_BITS)));
|
||||
vst2q_f32(dst1f + (x << 1) + 8, v_dst);
|
||||
}
|
||||
#endif
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
int fxy = src2 ? src2[x] & (INTER_TAB_SIZE2-1): 0;
|
||||
dst1f[x*2] = src1[x*2] + (fxy & (INTER_TAB_SIZE-1))*scale;
|
||||
@ -4389,13 +4809,29 @@ public:
|
||||
int Y0 = saturate_cast<int>((M[4]*(y + y1) + M[5])*AB_SCALE) + round_delta;
|
||||
|
||||
if( interpolation == INTER_NEAREST )
|
||||
for( x1 = 0; x1 < bw; x1++ )
|
||||
{
|
||||
x1 = 0;
|
||||
#if CV_NEON
|
||||
int32x4_t v_X0 = vdupq_n_s32(X0), v_Y0 = vdupq_n_s32(Y0);
|
||||
for( ; x1 <= bw - 8; x1 += 8 )
|
||||
{
|
||||
int16x8x2_t v_dst;
|
||||
v_dst.val[0] = vcombine_s16(vqmovn_s32(vshrq_n_s32(vaddq_s32(v_X0, vld1q_s32(adelta + x + x1)), AB_BITS)),
|
||||
vqmovn_s32(vshrq_n_s32(vaddq_s32(v_X0, vld1q_s32(adelta + x + x1 + 4)), AB_BITS)));
|
||||
v_dst.val[1] = vcombine_s16(vqmovn_s32(vshrq_n_s32(vaddq_s32(v_Y0, vld1q_s32(bdelta + x + x1)), AB_BITS)),
|
||||
vqmovn_s32(vshrq_n_s32(vaddq_s32(v_Y0, vld1q_s32(bdelta + x + x1 + 4)), AB_BITS)));
|
||||
|
||||
vst2q_s16(xy + (x1 << 1), v_dst);
|
||||
}
|
||||
#endif
|
||||
for( ; x1 < bw; x1++ )
|
||||
{
|
||||
int X = (X0 + adelta[x+x1]) >> AB_BITS;
|
||||
int Y = (Y0 + bdelta[x+x1]) >> AB_BITS;
|
||||
xy[x1*2] = saturate_cast<short>(X);
|
||||
xy[x1*2+1] = saturate_cast<short>(Y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
short* alpha = A + y1*bw;
|
||||
@ -4433,6 +4869,27 @@ public:
|
||||
_mm_storeu_si128((__m128i*)(alpha + x1), fx_);
|
||||
}
|
||||
}
|
||||
#elif CV_NEON
|
||||
int32x4_t v__X0 = vdupq_n_s32(X0), v__Y0 = vdupq_n_s32(Y0), v_mask = vdupq_n_s32(INTER_TAB_SIZE - 1);
|
||||
for( ; x1 <= bw - 8; x1 += 8 )
|
||||
{
|
||||
int32x4_t v_X0 = vshrq_n_s32(vaddq_s32(v__X0, vld1q_s32(adelta + x + x1)), AB_BITS - INTER_BITS);
|
||||
int32x4_t v_Y0 = vshrq_n_s32(vaddq_s32(v__Y0, vld1q_s32(bdelta + x + x1)), AB_BITS - INTER_BITS);
|
||||
int32x4_t v_X1 = vshrq_n_s32(vaddq_s32(v__X0, vld1q_s32(adelta + x + x1 + 4)), AB_BITS - INTER_BITS);
|
||||
int32x4_t v_Y1 = vshrq_n_s32(vaddq_s32(v__Y0, vld1q_s32(bdelta + x + x1 + 4)), AB_BITS - INTER_BITS);
|
||||
|
||||
int16x8x2_t v_xy;
|
||||
v_xy.val[0] = vcombine_s16(vqmovn_s32(vshrq_n_s32(v_X0, INTER_BITS)), vqmovn_s32(vshrq_n_s32(v_X1, INTER_BITS)));
|
||||
v_xy.val[1] = vcombine_s16(vqmovn_s32(vshrq_n_s32(v_Y0, INTER_BITS)), vqmovn_s32(vshrq_n_s32(v_Y1, INTER_BITS)));
|
||||
|
||||
vst2q_s16(xy + (x1 << 1), v_xy);
|
||||
|
||||
int16x4_t v_alpha0 = vmovn_s32(vaddq_s32(vshlq_n_s32(vandq_s32(v_Y0, v_mask), INTER_BITS),
|
||||
vandq_s32(v_X0, v_mask)));
|
||||
int16x4_t v_alpha1 = vmovn_s32(vaddq_s32(vshlq_n_s32(vandq_s32(v_Y1, v_mask), INTER_BITS),
|
||||
vandq_s32(v_X1, v_mask)));
|
||||
vst1q_s16(alpha + x1, vcombine_s16(v_alpha0, v_alpha1));
|
||||
}
|
||||
#endif
|
||||
for( ; x1 < bw; x1++ )
|
||||
{
|
||||
|
@ -49,9 +49,9 @@
|
||||
#ifdef WITH_SOBEL
|
||||
|
||||
#if cn == 1
|
||||
#define loadpix(addr) convert_intN(*(__global const TYPE *)(addr))
|
||||
#define loadpix(addr) convert_floatN(*(__global const TYPE *)(addr))
|
||||
#else
|
||||
#define loadpix(addr) convert_intN(vload3(0, (__global const TYPE *)(addr)))
|
||||
#define loadpix(addr) convert_floatN(vload3(0, (__global const TYPE *)(addr)))
|
||||
#endif
|
||||
#define storepix(value, addr) *(__global int *)(addr) = (int)(value)
|
||||
|
||||
@ -77,23 +77,21 @@ __constant int next[4][2] = {
|
||||
{ 1, 1 }
|
||||
};
|
||||
|
||||
inline int3 sobel(int idx, __local const intN *smem)
|
||||
inline float3 sobel(int idx, __local const floatN *smem)
|
||||
{
|
||||
// result: x, y, mag
|
||||
int3 res;
|
||||
float3 res;
|
||||
|
||||
intN dx = smem[idx + 2] - smem[idx]
|
||||
+ 2 * (smem[idx + GRP_SIZEX + 6] - smem[idx + GRP_SIZEX + 4])
|
||||
+ smem[idx + 2 * GRP_SIZEX + 10] - smem[idx + 2 * GRP_SIZEX + 8];
|
||||
floatN dx = fma(2, smem[idx + GRP_SIZEX + 6] - smem[idx + GRP_SIZEX + 4],
|
||||
smem[idx + 2] - smem[idx] + smem[idx + 2 * GRP_SIZEX + 10] - smem[idx + 2 * GRP_SIZEX + 8]);
|
||||
|
||||
intN dy = smem[idx] - smem[idx + 2 * GRP_SIZEX + 8]
|
||||
+ 2 * (smem[idx + 1] - smem[idx + 2 * GRP_SIZEX + 9])
|
||||
+ smem[idx + 2] - smem[idx + 2 * GRP_SIZEX + 10];
|
||||
floatN dy = fma(2, smem[idx + 1] - smem[idx + 2 * GRP_SIZEX + 9],
|
||||
smem[idx + 2] - smem[idx + 2 * GRP_SIZEX + 10] + smem[idx] - smem[idx + 2 * GRP_SIZEX + 8]);
|
||||
|
||||
#ifdef L2GRAD
|
||||
intN magN = dx * dx + dy * dy;
|
||||
floatN magN = fma(dx, dx, dy * dy);
|
||||
#else
|
||||
intN magN = convert_intN(abs(dx) + abs(dy));
|
||||
floatN magN = fabs(dx) + fabs(dy);
|
||||
#endif
|
||||
#if cn == 1
|
||||
res.z = magN;
|
||||
@ -120,9 +118,9 @@ inline int3 sobel(int idx, __local const intN *smem)
|
||||
|
||||
__kernel void stage1_with_sobel(__global const uchar *src, int src_step, int src_offset, int rows, int cols,
|
||||
__global uchar *map, int map_step, int map_offset,
|
||||
int low_thr, int high_thr)
|
||||
float low_thr, float high_thr)
|
||||
{
|
||||
__local intN smem[(GRP_SIZEX + 4) * (GRP_SIZEY + 4)];
|
||||
__local floatN smem[(GRP_SIZEX + 4) * (GRP_SIZEY + 4)];
|
||||
|
||||
int lidx = get_local_id(0);
|
||||
int lidy = get_local_id(1);
|
||||
@ -143,7 +141,7 @@ __kernel void stage1_with_sobel(__global const uchar *src, int src_step, int src
|
||||
//// Sobel, Magnitude
|
||||
//
|
||||
|
||||
__local int mag[(GRP_SIZEX + 2) * (GRP_SIZEY + 2)];
|
||||
__local float mag[(GRP_SIZEX + 2) * (GRP_SIZEY + 2)];
|
||||
|
||||
lidx++;
|
||||
lidy++;
|
||||
@ -164,13 +162,13 @@ __kernel void stage1_with_sobel(__global const uchar *src, int src_step, int src
|
||||
int idx = lidx + lidy * (GRP_SIZEX + 4);
|
||||
i = lidx + lidy * (GRP_SIZEX + 2);
|
||||
|
||||
int3 res = sobel(idx, smem);
|
||||
float3 res = sobel(idx, smem);
|
||||
mag[i] = res.z;
|
||||
int x = res.x;
|
||||
int y = res.y;
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
int x = (int) res.x;
|
||||
int y = (int) res.y;
|
||||
|
||||
//// Threshold + Non maxima suppression
|
||||
//
|
||||
|
||||
@ -218,7 +216,7 @@ __kernel void stage1_with_sobel(__global const uchar *src, int src_step, int src
|
||||
if (gidx >= cols || gidy >= rows)
|
||||
return;
|
||||
|
||||
int mag0 = mag[i];
|
||||
float mag0 = mag[i];
|
||||
|
||||
int value = 1;
|
||||
if (mag0 > low_thr)
|
||||
@ -235,8 +233,8 @@ __kernel void stage1_with_sobel(__global const uchar *src, int src_step, int src
|
||||
|
||||
int dir3 = (a * b) & (((x ^ y) & 0x80000000) >> 31); // if a = 1, b = 1, dy ^ dx < 0
|
||||
int dir = a * b + 2 * dir3;
|
||||
int prev_mag = mag[(lidy + prev[dir][0]) * (GRP_SIZEX + 2) + lidx + prev[dir][1]];
|
||||
int next_mag = mag[(lidy + next[dir][0]) * (GRP_SIZEX + 2) + lidx + next[dir][1]] + (dir & 1);
|
||||
float prev_mag = mag[(lidy + prev[dir][0]) * (GRP_SIZEX + 2) + lidx + prev[dir][1]];
|
||||
float next_mag = mag[(lidy + next[dir][0]) * (GRP_SIZEX + 2) + lidx + next[dir][1]] + (dir & 1);
|
||||
|
||||
if (mag0 > prev_mag && mag0 >= next_mag)
|
||||
{
|
||||
@ -384,12 +382,12 @@ __constant short move_dir[2][8] = {
|
||||
{ -1, 0, 1, -1, 1, -1, 0, 1 }
|
||||
};
|
||||
|
||||
__kernel void stage2_hysteresis(__global uchar *map, int map_step, int map_offset, int rows, int cols)
|
||||
__kernel void stage2_hysteresis(__global uchar *map_ptr, int map_step, int map_offset, int rows, int cols)
|
||||
{
|
||||
map += map_offset;
|
||||
map_ptr += map_offset;
|
||||
|
||||
int x = get_global_id(0);
|
||||
int y0 = get_global_id(1) * PIX_PER_WI;
|
||||
int y = get_global_id(1) * PIX_PER_WI;
|
||||
|
||||
int lid = get_local_id(0) + get_local_id(1) * LOCAL_X;
|
||||
|
||||
@ -400,15 +398,23 @@ __kernel void stage2_hysteresis(__global uchar *map, int map_step, int map_offse
|
||||
l_counter = 0;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
#pragma unroll
|
||||
for (int y = y0; y < min(y0 + PIX_PER_WI, rows); ++y)
|
||||
if (x < cols)
|
||||
{
|
||||
if (x < cols)
|
||||
__global uchar* map = map_ptr + mad24(y, map_step, x * (int)sizeof(int));
|
||||
|
||||
#pragma unroll
|
||||
for (int cy = 0; cy < PIX_PER_WI; ++cy)
|
||||
{
|
||||
int type = loadpix(map + mad24(y, map_step, x * (int)sizeof(int)));
|
||||
if (type == 2)
|
||||
if (y < rows)
|
||||
{
|
||||
l_stack[atomic_inc(&l_counter)] = (ushort2)(x, y);
|
||||
int type = loadpix(map);
|
||||
if (type == 2)
|
||||
{
|
||||
l_stack[atomic_inc(&l_counter)] = (ushort2)(x, y);
|
||||
}
|
||||
|
||||
y++;
|
||||
map += map_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -422,7 +428,6 @@ __kernel void stage2_hysteresis(__global uchar *map, int map_step, int map_offse
|
||||
int mod = l_counter % LOCAL_TOTAL;
|
||||
int pix_per_thr = l_counter / LOCAL_TOTAL + ((lid < mod) ? 1 : 0);
|
||||
|
||||
#pragma unroll
|
||||
for (int i = 0; i < pix_per_thr; ++i)
|
||||
{
|
||||
ushort2 pos = l_stack[ atomic_dec(&l_counter) - 1 ];
|
||||
@ -434,7 +439,7 @@ __kernel void stage2_hysteresis(__global uchar *map, int map_step, int map_offse
|
||||
ushort posy = pos.y + move_dir[1][j];
|
||||
if (posx < 0 || posy < 0 || posx >= cols || posy >= rows)
|
||||
continue;
|
||||
__global uchar *addr = map + mad24(posy, map_step, posx * (int)sizeof(int));
|
||||
__global uchar *addr = map_ptr + mad24(posy, map_step, posx * (int)sizeof(int));
|
||||
int type = loadpix(addr);
|
||||
if (type == 0)
|
||||
{
|
||||
@ -463,16 +468,26 @@ __kernel void getEdges(__global const uchar *mapptr, int map_step, int map_offse
|
||||
__global uchar *dst, int dst_step, int dst_offset)
|
||||
{
|
||||
int x = get_global_id(0);
|
||||
int y0 = get_global_id(1) * PIX_PER_WI;
|
||||
int y = get_global_id(1) * PIX_PER_WI;
|
||||
|
||||
#pragma unroll
|
||||
for (int y = y0; y < min(y0 + PIX_PER_WI, rows); ++y)
|
||||
if (x < cols)
|
||||
{
|
||||
int map_index = mad24(map_step, y, mad24(x, (int)sizeof(int), map_offset));
|
||||
int dst_index = mad24(dst_step, y, x) + dst_offset;
|
||||
int dst_index = mad24(dst_step, y, x + dst_offset);
|
||||
|
||||
__global const int * map = (__global const int *)(mapptr + map_index);
|
||||
dst[dst_index] = (uchar)(-(map[0] >> 1));
|
||||
#pragma unroll
|
||||
for (int cy = 0; cy < PIX_PER_WI; ++cy)
|
||||
{
|
||||
if (y < rows)
|
||||
{
|
||||
__global const int * map = (__global const int *)(mapptr + map_index);
|
||||
dst[dst_index] = (uchar)(-(map[0] >> 1));
|
||||
|
||||
y++;
|
||||
map_index += map_step;
|
||||
dst_index += dst_step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,146 +184,149 @@ __kernel void get_lines(__global const uchar * accum_ptr, int accum_step, int ac
|
||||
int x = get_global_id(0);
|
||||
int y = get_global_id(1);
|
||||
|
||||
__global uchar* accum = accum_ptr + mad24(y+1, accum_step, mad24(x+1, (int) sizeof(int), accum_offset));
|
||||
__global int4* lines = (__global int4*)(lines_ptr + lines_offset);
|
||||
__global int* lines_index = lines_index_ptr + 1;
|
||||
|
||||
int curVote = ACCUM(accum);
|
||||
|
||||
if (curVote >= threshold &&
|
||||
curVote > ACCUM(accum - accum_step - sizeof(int)) &&
|
||||
curVote > ACCUM(accum - accum_step) &&
|
||||
curVote > ACCUM(accum - accum_step + sizeof(int)) &&
|
||||
curVote > ACCUM(accum - sizeof(int)) &&
|
||||
curVote > ACCUM(accum + sizeof(int)) &&
|
||||
curVote > ACCUM(accum + accum_step - sizeof(int)) &&
|
||||
curVote > ACCUM(accum + accum_step) &&
|
||||
curVote > ACCUM(accum + accum_step + sizeof(int)))
|
||||
if (y < accum_rows-2)
|
||||
{
|
||||
const float radius = (x - (accum_cols - 2 - 1) * 0.5f) * rho;
|
||||
const float angle = y * theta;
|
||||
__global uchar* accum = accum_ptr + mad24(y+1, accum_step, mad24(x+1, (int) sizeof(int), accum_offset));
|
||||
__global int4* lines = (__global int4*)(lines_ptr + lines_offset);
|
||||
__global int* lines_index = lines_index_ptr + 1;
|
||||
|
||||
float cosa;
|
||||
float sina = sincos(angle, &cosa);
|
||||
int curVote = ACCUM(accum);
|
||||
|
||||
float2 p0 = (float2)(cosa * radius, sina * radius);
|
||||
float2 dir = (float2)(-sina, cosa);
|
||||
|
||||
float2 pb[4] = { (float2)(-1, -1), (float2)(-1, -1), (float2)(-1, -1), (float2)(-1, -1) };
|
||||
float a;
|
||||
|
||||
if (dir.x != 0)
|
||||
if (curVote >= threshold &&
|
||||
curVote > ACCUM(accum - accum_step - sizeof(int)) &&
|
||||
curVote > ACCUM(accum - accum_step) &&
|
||||
curVote > ACCUM(accum - accum_step + sizeof(int)) &&
|
||||
curVote > ACCUM(accum - sizeof(int)) &&
|
||||
curVote > ACCUM(accum + sizeof(int)) &&
|
||||
curVote > ACCUM(accum + accum_step - sizeof(int)) &&
|
||||
curVote > ACCUM(accum + accum_step) &&
|
||||
curVote > ACCUM(accum + accum_step + sizeof(int)))
|
||||
{
|
||||
a = -p0.x / dir.x;
|
||||
pb[0].x = 0;
|
||||
pb[0].y = p0.y + a * dir.y;
|
||||
const float radius = (x - (accum_cols - 2 - 1) * 0.5f) * rho;
|
||||
const float angle = y * theta;
|
||||
|
||||
a = (src_cols - 1 - p0.x) / dir.x;
|
||||
pb[1].x = src_cols - 1;
|
||||
pb[1].y = p0.y + a * dir.y;
|
||||
}
|
||||
float cosa;
|
||||
float sina = sincos(angle, &cosa);
|
||||
|
||||
if (dir.y != 0)
|
||||
{
|
||||
a = -p0.y / dir.y;
|
||||
pb[2].x = p0.x + a * dir.x;
|
||||
pb[2].y = 0;
|
||||
float2 p0 = (float2)(cosa * radius, sina * radius);
|
||||
float2 dir = (float2)(-sina, cosa);
|
||||
|
||||
a = (src_rows - 1 - p0.y) / dir.y;
|
||||
pb[3].x = p0.x + a * dir.x;
|
||||
pb[3].y = src_rows - 1;
|
||||
}
|
||||
float2 pb[4] = { (float2)(-1, -1), (float2)(-1, -1), (float2)(-1, -1), (float2)(-1, -1) };
|
||||
float a;
|
||||
|
||||
if (pb[0].x == 0 && (pb[0].y >= 0 && pb[0].y < src_rows))
|
||||
{
|
||||
p0 = pb[0];
|
||||
if (dir.x < 0)
|
||||
dir = -dir;
|
||||
}
|
||||
else if (pb[1].x == src_cols - 1 && (pb[1].y >= 0 && pb[1].y < src_rows))
|
||||
{
|
||||
p0 = pb[1];
|
||||
if (dir.x > 0)
|
||||
dir = -dir;
|
||||
}
|
||||
else if (pb[2].y == 0 && (pb[2].x >= 0 && pb[2].x < src_cols))
|
||||
{
|
||||
p0 = pb[2];
|
||||
if (dir.y < 0)
|
||||
dir = -dir;
|
||||
}
|
||||
else if (pb[3].y == src_rows - 1 && (pb[3].x >= 0 && pb[3].x < src_cols))
|
||||
{
|
||||
p0 = pb[3];
|
||||
if (dir.y > 0)
|
||||
dir = -dir;
|
||||
}
|
||||
|
||||
dir /= max(fabs(dir.x), fabs(dir.y));
|
||||
|
||||
float2 line_end[2];
|
||||
int gap;
|
||||
bool inLine = false;
|
||||
|
||||
if (p0.x < 0 || p0.x >= src_cols || p0.y < 0 || p0.y >= src_rows)
|
||||
return;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*(src_ptr + mad24(p0.y, src_step, p0.x + src_offset)))
|
||||
if (dir.x != 0)
|
||||
{
|
||||
gap = 0;
|
||||
a = -p0.x / dir.x;
|
||||
pb[0].x = 0;
|
||||
pb[0].y = p0.y + a * dir.y;
|
||||
|
||||
if (!inLine)
|
||||
{
|
||||
line_end[0] = p0;
|
||||
line_end[1] = p0;
|
||||
inLine = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_end[1] = p0;
|
||||
}
|
||||
}
|
||||
else if (inLine)
|
||||
{
|
||||
if (++gap > lineGap)
|
||||
{
|
||||
bool good_line = fabs(line_end[1].x - line_end[0].x) >= lineLength ||
|
||||
fabs(line_end[1].y - line_end[0].y) >= lineLength;
|
||||
|
||||
if (good_line)
|
||||
{
|
||||
int index = atomic_inc(lines_index);
|
||||
if (index < linesMax)
|
||||
lines[index] = (int4)(line_end[0].x, line_end[0].y, line_end[1].x, line_end[1].y);
|
||||
}
|
||||
|
||||
gap = 0;
|
||||
inLine = false;
|
||||
}
|
||||
a = (src_cols - 1 - p0.x) / dir.x;
|
||||
pb[1].x = src_cols - 1;
|
||||
pb[1].y = p0.y + a * dir.y;
|
||||
}
|
||||
|
||||
p0 = p0 + dir;
|
||||
if (dir.y != 0)
|
||||
{
|
||||
a = -p0.y / dir.y;
|
||||
pb[2].x = p0.x + a * dir.x;
|
||||
pb[2].y = 0;
|
||||
|
||||
a = (src_rows - 1 - p0.y) / dir.y;
|
||||
pb[3].x = p0.x + a * dir.x;
|
||||
pb[3].y = src_rows - 1;
|
||||
}
|
||||
|
||||
if (pb[0].x == 0 && (pb[0].y >= 0 && pb[0].y < src_rows))
|
||||
{
|
||||
p0 = pb[0];
|
||||
if (dir.x < 0)
|
||||
dir = -dir;
|
||||
}
|
||||
else if (pb[1].x == src_cols - 1 && (pb[1].y >= 0 && pb[1].y < src_rows))
|
||||
{
|
||||
p0 = pb[1];
|
||||
if (dir.x > 0)
|
||||
dir = -dir;
|
||||
}
|
||||
else if (pb[2].y == 0 && (pb[2].x >= 0 && pb[2].x < src_cols))
|
||||
{
|
||||
p0 = pb[2];
|
||||
if (dir.y < 0)
|
||||
dir = -dir;
|
||||
}
|
||||
else if (pb[3].y == src_rows - 1 && (pb[3].x >= 0 && pb[3].x < src_cols))
|
||||
{
|
||||
p0 = pb[3];
|
||||
if (dir.y > 0)
|
||||
dir = -dir;
|
||||
}
|
||||
|
||||
dir /= max(fabs(dir.x), fabs(dir.y));
|
||||
|
||||
float2 line_end[2];
|
||||
int gap;
|
||||
bool inLine = false;
|
||||
|
||||
if (p0.x < 0 || p0.x >= src_cols || p0.y < 0 || p0.y >= src_rows)
|
||||
return;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (inLine)
|
||||
if (*(src_ptr + mad24(p0.y, src_step, p0.x + src_offset)))
|
||||
{
|
||||
bool good_line = fabs(line_end[1].x - line_end[0].x) >= lineLength ||
|
||||
fabs(line_end[1].y - line_end[0].y) >= lineLength;
|
||||
gap = 0;
|
||||
|
||||
if (good_line)
|
||||
if (!inLine)
|
||||
{
|
||||
int index = atomic_inc(lines_index);
|
||||
if (index < linesMax)
|
||||
lines[index] = (int4)(line_end[0].x, line_end[0].y, line_end[1].x, line_end[1].y);
|
||||
line_end[0] = p0;
|
||||
line_end[1] = p0;
|
||||
inLine = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_end[1] = p0;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (inLine)
|
||||
{
|
||||
if (++gap > lineGap)
|
||||
{
|
||||
bool good_line = fabs(line_end[1].x - line_end[0].x) >= lineLength ||
|
||||
fabs(line_end[1].y - line_end[0].y) >= lineLength;
|
||||
|
||||
if (good_line)
|
||||
{
|
||||
int index = atomic_inc(lines_index);
|
||||
if (index < linesMax)
|
||||
lines[index] = (int4)(line_end[0].x, line_end[0].y, line_end[1].x, line_end[1].y);
|
||||
}
|
||||
|
||||
gap = 0;
|
||||
inLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
p0 = p0 + dir;
|
||||
if (p0.x < 0 || p0.x >= src_cols || p0.y < 0 || p0.y >= src_rows)
|
||||
{
|
||||
if (inLine)
|
||||
{
|
||||
bool good_line = fabs(line_end[1].x - line_end[0].x) >= lineLength ||
|
||||
fabs(line_end[1].y - line_end[0].y) >= lineLength;
|
||||
|
||||
if (good_line)
|
||||
{
|
||||
int index = atomic_inc(lines_index);
|
||||
if (index < linesMax)
|
||||
lines[index] = (int4)(line_end[0].x, line_end[0].y, line_end[1].x, line_end[1].y);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,11 +60,16 @@ template<typename T, int shift> struct FltCast
|
||||
rtype operator ()(type1 arg) const { return arg*(T)(1./(1 << shift)); }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2> struct NoVec
|
||||
template<typename T1, typename T2> struct PyrDownNoVec
|
||||
{
|
||||
int operator()(T1**, T2*, int, int) const { return 0; }
|
||||
};
|
||||
|
||||
template<typename T1, typename T2> struct PyrUpNoVec
|
||||
{
|
||||
int operator()(T1**, T2**, int, int) const { return 0; }
|
||||
};
|
||||
|
||||
#if CV_SSE2
|
||||
|
||||
struct PyrDownVec_32s8u
|
||||
@ -178,10 +183,13 @@ struct PyrDownVec_32f
|
||||
}
|
||||
};
|
||||
|
||||
typedef NoVec<int, ushort> PyrDownVec_32s16u;
|
||||
typedef NoVec<int, short> PyrDownVec_32s16s;
|
||||
typedef PyrDownNoVec<int, ushort> PyrDownVec_32s16u;
|
||||
typedef PyrDownNoVec<int, short> PyrDownVec_32s16s;
|
||||
|
||||
typedef NoVec<float, float> PyrUpVec_32f;
|
||||
typedef PyrUpNoVec<int, uchar> PyrUpVec_32s8u;
|
||||
typedef PyrUpNoVec<int, short> PyrUpVec_32s16s;
|
||||
typedef PyrUpNoVec<int, ushort> PyrUpVec_32s16u;
|
||||
typedef PyrUpNoVec<float, float> PyrUpVec_32f;
|
||||
|
||||
#elif CV_NEON
|
||||
|
||||
@ -203,9 +211,9 @@ struct PyrDownVec_32s8u
|
||||
uint16x8_t v_r3 = vcombine_u16(vqmovn_u32(vld1q_u32(row3 + x)), vqmovn_u32(vld1q_u32(row3 + x + 4)));
|
||||
uint16x8_t v_r4 = vcombine_u16(vqmovn_u32(vld1q_u32(row4 + x)), vqmovn_u32(vld1q_u32(row4 + x + 4)));
|
||||
|
||||
v_r0 = vqaddq_u16(vqaddq_u16(v_r0, v_r4), vqaddq_u16(v_r2, v_r2));
|
||||
v_r1 = vqaddq_u16(vqaddq_u16(v_r1, v_r2), v_r3);
|
||||
uint16x8_t v_dst0 = vqaddq_u16(v_r0, vshlq_n_u16(v_r1, 2));
|
||||
v_r0 = vaddq_u16(vaddq_u16(v_r0, v_r4), vaddq_u16(v_r2, v_r2));
|
||||
v_r1 = vaddq_u16(vaddq_u16(v_r1, v_r2), v_r3);
|
||||
uint16x8_t v_dst0 = vaddq_u16(v_r0, vshlq_n_u16(v_r1, 2));
|
||||
|
||||
v_r0 = vcombine_u16(vqmovn_u32(vld1q_u32(row0 + x + 8)), vqmovn_u32(vld1q_u32(row0 + x + 12)));
|
||||
v_r1 = vcombine_u16(vqmovn_u32(vld1q_u32(row1 + x + 8)), vqmovn_u32(vld1q_u32(row1 + x + 12)));
|
||||
@ -213,9 +221,9 @@ struct PyrDownVec_32s8u
|
||||
v_r3 = vcombine_u16(vqmovn_u32(vld1q_u32(row3 + x + 8)), vqmovn_u32(vld1q_u32(row3 + x + 12)));
|
||||
v_r4 = vcombine_u16(vqmovn_u32(vld1q_u32(row4 + x + 8)), vqmovn_u32(vld1q_u32(row4 + x + 12)));
|
||||
|
||||
v_r0 = vqaddq_u16(vqaddq_u16(v_r0, v_r4), vqaddq_u16(v_r2, v_r2));
|
||||
v_r1 = vqaddq_u16(vqaddq_u16(v_r1, v_r2), v_r3);
|
||||
uint16x8_t v_dst1 = vqaddq_u16(v_r0, vshlq_n_u16(v_r1, 2));
|
||||
v_r0 = vaddq_u16(vaddq_u16(v_r0, v_r4), vaddq_u16(v_r2, v_r2));
|
||||
v_r1 = vaddq_u16(vaddq_u16(v_r1, v_r2), v_r3);
|
||||
uint16x8_t v_dst1 = vaddq_u16(v_r0, vshlq_n_u16(v_r1, 2));
|
||||
|
||||
vst1q_u8(dst + x, vcombine_u8(vqmovn_u16(vshrq_n_u16(vaddq_u16(v_dst0, v_delta), 8)),
|
||||
vqmovn_u16(vshrq_n_u16(vaddq_u16(v_dst1, v_delta), 8))));
|
||||
@ -240,18 +248,17 @@ struct PyrDownVec_32s16u
|
||||
int32x4_t v_r20 = vld1q_s32(row2 + x), v_r21 = vld1q_s32(row2 + x + 4);
|
||||
int32x4_t v_r30 = vld1q_s32(row3 + x), v_r31 = vld1q_s32(row3 + x + 4);
|
||||
int32x4_t v_r40 = vld1q_s32(row4 + x), v_r41 = vld1q_s32(row4 + x + 4);
|
||||
int32x4_t shifted;
|
||||
|
||||
v_r00 = vaddq_s32(vqaddq_s32(v_r00, v_r40), vqaddq_s32(v_r20, v_r20));
|
||||
v_r10 = vaddq_s32(vqaddq_s32(v_r10, v_r20), v_r30);
|
||||
v_r00 = vaddq_s32(vaddq_s32(v_r00, v_r40), vaddq_s32(v_r20, v_r20));
|
||||
v_r10 = vaddq_s32(vaddq_s32(v_r10, v_r20), v_r30);
|
||||
|
||||
shifted = vshlq_n_s32(v_r10, 2);
|
||||
int32x4_t v_dst0 = vshrq_n_s32(vaddq_s32(vqaddq_s32(v_r00, shifted), v_delta), 8);
|
||||
v_r10 = vshlq_n_s32(v_r10, 2);
|
||||
int32x4_t v_dst0 = vshrq_n_s32(vaddq_s32(vaddq_s32(v_r00, v_r10), v_delta), 8);
|
||||
|
||||
v_r01 = vaddq_s32(vqaddq_s32(v_r01, v_r41), vqaddq_s32(v_r21, v_r21));
|
||||
v_r11 = vaddq_s32(vqaddq_s32(v_r11, v_r21), v_r31);
|
||||
shifted = vshlq_n_s32(v_r11, 2);
|
||||
int32x4_t v_dst1 = vshrq_n_s32(vaddq_s32(vqaddq_s32(v_r01, shifted), v_delta), 8);
|
||||
v_r01 = vaddq_s32(vaddq_s32(v_r01, v_r41), vaddq_s32(v_r21, v_r21));
|
||||
v_r11 = vaddq_s32(vaddq_s32(v_r11, v_r21), v_r31);
|
||||
v_r11 = vshlq_n_s32(v_r11, 2);
|
||||
int32x4_t v_dst1 = vshrq_n_s32(vaddq_s32(vaddq_s32(v_r01, v_r11), v_delta), 8);
|
||||
|
||||
vst1q_u16(dst + x, vcombine_u16(vqmovun_s32(v_dst0), vqmovun_s32(v_dst1)));
|
||||
}
|
||||
@ -275,17 +282,16 @@ struct PyrDownVec_32s16s
|
||||
int32x4_t v_r20 = vld1q_s32(row2 + x), v_r21 = vld1q_s32(row2 + x + 4);
|
||||
int32x4_t v_r30 = vld1q_s32(row3 + x), v_r31 = vld1q_s32(row3 + x + 4);
|
||||
int32x4_t v_r40 = vld1q_s32(row4 + x), v_r41 = vld1q_s32(row4 + x + 4);
|
||||
int32x4_t shifted;
|
||||
|
||||
v_r00 = vaddq_s32(vqaddq_s32(v_r00, v_r40), vqaddq_s32(v_r20, v_r20));
|
||||
v_r10 = vaddq_s32(vqaddq_s32(v_r10, v_r20), v_r30);
|
||||
shifted = vshlq_n_s32(v_r10, 2);
|
||||
int32x4_t v_dst0 = vshrq_n_s32(vaddq_s32(vqaddq_s32(v_r00, shifted), v_delta), 8);
|
||||
v_r00 = vaddq_s32(vaddq_s32(v_r00, v_r40), vaddq_s32(v_r20, v_r20));
|
||||
v_r10 = vaddq_s32(vaddq_s32(v_r10, v_r20), v_r30);
|
||||
v_r10 = vshlq_n_s32(v_r10, 2);
|
||||
int32x4_t v_dst0 = vshrq_n_s32(vaddq_s32(vaddq_s32(v_r00, v_r10), v_delta), 8);
|
||||
|
||||
v_r01 = vaddq_s32(vqaddq_s32(v_r01, v_r41), vqaddq_s32(v_r21, v_r21));
|
||||
v_r11 = vaddq_s32(vqaddq_s32(v_r11, v_r21), v_r31);
|
||||
shifted = vshlq_n_s32(v_r11, 2);
|
||||
int32x4_t v_dst1 = vshrq_n_s32(vaddq_s32(vqaddq_s32(v_r01, shifted), v_delta), 8);
|
||||
v_r01 = vaddq_s32(vaddq_s32(v_r01, v_r41), vaddq_s32(v_r21, v_r21));
|
||||
v_r11 = vaddq_s32(vaddq_s32(v_r11, v_r21), v_r31);
|
||||
v_r11 = vshlq_n_s32(v_r11, 2);
|
||||
int32x4_t v_dst1 = vshrq_n_s32(vaddq_s32(vaddq_s32(v_r01, v_r11), v_delta), 8);
|
||||
|
||||
vst1q_s16(dst + x, vcombine_s16(vqmovn_s32(v_dst0), vqmovn_s32(v_dst1)));
|
||||
}
|
||||
@ -329,14 +335,156 @@ struct PyrDownVec_32f
|
||||
}
|
||||
};
|
||||
|
||||
struct PyrUpVec_32f
|
||||
struct PyrUpVec_32s8u
|
||||
{
|
||||
int operator()(float** src, float* dst, int, int width) const
|
||||
int operator()(int** src, uchar** dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
uchar *dst0 = dst[0], *dst1 = dst[1];
|
||||
const uint *row0 = (uint *)src[0], *row1 = (uint *)src[1], *row2 = (uint *)src[2];
|
||||
uint16x8_t v_delta = vdupq_n_u16(32);
|
||||
|
||||
for( ; x <= width - 16; x += 16 )
|
||||
{
|
||||
uint16x8_t v_r0 = vcombine_u16(vqmovn_u32(vld1q_u32(row0 + x)), vqmovn_u32(vld1q_u32(row0 + x + 4)));
|
||||
uint16x8_t v_r1 = vcombine_u16(vqmovn_u32(vld1q_u32(row1 + x)), vqmovn_u32(vld1q_u32(row1 + x + 4)));
|
||||
uint16x8_t v_r2 = vcombine_u16(vqmovn_u32(vld1q_u32(row2 + x)), vqmovn_u32(vld1q_u32(row2 + x + 4)));
|
||||
|
||||
uint16x8_t v_2r1 = vaddq_u16(v_r1, v_r1), v_4r1 = vaddq_u16(v_2r1, v_2r1);
|
||||
uint16x8_t v_dst00 = vaddq_u16(vaddq_u16(v_r0, v_r2), vaddq_u16(v_2r1, v_4r1));
|
||||
uint16x8_t v_dst10 = vshlq_n_u16(vaddq_u16(v_r1, v_r2), 2);
|
||||
|
||||
v_r0 = vcombine_u16(vqmovn_u32(vld1q_u32(row0 + x + 8)), vqmovn_u32(vld1q_u32(row0 + x + 12)));
|
||||
v_r1 = vcombine_u16(vqmovn_u32(vld1q_u32(row1 + x + 8)), vqmovn_u32(vld1q_u32(row1 + x + 12)));
|
||||
v_r2 = vcombine_u16(vqmovn_u32(vld1q_u32(row2 + x + 8)), vqmovn_u32(vld1q_u32(row2 + x + 12)));
|
||||
|
||||
v_2r1 = vaddq_u16(v_r1, v_r1), v_4r1 = vaddq_u16(v_2r1, v_2r1);
|
||||
uint16x8_t v_dst01 = vaddq_u16(vaddq_u16(v_r0, v_r2), vaddq_u16(v_2r1, v_4r1));
|
||||
uint16x8_t v_dst11 = vshlq_n_u16(vaddq_u16(v_r1, v_r2), 2);
|
||||
|
||||
vst1q_u8(dst0 + x, vcombine_u8(vqmovn_u16(vshrq_n_u16(vaddq_u16(v_dst00, v_delta), 6)),
|
||||
vqmovn_u16(vshrq_n_u16(vaddq_u16(v_dst01, v_delta), 6))));
|
||||
vst1q_u8(dst1 + x, vcombine_u8(vqmovn_u16(vshrq_n_u16(vaddq_u16(v_dst10, v_delta), 6)),
|
||||
vqmovn_u16(vshrq_n_u16(vaddq_u16(v_dst11, v_delta), 6))));
|
||||
}
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
uint16x8_t v_r0 = vcombine_u16(vqmovn_u32(vld1q_u32(row0 + x)), vqmovn_u32(vld1q_u32(row0 + x + 4)));
|
||||
uint16x8_t v_r1 = vcombine_u16(vqmovn_u32(vld1q_u32(row1 + x)), vqmovn_u32(vld1q_u32(row1 + x + 4)));
|
||||
uint16x8_t v_r2 = vcombine_u16(vqmovn_u32(vld1q_u32(row2 + x)), vqmovn_u32(vld1q_u32(row2 + x + 4)));
|
||||
|
||||
uint16x8_t v_2r1 = vaddq_u16(v_r1, v_r1), v_4r1 = vaddq_u16(v_2r1, v_2r1);
|
||||
uint16x8_t v_dst0 = vaddq_u16(vaddq_u16(v_r0, v_r2), vaddq_u16(v_2r1, v_4r1));
|
||||
uint16x8_t v_dst1 = vshlq_n_u16(vaddq_u16(v_r1, v_r2), 2);
|
||||
|
||||
vst1_u8(dst0 + x, vqmovn_u16(vshrq_n_u16(vaddq_u16(v_dst0, v_delta), 6)));
|
||||
vst1_u8(dst1 + x, vqmovn_u16(vshrq_n_u16(vaddq_u16(v_dst1, v_delta), 6)));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
struct PyrUpVec_32s16u
|
||||
{
|
||||
int operator()(int** src, ushort** dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
ushort *dst0 = dst[0], *dst1 = dst[1];
|
||||
const uint *row0 = (uint *)src[0], *row1 = (uint *)src[1], *row2 = (uint *)src[2];
|
||||
uint32x4_t v_delta = vdupq_n_u32(32);
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
uint32x4_t v_r0 = vld1q_u32(row0 + x), v_r1 = vld1q_u32(row1 + x), v_r2 = vld1q_u32(row2 + x);
|
||||
uint32x4_t v_2r1 = vshlq_n_u32(v_r1, 1), v_4r1 = vshlq_n_u32(v_r1, 2);
|
||||
uint32x4_t v_dst00 = vaddq_u32(vaddq_u32(v_r0, v_r2), vaddq_u32(v_2r1, v_4r1));
|
||||
uint32x4_t v_dst10 = vshlq_n_u32(vaddq_u32(v_r1, v_r2), 2);
|
||||
|
||||
v_r0 = vld1q_u32(row0 + x + 4);
|
||||
v_r1 = vld1q_u32(row1 + x + 4);
|
||||
v_r2 = vld1q_u32(row2 + x + 4);
|
||||
v_2r1 = vshlq_n_u32(v_r1, 1);
|
||||
v_4r1 = vshlq_n_u32(v_r1, 2);
|
||||
uint32x4_t v_dst01 = vaddq_u32(vaddq_u32(v_r0, v_r2), vaddq_u32(v_2r1, v_4r1));
|
||||
uint32x4_t v_dst11 = vshlq_n_u32(vaddq_u32(v_r1, v_r2), 2);
|
||||
|
||||
vst1q_u16(dst0 + x, vcombine_u16(vmovn_u32(vshrq_n_u32(vaddq_u32(v_dst00, v_delta), 6)),
|
||||
vmovn_u32(vshrq_n_u32(vaddq_u32(v_dst01, v_delta), 6))));
|
||||
vst1q_u16(dst1 + x, vcombine_u16(vmovn_u32(vshrq_n_u32(vaddq_u32(v_dst10, v_delta), 6)),
|
||||
vmovn_u32(vshrq_n_u32(vaddq_u32(v_dst11, v_delta), 6))));
|
||||
}
|
||||
|
||||
for( ; x <= width - 4; x += 4 )
|
||||
{
|
||||
uint32x4_t v_r0 = vld1q_u32(row0 + x), v_r1 = vld1q_u32(row1 + x), v_r2 = vld1q_u32(row2 + x);
|
||||
uint32x4_t v_2r1 = vshlq_n_u32(v_r1, 1), v_4r1 = vshlq_n_u32(v_r1, 2);
|
||||
|
||||
uint32x4_t v_dst0 = vaddq_u32(vaddq_u32(v_r0, v_r2), vaddq_u32(v_2r1, v_4r1));
|
||||
uint32x4_t v_dst1 = vshlq_n_u32(vaddq_u32(v_r1, v_r2), 2);
|
||||
|
||||
vst1_u16(dst0 + x, vmovn_u32(vshrq_n_u32(vaddq_u32(v_dst0, v_delta), 6)));
|
||||
vst1_u16(dst1 + x, vmovn_u32(vshrq_n_u32(vaddq_u32(v_dst1, v_delta), 6)));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
struct PyrUpVec_32s16s
|
||||
{
|
||||
int operator()(int** src, short** dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
short *dst0 = dst[0], *dst1 = dst[1];
|
||||
const int *row0 = src[0], *row1 = src[1], *row2 = src[2];
|
||||
int32x4_t v_delta = vdupq_n_s32(32);
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
{
|
||||
int32x4_t v_r0 = vld1q_s32(row0 + x), v_r1 = vld1q_s32(row1 + x), v_r2 = vld1q_s32(row2 + x);
|
||||
int32x4_t v_2r1 = vshlq_n_s32(v_r1, 1), v_4r1 = vshlq_n_s32(v_r1, 2);
|
||||
int32x4_t v_dst00 = vaddq_s32(vaddq_s32(v_r0, v_r2), vaddq_s32(v_2r1, v_4r1));
|
||||
int32x4_t v_dst10 = vshlq_n_s32(vaddq_s32(v_r1, v_r2), 2);
|
||||
|
||||
v_r0 = vld1q_s32(row0 + x + 4);
|
||||
v_r1 = vld1q_s32(row1 + x + 4);
|
||||
v_r2 = vld1q_s32(row2 + x + 4);
|
||||
v_2r1 = vshlq_n_s32(v_r1, 1);
|
||||
v_4r1 = vshlq_n_s32(v_r1, 2);
|
||||
int32x4_t v_dst01 = vaddq_s32(vaddq_s32(v_r0, v_r2), vaddq_s32(v_2r1, v_4r1));
|
||||
int32x4_t v_dst11 = vshlq_n_s32(vaddq_s32(v_r1, v_r2), 2);
|
||||
|
||||
vst1q_s16(dst0 + x, vcombine_s16(vqmovn_s32(vshrq_n_s32(vaddq_s32(v_dst00, v_delta), 6)),
|
||||
vqmovn_s32(vshrq_n_s32(vaddq_s32(v_dst01, v_delta), 6))));
|
||||
vst1q_s16(dst1 + x, vcombine_s16(vqmovn_s32(vshrq_n_s32(vaddq_s32(v_dst10, v_delta), 6)),
|
||||
vqmovn_s32(vshrq_n_s32(vaddq_s32(v_dst11, v_delta), 6))));
|
||||
}
|
||||
|
||||
for( ; x <= width - 4; x += 4 )
|
||||
{
|
||||
int32x4_t v_r0 = vld1q_s32(row0 + x), v_r1 = vld1q_s32(row1 + x), v_r2 = vld1q_s32(row2 + x);
|
||||
int32x4_t v_2r1 = vshlq_n_s32(v_r1, 1), v_4r1 = vshlq_n_s32(v_r1, 2);
|
||||
|
||||
int32x4_t v_dst0 = vaddq_s32(vaddq_s32(v_r0, v_r2), vaddq_s32(v_2r1, v_4r1));
|
||||
int32x4_t v_dst1 = vshlq_n_s32(vaddq_s32(v_r1, v_r2), 2);
|
||||
|
||||
vst1_s16(dst0 + x, vqmovn_s32(vshrq_n_s32(vaddq_s32(v_dst0, v_delta), 6)));
|
||||
vst1_s16(dst1 + x, vqmovn_s32(vshrq_n_s32(vaddq_s32(v_dst1, v_delta), 6)));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
struct PyrUpVec_32f
|
||||
{
|
||||
int operator()(float** src, float** dst, int, int width) const
|
||||
{
|
||||
int x = 0;
|
||||
float ** dsts = (float **)dst;
|
||||
const float *row0 = src[0], *row1 = src[1], *row2 = src[2];
|
||||
float *dst0 = dsts[0], *dst1 = dsts[1];
|
||||
float *dst0 = dst[0], *dst1 = dst[1];
|
||||
float32x4_t v_6 = vdupq_n_f32(6.0f), v_scale = vdupq_n_f32(1.f/64.0f), v_scale4 = vmulq_n_f32(v_scale, 4.0f);
|
||||
|
||||
for( ; x <= width - 8; x += 8 )
|
||||
@ -362,12 +510,15 @@ struct PyrUpVec_32f
|
||||
|
||||
#else
|
||||
|
||||
typedef NoVec<int, uchar> PyrDownVec_32s8u;
|
||||
typedef NoVec<int, ushort> PyrDownVec_32s16u;
|
||||
typedef NoVec<int, short> PyrDownVec_32s16s;
|
||||
typedef NoVec<float, float> PyrDownVec_32f;
|
||||
typedef PyrDownNoVec<int, uchar> PyrDownVec_32s8u;
|
||||
typedef PyrDownNoVec<int, ushort> PyrDownVec_32s16u;
|
||||
typedef PyrDownNoVec<int, short> PyrDownVec_32s16s;
|
||||
typedef PyrDownNoVec<float, float> PyrDownVec_32f;
|
||||
|
||||
typedef NoVec<float, float> PyrUpVec_32f;
|
||||
typedef PyrUpNoVec<int, uchar> PyrUpVec_32s8u;
|
||||
typedef PyrUpNoVec<int, short> PyrUpVec_32s16s;
|
||||
typedef PyrUpNoVec<int, ushort> PyrUpVec_32s16u;
|
||||
typedef PyrUpNoVec<float, float> PyrUpVec_32f;
|
||||
|
||||
#endif
|
||||
|
||||
@ -574,7 +725,7 @@ pyrUp_( const Mat& _src, Mat& _dst, int)
|
||||
row0 = rows[0]; row1 = rows[1]; row2 = rows[2];
|
||||
dsts[0] = dst0; dsts[1] = dst1;
|
||||
|
||||
x = vecOp(rows, (T*)dsts, (int)_dst.step, dsize.width);
|
||||
x = vecOp(rows, dsts, (int)_dst.step, dsize.width);
|
||||
for( ; x < dsize.width; x++ )
|
||||
{
|
||||
T t1 = castOp((row1[x] + row2[x])*4);
|
||||
@ -761,7 +912,7 @@ void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borde
|
||||
else if( depth == CV_32F )
|
||||
func = pyrDown_<FltCast<float, 8>, PyrDownVec_32f>;
|
||||
else if( depth == CV_64F )
|
||||
func = pyrDown_<FltCast<double, 8>, NoVec<double, double> >;
|
||||
func = pyrDown_<FltCast<double, 8>, PyrDownNoVec<double, double> >;
|
||||
else
|
||||
CV_Error( CV_StsUnsupportedFormat, "" );
|
||||
|
||||
@ -830,15 +981,15 @@ void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderT
|
||||
|
||||
PyrFunc func = 0;
|
||||
if( depth == CV_8U )
|
||||
func = pyrUp_<FixPtCast<uchar, 6>, NoVec<int, uchar> >;
|
||||
func = pyrUp_<FixPtCast<uchar, 6>, PyrUpVec_32s8u >;
|
||||
else if( depth == CV_16S )
|
||||
func = pyrUp_<FixPtCast<short, 6>, NoVec<int, short> >;
|
||||
func = pyrUp_<FixPtCast<short, 6>, PyrUpVec_32s16s >;
|
||||
else if( depth == CV_16U )
|
||||
func = pyrUp_<FixPtCast<ushort, 6>, NoVec<int, ushort> >;
|
||||
func = pyrUp_<FixPtCast<ushort, 6>, PyrUpVec_32s16u >;
|
||||
else if( depth == CV_32F )
|
||||
func = pyrUp_<FltCast<float, 6>, PyrUpVec_32f >;
|
||||
else if( depth == CV_64F )
|
||||
func = pyrUp_<FltCast<double, 6>, NoVec<double, double> >;
|
||||
func = pyrUp_<FltCast<double, 6>, PyrUpNoVec<double, double> >;
|
||||
else
|
||||
CV_Error( CV_StsUnsupportedFormat, "" );
|
||||
|
||||
|
@ -1223,15 +1223,17 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
|
||||
else if (stype == CV_8UC4)
|
||||
IPP_FILTER_BOX_BORDER(Ipp8u, ipp8u, 8u_C4R);
|
||||
|
||||
else if (stype == CV_16UC1)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16u, ipp16u, 16u_C1R);
|
||||
// Oct 2014: performance with BORDER_CONSTANT
|
||||
//else if (stype == CV_16UC1)
|
||||
// IPP_FILTER_BOX_BORDER(Ipp16u, ipp16u, 16u_C1R);
|
||||
else if (stype == CV_16UC3)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16u, ipp16u, 16u_C3R);
|
||||
else if (stype == CV_16UC4)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16u, ipp16u, 16u_C4R);
|
||||
|
||||
else if (stype == CV_16SC1)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16s, ipp16s, 16s_C1R);
|
||||
// Oct 2014: performance with BORDER_CONSTANT
|
||||
//else if (stype == CV_16SC1)
|
||||
// IPP_FILTER_BOX_BORDER(Ipp16s, ipp16s, 16s_C1R);
|
||||
else if (stype == CV_16SC3)
|
||||
IPP_FILTER_BOX_BORDER(Ipp16s, ipp16s, 16s_C3R);
|
||||
else if (stype == CV_16SC4)
|
||||
|
@ -986,6 +986,110 @@ getThreshVal_Otsu_8u( const Mat& _src )
|
||||
return max_val;
|
||||
}
|
||||
|
||||
static double
|
||||
getThreshVal_Triangle_8u( const Mat& _src )
|
||||
{
|
||||
Size size = _src.size();
|
||||
int step = (int) _src.step;
|
||||
if( _src.isContinuous() )
|
||||
{
|
||||
size.width *= size.height;
|
||||
size.height = 1;
|
||||
step = size.width;
|
||||
}
|
||||
|
||||
const int N = 256;
|
||||
int i, j, h[N] = {0};
|
||||
for( i = 0; i < size.height; i++ )
|
||||
{
|
||||
const uchar* src = _src.ptr() + step*i;
|
||||
j = 0;
|
||||
#if CV_ENABLE_UNROLLED
|
||||
for( ; j <= size.width - 4; j += 4 )
|
||||
{
|
||||
int v0 = src[j], v1 = src[j+1];
|
||||
h[v0]++; h[v1]++;
|
||||
v0 = src[j+2]; v1 = src[j+3];
|
||||
h[v0]++; h[v1]++;
|
||||
}
|
||||
#endif
|
||||
for( ; j < size.width; j++ )
|
||||
h[src[j]]++;
|
||||
}
|
||||
|
||||
int left_bound = 0, right_bound = 0, max_ind = 0, max = 0;
|
||||
int temp;
|
||||
bool isflipped = false;
|
||||
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
if( h[i] > 0 )
|
||||
{
|
||||
left_bound = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( left_bound > 0 )
|
||||
left_bound--;
|
||||
|
||||
for( i = N-1; i > 0; i-- )
|
||||
{
|
||||
if( h[i] > 0 )
|
||||
{
|
||||
right_bound = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( right_bound < N-1 )
|
||||
right_bound++;
|
||||
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
if( h[i] > max)
|
||||
{
|
||||
max = h[i];
|
||||
max_ind = i;
|
||||
}
|
||||
}
|
||||
|
||||
if( max_ind-left_bound < right_bound-max_ind)
|
||||
{
|
||||
isflipped = true;
|
||||
i = 0, j = N-1;
|
||||
while( i < j )
|
||||
{
|
||||
temp = h[i]; h[i] = h[j]; h[j] = temp;
|
||||
i++; j--;
|
||||
}
|
||||
left_bound = N-1-right_bound;
|
||||
max_ind = N-1-max_ind;
|
||||
}
|
||||
|
||||
double thresh = left_bound;
|
||||
double a, b, dist = 0, tempdist;
|
||||
|
||||
/*
|
||||
* We do not need to compute precise distance here. Distance is maximized, so some constants can
|
||||
* be omitted. This speeds up a computation a bit.
|
||||
*/
|
||||
a = max; b = left_bound-max_ind;
|
||||
for( i = left_bound+1; i <= max_ind; i++ )
|
||||
{
|
||||
tempdist = a*i + b*h[i];
|
||||
if( tempdist > dist)
|
||||
{
|
||||
dist = tempdist;
|
||||
thresh = i;
|
||||
}
|
||||
}
|
||||
thresh--;
|
||||
|
||||
if( isflipped )
|
||||
thresh = N-1-thresh;
|
||||
|
||||
return thresh;
|
||||
}
|
||||
|
||||
class ThresholdRunner : public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
@ -1085,13 +1189,19 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m
|
||||
ocl_threshold(_src, _dst, thresh, maxval, type), thresh)
|
||||
|
||||
Mat src = _src.getMat();
|
||||
bool use_otsu = (type & THRESH_OTSU) != 0;
|
||||
int automatic_thresh = (type & ~CV_THRESH_MASK);
|
||||
type &= THRESH_MASK;
|
||||
|
||||
if( use_otsu )
|
||||
CV_Assert( automatic_thresh != (CV_THRESH_OTSU | CV_THRESH_TRIANGLE) );
|
||||
if( automatic_thresh == CV_THRESH_OTSU )
|
||||
{
|
||||
CV_Assert( src.type() == CV_8UC1 );
|
||||
thresh = getThreshVal_Otsu_8u(src);
|
||||
thresh = getThreshVal_Otsu_8u( src );
|
||||
}
|
||||
else if( automatic_thresh == CV_THRESH_TRIANGLE )
|
||||
{
|
||||
CV_Assert( src.type() == CV_8UC1 );
|
||||
thresh = getThreshVal_Triangle_8u( src );
|
||||
}
|
||||
|
||||
_dst.create( src.size(), src.type() );
|
||||
|
@ -121,7 +121,7 @@ OCL_TEST_P(WarpAffine, Mat)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
double eps = depth < CV_32F ? 0.03 : 0.06;
|
||||
double eps = depth < CV_32F ? 0.04 : 0.06;
|
||||
random_roi();
|
||||
|
||||
Mat M = getRotationMatrix2D(Point2f(src_roi.cols / 2.0f, src_roi.rows / 2.0f),
|
||||
|
@ -1100,7 +1100,7 @@ int CV_CompareHistTest::validate_test_results( int /*test_case_idx*/ )
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
break;
|
||||
}
|
||||
else if( fabs(v0 - v) > FLT_EPSILON*10*MAX(fabs(v0),0.1) )
|
||||
else if( fabs(v0 - v) > FLT_EPSILON*14*MAX(fabs(v0),0.1) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "The comparison result using the method #%d (%s)\n\tis inaccurate (=%g, should be =%g)\n",
|
||||
i, method_name, v, v0 );
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user