diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index a671d43e3d125e00578cca5119e5cc9266aea16a..81e18973f731a3fef8a8b68a9ff57f448653cc22 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -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} diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index c47496fa3b64916e2ceb32b4749b3210a977d8df..443eb6d493e49998c966f7c55bcddc373cd57cac 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -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 = diff --git a/doc/mymath.js b/doc/mymath.js new file mode 100644 index 0000000000000000000000000000000000000000..69bc91ab65c7dcdb732c016878ba0ed65055d343 --- /dev/null +++ b/doc/mymath.js @@ -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] + } + } + }); diff --git a/doc/mymath.sty b/doc/mymath.sty index 4da8282121caafe0c03d5d2ff3e8a590fa8916e8..24dae263a57a5fc91c5f42cea4cf6bab95ab829f 100644 --- a/doc/mymath.sty +++ b/doc/mymath.sty @@ -1,5 +1,9 @@ \ProvidesPackage{mymath} +\usepackage{euler} +\usepackage{amssymb} +\usepackage{amsmath} + \newcommand{\matTT}[9]{ \[ \left|\begin{array}{ccc} diff --git a/doc/root.markdown.in b/doc/root.markdown.in new file mode 100644 index 0000000000000000000000000000000000000000..63e7c543b0eee465e06975c29b880d4a4957f913 --- /dev/null +++ b/doc/root.markdown.in @@ -0,0 +1,7 @@ +OpenCV modules {#mainpage} +============== + +- @subpage intro +- @subpage core + + diff --git a/modules/core/doc/intro.markdown b/modules/core/doc/intro.markdown new file mode 100644 index 0000000000000000000000000000000000000000..952b7dc096d8eb4abe613c19c644399085355e72 --- /dev/null +++ b/modules/core/doc/intro.markdown @@ -0,0 +1,318 @@ +Introduction {#intro} +============ + +OpenCV (Open Source Computer Vision Library: ) 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 ptr(new T(...)); +@endcode +or: +@code + Ptr ptr = makePtr(...); +@endcode +Ptr\ 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(y, x) = saturate_cast(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. diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index a8f2db2470129a8d70f9fabe7701d74b8446ae88..2f31ee3fc0cb16b8060734bf6ef9c0152a1e2c59 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -57,14 +57,38 @@ #include "opencv2/core/mat.hpp" #include "opencv2/core/persistence.hpp" -/*! \namespace cv - Namespace where all the C++ OpenCV functionality resides -*/ +/** +@defgroup core Core functionality +@{ + @defgroup core_basic Basic structures + @defgroup core_c C structures and operations + @{ + @defgroup core_c_glue Connections with C++ + @} + @defgroup core_array Operations on arrays + @defgroup core_xml XML/YAML Persistence + @defgroup core_cluster Clustering + @defgroup core_utils Utility and system functions and macros + @{ + @defgroup core_utils_neon NEON utilities + @} + @defgroup core_opengl OpenGL interoperability + @defgroup core_ipp Intel IPP Asynchronous C/C++ Converters + @defgroup core_optim Optimization Algorithms +@} + */ + namespace cv { -/*! - The standard OpenCV exception class. - Instances of the class are thrown by various functions and methods in the case of critical errors. +//! @addtogroup core_utils +//! @{ + +/*! @brief Class passed to an error. + +This class encapsulates all or almost all necessary +information about the error happened in the program. The exception is +usually constructed and thrown implicitly via CV_Error and CV_Error_ macros. +@see error */ class CV_EXPORTS Exception : public std::exception { @@ -95,41 +119,80 @@ public: int line; ///< line number in the source file where the error has occured }; +/*! @brief Signals an error and raises the exception. -//! 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 exc the exception raisen. - \todo drop this version +By default the function prints information about the error to stderr, +then it either stops if cv::setBreakOnError() had been called before or raises the exception. +It is possible to alternate error processing by using cv::redirectError(). +@param exc the exception raisen. +@deprecated drop this version */ - CV_EXPORTS void error( const Exception& exc ); +enum SortFlags { SORT_EVERY_ROW = 0, //!< each matrix row is sorted independently + SORT_EVERY_COLUMN = 1, //!< each matrix column is sorted + //!< independently; this flag and the previous one are + //!< mutually exclusive. + SORT_ASCENDING = 0, //!< each matrix row is sorted in the ascending + //!< order. + SORT_DESCENDING = 16 //!< each matrix row is sorted in the + //!< descending order; this flag and the previous one are also + //!< mutually exclusive. + }; + +//! @} core_utils + +//! @addtogroup core +//! @{ + +//! Covariation flags +enum CovarFlags { + /** The output covariance matrix is calculated as: + \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...],\f] + The covariance matrix will be nsamples x nsamples. Such an unusual covariance matrix is used + for fast PCA of a set of very large vectors (see, for example, the EigenFaces technique for + face recognition). Eigenvalues of this "scrambled" matrix match the eigenvalues of the true + covariance matrix. The "true" eigenvectors can be easily calculated from the eigenvectors of + the "scrambled" covariance matrix. */ + COVAR_SCRAMBLED = 0, + /**The output covariance matrix is calculated as: + \f[\texttt{scale} \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...] \cdot [ \texttt{vects} [0]- \texttt{mean} , \texttt{vects} [1]- \texttt{mean} ,...]^T,\f] + covar will be a square matrix of the same size as the total number of elements in each input + vector. One and only one of COVAR_SCRAMBLED and COVAR_NORMAL must be specified.*/ + COVAR_NORMAL = 1, + /** If the flag is specified, the function does not calculate mean from + the input vectors but, instead, uses the passed mean vector. This is useful if mean has been + pre-calculated or known in advance, or if the covariance matrix is calculated by parts. In + this case, mean is not a mean vector of the input sub-set of vectors but rather the mean + vector of the whole set.*/ + COVAR_USE_AVG = 2, + /** If the flag is specified, the covariance matrix is scaled. In the + "normal" mode, scale is 1./nsamples . In the "scrambled" mode, scale is the reciprocal of the + total number of elements in each input vector. By default (if the flag is not specified), the + covariance matrix is not scaled ( scale=1 ).*/ + COVAR_SCALE = 4, + /** If the flag is + specified, all the input vectors are stored as rows of the samples matrix. mean should be a + single-row vector in this case.*/ + COVAR_ROWS = 8, + /** If the flag is + specified, all the input vectors are stored as columns of the samples matrix. mean should be a + single-column vector in this case.*/ + COVAR_COLS = 16 +}; -enum { SORT_EVERY_ROW = 0, - SORT_EVERY_COLUMN = 1, - SORT_ASCENDING = 0, - SORT_DESCENDING = 16 - }; - -enum { COVAR_SCRAMBLED = 0, - COVAR_NORMAL = 1, - COVAR_USE_AVG = 2, - COVAR_SCALE = 4, - COVAR_ROWS = 8, - COVAR_COLS = 16 - }; - -/*! - k-Means flags -*/ -enum { KMEANS_RANDOM_CENTERS = 0, // Chooses random centers for k-Means initialization - KMEANS_PP_CENTERS = 2, // Uses k-Means++ algorithm for initialization - KMEANS_USE_INITIAL_LABELS = 1 // Uses the user-provided labels for K-Means initialization - }; +//! k-Means flags +enum KmeansFlags { + /** Select random initial centers in each attempt.*/ + KMEANS_RANDOM_CENTERS = 0, + /** Use kmeans++ center initialization by Arthur and Vassilvitskii [Arthur2007].*/ + KMEANS_PP_CENTERS = 2, + /** During the first (and possibly the only) attempt, use the + user-supplied labels instead of computing them from the initial centers. For the second and + further attempts, use the random or semi-random centers. Use one of KMEANS_\*_CENTERS flag + to specify the exact method.*/ + KMEANS_USE_INITIAL_LABELS = 1 +}; enum { FILLED = -1, LINE_4 = 4, @@ -148,450 +211,2013 @@ enum { FONT_HERSHEY_SIMPLEX = 0, FONT_ITALIC = 16 }; -enum { REDUCE_SUM = 0, - REDUCE_AVG = 1, - REDUCE_MAX = 2, - REDUCE_MIN = 3 - }; +enum ReduceTypes { REDUCE_SUM = 0, //!< the output is the sum of all rows/columns of the matrix. + REDUCE_AVG = 1, //!< the output is the mean vector of all rows/columns of the matrix. + REDUCE_MAX = 2, //!< the output is the maximum (column/row-wise) of all rows/columns of the matrix. + REDUCE_MIN = 3 //!< the output is the minimum (column/row-wise) of all rows/columns of the matrix. + }; -//! swaps two matrices +/** @brief Swaps two matrices +*/ CV_EXPORTS void swap(Mat& a, Mat& b); - -//! swaps two umatrices +/** @overload */ CV_EXPORTS void swap( UMat& a, UMat& b ); -//! 1D interpolation function: returns coordinate of the "donor" pixel for the specified location p. +//! @} core + +//! @addtogroup core_array +//! @{ + +/** @brief Computes the source location of an extrapolated pixel. + +The function computes and returns the coordinate of a donor pixel corresponding to the specified +extrapolated pixel when using the specified extrapolation border mode. For example, if you use +cv::BORDER_WRAP mode in the horizontal direction, cv::BORDER_REFLECT_101 in the vertical direction and +want to compute value of the "virtual" pixel Point(-5, 100) in a floating-point image img , it +looks like: +@code{.cpp} + float val = img.at(borderInterpolate(100, img.rows, cv::BORDER_REFLECT_101), + borderInterpolate(-5, img.cols, cv::BORDER_WRAP)); +@endcode +Normally, the function is not called directly. It is used inside filtering functions and also in +copyMakeBorder. +@param p 0-based coordinate of the extrapolated pixel along one of the axes, likely \<0 or \>= len +@param len Length of the array along the corresponding axis. +@param borderType Border type, one of the cv::BorderTypes, except for cv::BORDER_TRANSPARENT and +cv::BORDER_ISOLATED . When borderType==cv::BORDER_CONSTANT , the function always returns -1, regardless +of p and len. + +@sa copyMakeBorder +*/ CV_EXPORTS_W int borderInterpolate(int p, int len, int borderType); -//! copies 2D array to a larger destination array with extrapolation of the outer part of src using the specified border mode +/** @brief Forms a border around an image. + +The function copies the source image into the middle of the destination image. The areas to the +left, to the right, above and below the copied source image will be filled with extrapolated +pixels. This is not what filtering functions based on it do (they extrapolate pixels on-fly), but +what other more complex functions, including your own, may do to simplify image boundary handling. + +The function supports the mode when src is already in the middle of dst . In this case, the +function does not copy src itself but simply constructs the border, for example: + +@code{.cpp} + // let border be the same in all directions + int border=2; + // constructs a larger image to fit both the image and the border + Mat gray_buf(rgb.rows + border*2, rgb.cols + border*2, rgb.depth()); + // select the middle part of it w/o copying data + Mat gray(gray_canvas, Rect(border, border, rgb.cols, rgb.rows)); + // convert image from RGB to grayscale + cvtColor(rgb, gray, COLOR_RGB2GRAY); + // form a border in-place + copyMakeBorder(gray, gray_buf, border, border, + border, border, BORDER_REPLICATE); + // now do some custom filtering ... + ... +@endcode +@note When the source image is a part (ROI) of a bigger image, the function will try to use the +pixels outside of the ROI to form a border. To disable this feature and always do extrapolation, as +if src was not a ROI, use borderType | BORDER_ISOLATED. + +@param src Source image. +@param dst Destination image of the same type as src and the size Size(src.cols+left+right, +src.rows+top+bottom) . +@param top +@param bottom +@param left +@param right Parameter specifying how many pixels in each direction from the source image rectangle +to extrapolate. For example, top=1, bottom=1, left=1, right=1 mean that 1 pixel-wide border needs +to be built. +@param borderType Border type. See borderInterpolate for details. +@param value Border value if borderType==BORDER_CONSTANT . + +@sa borderInterpolate +*/ CV_EXPORTS_W void copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar& value = Scalar() ); -//! adds one matrix to another (dst = src1 + src2) +/** @brief Calculates the per-element sum of two arrays or an array and a scalar. + +The function add calculates: +- Sum of two arrays when both input arrays have the same size and the same number of channels: +\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f] +- Sum of an array and a scalar when src2 is constructed from Scalar or has the same number of +elements as `src1.channels()`: +\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) + \texttt{src2} ) \quad \texttt{if mask}(I) \ne0\f] +- Sum of a scalar and an array when src1 is constructed from Scalar or has the same number of +elements as `src2.channels()`: +\f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} + \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0\f] +where `I` is a multi-dimensional index of array elements. In case of multi-channel arrays, each +channel is processed independently. + +The first function in the list above can be replaced with matrix expressions: +@code{.cpp} + dst = src1 + src2; + dst += src1; // equivalent to add(dst, src1, dst); +@endcode +The input arrays and the output array can all have the same or different depths. For example, you +can add a 16-bit unsigned array to a 8-bit signed array and store the sum as a 32-bit +floating-point array. Depth of the output array is determined by the dtype parameter. In the second +and third cases above, as well as in the first case, when src1.depth() == src2.depth(), dtype can +be set to the default -1. In this case, the output array will have the same depth as the input +array, be it src1, src2 or both. +@note Saturation is not applied when the output array has the depth CV_32S. You may even get +result of an incorrect sign in the case of overflow. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and number of channels as the input array(s); the +depth is defined by dtype or src1/src2. +@param mask optional operation mask - 8-bit single channel array, that specifies elements of the +output array to be changed. +@param dtype optional depth of the output array (see the discussion below). +@sa subtract, addWeighted, scaleAdd, Mat::convertTo +*/ CV_EXPORTS_W void add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1); -//! subtracts one matrix from another (dst = src1 - src2) +/** @brief Calculates the per-element difference between two arrays or array and a scalar. + +The function subtract calculates: +- Difference between two arrays, when both input arrays have the same size and the same number of +channels: + \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2}(I)) \quad \texttt{if mask}(I) \ne0\f] +- Difference between an array and a scalar, when src2 is constructed from Scalar or has the same +number of elements as `src1.channels()`: + \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1}(I) - \texttt{src2} ) \quad \texttt{if mask}(I) \ne0\f] +- Difference between a scalar and an array, when src1 is constructed from Scalar or has the same +number of elements as `src2.channels()`: + \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src1} - \texttt{src2}(I) ) \quad \texttt{if mask}(I) \ne0\f] +- The reverse difference between a scalar and an array in the case of `SubRS`: + \f[\texttt{dst}(I) = \texttt{saturate} ( \texttt{src2} - \texttt{src1}(I) ) \quad \texttt{if mask}(I) \ne0\f] +where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each +channel is processed independently. + +The first function in the list above can be replaced with matrix expressions: +@code{.cpp} + dst = src1 - src2; + dst -= src1; // equivalent to subtract(dst, src1, dst); +@endcode +The input arrays and the output array can all have the same or different depths. For example, you +can subtract to 8-bit unsigned arrays and store the difference in a 16-bit signed array. Depth of +the output array is determined by dtype parameter. In the second and third cases above, as well as +in the first case, when src1.depth() == src2.depth(), dtype can be set to the default -1. In this +case the output array will have the same depth as the input array, be it src1, src2 or both. +@note Saturation is not applied when the output array has the depth CV_32S. You may even get +result of an incorrect sign in the case of overflow. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array of the same size and the same number of channels as the input array. +@param mask optional operation mask; this is an 8-bit single channel array that specifies elements +of the output array to be changed. +@param dtype optional depth of the output array +@sa add, addWeighted, scaleAdd, Mat::convertTo + */ CV_EXPORTS_W void subtract(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray(), int dtype = -1); -//! computes element-wise weighted product of the two arrays (dst = scale*src1*src2) + +/** @brief Calculates the per-element scaled product of two arrays. + +The function multiply calculates the per-element product of two arrays: + +\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I))\f] + +There is also a @ref MatrixExpressions -friendly variant of the first function. See Mat::mul . + +For a not-per-element matrix product, see gemm . + +@note Saturation is not applied when the output array has the depth +CV_32S. You may even get result of an incorrect sign in the case of +overflow. +@param src1 first input array. +@param src2 second input array of the same size and the same type as src1. +@param dst output array of the same size and type as src1. +@param scale optional scale factor. +@param dtype optional depth of the output array +@sa add, subtract, divide, scaleAdd, addWeighted, accumulate, accumulateProduct, accumulateSquare, +Mat::convertTo +*/ CV_EXPORTS_W void multiply(InputArray src1, InputArray src2, OutputArray dst, double scale = 1, int dtype = -1); -//! computes element-wise weighted quotient of the two arrays (dst = scale * src1 / src2) +/** @brief Performs per-element division of two arrays or a scalar by an array. + +The functions divide divide one array by another: +\f[\texttt{dst(I) = saturate(src1(I)*scale/src2(I))}\f] +or a scalar by an array when there is no src1 : +\f[\texttt{dst(I) = saturate(scale/src2(I))}\f] + +When src2(I) is zero, dst(I) will also be zero. Different channels of +multi-channel arrays are processed independently. + +@note Saturation is not applied when the output array has the depth CV_32S. You may even get +result of an incorrect sign in the case of overflow. +@param src1 first input array. +@param src2 second input array of the same size and type as src1. +@param scale scalar factor. +@param dst output array of the same size and type as src2. +@param dtype optional depth of the output array; if -1, dst will have depth src2.depth(), but in +case of an array-by-array division, you can only pass -1 when src1.depth()==src2.depth(). +@sa multiply, add, subtract +*/ CV_EXPORTS_W void divide(InputArray src1, InputArray src2, OutputArray dst, double scale = 1, int dtype = -1); -//! computes element-wise weighted reciprocal of an array (dst = scale/src2) +/** @overload */ CV_EXPORTS_W void divide(double scale, InputArray src2, OutputArray dst, int dtype = -1); -//! adds scaled array to another one (dst = alpha*src1 + src2) +/** @brief Calculates the sum of a scaled array and another array. + +The function scaleAdd is one of the classical primitive linear algebra operations, known as DAXPY +or SAXPY in [BLAS](http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms). It calculates +the sum of a scaled array and another array: +\f[\texttt{dst} (I)= \texttt{scale} \cdot \texttt{src1} (I) + \texttt{src2} (I)\f] +The function can also be emulated with a matrix expression, for example: +@code{.cpp} + Mat A(3, 3, CV_64F); + ... + A.row(0) = A.row(1)*2 + A.row(2); +@endcode +@param src1 first input array. +@param alpha scale factor for the first array. +@param src2 second input array of the same size and type as src1. +@param dst output array of the same size and type as src1. +@sa add, addWeighted, subtract, Mat::dot, Mat::convertTo +*/ CV_EXPORTS_W void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst); -//! computes weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma) +/** @brief Calculates the weighted sum of two arrays. + +The function addWeighted calculates the weighted sum of two arrays as follows: +\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* \texttt{beta} + \texttt{gamma} )\f] +where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each +channel is processed independently. +The function can be replaced with a matrix expression: +@code{.cpp} + dst = src1*alpha + src2*beta + gamma; +@endcode +@note Saturation is not applied when the output array has the depth CV_32S. You may even get +result of an incorrect sign in the case of overflow. +@param src1 first input array. +@param alpha weight of the first array elements. +@param src2 second input array of the same size and channel number as src1. +@param beta weight of the second array elements. +@param gamma scalar added to each sum. +@param dst output array that has the same size and number of channels as the input arrays. +@param dtype optional depth of the output array; when both input arrays have the same depth, dtype +can be set to -1, which will be equivalent to src1.depth(). +@sa add, subtract, scaleAdd, Mat::convertTo +*/ CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1); -//! scales array elements, computes absolute values and converts the results to 8-bit unsigned integers: dst(i)=saturate_castabs(src(i)*alpha+beta) +/** @brief Scales, calculates absolute values, and converts the result to 8-bit. + +On each element of the input array, the function convertScaleAbs +performs three operations sequentially: scaling, taking an absolute +value, conversion to an unsigned 8-bit type: +\f[\texttt{dst} (I)= \texttt{saturate\_cast} (| \texttt{src} (I)* \texttt{alpha} + \texttt{beta} |)\f] +In case of multi-channel arrays, the function processes each channel +independently. When the output is not 8-bit, the operation can be +emulated by calling the Mat::convertTo method (or by using matrix +expressions) and then by calculating an absolute value of the result. +For example: +@code{.cpp} + Mat_ A(30,30); + randu(A, Scalar(-100), Scalar(100)); + Mat_ B = A*5 + 3; + B = abs(B); + // Mat_ B = abs(A*5+3) will also do the job, + // but it will allocate a temporary matrix +@endcode +@param src input array. +@param dst output array. +@param alpha optional scale factor. +@param beta optional delta added to the scaled values. +@sa Mat::convertTo, cv::abs(const Mat&) +*/ CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst, double alpha = 1, double beta = 0); -//! transforms array of numbers using a lookup table: dst(i)=lut(src(i)) +/** @brief Performs a look-up table transform of an array. + +The function LUT fills the output array with values from the look-up table. Indices of the entries +are taken from the input array. That is, the function processes each element of src as follows: +\f[\texttt{dst} (I) \leftarrow \texttt{lut(src(I) + d)}\f] +where +\f[d = \fork{0}{if \texttt{src} has depth \texttt{CV\_8U}}{128}{if \texttt{src} has depth \texttt{CV\_8S}}\f] +@param src input array of 8-bit elements. +@param lut look-up table of 256 elements; in case of multi-channel input array, the table should +either have a single channel (in this case the same table is used for all channels) or the same +number of channels as in the input array. +@param dst output array of the same size and number of channels as src, and the same depth as lut. +@sa convertScaleAbs, Mat::convertTo +*/ CV_EXPORTS_W void LUT(InputArray src, InputArray lut, OutputArray dst); -//! computes sum of array elements +/** @brief Calculates the sum of array elements. + +The functions sum calculate and return the sum of array elements, +independently for each channel. +@param src input array that must have from 1 to 4 channels. +@sa countNonZero, mean, meanStdDev, norm, minMaxLoc, reduce +*/ CV_EXPORTS_AS(sumElems) Scalar sum(InputArray src); -//! computes the number of nonzero array elements +/** @brief Counts non-zero array elements. + +The function returns the number of non-zero elements in src : +\f[\sum _{I: \; \texttt{src} (I) \ne0 } 1\f] +@param src single-channel array. +@sa mean, meanStdDev, norm, minMaxLoc, calcCovarMatrix +*/ CV_EXPORTS_W int countNonZero( InputArray src ); -//! returns the list of locations of non-zero pixels +/** @brief returns the list of locations of non-zero pixels +@todo document +*/ CV_EXPORTS_W void findNonZero( InputArray src, OutputArray idx ); -//! computes mean value of selected array elements +/** @brief Calculates an average (mean) of array elements. + +The function mean calculates the mean value M of array elements, +independently for each channel, and return it: +\f[\begin{array}{l} N = \sum _{I: \; \texttt{mask} (I) \ne 0} 1 \\ M_c = \left ( \sum _{I: \; \texttt{mask} (I) \ne 0}{ \texttt{mtx} (I)_c} \right )/N \end{array}\f] +When all the mask elements are 0's, the functions return Scalar::all(0) +@param src input array that should have from 1 to 4 channels so that the result can be stored in +Scalar_ . +@param mask optional operation mask. +@sa countNonZero, meanStdDev, norm, minMaxLoc +*/ CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask = noArray()); -//! computes mean value and standard deviation of all or selected array elements +/** Calculates a mean and standard deviation of array elements. + +The function meanStdDev calculates the mean and the standard deviation M +of array elements independently for each channel and returns it via the +output parameters: +\f[\begin{array}{l} N = \sum _{I, \texttt{mask} (I) \ne 0} 1 \\ \texttt{mean} _c = \frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \texttt{src} (I)_c}{N} \\ \texttt{stddev} _c = \sqrt{\frac{\sum_{ I: \; \texttt{mask}(I) \ne 0} \left ( \texttt{src} (I)_c - \texttt{mean} _c \right )^2}{N}} \end{array}\f] +When all the mask elements are 0's, the functions return +mean=stddev=Scalar::all(0). +@note The calculated standard deviation is only the diagonal of the +complete normalized covariance matrix. If the full matrix is needed, you +can reshape the multi-channel array M x N to the single-channel array +M\*N x mtx.channels() (only possible when the matrix is continuous) and +then pass the matrix to calcCovarMatrix . +@param src input array that should have from 1 to 4 channels so that the results can be stored in +Scalar_ 's. +@param mean output parameter: calculated mean value. +@param stddev output parameter: calculateded standard deviation. +@param mask optional operation mask. +@sa countNonZero, mean, norm, minMaxLoc, calcCovarMatrix +*/ CV_EXPORTS_W void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev, InputArray mask=noArray()); -//! computes norm of the selected array part +/** @brief Calculates an absolute array norm, an absolute difference norm, or a +relative difference norm. + +The functions norm calculate an absolute norm of src1 (when there is no +src2 ): + +\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] + +or an absolute or relative difference norm if src2 is there: + +\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] + +or + +\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] + +The functions norm return the calculated norm. + +When the mask parameter is specified and it is not empty, the norm is +calculated only over the region specified by the mask. + +A multi-channel input arrays are treated as a single-channel, that is, +the results for all channels are combined. + +@param src1 first input array. +@param normType type of the norm (see cv::NormTypes). +@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type. +*/ CV_EXPORTS_W double norm(InputArray src1, int normType = NORM_L2, InputArray mask = noArray()); -//! computes norm of selected part of the difference between two arrays +/** @overload +@param src1 first input array. +@param src2 second input array of the same size and the same type as src1. +@param normType type of the norm (cv::NormTypes). +@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type. +*/ CV_EXPORTS_W double norm(InputArray src1, InputArray src2, int normType = NORM_L2, InputArray mask = noArray()); +/** @overload +@param src first input array. +@param normType type of the norm (see cv::NormTypes). +*/ +CV_EXPORTS double norm( const SparseMat& src, int normType ); -//! computes PSNR image/video quality metric +/** @brief computes PSNR image/video quality metric + +see http://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio for details +@todo document + */ CV_EXPORTS_W double PSNR(InputArray src1, InputArray src2); -//! computes norm of a sparse matrix -CV_EXPORTS double norm( const SparseMat& src, int normType ); +/** @brief naive nearest neighbor finder -//! naive nearest neighbor finder +see http://en.wikipedia.org/wiki/Nearest_neighbor_search +@todo document + */ CV_EXPORTS_W void batchDistance(InputArray src1, InputArray src2, OutputArray dist, int dtype, OutputArray nidx, int normType = NORM_L2, int K = 0, InputArray mask = noArray(), int update = 0, bool crosscheck = false); -//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values +/** @brief Normalizes the norm or value range of an array. + +The functions normalize scale and shift the input array elements so that +\f[\| \texttt{dst} \| _{L_p}= \texttt{alpha}\f] +(where p=Inf, 1 or 2) when normType=NORM_INF, NORM_L1, or NORM_L2, respectively; or so that +\f[\min _I \texttt{dst} (I)= \texttt{alpha} , \, \, \max _I \texttt{dst} (I)= \texttt{beta}\f] + +when normType=NORM_MINMAX (for dense arrays only). The optional mask specifies a sub-array to be +normalized. This means that the norm or min-n-max are calculated over the sub-array, and then this +sub-array is modified to be normalized. If you want to only use the mask to calculate the norm or +min-max but modify the whole array, you can use norm and Mat::convertTo. + +In case of sparse matrices, only the non-zero values are analyzed and transformed. Because of this, +the range transformation for sparse matrices is not allowed since it can shift the zero level. + +@param src input array. +@param dst output array of the same size as src . +@param alpha norm value to normalize to or the lower range boundary in case of the range +normalization. +@param beta upper range boundary in case of the range normalization; it is not used for the norm +normalization. +@param norm_type normalization type (see cv::NormTypes). +@param dtype when negative, the output array has the same type as src; otherwise, it has the same +number of channels as src and the depth =CV_MAT_DEPTH(dtype). +@param mask optional operation mask. +@sa norm, Mat::convertTo, SparseMat::convertTo +*/ CV_EXPORTS_W void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray()); -//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values +/** @overload +@param src input array. +@param dst output array of the same size as src . +@param alpha norm value to normalize to or the lower range boundary in case of the range +normalization. +@param normType normalization type (see cv::NormTypes). +*/ CV_EXPORTS void normalize( const SparseMat& src, SparseMat& dst, double alpha, int normType ); -//! finds global minimum and maximum array elements and returns their values and their locations +/** @brief Finds the global minimum and maximum in an array. + +The functions minMaxLoc find the minimum and maximum element values and their positions. The +extremums are searched across the whole array or, if mask is not an empty array, in the specified +array region. + +The functions do not work with multi-channel arrays. If you need to find minimum or maximum +elements across all the channels, use Mat::reshape first to reinterpret the array as +single-channel. Or you may extract the particular channel using either extractImageCOI , or +mixChannels , or split . +@param src input single-channel array. +@param minVal pointer to the returned minimum value; NULL is used if not required. +@param maxVal pointer to the returned maximum value; NULL is used if not required. +@param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required. +@param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required. +@param mask optional mask used to select a sub-array. +@sa max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape +*/ CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal, CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0, CV_OUT Point* maxLoc = 0, InputArray mask = noArray()); + +/** @brief Finds the global minimum and maximum in an array + +The function minMaxIdx finds the minimum and maximum element values and their positions. The +extremums are searched across the whole array or, if mask is not an empty array, in the specified +array region. The function does not work with multi-channel arrays. If you need to find minimum or +maximum elements across all the channels, use Mat::reshape first to reinterpret the array as +single-channel. Or you may extract the particular channel using either extractImageCOI , or +mixChannels , or split . In case of a sparse matrix, the minimum is found among non-zero elements +only. +@note When minIdx is not NULL, it must have at least 2 elements (as well as maxIdx), even if src is +a single-row or single-column matrix. In OpenCV (following MATLAB) each array has at least 2 +dimensions, i.e. single-column matrix is Mx1 matrix (and therefore minIdx/maxIdx will be +(i1,0)/(i2,0)) and single-row matrix is 1xN matrix (and therefore minIdx/maxIdx will be +(0,j1)/(0,j2)). +@param src input single-channel array. +@param minVal pointer to the returned minimum value; NULL is used if not required. +@param maxVal pointer to the returned maximum value; NULL is used if not required. +@param minIdx pointer to the returned minimum location (in nD case); NULL is used if not required; +Otherwise, it must point to an array of src.dims elements, the coordinates of the minimum element +in each dimension are stored there sequentially. +@param maxIdx pointer to the returned maximum location (in nD case). NULL is used if not required. +@param mask specified array region +*/ CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal = 0, int* minIdx = 0, int* maxIdx = 0, InputArray mask = noArray()); -//! finds global minimum and maximum sparse array elements and returns their values and their locations +/** @overload +@param a input single-channel array. +@param minVal pointer to the returned minimum value; NULL is used if not required. +@param maxVal pointer to the returned maximum value; NULL is used if not required. +@param minIdx pointer to the returned minimum location (in nD case); NULL is used if not required; +Otherwise, it must point to an array of src.dims elements, the coordinates of the minimum element +in each dimension are stored there sequentially. +@param maxIdx pointer to the returned maximum location (in nD case). NULL is used if not required. +*/ CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal, double* maxVal, int* minIdx = 0, int* maxIdx = 0); -//! transforms 2D matrix to 1D row or column vector by taking sum, minimum, maximum or mean value over all the rows +/** @brief Reduces a matrix to a vector. + +The function reduce reduces the matrix to a vector by treating the matrix rows/columns as a set of +1D vectors and performing the specified operation on the vectors until a single row/column is +obtained. For example, the function can be used to compute horizontal and vertical projections of a +raster image. In case of REDUCE_SUM and REDUCE_AVG , the output may have a larger element +bit-depth to preserve accuracy. And multi-channel arrays are also supported in these two reduction +modes. +@param src input 2D matrix. +@param dst output vector. Its size and type is defined by dim and dtype parameters. +@param dim dimension index along which the matrix is reduced. 0 means that the matrix is reduced to +a single row. 1 means that the matrix is reduced to a single column. +@param rtype reduction operation that could be one of cv::ReduceTypes +@param dtype when negative, the output vector will have the same type as the input matrix, +otherwise, its type will be CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), src.channels()). +@sa repeat +*/ CV_EXPORTS_W void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype = -1); -//! makes multi-channel array out of several single-channel arrays +/** @brief Creates one multichannel array out of several single-channel ones. + +The functions merge merge several arrays to make a single multi-channel array. That is, each +element of the output array will be a concatenation of the elements of the input arrays, where +elements of i-th input array are treated as mv[i].channels()-element vectors. + +The function split does the reverse operation. If you need to shuffle channels in some other +advanced way, use mixChannels . +@param mv input array of matrices to be merged; all the matrices in mv must have the same +size and the same depth. +@param count number of input matrices when mv is a plain C array; it must be greater than zero. +@param dst output array of the same size and the same depth as mv[0]; The number of channels will +be the total number of channels in the matrix array. +@sa mixChannels, split, Mat::reshape +*/ CV_EXPORTS void merge(const Mat* mv, size_t count, OutputArray dst); -//! makes multi-channel array out of several single-channel arrays +/** @overload +@param mv input vector of matrices to be merged; all the matrices in mv must have the same +size and the same depth. +@param dst output array of the same size and the same depth as mv[0]; The number of channels will +be the total number of channels in the matrix array. + */ CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst); -//! copies each plane of a multi-channel array to a dedicated array +/** @brief Divides a multi-channel array into several single-channel arrays. + +The functions split split a multi-channel array into separate single-channel arrays: +\f[\texttt{mv} [c](I) = \texttt{src} (I)_c\f] +If you need to extract a single channel or do some other sophisticated channel permutation, use +mixChannels . +@param src input multi-channel array. +@param mvbegin output array; the number of arrays must match src.channels(); the arrays themselves are +reallocated, if needed. +@sa merge, mixChannels, cvtColor +*/ CV_EXPORTS void split(const Mat& src, Mat* mvbegin); -//! copies each plane of a multi-channel array to a dedicated array +/** @overload +@param m input multi-channel array. +@param mv output vector of arrays; the arrays themselves are reallocated, if needed. +*/ CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv); -//! copies selected channels from the input arrays to the selected channels of the output arrays +/** @brief Copies specified channels from input arrays to the specified channels of +output arrays. + +The functions mixChannels provide an advanced mechanism for shuffling image channels. + +split and merge and some forms of cvtColor are partial cases of mixChannels . + +In the example below, the code splits a 4-channel RGBA image into a 3-channel BGR (with R and B +channels swapped) and a separate alpha-channel image: +@code{.cpp} + Mat rgba( 100, 100, CV_8UC4, Scalar(1,2,3,4) ); + Mat bgr( rgba.rows, rgba.cols, CV_8UC3 ); + Mat alpha( rgba.rows, rgba.cols, CV_8UC1 ); + + // forming an array of matrices is a quite efficient operation, + // because the matrix data is not copied, only the headers + Mat out[] = { bgr, alpha }; + // rgba[0] -> bgr[2], rgba[1] -> bgr[1], + // rgba[2] -> bgr[0], rgba[3] -> alpha[0] + int from_to[] = { 0,2, 1,1, 2,0, 3,3 }; + mixChannels( &rgba, 1, out, 2, from_to, 4 ); +@endcode +@note Unlike many other new-style C++ functions in OpenCV (see the introduction section and +Mat::create ), mixChannels requires the output arrays to be pre-allocated before calling the +function. +@param src input array or vector of matricesl; all of the matrices must have the same size and the +same depth. +@param nsrcs number of matrices in src. +@param dst output array or vector of matrices; all the matrices *must be allocated*; their size and +depth must be the same as in src[0]. +@param ndsts number of matrices in dst. +@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is +a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in +dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to +src[0].channels()-1, the second input image channels are indexed from src[0].channels() to +src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image +channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is +filled with zero . +@param npairs number of index pairs in fromTo. +@sa split, merge, cvtColor +*/ CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs); +/** @overload +@param src input array or vector of matricesl; all of the matrices must have the same size and the +same depth. +@param dst output array or vector of matrices; all the matrices *must be allocated*; their size and +depth must be the same as in src[0]. +@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is +a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in +dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to +src[0].channels()-1, the second input image channels are indexed from src[0].channels() to +src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image +channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is +filled with zero . +@param npairs number of index pairs in fromTo. +*/ CV_EXPORTS void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst, const int* fromTo, size_t npairs); +/** @overload +@param src input array or vector of matricesl; all of the matrices must have the same size and the +same depth. +@param dst output array or vector of matrices; all the matrices *must be allocated*; their size and +depth must be the same as in src[0]. +@param fromTo array of index pairs specifying which channels are copied and where; fromTo[k\*2] is +a 0-based index of the input channel in src, fromTo[k\*2+1] is an index of the output channel in +dst; the continuous channel numbering is used: the first input image channels are indexed from 0 to +src[0].channels()-1, the second input image channels are indexed from src[0].channels() to +src[0].channels() + src[1].channels()-1, and so on, the same scheme is used for the output image +channels; as a special case, when fromTo[k\*2] is negative, the corresponding output channel is +filled with zero . +*/ CV_EXPORTS_W void mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst, const std::vector& fromTo); -//! extracts a single channel from src (coi is 0-based index) +/** @brief extracts a single channel from src (coi is 0-based index) +@todo document +*/ CV_EXPORTS_W void extractChannel(InputArray src, OutputArray dst, int coi); -//! inserts a single channel to dst (coi is 0-based index) +/** @brief inserts a single channel to dst (coi is 0-based index) +@todo document +*/ CV_EXPORTS_W void insertChannel(InputArray src, InputOutputArray dst, int coi); -//! reverses the order of the rows, columns or both in a matrix +/** @brief Flips a 2D array around vertical, horizontal, or both axes. + +The function flip flips the array in one of three different ways (row +and column indices are 0-based): +\f[\texttt{dst} _{ij} = +\left\{ +\begin{array}{l l} +\texttt{src} _{\texttt{src.rows}-i-1,j} & if\; \texttt{flipCode} = 0 \\ +\texttt{src} _{i, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} > 0 \\ +\texttt{src} _{ \texttt{src.rows} -i-1, \texttt{src.cols} -j-1} & if\; \texttt{flipCode} < 0 \\ +\end{array} +\right.\f] +The example scenarios of using the function are the following: +* Vertical flipping of the image (flipCode == 0) to switch between + top-left and bottom-left image origin. This is a typical operation + in video processing on Microsoft Windows\* OS. +* Horizontal flipping of the image with the subsequent horizontal + shift and absolute difference calculation to check for a + vertical-axis symmetry (flipCode \> 0). +* Simultaneous horizontal and vertical flipping of the image with + the subsequent shift and absolute difference calculation to check + for a central symmetry (flipCode \< 0). +* Reversing the order of point arrays (flipCode \> 0 or + flipCode == 0). +@param src input array. +@param dst output array of the same size and type as src. +@param flipCode a flag to specify how to flip the array; 0 means +flipping around the x-axis and positive value (for example, 1) means +flipping around y-axis. Negative value (for example, -1) means flipping +around both axes. +@sa transpose , repeat , completeSymm +*/ CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode); -//! replicates the input matrix the specified number of times in the horizontal and/or vertical direction +/** @brief Fills the output array with repeated copies of the input array. + +The functions repeat duplicate the input array one or more times along each of the two axes: +\f[\texttt{dst} _{ij}= \texttt{src} _{i\mod src.rows, \; j\mod src.cols }\f] +The second variant of the function is more convenient to use with @ref MatrixExpressions. +@param src input array to replicate. +@param dst output array of the same type as src. +@param ny Flag to specify how many times the src is repeated along the +vertical axis. +@param nx Flag to specify how many times the src is repeated along the +horizontal axis. +@sa reduce +*/ CV_EXPORTS_W void repeat(InputArray src, int ny, int nx, OutputArray dst); +/** @overload +@param src input array to replicate. +@param ny Flag to specify how many times the src is repeated along the +vertical axis. +@param nx Flag to specify how many times the src is repeated along the +horizontal axis. + */ CV_EXPORTS Mat repeat(const Mat& src, int ny, int nx); +/** @brief concatenate matrices horizontally +@todo document +*/ CV_EXPORTS void hconcat(const Mat* src, size_t nsrc, OutputArray dst); - +/** @overload */ CV_EXPORTS void hconcat(InputArray src1, InputArray src2, OutputArray dst); - +/** @overload */ CV_EXPORTS_W void hconcat(InputArrayOfArrays src, OutputArray dst); +/** @brief concatenate matrices vertically +@todo document +*/ CV_EXPORTS void vconcat(const Mat* src, size_t nsrc, OutputArray dst); - +/** @overload */ CV_EXPORTS void vconcat(InputArray src1, InputArray src2, OutputArray dst); - +/** @overload */ CV_EXPORTS_W void vconcat(InputArrayOfArrays src, OutputArray dst); -//! computes bitwise conjunction of the two arrays (dst = src1 & src2) +/** @brief computes bitwise conjunction of the two arrays (dst = src1 & src2) +Calculates the per-element bit-wise conjunction of two arrays or an +array and a scalar. + +The function calculates the per-element bit-wise logical conjunction for: +* Two arrays when src1 and src2 have the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +* An array and a scalar when src2 is constructed from Scalar or has + the same number of elements as `src1.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} (I) \wedge \texttt{src2} \quad \texttt{if mask} (I) \ne0\f] +* A scalar and an array when src1 is constructed from Scalar or has + the same number of elements as `src2.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} \wedge \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +In case of floating-point arrays, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel arrays, each channel is processed +independently. In the second and third cases above, the scalar is first +converted to the array type. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and type as the input +arrays. +@param mask optional operation mask, 8-bit single channel array, that +specifies elements of the output array to be changed. +*/ CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray()); -//! computes bitwise disjunction of the two arrays (dst = src1 | src2) +/** @brief Calculates the per-element bit-wise disjunction of two arrays or an +array and a scalar. + +The function calculates the per-element bit-wise logical disjunction for: +* Two arrays when src1 and src2 have the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +* An array and a scalar when src2 is constructed from Scalar or has + the same number of elements as `src1.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} (I) \vee \texttt{src2} \quad \texttt{if mask} (I) \ne0\f] +* A scalar and an array when src1 is constructed from Scalar or has + the same number of elements as `src2.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} \vee \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +In case of floating-point arrays, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel arrays, each channel is processed +independently. In the second and third cases above, the scalar is first +converted to the array type. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and type as the input +arrays. +@param mask optional operation mask, 8-bit single channel array, that +specifies elements of the output array to be changed. +*/ CV_EXPORTS_W void bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray()); -//! computes bitwise exclusive-or of the two arrays (dst = src1 ^ src2) +/** @brief Calculates the per-element bit-wise "exclusive or" operation on two +arrays or an array and a scalar. + +The function calculates the per-element bit-wise logical "exclusive-or" +operation for: +* Two arrays when src1 and src2 have the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +* An array and a scalar when src2 is constructed from Scalar or has + the same number of elements as `src1.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} (I) \oplus \texttt{src2} \quad \texttt{if mask} (I) \ne0\f] +* A scalar and an array when src1 is constructed from Scalar or has + the same number of elements as `src2.channels()`: + \f[\texttt{dst} (I) = \texttt{src1} \oplus \texttt{src2} (I) \quad \texttt{if mask} (I) \ne0\f] +In case of floating-point arrays, their machine-specific bit +representations (usually IEEE754-compliant) are used for the operation. +In case of multi-channel arrays, each channel is processed +independently. In the 2nd and 3rd cases above, the scalar is first +converted to the array type. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and type as the input +arrays. +@param mask optional operation mask, 8-bit single channel array, that +specifies elements of the output array to be changed. +*/ CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray()); -//! inverts each bit of array (dst = ~src) +/** @brief Inverts every bit of an array. + +The function calculates per-element bit-wise inversion of the input +array: +\f[\texttt{dst} (I) = \neg \texttt{src} (I)\f] +In case of a floating-point input array, its machine-specific bit +representation (usually IEEE754-compliant) is used for the operation. In +case of multi-channel arrays, each channel is processed independently. +@param src input array. +@param dst output array that has the same size and type as the input +array. +@param mask optional operation mask, 8-bit single channel array, that +specifies elements of the output array to be changed. +*/ CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst, InputArray mask = noArray()); -//! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2)) +/** @brief Calculates the per-element absolute difference between two arrays or between an array and a scalar. + +The function absdiff calculates: +* Absolute difference between two arrays when they have the same + size and type: + \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2}(I)|)\f] +* Absolute difference between an array and a scalar when the second + array is constructed from Scalar or has as many elements as the + number of channels in `src1`: + \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1}(I) - \texttt{src2} |)\f] +* Absolute difference between a scalar and an array when the first + array is constructed from Scalar or has as many elements as the + number of channels in `src2`: + \f[\texttt{dst}(I) = \texttt{saturate} (| \texttt{src1} - \texttt{src2}(I) |)\f] + where I is a multi-dimensional index of array elements. In case of + multi-channel arrays, each channel is processed independently. +@note Saturation is not applied when the arrays have the depth CV_32S. +You may even get a negative value in the case of overflow. +@param src1 first input array or a scalar. +@param src2 second input array or a scalar. +@param dst output array that has the same size and type as input arrays. +@sa cv::abs(const Mat&) +*/ CV_EXPORTS_W void absdiff(InputArray src1, InputArray src2, OutputArray dst); -//! set mask elements for those array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb) +/** @brief Checks if array elements lie between the elements of two other arrays. + +The function checks the range as follows: +- For every element of a single-channel input array: + \f[\texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0\f] +- For two-channel arrays: + \f[\texttt{dst} (I)= \texttt{lowerb} (I)_0 \leq \texttt{src} (I)_0 \leq \texttt{upperb} (I)_0 \land \texttt{lowerb} (I)_1 \leq \texttt{src} (I)_1 \leq \texttt{upperb} (I)_1\f] +- and so forth. + +That is, dst (I) is set to 255 (all 1 -bits) if src (I) is within the +specified 1D, 2D, 3D, ... box and 0 otherwise. + +When the lower and/or upper boundary parameters are scalars, the indexes +(I) at lowerb and upperb in the above formulas should be omitted. +@param src first input array. +@param lowerb inclusive lower boundary array or a scalar. +@param upperb inclusive upper boundary array or a scalar. +@param dst output array of the same size as src and CV_8U type. +*/ CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst); -//! compares elements of two arrays (dst = src1 \ src2) +/** @brief Performs the per-element comparison of two arrays or an array and scalar value. + +The function compares: +* Elements of two arrays when src1 and src2 have the same size: + \f[\texttt{dst} (I) = \texttt{src1} (I) \,\texttt{cmpop}\, \texttt{src2} (I)\f] +* Elements of src1 with a scalar src2 when src2 is constructed from + Scalar or has a single element: + \f[\texttt{dst} (I) = \texttt{src1}(I) \,\texttt{cmpop}\, \texttt{src2}\f] +* src1 with elements of src2 when src1 is constructed from Scalar or + has a single element: + \f[\texttt{dst} (I) = \texttt{src1} \,\texttt{cmpop}\, \texttt{src2} (I)\f] +When the comparison result is true, the corresponding element of output +array is set to 255. The comparison operations can be replaced with the +equivalent matrix expressions: +@code{.cpp} + Mat dst1 = src1 >= src2; + Mat dst2 = src1 < 8; + ... +@endcode +@param src1 first input array or a scalar; when it is an array, it must have a single channel. +@param src2 second input array or a scalar; when it is an array, it must have a single channel. +@param dst output array that has the same size and type as the input arrays. +@param cmpop a flag, that specifies correspondence between the arrays (cv::CmpTypes) +@sa checkRange, min, max, threshold +*/ CV_EXPORTS_W void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop); -//! computes per-element minimum of two arrays (dst = min(src1, src2)) +/** @brief Calculates per-element minimum of two arrays or an array and a scalar. + +The functions min calculate the per-element minimum of two arrays: +\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I))\f] +or array and a scalar: +\f[\texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{value} )\f] +@param src1 first input array. +@param src2 second input array of the same size and type as src1. +@param dst output array of the same size and type as src1. +@sa max, compare, inRange, minMaxLoc +*/ CV_EXPORTS_W void min(InputArray src1, InputArray src2, OutputArray dst); +/** @overload +needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare) +*/ +CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst); +/** @overload +needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare) +*/ +CV_EXPORTS void min(const UMat& src1, const UMat& src2, UMat& dst); -//! computes per-element maximum of two arrays (dst = max(src1, src2)) -CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst); +/** @brief Calculates per-element maximum of two arrays or an array and a scalar. -// the following overloads are needed to avoid conflicts with -// const _Tp& std::min(const _Tp&, const _Tp&, _Compare) -//! computes per-element minimum of two arrays (dst = min(src1, src2)) -CV_EXPORTS void min(const Mat& src1, const Mat& src2, Mat& dst); -//! computes per-element maximum of two arrays (dst = max(src1, src2)) +The functions max calculate the per-element maximum of two arrays: +\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I))\f] +or array and a scalar: +\f[\texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{value} )\f] +@param src1 first input array. +@param src2 second input array of the same size and type as src1 . +@param dst output array of the same size and type as src1. +@sa min, compare, inRange, minMaxLoc, @ref MatrixExpressions +*/ +CV_EXPORTS_W void max(InputArray src1, InputArray src2, OutputArray dst); +/** @overload +needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare) +*/ CV_EXPORTS void max(const Mat& src1, const Mat& src2, Mat& dst); -//! computes per-element minimum of two arrays (dst = min(src1, src2)) -CV_EXPORTS void min(const UMat& src1, const UMat& src2, UMat& dst); -//! computes per-element maximum of two arrays (dst = max(src1, src2)) +/** @overload +needed to avoid conflicts with const _Tp& std::min(const _Tp&, const _Tp&, _Compare) +*/ CV_EXPORTS void max(const UMat& src1, const UMat& src2, UMat& dst); -//! computes square root of each matrix element (dst = src**0.5) +/** @brief Calculates a square root of array elements. + +The functions sqrt calculate a square root of each input array element. +In case of multi-channel arrays, each channel is processed +independently. The accuracy is approximately the same as of the built-in +std::sqrt . +@param src input floating-point array. +@param dst output array of the same size and type as src. +*/ CV_EXPORTS_W void sqrt(InputArray src, OutputArray dst); -//! raises the input matrix elements to the specified power (b = a**power) +/** @brief Raises every array element to a power. + +The function pow raises every element of the input array to power : +\f[\texttt{dst} (I) = \fork{\texttt{src}(I)^power}{if \texttt{power} is integer}{|\texttt{src}(I)|^power}{otherwise}\f] + +So, for a non-integer power exponent, the absolute values of input array +elements are used. However, it is possible to get true values for +negative values using some extra operations. In the example below, +computing the 5th root of array src shows: +@code{.cpp} + Mat mask = src < 0; + pow(src, 1./5, dst); + subtract(Scalar::all(0), dst, dst, mask); +@endcode +For some values of power, such as integer values, 0.5 and -0.5, +specialized faster algorithms are used. + +Special values (NaN, Inf) are not handled. +@param src input array. +@param power exponent of power. +@param dst output array of the same size and type as src. +@sa sqrt, exp, log, cartToPolar, polarToCart +*/ CV_EXPORTS_W void pow(InputArray src, double power, OutputArray dst); -//! computes exponent of each matrix element (dst = e**src) +/** @brief Calculates the exponent of every array element. + +The function exp calculates the exponent of every element of the input +array: +\f[\texttt{dst} [I] = e^{ src(I) }\f] + +The maximum relative error is about 7e-6 for single-precision input and +less than 1e-10 for double-precision input. Currently, the function +converts denormalized values to zeros on output. Special values (NaN, +Inf) are not handled. +@param src input array. +@param dst output array of the same size and type as src. +@sa log , cartToPolar , polarToCart , phase , pow , sqrt , magnitude +*/ CV_EXPORTS_W void exp(InputArray src, OutputArray dst); -//! computes natural logarithm of absolute value of each matrix element: dst = log(abs(src)) +/** @brief Calculates the natural logarithm of every array element. + +The function log calculates the natural logarithm of the absolute value +of every element of the input array: +\f[\texttt{dst} (I) = \fork{\log |\texttt{src}(I)|}{if \(\texttt{src}(I) \ne 0\) }{\texttt{C}}{otherwise}\f] + +where C is a large negative number (about -700 in the current +implementation). The maximum relative error is about 7e-6 for +single-precision input and less than 1e-10 for double-precision input. +Special values (NaN, Inf) are not handled. +@param src input array. +@param dst output array of the same size and type as src . +@sa exp, cartToPolar, polarToCart, phase, pow, sqrt, magnitude +*/ CV_EXPORTS_W void log(InputArray src, OutputArray dst); -//! converts polar coordinates to Cartesian +/** @brief Calculates x and y coordinates of 2D vectors from their magnitude and angle. + +The function polarToCart calculates the Cartesian coordinates of each 2D +vector represented by the corresponding elements of magnitude and angle: +\f[\begin{array}{l} \texttt{x} (I) = \texttt{magnitude} (I) \cos ( \texttt{angle} (I)) \\ \texttt{y} (I) = \texttt{magnitude} (I) \sin ( \texttt{angle} (I)) \\ \end{array}\f] + +The relative accuracy of the estimated coordinates is about 1e-6. +@param magnitude input floating-point array of magnitudes of 2D vectors; +it can be an empty matrix (=Mat()), in this case, the function assumes +that all the magnitudes are =1; if it is not empty, it must have the +same size and type as angle. +@param angle input floating-point array of angles of 2D vectors. +@param x output array of x-coordinates of 2D vectors; it has the same +size and type as angle. +@param y output array of y-coordinates of 2D vectors; it has the same +size and type as angle. +@param angleInDegrees when true, the input angles are measured in +degrees, otherwise, they are measured in radians. +@sa cartToPolar, magnitude, phase, exp, log, pow, sqrt +*/ CV_EXPORTS_W void polarToCart(InputArray magnitude, InputArray angle, OutputArray x, OutputArray y, bool angleInDegrees = false); -//! converts Cartesian coordinates to polar +/** @brief Calculates the magnitude and angle of 2D vectors. + +The function cartToPolar calculates either the magnitude, angle, or both +for every 2D vector (x(I),y(I)): +\f[\begin{array}{l} \texttt{magnitude} (I)= \sqrt{\texttt{x}(I)^2+\texttt{y}(I)^2} , \\ \texttt{angle} (I)= \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))[ \cdot180 / \pi ] \end{array}\f] + +The angles are calculated with accuracy about 0.3 degrees. For the point +(0,0), the angle is set to 0. +@param x array of x-coordinates; this must be a single-precision or +double-precision floating-point array. +@param y array of y-coordinates, that must have the same size and same type as x. +@param magnitude output array of magnitudes of the same size and type as x. +@param angle output array of angles that has the same size and type as +x; the angles are measured in radians (from 0 to 2\*Pi) or in degrees (0 to 360 degrees). +@param angleInDegrees a flag, indicating whether the angles are measured +in radians (which is by default), or in degrees. +@sa Sobel, Scharr +*/ CV_EXPORTS_W void cartToPolar(InputArray x, InputArray y, OutputArray magnitude, OutputArray angle, bool angleInDegrees = false); -//! computes angle (angle(i)) of each (x(i), y(i)) vector +/** @brief Calculates the rotation angle of 2D vectors. + +The function phase calculates the rotation angle of each 2D vector that +is formed from the corresponding elements of x and y : +\f[\texttt{angle} (I) = \texttt{atan2} ( \texttt{y} (I), \texttt{x} (I))\f] + +The angle estimation accuracy is about 0.3 degrees. When x(I)=y(I)=0 , +the corresponding angle(I) is set to 0. +@param x input floating-point array of x-coordinates of 2D vectors. +@param y input array of y-coordinates of 2D vectors; it must have the +same size and the same type as x. +@param angle output array of vector angles; it has the same size and +same type as x . +@param angleInDegrees when true, the function calculates the angle in +degrees, otherwise, they are measured in radians. +*/ CV_EXPORTS_W void phase(InputArray x, InputArray y, OutputArray angle, bool angleInDegrees = false); -//! computes magnitude (magnitude(i)) of each (x(i), y(i)) vector +/** @brief Calculates the magnitude of 2D vectors. + +The function magnitude calculates the magnitude of 2D vectors formed +from the corresponding elements of x and y arrays: +\f[\texttt{dst} (I) = \sqrt{\texttt{x}(I)^2 + \texttt{y}(I)^2}\f] +@param x floating-point array of x-coordinates of the vectors. +@param y floating-point array of y-coordinates of the vectors; it must +have the same size as x. +@param magnitude output array of the same size and type as x. +@sa cartToPolar, polarToCart, phase, sqrt +*/ CV_EXPORTS_W void magnitude(InputArray x, InputArray y, OutputArray magnitude); -//! checks that each matrix element is within the specified range. +/** @brief Checks every element of an input array for invalid values. + +The functions checkRange check that every array element is neither NaN nor infinite. When minVal \< +-DBL_MAX and maxVal \< DBL_MAX, the functions also check that each value is between minVal and +maxVal. In case of multi-channel arrays, each channel is processed independently. If some values +are out of range, position of the first outlier is stored in pos (when pos != NULL). Then, the +functions either return false (when quiet=true) or throw an exception. +@param a input array. +@param quiet a flag, indicating whether the functions quietly return false when the array elements +are out of range or they throw an exception. +@param pos optional output parameter, when not NULL, must be a pointer to array of src.dims +elements. +@param minVal inclusive lower boundary of valid values range. +@param maxVal exclusive upper boundary of valid values range. +*/ CV_EXPORTS_W bool checkRange(InputArray a, bool quiet = true, CV_OUT Point* pos = 0, double minVal = -DBL_MAX, double maxVal = DBL_MAX); -//! converts NaN's to the given number +/** @brief converts NaN's to the given number +*/ CV_EXPORTS_W void patchNaNs(InputOutputArray a, double val = 0); -//! implements generalized matrix product algorithm GEMM from BLAS +/** @brief Performs generalized matrix multiplication. + +The function performs generalized matrix multiplication similar to the +gemm functions in BLAS level 3. For example, +`gemm(src1, src2, alpha, src3, beta, dst, GEMM_1_T + GEMM_3_T)` +corresponds to +\f[\texttt{dst} = \texttt{alpha} \cdot \texttt{src1} ^T \cdot \texttt{src2} + \texttt{beta} \cdot \texttt{src3} ^T\f] + +In case of complex (two-channel) data, performed a complex matrix +multiplication. + +The function can be replaced with a matrix expression. For example, the +above call can be replaced with: +@code{.cpp} + dst = alpha*src1.t()*src2 + beta*src3.t(); +@endcode +@param src1 first multiplied input matrix that could be real(CV_32FC1, +CV_64FC1) or complex(CV_32FC2, CV_64FC2). +@param src2 second multiplied input matrix of the same type as src1. +@param alpha weight of the matrix product. +@param src3 third optional delta matrix added to the matrix product; it +should have the same type as src1 and src2. +@param beta weight of src3. +@param dst output matrix; it has the proper size and the same type as +input matrices. +@param flags operation flags (cv::GemmFlags) +@sa mulTransposed , transform +*/ CV_EXPORTS_W void gemm(InputArray src1, InputArray src2, double alpha, InputArray src3, double beta, OutputArray dst, int flags = 0); -//! multiplies matrix by its transposition from the left or from the right +/** @brief Calculates the product of a matrix and its transposition. + +The function mulTransposed calculates the product of src and its +transposition: +\f[\texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} )^T ( \texttt{src} - \texttt{delta} )\f] +if aTa=true , and +\f[\texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} ) ( \texttt{src} - \texttt{delta} )^T\f] +otherwise. The function is used to calculate the covariance matrix. With +zero delta, it can be used as a faster substitute for general matrix +product A\*B when B=A' +@param src input single-channel matrix. Note that unlike gemm, the +function can multiply not only floating-point matrices. +@param dst output square matrix. +@param aTa Flag specifying the multiplication ordering. See the +description below. +@param delta Optional delta matrix subtracted from src before the +multiplication. When the matrix is empty ( delta=noArray() ), it is +assumed to be zero, that is, nothing is subtracted. If it has the same +size as src , it is simply subtracted. Otherwise, it is "repeated" (see +repeat ) to cover the full src and then subtracted. Type of the delta +matrix, when it is not empty, must be the same as the type of created +output matrix. See the dtype parameter description below. +@param scale Optional scale factor for the matrix product. +@param dtype Optional type of the output matrix. When it is negative, +the output matrix will have the same type as src . Otherwise, it will be +type=CV_MAT_DEPTH(dtype) that should be either CV_32F or CV_64F . +@sa calcCovarMatrix, gemm, repeat, reduce +*/ CV_EXPORTS_W void mulTransposed( InputArray src, OutputArray dst, bool aTa, InputArray delta = noArray(), double scale = 1, int dtype = -1 ); -//! transposes the matrix +/** @brief Transposes a matrix. + +The function transpose transposes the matrix src : +\f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f] +@note No complex conjugation is done in case of a complex matrix. It it +should be done separately if needed. +@param src input array. +@param dst output array of the same type as src. +*/ CV_EXPORTS_W void transpose(InputArray src, OutputArray dst); -//! performs affine transformation of each element of multi-channel input matrix +/** @brief Performs the matrix transformation of every array element. + +The function transform performs the matrix transformation of every +element of the array src and stores the results in dst : +\f[\texttt{dst} (I) = \texttt{m} \cdot \texttt{src} (I)\f] +(when m.cols=src.channels() ), or +\f[\texttt{dst} (I) = \texttt{m} \cdot [ \texttt{src} (I); 1]\f] +(when m.cols=src.channels()+1 ) + +Every element of the N -channel array src is interpreted as N -element +vector that is transformed using the M x N or M x (N+1) matrix m to +M-element vector - the corresponding element of the output array dst . + +The function may be used for geometrical transformation of +N -dimensional points, arbitrary linear color space transformation (such +as various kinds of RGB to YUV transforms), shuffling the image +channels, and so forth. +@param src input array that must have as many channels (1 to 4) as +m.cols or m.cols-1. +@param dst output array of the same size and depth as src; it has as +many channels as m.rows. +@param m transformation 2x2 or 2x3 floating-point matrix. +@sa perspectiveTransform, getAffineTransform, estimateRigidTransform, warpAffine, warpPerspective +*/ CV_EXPORTS_W void transform(InputArray src, OutputArray dst, InputArray m ); -//! performs perspective transformation of each element of multi-channel input matrix +/** @brief Performs the perspective matrix transformation of vectors. + +The function perspectiveTransform transforms every element of src by +treating it as a 2D or 3D vector, in the following way: +\f[(x, y, z) \rightarrow (x'/w, y'/w, z'/w)\f] +where +\f[(x', y', z', w') = \texttt{mat} \cdot \begin{bmatrix} x & y & z & 1 \end{bmatrix}\f] +and +\f[w = \fork{w'}{if \(w' \ne 0\)}{\infty}{otherwise}\f] + +Here a 3D vector transformation is shown. In case of a 2D vector +transformation, the z component is omitted. + +@note The function transforms a sparse set of 2D or 3D vectors. If you +want to transform an image using perspective transformation, use +warpPerspective . If you have an inverse problem, that is, you want to +compute the most probable perspective transformation out of several +pairs of corresponding points, you can use getPerspectiveTransform or +findHomography . +@param src input two-channel or three-channel floating-point array; each +element is a 2D/3D vector to be transformed. +@param dst output array of the same size and type as src. +@param m 3x3 or 4x4 floating-point transformation matrix. +@sa transform, warpPerspective, getPerspectiveTransform, findHomography +*/ CV_EXPORTS_W void perspectiveTransform(InputArray src, OutputArray dst, InputArray m ); -//! extends the symmetrical matrix from the lower half or from the upper half +/** @brief Copies the lower or the upper half of a square matrix to another half. + +The function completeSymm copies the lower half of a square matrix to +its another half. The matrix diagonal remains unchanged: +* \f$\texttt{mtx}_{ij}=\texttt{mtx}_{ji}\f$ for \f$i > j\f$ if + lowerToUpper=false +* \f$\texttt{mtx}_{ij}=\texttt{mtx}_{ji}\f$ for \f$i < j\f$ if + lowerToUpper=true +@param mtx input-output floating-point square matrix. +@param lowerToUpper operation flag; if true, the lower half is copied to +the upper half. Otherwise, the upper half is copied to the lower half. +@sa flip, transpose +*/ CV_EXPORTS_W void completeSymm(InputOutputArray mtx, bool lowerToUpper = false); -//! initializes scaled identity matrix +/** @brief Initializes a scaled identity matrix. + +The function setIdentity initializes a scaled identity matrix: +\f[\texttt{mtx} (i,j)= \fork{\texttt{value}}{ if \(i=j\)}{0}{otherwise}\f] + +The function can also be emulated using the matrix initializers and the +matrix expressions: +@code + Mat A = Mat::eye(4, 3, CV_32F)*5; + // A will be set to [[5, 0, 0], [0, 5, 0], [0, 0, 5], [0, 0, 0]] +@endcode +@param mtx matrix to initialize (not necessarily square). +@param s value to assign to diagonal elements. +@sa Mat::zeros, Mat::ones, Mat::setTo, Mat::operator= +*/ CV_EXPORTS_W void setIdentity(InputOutputArray mtx, const Scalar& s = Scalar(1)); -//! computes determinant of a square matrix +/** @brief Returns the determinant of a square floating-point matrix. + +The function determinant calculates and returns the determinant of the +specified matrix. For small matrices ( mtx.cols=mtx.rows\<=3 ), the +direct method is used. For larger matrices, the function uses LU +factorization with partial pivoting. + +For symmetric positively-determined matrices, it is also possible to use +eigen decomposition to calculate the determinant. +@param mtx input matrix that must have CV_32FC1 or CV_64FC1 type and +square size. +@sa trace, invert, solve, eigen, @ref MatrixExpressions +*/ CV_EXPORTS_W double determinant(InputArray mtx); -//! computes trace of a matrix +/** @brief Returns the trace of a matrix. + +The function trace returns the sum of the diagonal elements of the +matrix mtx . +\f[\mathrm{tr} ( \texttt{mtx} ) = \sum _i \texttt{mtx} (i,i)\f] +@param mtx input matrix. +*/ CV_EXPORTS_W Scalar trace(InputArray mtx); -//! computes inverse or pseudo-inverse matrix +/** @brief Finds the inverse or pseudo-inverse of a matrix. + +The function invert inverts the matrix src and stores the result in dst +. When the matrix src is singular or non-square, the function calculates +the pseudo-inverse matrix (the dst matrix) so that norm(src\*dst - I) is +minimal, where I is an identity matrix. + +In case of the DECOMP_LU method, the function returns non-zero value if +the inverse has been successfully calculated and 0 if src is singular. + +In case of the DECOMP_SVD method, the function returns the inverse +condition number of src (the ratio of the smallest singular value to the +largest singular value) and 0 if src is singular. The SVD method +calculates a pseudo-inverse matrix if src is singular. + +Similarly to DECOMP_LU, the method DECOMP_CHOLESKY works only with +non-singular square matrices that should also be symmetrical and +positively defined. In this case, the function stores the inverted +matrix in dst and returns non-zero. Otherwise, it returns 0. + +@param src input floating-point M x N matrix. +@param dst output matrix of N x M size and the same type as src. +@param flags inversion method (cv::DecompTypes) +@sa solve, SVD +*/ CV_EXPORTS_W double invert(InputArray src, OutputArray dst, int flags = DECOMP_LU); -//! solves linear system or a least-square problem +/** @brief Solves one or more linear systems or least-squares problems. + +The function solve solves a linear system or least-squares problem (the +latter is possible with SVD or QR methods, or by specifying the flag +DECOMP_NORMAL ): +\f[\texttt{dst} = \arg \min _X \| \texttt{src1} \cdot \texttt{X} - \texttt{src2} \|\f] + +If DECOMP_LU or DECOMP_CHOLESKY method is used, the function returns 1 +if src1 (or \f$\texttt{src1}^T\texttt{src1}\f$ ) is non-singular. Otherwise, +it returns 0. In the latter case, dst is not valid. Other methods find a +pseudo-solution in case of a singular left-hand side part. + +@note If you want to find a unity-norm solution of an under-defined +singular system \f$\texttt{src1}\cdot\texttt{dst}=0\f$ , the function solve +will not do the work. Use SVD::solveZ instead. + +@param src1 input matrix on the left-hand side of the system. +@param src2 input matrix on the right-hand side of the system. +@param dst output solution. +@param flags solution (matrix inversion) method (cv::DecompTypes) +@sa invert, SVD, eigen +*/ CV_EXPORTS_W bool solve(InputArray src1, InputArray src2, OutputArray dst, int flags = DECOMP_LU); -//! sorts independently each matrix row or each matrix column +/** @brief Sorts each row or each column of a matrix. + +The function sort sorts each matrix row or each matrix column in +ascending or descending order. So you should pass two operation flags to +get desired behaviour. If you want to sort matrix rows or columns +lexicographically, you can use STL std::sort generic function with the +proper comparison predicate. + +@param src input single-channel array. +@param dst output array of the same size and type as src. +@param flags operation flags, a combination of cv::SortFlags +@sa sortIdx, randShuffle +*/ CV_EXPORTS_W void sort(InputArray src, OutputArray dst, int flags); -//! sorts independently each matrix row or each matrix column +/** @brief Sorts each row or each column of a matrix. + +The function sortIdx sorts each matrix row or each matrix column in the +ascending or descending order. So you should pass two operation flags to +get desired behaviour. Instead of reordering the elements themselves, it +stores the indices of sorted elements in the output array. For example: +@code + Mat A = Mat::eye(3,3,CV_32F), B; + sortIdx(A, B, SORT_EVERY_ROW + SORT_ASCENDING); + // B will probably contain + // (because of equal elements in A some permutations are possible): + // [[1, 2, 0], [0, 2, 1], [0, 1, 2]] +@endcode +@param src input single-channel array. +@param dst output integer array of the same size as src. +@param flags operation flags that could be a combination of cv::SortFlags +@sa sort, randShuffle +*/ CV_EXPORTS_W void sortIdx(InputArray src, OutputArray dst, int flags); -//! finds real roots of a cubic polynomial +/** @brief Finds the real roots of a cubic equation. + +The function solveCubic finds the real roots of a cubic equation: +- if coeffs is a 4-element vector: +\f[\texttt{coeffs} [0] x^3 + \texttt{coeffs} [1] x^2 + \texttt{coeffs} [2] x + \texttt{coeffs} [3] = 0\f] +- if coeffs is a 3-element vector: +\f[x^3 + \texttt{coeffs} [0] x^2 + \texttt{coeffs} [1] x + \texttt{coeffs} [2] = 0\f] + +The roots are stored in the roots array. +@param coeffs equation coefficients, an array of 3 or 4 elements. +@param roots output array of real roots that has 1 or 3 elements. +*/ CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots); -//! finds real and complex roots of a polynomial +/** @brief Finds the real or complex roots of a polynomial equation. + +The function solvePoly finds real and complex roots of a polynomial equation: +\f[\texttt{coeffs} [n] x^{n} + \texttt{coeffs} [n-1] x^{n-1} + ... + \texttt{coeffs} [1] x + \texttt{coeffs} [0] = 0\f] +@param coeffs array of polynomial coefficients. +@param roots output (complex) array of roots. +@param maxIters maximum number of iterations the algorithm does. +*/ CV_EXPORTS_W double solvePoly(InputArray coeffs, OutputArray roots, int maxIters = 300); -//! finds eigenvalues and eigenvectors of a symmetric matrix +/** @brief Calculates eigenvalues and eigenvectors of a symmetric matrix. + +The functions eigen calculate just eigenvalues, or eigenvalues and eigenvectors of the symmetric +matrix src: +@code + src*eigenvectors.row(i).t() = eigenvalues.at(i)*eigenvectors.row(i).t() +@endcode +@note in the new and the old interfaces different ordering of eigenvalues and eigenvectors +parameters is used. +@param src input matrix that must have CV_32FC1 or CV_64FC1 type, square size and be symmetrical +(src ^T^ == src). +@param eigenvalues output vector of eigenvalues of the same type as src; the eigenvalues are stored +in the descending order. +@param eigenvectors output matrix of eigenvectors; it has the same size and type as src; the +eigenvectors are stored as subsequent matrix rows, in the same order as the corresponding +eigenvalues. +@sa completeSymm , PCA +*/ CV_EXPORTS_W bool eigen(InputArray src, OutputArray eigenvalues, OutputArray eigenvectors = noArray()); -//! computes covariation matrix of a set of samples +/** @brief Calculates the covariance matrix of a set of vectors. + +The functions calcCovarMatrix calculate the covariance matrix and, optionally, the mean vector of +the set of input vectors. +@param samples samples stored as separate matrices +@param nsamples number of samples +@param covar output covariance matrix of the type ctype and square size. +@param mean input or output (depending on the flags) array as the average value of the input vectors. +@param flags operation flags as a combination of cv::CovarFlags +@param ctype type of the matrixl; it equals 'CV_64F' by default. +@sa PCA, mulTransposed, Mahalanobis +@todo InputArrayOfArrays +*/ CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples, Mat& covar, Mat& mean, - int flags, int ctype = CV_64F); //TODO: InputArrayOfArrays - -//! computes covariation matrix of a set of samples + int flags, int ctype = CV_64F); + +/** @overload +@note use cv::COVAR_ROWS or cv::COVAR_COLS flag +@param samples samples stored as rows/columns of a single matrix. +@param covar output covariance matrix of the type ctype and square size. +@param mean input or output (depending on the flags) array as the average value of the input vectors. +@param flags operation flags as a combination of cv::CovarFlags +@param ctype type of the matrixl; it equals 'CV_64F' by default. +*/ CV_EXPORTS_W void calcCovarMatrix( InputArray samples, OutputArray covar, InputOutputArray mean, int flags, int ctype = CV_64F); +/** wrap PCA::operator() */ CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean, OutputArray eigenvectors, int maxComponents = 0); +/** wrap PCA::operator() */ CV_EXPORTS_W void PCACompute(InputArray data, InputOutputArray mean, OutputArray eigenvectors, double retainedVariance); +/** wrap PCA::project */ CV_EXPORTS_W void PCAProject(InputArray data, InputArray mean, InputArray eigenvectors, OutputArray result); +/** wrap PCA::backProject */ CV_EXPORTS_W void PCABackProject(InputArray data, InputArray mean, InputArray eigenvectors, OutputArray result); -//! computes SVD of src +/** wrap SVD::compute */ CV_EXPORTS_W void SVDecomp( InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags = 0 ); -//! performs back substitution for the previously computed SVD +/** wrap SVD::backSubst */ CV_EXPORTS_W void SVBackSubst( InputArray w, InputArray u, InputArray vt, InputArray rhs, OutputArray dst ); -//! computes Mahalanobis distance between two vectors: sqrt((v1-v2)'*icovar*(v1-v2)), where icovar is the inverse covariation matrix +/** @brief Calculates the Mahalanobis distance between two vectors. + +The function Mahalanobis calculates and returns the weighted distance between two vectors: +\f[d( \texttt{vec1} , \texttt{vec2} )= \sqrt{\sum_{i,j}{\texttt{icovar(i,j)}\cdot(\texttt{vec1}(I)-\texttt{vec2}(I))\cdot(\texttt{vec1(j)}-\texttt{vec2(j)})} }\f] +The covariance matrix may be calculated using the cv::calcCovarMatrix function and then inverted using +the invert function (preferably using the cv::DECOMP_SVD method, as the most accurate). +@param v1 first 1D input vector. +@param v2 second 1D input vector. +@param icovar inverse covariance matrix. +*/ CV_EXPORTS_W double Mahalanobis(InputArray v1, InputArray v2, InputArray icovar); -//! performs forward or inverse 1D or 2D Discrete Fourier Transformation +/** @brief Performs a forward or inverse Discrete Fourier transform of a 1D or 2D floating-point array. + +The function performs one of the following: +- Forward the Fourier transform of a 1D vector of N elements: + \f[Y = F^{(N)} \cdot X,\f] + where \f$F^{(N)}_{jk}=\exp(-2\pi i j k/N)\f$ and \f$i=\sqrt{-1}\f$ +- Inverse the Fourier transform of a 1D vector of N elements: + \f[\begin{array}{l} X'= \left (F^{(N)} \right )^{-1} \cdot Y = \left (F^{(N)} \right )^* \cdot y \\ X = (1/N) \cdot X, \end{array}\f] + where \f$F^*=\left(\textrm{Re}(F^{(N)})-\textrm{Im}(F^{(N)})\right)^T\f$ +- Forward the 2D Fourier transform of a M x N matrix: + \f[Y = F^{(M)} \cdot X \cdot F^{(N)}\f] +- Inverse the 2D Fourier transform of a M x N matrix: + \f[\begin{array}{l} X'= \left (F^{(M)} \right )^* \cdot Y \cdot \left (F^{(N)} \right )^* \\ X = \frac{1}{M \cdot N} \cdot X' \end{array}\f] + +In case of real (single-channel) data, the output spectrum of the forward Fourier transform or input +spectrum of the inverse Fourier transform can be represented in a packed format called *CCS* +(complex-conjugate-symmetrical). It was borrowed from IPL (Intel\* Image Processing Library). Here +is how 2D *CCS* spectrum looks: +\f[\begin{bmatrix} Re Y_{0,0} & Re Y_{0,1} & Im Y_{0,1} & Re Y_{0,2} & Im Y_{0,2} & \cdots & Re Y_{0,N/2-1} & Im Y_{0,N/2-1} & Re Y_{0,N/2} \\ Re Y_{1,0} & Re Y_{1,1} & Im Y_{1,1} & Re Y_{1,2} & Im Y_{1,2} & \cdots & Re Y_{1,N/2-1} & Im Y_{1,N/2-1} & Re Y_{1,N/2} \\ Im Y_{1,0} & Re Y_{2,1} & Im Y_{2,1} & Re Y_{2,2} & Im Y_{2,2} & \cdots & Re Y_{2,N/2-1} & Im Y_{2,N/2-1} & Im Y_{1,N/2} \\ \hdotsfor{9} \\ Re Y_{M/2-1,0} & Re Y_{M-3,1} & Im Y_{M-3,1} & \hdotsfor{3} & Re Y_{M-3,N/2-1} & Im Y_{M-3,N/2-1}& Re Y_{M/2-1,N/2} \\ Im Y_{M/2-1,0} & Re Y_{M-2,1} & Im Y_{M-2,1} & \hdotsfor{3} & Re Y_{M-2,N/2-1} & Im Y_{M-2,N/2-1}& Im Y_{M/2-1,N/2} \\ Re Y_{M/2,0} & Re Y_{M-1,1} & Im Y_{M-1,1} & \hdotsfor{3} & Re Y_{M-1,N/2-1} & Im Y_{M-1,N/2-1}& Re Y_{M/2,N/2} \end{bmatrix}\f] + +In case of 1D transform of a real vector, the output looks like the first row of the matrix above. + +So, the function chooses an operation mode depending on the flags and size of the input array: +- If DFT_ROWS is set or the input array has a single row or single column, the function + performs a 1D forward or inverse transform of each row of a matrix when DFT_ROWS is set. + Otherwise, it performs a 2D transform. +- If the input array is real and DFT_INVERSE is not set, the function performs a forward 1D or + 2D transform: + - When DFT_COMPLEX_OUTPUT is set, the output is a complex matrix of the same size as + input. + - When DFT_COMPLEX_OUTPUT is not set, the output is a real matrix of the same size as + input. In case of 2D transform, it uses the packed format as shown above. In case of a + single 1D transform, it looks like the first row of the matrix above. In case of + multiple 1D transforms (when using the DFT_ROWS flag), each row of the output matrix + looks like the first row of the matrix above. +- If the input array is complex and either DFT_INVERSE or DFT_REAL_OUTPUT are not set, the + output is a complex array of the same size as input. The function performs a forward or + inverse 1D or 2D transform of the whole input array or each row of the input array + independently, depending on the flags DFT_INVERSE and DFT_ROWS. +- When DFT_INVERSE is set and the input array is real, or it is complex but DFT_REAL_OUTPUT + is set, the output is a real array of the same size as input. The function performs a 1D or 2D + inverse transformation of the whole input array or each individual row, depending on the flags + DFT_INVERSE and DFT_ROWS. + +If DFT_SCALE is set, the scaling is done after the transformation. + +Unlike dct , the function supports arrays of arbitrary size. But only those arrays are processed +efficiently, whose sizes can be factorized in a product of small prime numbers (2, 3, and 5 in the +current implementation). Such an efficient DFT size can be calculated using the getOptimalDFTSize +method. + +The sample below illustrates how to calculate a DFT-based convolution of two 2D real arrays: +@code + void convolveDFT(InputArray A, InputArray B, OutputArray C) + { + // reallocate the output array if needed + C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type()); + Size dftSize; + // calculate the size of DFT transform + dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1); + dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1); + + // allocate temporary buffers and initialize them with 0's + Mat tempA(dftSize, A.type(), Scalar::all(0)); + Mat tempB(dftSize, B.type(), Scalar::all(0)); + + // copy A and B to the top-left corners of tempA and tempB, respectively + Mat roiA(tempA, Rect(0,0,A.cols,A.rows)); + A.copyTo(roiA); + Mat roiB(tempB, Rect(0,0,B.cols,B.rows)); + B.copyTo(roiB); + + // now transform the padded A & B in-place; + // use "nonzeroRows" hint for faster processing + dft(tempA, tempA, 0, A.rows); + dft(tempB, tempB, 0, B.rows); + + // multiply the spectrums; + // the function handles packed spectrum representations well + mulSpectrums(tempA, tempB, tempA); + + // transform the product back from the frequency domain. + // Even though all the result rows will be non-zero, + // you need only the first C.rows of them, and thus you + // pass nonzeroRows == C.rows + dft(tempA, tempA, DFT_INVERSE + DFT_SCALE, C.rows); + + // now copy the result back to C. + tempA(Rect(0, 0, C.cols, C.rows)).copyTo(C); + + // all the temporary buffers will be deallocated automatically + } +@endcode +To optimize this sample, consider the following approaches: +- Since nonzeroRows != 0 is passed to the forward transform calls and since A and B are copied to + the top-left corners of tempA and tempB, respectively, it is not necessary to clear the whole + tempA and tempB. It is only necessary to clear the tempA.cols - A.cols ( tempB.cols - B.cols) + rightmost columns of the matrices. +- This DFT-based convolution does not have to be applied to the whole big arrays, especially if B + is significantly smaller than A or vice versa. Instead, you can calculate convolution by parts. + To do this, you need to split the output array C into multiple tiles. For each tile, estimate + which parts of A and B are required to calculate convolution in this tile. If the tiles in C are + too small, the speed will decrease a lot because of repeated work. In the ultimate case, when + each tile in C is a single pixel, the algorithm becomes equivalent to the naive convolution + algorithm. If the tiles are too big, the temporary arrays tempA and tempB become too big and + there is also a slowdown because of bad cache locality. So, there is an optimal tile size + somewhere in the middle. +- If different tiles in C can be calculated in parallel and, thus, the convolution is done by + parts, the loop can be threaded. + +All of the above improvements have been implemented in matchTemplate and filter2D . Therefore, by +using them, you can get the performance even better than with the above theoretically optimal +implementation. Though, those two functions actually calculate cross-correlation, not convolution, +so you need to "flip" the second convolution operand B vertically and horizontally using flip . +@note +- An example using the discrete fourier transform can be found at + opencv_source_code/samples/cpp/dft.cpp +- (Python) An example using the dft functionality to perform Wiener deconvolution can be found + at opencv_source/samples/python2/deconvolution.py +- (Python) An example rearranging the quadrants of a Fourier image can be found at + opencv_source/samples/python2/dft.py +@param src input array that could be real or complex. +@param dst output array whose size and type depends on the flags . +@param flags transformation flags, representing a combination of the cv::DftFlags +@param nonzeroRows when the parameter is not zero, the function assumes that only the first +nonzeroRows rows of the input array (DFT_INVERSE is not set) or only the first nonzeroRows of the +output array (DFT_INVERSE is set) contain non-zeros, thus, the function can handle the rest of the +rows more efficiently and save some time; this technique is very useful for calculating array +cross-correlation or convolution using DFT. +@sa dct , getOptimalDFTSize , mulSpectrums, filter2D , matchTemplate , flip , cartToPolar , +magnitude , phase +*/ CV_EXPORTS_W void dft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0); -//! performs inverse 1D or 2D Discrete Fourier Transformation +/** @brief Calculates the inverse Discrete Fourier Transform of a 1D or 2D array. + +idft(src, dst, flags) is equivalent to dft(src, dst, flags | DFT_INVERSE) . +@note None of dft and idft scales the result by default. So, you should pass DFT_SCALE to one of +dft or idft explicitly to make these transforms mutually inverse. +@sa dft, dct, idct, mulSpectrums, getOptimalDFTSize +@param src input floating-point real or complex array. +@param dst output array whose size and type depend on the flags. +@param flags operation flags (see dft and cv::DftFlags). +@param nonzeroRows number of dst rows to process; the rest of the rows have undefined content (see +the convolution sample in dft description. +*/ CV_EXPORTS_W void idft(InputArray src, OutputArray dst, int flags = 0, int nonzeroRows = 0); -//! performs forward or inverse 1D or 2D Discrete Cosine Transformation +/** @brief Performs a forward or inverse discrete Cosine transform of 1D or 2D array. + +The function dct performs a forward or inverse discrete Cosine transform (DCT) of a 1D or 2D +floating-point array: +- Forward Cosine transform of a 1D vector of N elements: + \f[Y = C^{(N)} \cdot X\f] + where + \f[C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right )\f] + and + \f$\alpha_0=1\f$, \f$\alpha_j=2\f$ for *j \> 0*. +- Inverse Cosine transform of a 1D vector of N elements: + \f[X = \left (C^{(N)} \right )^{-1} \cdot Y = \left (C^{(N)} \right )^T \cdot Y\f] + (since \f$C^{(N)}\f$ is an orthogonal matrix, \f$C^{(N)} \cdot \left(C^{(N)}\right)^T = I\f$ ) +- Forward 2D Cosine transform of M x N matrix: + \f[Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T\f] +- Inverse 2D Cosine transform of M x N matrix: + \f[X = \left (C^{(N)} \right )^T \cdot X \cdot C^{(N)}\f] + +The function chooses the mode of operation by looking at the flags and size of the input array: +- If (flags & DCT_INVERSE) == 0 , the function does a forward 1D or 2D transform. Otherwise, it + is an inverse 1D or 2D transform. +- If (flags & DCT_ROWS) != 0 , the function performs a 1D transform of each row. +- If the array is a single column or a single row, the function performs a 1D transform. +- If none of the above is true, the function performs a 2D transform. + +@note Currently dct supports even-size arrays (2, 4, 6 ...). For data analysis and approximation, you +can pad the array when necessary. +Also, the function performance depends very much, and not monotonically, on the array size (see +getOptimalDFTSize ). In the current implementation DCT of a vector of size N is calculated via DFT +of a vector of size N/2 . Thus, the optimal DCT size N1 \>= N can be calculated as: +@code + size_t getOptimalDCTSize(size_t N) { return 2*getOptimalDFTSize((N+1)/2); } + N1 = getOptimalDCTSize(N); +@endcode +@param src input floating-point array. +@param dst output array of the same size and type as src . +@param flags transformation flags as a combination of cv::DftFlags (DCT_*) +@sa dft , getOptimalDFTSize , idct +*/ CV_EXPORTS_W void dct(InputArray src, OutputArray dst, int flags = 0); -//! performs inverse 1D or 2D Discrete Cosine Transformation +/** @brief Calculates the inverse Discrete Cosine Transform of a 1D or 2D array. + +idct(src, dst, flags) is equivalent to dct(src, dst, flags | DCT_INVERSE). +@param src input floating-point single-channel array. +@param dst output array of the same size and type as src. +@param flags operation flags. +@sa dct, dft, idft, getOptimalDFTSize +*/ CV_EXPORTS_W void idct(InputArray src, OutputArray dst, int flags = 0); -//! computes element-wise product of the two Fourier spectrums. The second spectrum can optionally be conjugated before the multiplication +/** @brief Performs the per-element multiplication of two Fourier spectrums. + +The function mulSpectrums performs the per-element multiplication of the two CCS-packed or complex +matrices that are results of a real or complex Fourier transform. + +The function, together with dft and idft , may be used to calculate convolution (pass conjB=false ) +or correlation (pass conjB=true ) of two arrays rapidly. When the arrays are complex, they are +simply multiplied (per element) with an optional conjugation of the second-array elements. When the +arrays are real, they are assumed to be CCS-packed (see dft for details). +@param a first input array. +@param b second input array of the same size and type as src1 . +@param c output array of the same size and type as src1 . +@param flags operation flags; currently, the only supported flag is cv::DFT_ROWS, which indicates that +each row of src1 and src2 is an independent 1D Fourier spectrum. +@param conjB optional flag that conjugates the second input array before the multiplication (true) +or not (false). +*/ CV_EXPORTS_W void mulSpectrums(InputArray a, InputArray b, OutputArray c, int flags, bool conjB = false); -//! computes the minimal vector size vecsize1 >= vecsize so that the dft() of the vector of length vecsize1 can be computed efficiently +/** @brief Returns the optimal DFT size for a given vector size. + +DFT performance is not a monotonic function of a vector size. Therefore, when you calculate +convolution of two arrays or perform the spectral analysis of an array, it usually makes sense to +pad the input data with zeros to get a bit larger array that can be transformed much faster than the +original one. Arrays whose size is a power-of-two (2, 4, 8, 16, 32, ...) are the fastest to process. +Though, the arrays whose size is a product of 2's, 3's, and 5's (for example, 300 = 5\*5\*3\*2\*2) +are also processed quite efficiently. + +The function getOptimalDFTSize returns the minimum number N that is greater than or equal to vecsize +so that the DFT of a vector of size N can be processed efficiently. In the current implementation N += 2 ^p^ \* 3 ^q^ \* 5 ^r^ for some integer p, q, r. + +The function returns a negative number if vecsize is too large (very close to INT_MAX ). + +While the function cannot be used directly to estimate the optimal vector size for DCT transform +(since the current DCT implementation supports only even-size vectors), it can be easily processed +as getOptimalDFTSize((vecsize+1)/2)\*2. +@param vecsize vector size. +@sa dft , dct , idft , idct , mulSpectrums +*/ CV_EXPORTS_W int getOptimalDFTSize(int vecsize); -//! clusters the input data using k-Means algorithm -CV_EXPORTS_W double kmeans( InputArray data, int K, InputOutputArray bestLabels, - TermCriteria criteria, int attempts, - int flags, OutputArray centers = noArray() ); +/** @brief Returns the default random number generator. -//! returns the thread-local Random number generator +The function theRNG returns the default random number generator. For each thread, there is a +separate random number generator, so you can use the function safely in multi-thread environments. +If you just need to get a single random number using this generator or initialize an array, you can +use randu or randn instead. But if you are going to generate many random numbers inside a loop, it +is much faster to use this function to retrieve the generator and then use RNG::operator _Tp() . +@sa RNG, randu, randn +*/ CV_EXPORTS RNG& theRNG(); -//! fills array with uniformly-distributed random numbers from the range [low, high) +/** @brief Generates a single uniformly-distributed random number or an array of random numbers. + +Non-template variant of the function fills the matrix dst with uniformly-distributed +random numbers from the specified range: +\f[\texttt{low} _c \leq \texttt{dst} (I)_c < \texttt{high} _c\f] +@param dst output array of random numbers; the array must be pre-allocated. +@param low inclusive lower boundary of the generated random numbers. +@param high exclusive upper boundary of the generated random numbers. +@sa RNG, randn, theRNG +*/ CV_EXPORTS_W void randu(InputOutputArray dst, InputArray low, InputArray high); -//! fills array with normally-distributed random numbers with the specified mean and the standard deviation -CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev); +/** @brief Fills the array with normally distributed random numbers. -//! shuffles the input array elements -CV_EXPORTS_W void randShuffle(InputOutputArray dst, double iterFactor = 1., RNG* rng = 0); +The function randn fills the matrix dst with normally distributed random numbers with the specified +mean vector and the standard deviation matrix. The generated random numbers are clipped to fit the +value range of the output array data type. +@param dst output array of random numbers; the array must be pre-allocated and have 1 to 4 channels. +@param mean mean value (expectation) of the generated random numbers. +@param stddev standard deviation of the generated random numbers; it can be either a vector (in +which case a diagonal standard deviation matrix is assumed) or a square matrix. +@sa RNG, randu +*/ +CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev); -/*! - Principal Component Analysis +/** @brief Shuffles the array elements randomly. - The class PCA is used to compute the special basis for a set of vectors. - The basis will consist of eigenvectors of the covariance matrix computed - from the input set of vectors. After PCA is performed, vectors can be transformed from - the original high-dimensional space to the subspace formed by a few most - prominent eigenvectors (called the principal components), - corresponding to the largest eigenvalues of the covariation matrix. - Thus the dimensionality of the vector and the correlation between the coordinates is reduced. +The function randShuffle shuffles the specified 1D array by randomly choosing pairs of elements and +swapping them. The number of such swap operations will be dst.rows\*dst.cols\*iterFactor . +@param dst input/output numerical 1D array. +@param iterFactor scale factor that determines the number of random swap operations (see the details +below). +@param rng optional random number generator used for shuffling; if it is zero, theRNG () is used +instead. +@sa RNG, sort +*/ +CV_EXPORTS_W void randShuffle(InputOutputArray dst, double iterFactor = 1., RNG* rng = 0); - The following sample is the function that takes two matrices. The first one stores the set - of vectors (a row per vector) that is used to compute PCA, the second one stores another - "test" set of vectors (a row per vector) that are first compressed with PCA, - then reconstructed back and then the reconstruction error norm is computed and printed for each vector. +/** @brief Principal Component Analysis + +The class is used to calculate a special basis for a set of vectors. The +basis will consist of eigenvectors of the covariance matrix calculated +from the input set of vectors. The class %PCA can also transform +vectors to/from the new coordinate space defined by the basis. Usually, +in this new coordinate system, each vector from the original set (and +any linear combination of such vectors) can be quite accurately +approximated by taking its first few components, corresponding to the +eigenvectors of the largest eigenvalues of the covariance matrix. +Geometrically it means that you calculate a projection of the vector to +a subspace formed by a few eigenvectors corresponding to the dominant +eigenvalues of the covariance matrix. And usually such a projection is +very close to the original vector. So, you can represent the original +vector from a high-dimensional space with a much shorter vector +consisting of the projected vector's coordinates in the subspace. Such a +transformation is also known as Karhunen-Loeve Transform, or KLT. +See http://en.wikipedia.org/wiki/Principal_component_analysis + +The sample below is the function that takes two matrices. The first +function stores a set of vectors (a row per vector) that is used to +calculate PCA. The second function stores another "test" set of vectors +(a row per vector). First, these vectors are compressed with PCA, then +reconstructed back, and then the reconstruction error norm is computed +and printed for each vector. : + +@code{.cpp} +using namespace cv; + +PCA compressPCA(const Mat& pcaset, int maxComponents, + const Mat& testset, Mat& compressed) +{ + PCA pca(pcaset, // pass the data + Mat(), // we do not have a pre-computed mean vector, + // so let the PCA engine to compute it + PCA::DATA_AS_ROW, // indicate that the vectors + // are stored as matrix rows + // (use PCA::DATA_AS_COL if the vectors are + // the matrix columns) + maxComponents // specify, how many principal components to retain + ); + // if there is no test data, just return the computed basis, ready-to-use + if( !testset.data ) + return pca; + CV_Assert( testset.cols == pcaset.cols ); - \code - using namespace cv; + compressed.create(testset.rows, maxComponents, testset.type()); - PCA compressPCA(const Mat& pcaset, int maxComponents, - const Mat& testset, Mat& compressed) + Mat reconstructed; + for( int i = 0; i < testset.rows; i++ ) { - PCA pca(pcaset, // pass the data - Mat(), // we do not have a pre-computed mean vector, - // so let the PCA engine to compute it - PCA::DATA_AS_ROW, // indicate that the vectors - // are stored as matrix rows - // (use PCA::DATA_AS_COL if the vectors are - // the matrix columns) - maxComponents // specify, how many principal components to retain - ); - // if there is no test data, just return the computed basis, ready-to-use - if( !testset.data ) - return pca; - CV_Assert( testset.cols == pcaset.cols ); - - compressed.create(testset.rows, maxComponents, testset.type()); - - Mat reconstructed; - for( int i = 0; i < testset.rows; i++ ) - { - Mat vec = testset.row(i), coeffs = compressed.row(i), reconstructed; - // compress the vector, the result will be stored - // in the i-th row of the output matrix - pca.project(vec, coeffs); - // and then reconstruct it - pca.backProject(coeffs, reconstructed); - // and measure the error - printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2)); - } - return pca; + Mat vec = testset.row(i), coeffs = compressed.row(i), reconstructed; + // compress the vector, the result will be stored + // in the i-th row of the output matrix + pca.project(vec, coeffs); + // and then reconstruct it + pca.backProject(coeffs, reconstructed); + // and measure the error + printf("%d. diff = %g\n", i, norm(vec, reconstructed, NORM_L2)); } - \endcode + return pca; +} +@endcode +@sa calcCovarMatrix, mulTransposed, SVD, dft, dct */ class CV_EXPORTS PCA { public: - enum { DATA_AS_ROW = 0, - DATA_AS_COL = 1, - USE_AVG = 2 - }; + enum Flags { DATA_AS_ROW = 0, //!< indicates that the input samples are stored as matrix rows + DATA_AS_COL = 1, //!< indicates that the input samples are stored as matrix columns + USE_AVG = 2 //! + }; - //! default constructor + /** @brief default constructor + + The default constructor initializes an empty %PCA structure. The other + constructors initialize the structure and call PCA::operator()(). + */ PCA(); - //! the constructor that performs PCA + /** @overload + @param data input samples stored as matrix rows or matrix columns. + @param mean optional mean value; if the matrix is empty (@c noArray()), + the mean is computed from the data. + @param flags operation flags; currently the parameter is only used to + specify the data layout (PCA::Flags) + @param maxComponents maximum number of components that %PCA should + retain; by default, all the components are retained. + */ PCA(InputArray data, InputArray mean, int flags, int maxComponents = 0); + + /** @overload + @param data input samples stored as matrix rows or matrix columns. + @param mean optional mean value; if the matrix is empty (noArray()), + the mean is computed from the data. + @param flags operation flags; currently the parameter is only used to + specify the data layout (PCA::Flags) + @param retainedVariance Percentage of variance that PCA should retain. + Using this parameter will let the PCA decided how many components to + retain but it will always keep at least 2. + */ PCA(InputArray data, InputArray mean, int flags, double retainedVariance); - //! operator that performs PCA. The previously stored data, if any, is released + /** @brief performs %PCA + + The operator performs %PCA of the supplied dataset. It is safe to reuse + the same PCA structure for multiple datasets. That is, if the structure + has been previously used with another dataset, the existing internal + data is reclaimed and the new eigenvalues, @ref eigenvectors , and @ref + mean are allocated and computed. + + The computed eigenvalues are sorted from the largest to the smallest and + the corresponding eigenvectors are stored as eigenvectors rows. + + @param data input samples stored as the matrix rows or as the matrix + columns. + @param mean optional mean value; if the matrix is empty (noArray()), + the mean is computed from the data. + @param flags operation flags; currently the parameter is only used to + specify the data layout. (Flags) + @param maxComponents maximum number of components that PCA should + retain; by default, all the components are retained. + */ PCA& operator()(InputArray data, InputArray mean, int flags, int maxComponents = 0); + + /** @overload + @param data input samples stored as the matrix rows or as the matrix + columns. + @param mean optional mean value; if the matrix is empty (noArray()), + the mean is computed from the data. + @param flags operation flags; currently the parameter is only used to + specify the data layout. (PCA::Flags) + @param retainedVariance Percentage of variance that %PCA should retain. + Using this parameter will let the %PCA decided how many components to + retain but it will always keep at least 2. + */ PCA& operator()(InputArray data, InputArray mean, int flags, double retainedVariance); - //! projects vector from the original space to the principal components subspace + /** @brief Projects vector(s) to the principal component subspace. + + The methods project one or more vectors to the principal component + subspace, where each vector projection is represented by coefficients in + the principal component basis. The first form of the method returns the + matrix that the second form writes to the result. So the first form can + be used as a part of expression while the second form can be more + efficient in a processing loop. + @param vec input vector(s); must have the same dimensionality and the + same layout as the input data used at %PCA phase, that is, if + DATA_AS_ROW are specified, then `vec.cols==data.cols` + (vector dimensionality) and `vec.rows` is the number of vectors to + project, and the same is true for the PCA::DATA_AS_COL case. + */ Mat project(InputArray vec) const; - //! projects vector from the original space to the principal components subspace + /** @overload + @param vec input vector(s); must have the same dimensionality and the + same layout as the input data used at PCA phase, that is, if + DATA_AS_ROW are specified, then `vec.cols==data.cols` + (vector dimensionality) and `vec.rows` is the number of vectors to + project, and the same is true for the PCA::DATA_AS_COL case. + @param result output vectors; in case of PCA::DATA_AS_COL, the + output matrix has as many columns as the number of input vectors, this + means that `result.cols==vec.cols` and the number of rows match the + number of principal components (for example, `maxComponents` parameter + passed to the constructor). + */ void project(InputArray vec, OutputArray result) const; - //! reconstructs the original vector from the projection + /** @brief Reconstructs vectors from their PC projections. + + The methods are inverse operations to PCA::project. They take PC + coordinates of projected vectors and reconstruct the original vectors. + Unless all the principal components have been retained, the + reconstructed vectors are different from the originals. But typically, + the difference is small if the number of components is large enough (but + still much smaller than the original vector dimensionality). As a + result, PCA is used. + @param vec coordinates of the vectors in the principal component + subspace, the layout and size are the same as of PCA::project output + vectors. + */ Mat backProject(InputArray vec) const; - //! reconstructs the original vector from the projection + /** @overload + @param vec coordinates of the vectors in the principal component + subspace, the layout and size are the same as of PCA::project output + vectors. + @param result reconstructed vectors; the layout and size are the same as + of PCA::project input vectors. + */ void backProject(InputArray vec, OutputArray result) const; - //! write and load PCA matrix + /** @brief write and load PCA matrix + +*/ void write(FileStorage& fs ) const; void read(const FileNode& fs); @@ -600,48 +2226,68 @@ public: Mat mean; //!< mean value subtracted before the projection and added after the back projection }; -// Linear Discriminant Analysis +/** @example pca.cpp + An example using %PCA for dimensionality reduction while maintaining an amount of variance + */ + +/** + @brief Linear Discriminant Analysis + @todo document this class + */ class CV_EXPORTS LDA { public: - // Initializes a LDA with num_components (default 0) and specifies how - // samples are aligned (default dataAsRow=true). + /** @brief constructor + Initializes a LDA with num_components (default 0) and specifies how + samples are aligned (default dataAsRow=true). + */ explicit LDA(int num_components = 0); - // Initializes and performs a Discriminant Analysis with Fisher's - // Optimization Criterion on given data in src and corresponding labels - // in labels. If 0 (or less) number of components are given, they are - // automatically determined for given data in computation. + /** Initializes and performs a Discriminant Analysis with Fisher's + Optimization Criterion on given data in src and corresponding labels + in labels. If 0 (or less) number of components are given, they are + automatically determined for given data in computation. + */ LDA(InputArrayOfArrays src, InputArray labels, int num_components = 0); - // Serializes this object to a given filename. + /** Serializes this object to a given filename. + */ void save(const String& filename) const; - // Deserializes this object from a given filename. + /** Deserializes this object from a given filename. + */ void load(const String& filename); - // Serializes this object to a given cv::FileStorage. + /** Serializes this object to a given cv::FileStorage. + */ void save(FileStorage& fs) const; - // Deserializes this object from a given cv::FileStorage. + /** Deserializes this object from a given cv::FileStorage. + */ void load(const FileStorage& node); - // Destructor. + /** destructor + */ ~LDA(); - //! Compute the discriminants for data in src and labels. + /** Compute the discriminants for data in src and labels. + */ void compute(InputArrayOfArrays src, InputArray labels); - // Projects samples into the LDA subspace. + /** Projects samples into the LDA subspace. + */ Mat project(InputArray src); - // Reconstructs projections from the LDA subspace. + /** Reconstructs projections from the LDA subspace. + */ Mat reconstruct(InputArray src); - // Returns the eigenvectors of this LDA. + /** Returns the eigenvectors of this LDA. + */ Mat eigenvectors() const { return _eigenvectors; } - // Returns the eigenvalues of this LDA. + /** Returns the eigenvalues of this LDA. + */ Mat eigenvalues() const { return _eigenvalues; } static Mat subspaceProject(InputArray W, InputArray mean, InputArray src); @@ -656,101 +2302,160 @@ protected: void lda(InputArrayOfArrays src, InputArray labels); }; -/*! - Singular Value Decomposition class +/** @brief Singular Value Decomposition + +Class for computing Singular Value Decomposition of a floating-point +matrix. The Singular Value Decomposition is used to solve least-square +problems, under-determined linear systems, invert matrices, compute +condition numbers, and so on. - The class is used to compute Singular Value Decomposition of a floating-point matrix and then - use it to solve least-square problems, under-determined linear systems, invert matrices, - compute condition numbers etc. +For a faster operation, you can pass flags=SVD::MODIFY_A|... to modify +the decomposed matrix when it is not necessary to preserve it. If you +want to compute a condition number of a matrix or an absolute value of +its determinant, you do not need `u` and `vt`. You can pass +flags=SVD::NO_UV|... . Another flag SVD::FULL_UV indicates that full-size u +and vt must be computed, which is not necessary most of the time. - For a bit faster operation you can pass flags=SVD::MODIFY_A|... to modify the decomposed matrix - when it is not necessarily to preserve it. If you want to compute condition number of a matrix - or absolute value of its determinant - you do not need SVD::u or SVD::vt, - so you can pass flags=SVD::NO_UV|... . Another flag SVD::FULL_UV indicates that the full-size SVD::u and SVD::vt - must be computed, which is not necessary most of the time. +@sa invert, solve, eigen, determinant */ class CV_EXPORTS SVD { public: - enum { MODIFY_A = 1, - NO_UV = 2, - FULL_UV = 4 - }; - - //! the default constructor + enum Flags { + /** use the algorithm to modify the decomposed matrix; it can save space and speed up + processing */ + MODIFY_A = 1, + /** indicates that only a vector of singular values `w` is to be processed, while u and vt + will be set to empty matrices */ + NO_UV = 2, + /** when the matrix is not square, by default the algorithm produces u and vt matrices of + sufficiently large size for the further A reconstruction; if, however, FULL_UV flag is + specified, u and vt will be full-size square orthogonal matrices.*/ + FULL_UV = 4 + }; + + /** @brief the default constructor + + initializes an empty SVD structure + */ SVD(); - //! the constructor that performs SVD + /** @overload + initializes an empty SVD structure and then calls SVD::operator() + @param src decomposed matrix. + @param flags operation flags (SVD::Flags) + */ SVD( InputArray src, int flags = 0 ); - //! the operator that performs SVD. The previously allocated SVD::u, SVD::w are SVD::vt are released. + /** @brief the operator that performs SVD. The previously allocated u, w and vt are released. + + The operator performs the singular value decomposition of the supplied + matrix. The u,`vt` , and the vector of singular values w are stored in + the structure. The same SVD structure can be reused many times with + different matrices. Each time, if needed, the previous u,`vt` , and w + are reclaimed and the new matrices are created, which is all handled by + Mat::create. + @param src decomposed matrix. + @param flags operation flags (SVD::Flags) + */ SVD& operator ()( InputArray src, int flags = 0 ); - //! decomposes matrix and stores the results to user-provided matrices + /** @brief decomposes matrix and stores the results to user-provided matrices + + The methods/functions perform SVD of matrix. Unlike SVD::SVD constructor + and SVD::operator(), they store the results to the user-provided + matrices: + + @code{.cpp} + Mat A, w, u, vt; + SVD::compute(A, w, u, vt); + @endcode + + @param src decomposed matrix + @param w calculated singular values + @param u calculated left singular vectors + @param vt transposed matrix of right singular values + @param flags operation flags - see SVD::SVD. + */ static void compute( InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags = 0 ); - //! computes singular values of a matrix + /** @overload + computes singular values of a matrix + @param src decomposed matrix + @param w calculated singular values + @param flags operation flags - see SVD::Flags. + */ static void compute( InputArray src, OutputArray w, int flags = 0 ); - //! performs back substitution + /** @brief performs back substitution + */ static void backSubst( InputArray w, InputArray u, InputArray vt, InputArray rhs, OutputArray dst ); - //! finds dst = arg min_{|dst|=1} |m*dst| + /** @brief solves an under-determined singular linear system + + The method finds a unit-length solution x of a singular linear system + A\*x = 0. Depending on the rank of A, there can be no solutions, a + single solution or an infinite number of solutions. In general, the + algorithm solves the following problem: + \f[dst = \arg \min _{x: \| x \| =1} \| src \cdot x \|\f] + @param src left-hand-side matrix. + @param dst found solution. + */ static void solveZ( InputArray src, OutputArray dst ); - //! performs back substitution, so that dst is the solution or pseudo-solution of m*dst = rhs, where m is the decomposed matrix + /** @brief performs a singular value back substitution. + + The method calculates a back substitution for the specified right-hand + side: + + \f[\texttt{x} = \texttt{vt} ^T \cdot diag( \texttt{w} )^{-1} \cdot \texttt{u} ^T \cdot \texttt{rhs} \sim \texttt{A} ^{-1} \cdot \texttt{rhs}\f] + + Using this technique you can either get a very accurate solution of the + convenient linear system, or the best (in the least-squares terms) + pseudo-solution of an overdetermined linear system. + + @param rhs right-hand side of a linear system (u\*w\*v')\*dst = rhs to + be solved, where A has been previously decomposed. + + @param dst found solution of the system. + + @note Explicit SVD with the further back substitution only makes sense + if you need to solve many linear systems with the same left-hand side + (for example, src ). If all you need is to solve a single system + (possibly with multiple rhs immediately available), simply call solve + add pass DECOMP_SVD there. It does absolutely the same thing. + */ void backSubst( InputArray rhs, OutputArray dst ) const; + /** @todo document */ template static void compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt ); + /** @todo document */ template static void compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w ); + /** @todo document */ template static void backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst ); Mat u, w, vt; }; - - -/*! - Line iterator class - - The class is used to iterate over all the pixels on the raster line - segment connecting two specified points. -*/ -class CV_EXPORTS LineIterator -{ -public: - //! intializes the iterator - LineIterator( const Mat& img, Point pt1, Point pt2, - int connectivity = 8, bool leftToRight = false ); - //! returns pointer to the current pixel - uchar* operator *(); - //! prefix increment operator (++it). shifts iterator to the next pixel - LineIterator& operator ++(); - //! postfix increment operator (it++). shifts iterator to the next pixel - LineIterator operator ++(int); - //! returns coordinates of the current pixel - Point pos() const; - - uchar* ptr; - const uchar* ptr0; - int step, elemSize; - int err, count; - int minusDelta, plusDelta; - int minusStep, plusStep; -}; - -/*! - Random Number Generator - - The class implements RNG using Multiply-with-Carry algorithm +/** @brief Random Number Generator + +Random number generator. It encapsulates the state (currently, a 64-bit +integer) and has methods to return scalar random values and to fill +arrays with random values. Currently it supports uniform and Gaussian +(normal) distributions. The generator uses Multiply-With-Carry +algorithm, introduced by G. Marsaglia ( + ). +Gaussian-distribution random numbers are generated using the Ziggurat +algorithm ( ), +introduced by G. Marsaglia and W. W. Tsang. */ class CV_EXPORTS RNG { @@ -759,35 +2464,154 @@ public: NORMAL = 1 }; + /** @brief constructor + + These are the RNG constructors. The first form sets the state to some + pre-defined value, equal to 2\*\*32-1 in the current implementation. The + second form sets the state to the specified value. If you passed state=0 + , the constructor uses the above default value instead to avoid the + singular random number sequence, consisting of all zeros. + */ RNG(); + /** @overload + @param state 64-bit value used to initialize the RNG. + */ RNG(uint64 state); - //! updates the state and returns the next 32-bit unsigned integer random number + /**The method updates the state using the MWC algorithm and returns the + next 32-bit random number.*/ unsigned next(); + /**Each of the methods updates the state using the MWC algorithm and + returns the next random number of the specified type. In case of integer + types, the returned number is from the available value range for the + specified type. In case of floating-point types, the returned value is + from [0,1) range. + */ operator uchar(); + /** @overload */ operator schar(); + /** @overload */ operator ushort(); + /** @overload */ operator short(); + /** @overload */ operator unsigned(); - //! returns a random integer sampled uniformly from [0, N). - unsigned operator ()(unsigned N); - unsigned operator ()(); + /** @overload */ operator int(); + /** @overload */ operator float(); + /** @overload */ operator double(); - //! returns uniformly distributed integer random number from [a,b) range + + /** @brief returns a random integer sampled uniformly from [0, N). + + The methods transform the state using the MWC algorithm and return the + next random number. The first form is equivalent to RNG::next . The + second form returns the random number modulo N , which means that the + result is in the range [0, N) . + */ + unsigned operator ()(); + /** @overload + @param N upper non-inclusive boundary of the returned random number. + */ + unsigned operator ()(unsigned N); + + /** @brief returns uniformly distributed integer random number from [a,b) range + + The methods transform the state using the MWC algorithm and return the + next uniformly-distributed random number of the specified type, deduced + from the input parameter type, from the range [a, b) . There is a nuance + illustrated by the following sample: + + @code{.cpp} + RNG rng; + + // always produces 0 + double a = rng.uniform(0, 1); + + // produces double from [0, 1) + double a1 = rng.uniform((double)0, (double)1); + + // produces float from [0, 1) + double b = rng.uniform(0.f, 1.f); + + // produces double from [0, 1) + double c = rng.uniform(0., 1.); + + // may cause compiler error because of ambiguity: + // RNG::uniform(0, (int)0.999999)? or RNG::uniform((double)0, 0.99999)? + double d = rng.uniform(0, 0.999999); + @endcode + + The compiler does not take into account the type of the variable to + which you assign the result of RNG::uniform . The only thing that + matters to the compiler is the type of a and b parameters. So, if you + want a floating-point random number, but the range boundaries are + integer numbers, either put dots in the end, if they are constants, or + use explicit type cast operators, as in the a1 initialization above. + @param a lower inclusive boundary of the returned random numbers. + @param b upper non-inclusive boundary of the returned random numbers. + */ int uniform(int a, int b); - //! returns uniformly distributed floating-point random number from [a,b) range + /** @overload */ float uniform(float a, float b); - //! returns uniformly distributed double-precision floating-point random number from [a,b) range + /** @overload */ double uniform(double a, double b); + + /** @brief Fills arrays with random numbers. + + @param mat 2D or N-dimensional matrix; currently matrices with more than + 4 channels are not supported by the methods, use Mat::reshape as a + possible workaround. + @param distType distribution type, RNG::UNIFORM or RNG::NORMAL. + @param a first distribution parameter; in case of the uniform + distribution, this is an inclusive lower boundary, in case of the normal + distribution, this is a mean value. + @param b second distribution parameter; in case of the uniform + distribution, this is a non-inclusive upper boundary, in case of the + normal distribution, this is a standard deviation (diagonal of the + standard deviation matrix or the full standard deviation matrix). + @param saturateRange pre-saturation flag; for uniform distribution only; + if true, the method will first convert a and b to the acceptable value + range (according to the mat datatype) and then will generate uniformly + distributed random numbers within the range [saturate(a), saturate(b)), + if saturateRange=false, the method will generate uniformly distributed + random numbers in the original range [a, b) and then will saturate them, + it means, for example, that + theRNG().fill(mat_8u, RNG::UNIFORM, -DBL_MAX, DBL_MAX) will likely + produce array mostly filled with 0's and 255's, since the range (0, 255) + is significantly smaller than [-DBL_MAX, DBL_MAX). + + Each of the methods fills the matrix with the random values from the + specified distribution. As the new numbers are generated, the RNG state + is updated accordingly. In case of multiple-channel images, every + channel is filled independently, which means that RNG cannot generate + samples from the multi-dimensional Gaussian distribution with + non-diagonal covariance matrix directly. To do that, the method + generates samples from multi-dimensional standard Gaussian distribution + with zero mean and identity covariation matrix, and then transforms them + using transform to get samples from the specified Gaussian distribution. + */ void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange = false ); - //! returns Gaussian random variate with mean zero. + + /** @brief Returns the next random number sampled from the Gaussian distribution + @param sigma standard deviation of the distribution. + + The method transforms the state using the MWC algorithm and returns the + next random number from the Gaussian distribution N(0,sigma) . That is, + the mean value of the returned random numbers is zero and the standard + deviation is the specified sigma . + */ double gaussian(double sigma); uint64 state; }; +/** @brief Mersenne Twister random number generator + +Inspired by http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c +@todo document + */ class CV_EXPORTS RNG_MT19937 { public: @@ -805,11 +2629,17 @@ public: unsigned operator ()(unsigned N); unsigned operator ()(); - // returns uniformly distributed integer random number from [a,b) range + /** @brief returns uniformly distributed integer random number from [a,b) range + +*/ int uniform(int a, int b); - // returns uniformly distributed floating-point random number from [a,b) range + /** @brief returns uniformly distributed floating-point random number from [a,b) range + +*/ float uniform(float a, float b); - // returns uniformly distributed double-precision floating-point random number from [a,b) range + /** @brief returns uniformly distributed double-precision floating-point random number from [a,b) range + +*/ double uniform(double a, double b); private: @@ -818,10 +2648,132 @@ private: int mti; }; +//! @} core_array + +//! @addtogroup core_cluster +//! @{ + +/** @example kmeans.cpp + An example on K-means clustering +*/ + +/** @brief Finds centers of clusters and groups input samples around the clusters. + +The function kmeans implements a k-means algorithm that finds the centers of cluster_count clusters +and groups the input samples around the clusters. As an output, \f$\texttt{labels}_i\f$ contains a +0-based cluster index for the sample stored in the \f$i^{th}\f$ row of the samples matrix. + +@note +- (Python) An example on K-means clustering can be found at + opencv_source_code/samples/python2/kmeans.py +@param data Data for clustering. An array of N-Dimensional points with float coordinates is needed. +Examples of this array can be: +- Mat points(count, 2, CV_32F); +- Mat points(count, 1, CV_32FC2); +- Mat points(1, count, CV_32FC2); +- std::vector\ points(sampleCount); +@param K Number of clusters to split the set by. +@param bestLabels Input/output integer array that stores the cluster indices for every sample. +@param criteria The algorithm termination criteria, that is, the maximum number of iterations and/or +the desired accuracy. The accuracy is specified as criteria.epsilon. As soon as each of the cluster +centers moves by less than criteria.epsilon on some iteration, the algorithm stops. +@param attempts Flag to specify the number of times the algorithm is executed using different +initial labellings. The algorithm returns the labels that yield the best compactness (see the last +function parameter). +@param flags Flag that can take values of cv::KmeansFlags +@param centers Output matrix of the cluster centers, one row per each cluster center. +@return The function returns the compactness measure that is computed as +\f[\sum _i \| \texttt{samples} _i - \texttt{centers} _{ \texttt{labels} _i} \| ^2\f] +after every attempt. The best (minimum) value is chosen and the corresponding labels and the +compactness value are returned by the function. Basically, you can use only the core of the +function, set the number of attempts to 1, initialize labels each time using a custom algorithm, +pass them with the ( flags = KMEANS_USE_INITIAL_LABELS ) flag, and then choose the best +(most-compact) clustering. +*/ +CV_EXPORTS_W double kmeans( InputArray data, int K, InputOutputArray bestLabels, + TermCriteria criteria, int attempts, + int flags, OutputArray centers = noArray() ); + +//! @} core_cluster + +//! @addtogroup imgproc_drawing +//! @{ + +/*! @brief Line iterator + +The class is used to iterate over all the pixels on the raster line +segment connecting two specified points. + +The class LineIterator is used to get each pixel of a raster line. It +can be treated as versatile implementation of the Bresenham algorithm +where you can stop at each pixel and do some extra processing, for +example, grab pixel values along the line or draw a line with an effect +(for example, with XOR operation). + +The number of pixels along the line is stored in LineIterator::count. +The method LineIterator::pos returns the current position in the image: + +@code{.cpp} +// grabs pixels along the line (pt1, pt2) +// from 8-bit 3-channel image to the buffer +LineIterator it(img, pt1, pt2, 8); +LineIterator it2 = it; +vector buf(it.count); + +for(int i = 0; i < it.count; i++, ++it) + buf[i] = *(const Vec3b)*it; + +// alternative way of iterating through the line +for(int i = 0; i < it2.count; i++, ++it2) +{ + Vec3b val = img.at(it2.pos()); + CV_Assert(buf[i] == val); +} +@endcode +*/ +class CV_EXPORTS LineIterator +{ +public: + /** @brief intializes the iterator + + creates iterators for the line connecting pt1 and pt2 + the line will be clipped on the image boundaries + the line is 8-connected or 4-connected + If leftToRight=true, then the iteration is always done + from the left-most point to the right most, + not to depend on the ordering of pt1 and pt2 parameters + */ + LineIterator( const Mat& img, Point pt1, Point pt2, + int connectivity = 8, bool leftToRight = false ); + /** @brief returns pointer to the current pixel + */ + uchar* operator *(); + /** @brief prefix increment operator (++it). shifts iterator to the next pixel + */ + LineIterator& operator ++(); + /** @brief postfix increment operator (it++). shifts iterator to the next pixel + */ + LineIterator operator ++(int); + /** @brief returns coordinates of the current pixel + */ + Point pos() const; + + uchar* ptr; + const uchar* ptr0; + int step, elemSize; + int err, count; + int minusDelta, plusDelta; + int minusStep, plusStep; +}; + +//! @} imgproc_drawing +//! @addtogroup core_basic +//! @{ /////////////////////////////// Formatted output of cv::Mat /////////////////////////// +/** @todo document */ class CV_EXPORTS Formatted { public: @@ -830,7 +2782,7 @@ public: virtual ~Formatted(); }; - +/** @todo document */ class CV_EXPORTS Formatter { public: @@ -855,7 +2807,6 @@ public: }; - //////////////////////////////////////// Algorithm //////////////////////////////////// class CV_EXPORTS Algorithm; @@ -864,17 +2815,109 @@ struct CV_EXPORTS AlgorithmInfoData; template struct ParamType {}; -/*! - Base class for high-level OpenCV algorithms -*/ + +/** @brief This is a base class for all more or less complex algorithms in OpenCV + +especially for classes of algorithms, for which there can be multiple implementations. The examples +are stereo correspondence (for which there are algorithms like block matching, semi-global block +matching, graph-cut etc.), background subtraction (which can be done using mixture-of-gaussians +models, codebook-based algorithm etc.), optical flow (block matching, Lucas-Kanade, Horn-Schunck +etc.). + +The class provides the following features for all derived classes: + +- so called "virtual constructor". That is, each Algorithm derivative is registered at program + start and you can get the list of registered algorithms and create instance of a particular + algorithm by its name (see Algorithm::create). If you plan to add your own algorithms, it is + good practice to add a unique prefix to your algorithms to distinguish them from other + algorithms. +- setting/retrieving algorithm parameters by name. If you used video capturing functionality + from OpenCV videoio module, you are probably familar with cvSetCaptureProperty(), + cvGetCaptureProperty(), VideoCapture::set() and VideoCapture::get(). Algorithm provides + similar method where instead of integer id's you specify the parameter names as text strings. + See Algorithm::set and Algorithm::get for details. +- reading and writing parameters from/to XML or YAML files. Every Algorithm derivative can store + all its parameters and then read them back. There is no need to re-implement it each time. + +Here is example of SIFT use in your application via Algorithm interface: +@code + #include "opencv2/opencv.hpp" + #include "opencv2/xfeatures2d.hpp" + + using namespace cv::xfeatures2d; + + ... + + Ptr sift = SIFT::create(); + + FileStorage fs("sift_params.xml", FileStorage::READ); + if( fs.isOpened() ) // if we have file with parameters, read them + { + sift->read(fs["sift_params"]); + fs.release(); + } + else // else modify the parameters and store them; user can later edit the file to use different parameters + { + sift->setContrastThreshold(0.01f); // lower the contrast threshold, compared to the default value + + { + WriteStructContext ws(fs, "sift_params", CV_NODE_MAP); + sift->write(fs); + } + } + + Mat image = imread("myimage.png", 0), descriptors; + vector keypoints; + sift->detectAndCompute(image, noArray(), keypoints, descriptors); +@endcode + +Creating Own Algorithms +----------------------- +If you want to make your own algorithm, derived from Algorithm, you should basically follow a few +conventions and add a little semi-standard piece of code to your class: +- Make a class and specify Algorithm as its base class. +- The algorithm parameters should be the class members. See Algorithm::get() for the list of + possible types of the parameters. +- Add public virtual method `AlgorithmInfo* info() const;` to your class. +- Add constructor function, AlgorithmInfo instance and implement the info() method. The simplest + way is to take as + the reference and modify it according to the list of your parameters. +- Add some public function (e.g. `initModule_()`) that calls info() of your algorithm + and put it into the same source file as info() implementation. This is to force C++ linker to + include this object file into the target application. See Algorithm::create() for details. + */ class CV_EXPORTS_W Algorithm -{ -public: + { + public: Algorithm(); virtual ~Algorithm(); + /**Returns the algorithm name*/ String name() const; + /** @brief returns the algorithm parameter + + The method returns value of the particular parameter. Since the compiler can not deduce the + type of the returned parameter, you should specify it explicitly in angle brackets. Here are + the allowed forms of get: + + - myalgo.get\("param_name") + - myalgo.get\("param_name") + - myalgo.get\("param_name") + - myalgo.get\("param_name") + - myalgo.get\("param_name") + - myalgo.get\ \>("param_name") + - myalgo.get\("param_name") (it returns Ptr\). + + In some cases the actual type of the parameter can be cast to the specified type, e.g. integer + parameter can be cast to double, bool can be cast to int. But "dangerous" transformations + (string\<-\>number, double-\>int, 1x1 Mat\<-\>number, ...) are not performed and the method + will throw an exception. In the case of Mat or vector\ parameters the method does not + clone the matrix data, so do not modify the matrices. Use Algorithm::set instead - slower, but + more safe. + @param name The parameter name. + */ template typename ParamType<_Tp>::member_type get(const String& name) const; + /** @overload */ template typename ParamType<_Tp>::member_type get(const char* name) const; CV_WRAP int getInt(const String& name) const; @@ -885,6 +2928,14 @@ public: CV_WRAP std::vector getMatVector(const String& name) const; CV_WRAP Ptr getAlgorithm(const String& name) const; + /** @brief Sets the algorithm parameter + + The method sets value of the particular parameter. Some of the algorithm + parameters may be declared as read-only. If you try to set such a + parameter, you will get exception with the corresponding error message. + @param name The parameter name. + @param value The parameter value. + */ void set(const String& name, int value); void set(const String& name, double value); void set(const String& name, bool value); @@ -926,22 +2977,97 @@ public: CV_WRAP int paramType(const String& name) const; CV_WRAP void getParams(CV_OUT std::vector& names) const; - + /** @brief Stores algorithm parameters in a file storage + + The method stores all the algorithm parameters (in alphabetic order) to + the file storage. The method is virtual. If you define your own + Algorithm derivative, your can override the method and store some extra + information. However, it's rarely needed. Here are some examples: + - SIFT feature detector (from xfeatures2d module). The class only + stores algorithm parameters and no keypoints or their descriptors. + Therefore, it's enough to store the algorithm parameters, which is + what Algorithm::write() does. Therefore, there is no dedicated + SIFT::write(). + - Background subtractor (from video module). It has the algorithm + parameters and also it has the current background model. However, + the background model is not stored. First, it's rather big. Then, + if you have stored the background model, it would likely become + irrelevant on the next run (because of shifted camera, changed + background, different lighting etc.). Therefore, + BackgroundSubtractorMOG and BackgroundSubtractorMOG2 also rely on + the standard Algorithm::write() to store just the algorithm + parameters. + - Expectation Maximization (from ml module). The algorithm finds + mixture of gaussians that approximates user data best of all. In + this case the model may be re-used on the next run to test new + data against the trained statistical model. So EM needs to store + the model. However, since the model is described by a few + parameters that are available as read-only algorithm parameters + (i.e. they are available via EM::get()), EM also relies on + Algorithm::write() to store both EM parameters and the model + (represented by read-only algorithm parameters). + @param fs File storage. + */ virtual void write(FileStorage& fs) const; + + /** @brief Reads algorithm parameters from a file storage + + The method reads all the algorithm parameters from the specified node of + a file storage. Similarly to Algorithm::write(), if you implement an + algorithm that needs to read some extra data and/or re-compute some + internal data, you may override the method. + @param fn File node of the file storage. + */ virtual void read(const FileNode& fn); typedef Algorithm* (*Constructor)(void); typedef int (Algorithm::*Getter)() const; typedef void (Algorithm::*Setter)(int); + /** @brief Returns the list of registered algorithms + + This static method returns the list of registered algorithms in + alphabetical order. Here is how to use it : + @code{.cpp} + vector algorithms; + Algorithm::getList(algorithms); + cout << "Algorithms: " << algorithms.size() << endl; + for (size_t i=0; i < algorithms.size(); i++) + cout << algorithms[i] << endl; + @endcode + @param algorithms The output vector of algorithm names. + */ CV_WRAP static void getList(CV_OUT std::vector& algorithms); CV_WRAP static Ptr _create(const String& name); + + /** @brief Creates algorithm instance by name + + This static method creates a new instance of the specified algorithm. If + there is no such algorithm, the method will silently return a null + pointer. Also, you should specify the particular Algorithm subclass as + _Tp (or simply Algorithm if you do not know it at that point). : + @code{.cpp} + Ptr bgfg = Algorithm::create("BackgroundSubtractor.MOG2"); + @endcode + @note This is important note about seemingly mysterious behavior of + Algorithm::create() when it returns NULL while it should not. The reason + is simple - Algorithm::create() resides in OpenCV's core module and the + algorithms are implemented in other modules. If you create algorithms + dynamically, C++ linker may decide to throw away the modules where the + actual algorithms are implemented, since you do not call any functions + from the modules. To avoid this problem, you need to call + initModule_\(); somewhere in the beginning of the program + before Algorithm::create(). For example, call initModule_xfeatures2d() + in order to use SURF/SIFT, call initModule_ml() to use expectation + maximization etc. + @param name The algorithm name, one of the names returned by Algorithm::getList(). + */ template static Ptr<_Tp> create(const String& name); virtual AlgorithmInfo* info() const /* TODO: make it = 0;*/ { return 0; } }; - +/** @todo document */ class CV_EXPORTS AlgorithmInfo { public: @@ -1032,7 +3158,7 @@ protected: const void* value, bool force=false) const; }; - +/** @todo document */ struct CV_EXPORTS Param { enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, UNSIGNED_INT=8, UINT64=9, UCHAR=11 }; @@ -1138,6 +3264,8 @@ template<> struct ParamType enum { type = Param::UCHAR }; }; +//! @} core_basic + } //namespace cv #include "opencv2/core/operations.hpp" diff --git a/modules/core/include/opencv2/core/affine.hpp b/modules/core/include/opencv2/core/affine.hpp index 172f5297c6ce1fc8191b95e5a95d038aff27972b..f8e84b97ad5b45feb09345a887d150fac9539028 100644 --- a/modules/core/include/opencv2/core/affine.hpp +++ b/modules/core/include/opencv2/core/affine.hpp @@ -48,10 +48,15 @@ #include -/*! @file */ - namespace cv { + +//! @addtogroup core +//! @{ + + /** @brief Affine transform + @todo document + */ template 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 operator Affine3() const; @@ -155,11 +161,15 @@ namespace cv typedef Vec vec_type; }; + +//! @} core + } +//! @cond IGNORED /////////////////////////////////////////////////////////////////////////////////// -/// Implementaiton +// Implementaiton template inline cv::Affine3::Affine3() @@ -431,7 +441,6 @@ cv::Affine3 cv::Affine3::cast() const return Affine3(matrix); } -/** @cond IGNORED */ template inline cv::Affine3 cv::operator*(const cv::Affine3& affine1, const cv::Affine3& affine2) { @@ -449,7 +458,6 @@ V cv::operator*(const cv::Affine3& 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::operator Eigen::Transform() const #endif /* defined EIGEN_WORLD_VERSION && defined EIGEN_GEOMETRY_MODULE_H */ +//! @endcond #endif /* __cplusplus */ diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index d39b47259e36cdd2814b7f166ddee2c2eb82e447..5b3ef205cc730faac3b5d246895770a9b2977bd5 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -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 - }; - -// 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 - }; - -// comparison types -enum { CMP_EQ = 0, - CMP_GT = 1, - CMP_GE = 2, - CMP_LT = 3, - CMP_LE = 4, - CMP_NE = 5 - }; - -enum { GEMM_1_T = 1, - GEMM_2_T = 2, - GEMM_3_T = 4 - }; - -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 - }; - -//! 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 - - BORDER_REFLECT101 = BORDER_REFLECT_101, - BORDER_DEFAULT = BORDER_REFLECT_101, - BORDER_ISOLATED = 16 // do not look outside of ROI - }; +//! @} core_utils + +//! @addtogroup core_array +//! @{ + +//! 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 +}; +/** 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] + +- 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] + +- 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 + }; + +//! 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 +}; -//////////////// static assert ///////////////// +//! @} 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__) @@ -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\() +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(-100); // a = 0 (UCHAR_MIN) + short b = saturate_cast(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 static inline _Tp saturate_cast(uchar v) { return _Tp(v); } +/** @overload */ template static inline _Tp saturate_cast(schar v) { return _Tp(v); } +/** @overload */ template static inline _Tp saturate_cast(ushort v) { return _Tp(v); } +/** @overload */ template static inline _Tp saturate_cast(short v) { return _Tp(v); } +/** @overload */ template static inline _Tp saturate_cast(unsigned v) { return _Tp(v); } +/** @overload */ template static inline _Tp saturate_cast(int v) { return _Tp(v); } +/** @overload */ template static inline _Tp saturate_cast(float v) { return _Tp(v); } +/** @overload */ template static inline _Tp saturate_cast(double v) { return _Tp(v); } +//! @cond IGNORED + template<> inline uchar saturate_cast(schar v) { return (uchar)std::max((int)v, 0); } template<> inline uchar saturate_cast(ushort v) { return (uchar)std::min((unsigned)v, (unsigned)UCHAR_MAX); } template<> inline uchar saturate_cast(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } @@ -341,7 +480,7 @@ template<> inline int saturate_cast(double v) { return cvRound(v) template<> inline unsigned saturate_cast(float v) { return cvRound(v); } template<> inline unsigned saturate_cast(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) -CV_EXPORTS_W float fastAtan2(float y, float x); +/** @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 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 class Vec; template 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) @@ -649,6 +809,8 @@ inline float32x2_t cv_vsqrt_f32(float32x2_t val) #endif +//! @} core_utils_neon + } // cv #endif //__OPENCV_CORE_BASE_HPP__ diff --git a/modules/core/include/opencv2/core/bufferpool.hpp b/modules/core/include/opencv2/core/bufferpool.hpp index c2de95a9f2aa1e06e841a2c1cc2decec56f76264..76df2d29fb5b607d2cec72af7944bbba20e0b395 100644 --- a/modules/core/include/opencv2/core/bufferpool.hpp +++ b/modules/core/include/opencv2/core/bufferpool.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__ diff --git a/modules/core/include/opencv2/core/core_c.h b/modules/core/include/opencv2/core/core_c.h index 61a93a46e9ee7f25531aa7eee3728ac9fbf3f23c..a0ed632642c98d4129ef54cc0198f06ed1c2bc92 100644 --- a/modules/core/include/opencv2/core/core_c.h +++ b/modules/core/include/opencv2/core/core_c.h @@ -65,17 +65,21 @@ extern "C" { #endif +/** @addtogroup core_c + @{ +*/ + /****************************************************************************************\ * Array allocation, deallocation, initialization and access to elements * \****************************************************************************************/ -/* wrapper. +/** `malloc` wrapper. If there is no enough memory, the function (as well as other OpenCV functions that call cvAlloc) raises an error. */ CVAPI(void*) cvAlloc( size_t size ); -/* wrapper. +/** `free` wrapper. Here and further all the memory releasing functions (that all call cvFree) take double pointer in order to to clear pointer to the data after releasing it. @@ -84,61 +88,213 @@ CVAPI(void*) cvAlloc( size_t size ); CVAPI(void) cvFree_( void* ptr ); #define cvFree(ptr) (cvFree_(*(ptr)), *(ptr)=0) -/* Allocates and initializes IplImage header */ +/** @brief Creates an image header but does not allocate the image data. + +@param size Image width and height +@param depth Image depth (see cvCreateImage ) +@param channels Number of channels (see cvCreateImage ) + */ CVAPI(IplImage*) cvCreateImageHeader( CvSize size, int depth, int channels ); -/* Inializes IplImage header */ +/** @brief Initializes an image header that was previously allocated. + +The returned IplImage\* points to the initialized header. +@param image Image header to initialize +@param size Image width and height +@param depth Image depth (see cvCreateImage ) +@param channels Number of channels (see cvCreateImage ) +@param origin Top-left IPL_ORIGIN_TL or bottom-left IPL_ORIGIN_BL +@param align Alignment for image rows, typically 4 or 8 bytes + */ CVAPI(IplImage*) cvInitImageHeader( IplImage* image, CvSize size, int depth, int channels, int origin CV_DEFAULT(0), int align CV_DEFAULT(4)); -/* Creates IPL image (header and data) */ +/** @brief Creates an image header and allocates the image data. + +This function call is equivalent to the following code: +@code + header = cvCreateImageHeader(size, depth, channels); + cvCreateData(header); +@endcode +@param size Image width and height +@param depth Bit depth of image elements. See IplImage for valid depths. +@param channels Number of channels per pixel. See IplImage for details. This function only creates +images with interleaved channels. + */ CVAPI(IplImage*) cvCreateImage( CvSize size, int depth, int channels ); -/* Releases (i.e. deallocates) IPL image header */ +/** @brief Deallocates an image header. + +This call is an analogue of : +@code + if(image ) + { + iplDeallocate(*image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI); + *image = 0; + } +@endcode +but it does not use IPL functions by default (see the CV_TURN_ON_IPL_COMPATIBILITY macro). +@param image Double pointer to the image header + */ CVAPI(void) cvReleaseImageHeader( IplImage** image ); -/* Releases IPL image header and data */ +/** @brief Deallocates the image header and the image data. + +This call is a shortened form of : +@code + if(*image ) + { + cvReleaseData(*image); + cvReleaseImageHeader(image); + } +@endcode +@param image Double pointer to the image header +*/ CVAPI(void) cvReleaseImage( IplImage** image ); -/* Creates a copy of IPL image (widthStep may differ) */ +/** Creates a copy of IPL image (widthStep may differ) */ CVAPI(IplImage*) cvCloneImage( const IplImage* image ); -/* Sets a Channel Of Interest (only a few functions support COI) - - use cvCopy to extract the selected channel and/or put it back */ +/** @brief Sets the channel of interest in an IplImage. + +If the ROI is set to NULL and the coi is *not* 0, the ROI is allocated. Most OpenCV functions do +*not* support the COI setting, so to process an individual image/matrix channel one may copy (via +cvCopy or cvSplit) the channel to a separate image/matrix, process it and then copy the result +back (via cvCopy or cvMerge) if needed. +@param image A pointer to the image header +@param coi The channel of interest. 0 - all channels are selected, 1 - first channel is selected, +etc. Note that the channel indices become 1-based. + */ CVAPI(void) cvSetImageCOI( IplImage* image, int coi ); -/* Retrieves image Channel Of Interest */ +/** @brief Returns the index of the channel of interest. + +Returns the channel of interest of in an IplImage. Returned values correspond to the coi in +cvSetImageCOI. +@param image A pointer to the image header + */ CVAPI(int) cvGetImageCOI( const IplImage* image ); -/* Sets image ROI (region of interest) (COI is not changed) */ +/** @brief Sets an image Region Of Interest (ROI) for a given rectangle. + +If the original image ROI was NULL and the rect is not the whole image, the ROI structure is +allocated. + +Most OpenCV functions support the use of ROI and treat the image rectangle as a separate image. For +example, all of the pixel coordinates are counted from the top-left (or bottom-left) corner of the +ROI, not the original image. +@param image A pointer to the image header +@param rect The ROI rectangle + */ CVAPI(void) cvSetImageROI( IplImage* image, CvRect rect ); -/* Resets image ROI and COI */ +/** @brief Resets the image ROI to include the entire image and releases the ROI structure. + +This produces a similar result to the following, but in addition it releases the ROI structure. : +@code + cvSetImageROI(image, cvRect(0, 0, image->width, image->height )); + cvSetImageCOI(image, 0); +@endcode +@param image A pointer to the image header + */ CVAPI(void) cvResetImageROI( IplImage* image ); -/* Retrieves image ROI */ +/** @brief Returns the image ROI. + +If there is no ROI set, cvRect(0,0,image-\>width,image-\>height) is returned. +@param image A pointer to the image header + */ CVAPI(CvRect) cvGetImageROI( const IplImage* image ); -/* Allocates and initializes CvMat header */ +/** @brief Creates a matrix header but does not allocate the matrix data. + +The function allocates a new matrix header and returns a pointer to it. The matrix data can then be +allocated using cvCreateData or set explicitly to user-allocated data via cvSetData. +@param rows Number of rows in the matrix +@param cols Number of columns in the matrix +@param type Type of the matrix elements, see cvCreateMat + */ CVAPI(CvMat*) cvCreateMatHeader( int rows, int cols, int type ); #define CV_AUTOSTEP 0x7fffffff -/* Initializes CvMat header */ +/** @brief Initializes a pre-allocated matrix header. + +This function is often used to process raw data with OpenCV matrix functions. For example, the +following code computes the matrix product of two matrices, stored as ordinary arrays: +@code + double a[] = { 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12 }; + + double b[] = { 1, 5, 9, + 2, 6, 10, + 3, 7, 11, + 4, 8, 12 }; + + double c[9]; + CvMat Ma, Mb, Mc ; + + cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a); + cvInitMatHeader(&Mb, 4, 3, CV_64FC1, b); + cvInitMatHeader(&Mc, 3, 3, CV_64FC1, c); + + cvMatMulAdd(&Ma, &Mb, 0, &Mc); + // the c array now contains the product of a (3x4) and b (4x3) +@endcode +@param mat A pointer to the matrix header to be initialized +@param rows Number of rows in the matrix +@param cols Number of columns in the matrix +@param type Type of the matrix elements, see cvCreateMat . +@param data Optional: data pointer assigned to the matrix header +@param step Optional: full row width in bytes of the assigned data. By default, the minimal +possible step is used which assumes there are no gaps between subsequent rows of the matrix. + */ CVAPI(CvMat*) cvInitMatHeader( CvMat* mat, int rows, int cols, int type, void* data CV_DEFAULT(NULL), int step CV_DEFAULT(CV_AUTOSTEP) ); -/* Allocates and initializes CvMat header and allocates data */ +/** @brief Creates a matrix header and allocates the matrix data. + +The function call is equivalent to the following code: +@code + CvMat* mat = cvCreateMatHeader(rows, cols, type); + cvCreateData(mat); +@endcode +@param rows Number of rows in the matrix +@param cols Number of columns in the matrix +@param type The type of the matrix elements in the form +CV_\\C\ , where S=signed, U=unsigned, F=float. For +example, CV _ 8UC1 means the elements are 8-bit unsigned and the there is 1 channel, and CV _ +32SC2 means the elements are 32-bit signed and there are 2 channels. + */ CVAPI(CvMat*) cvCreateMat( int rows, int cols, int type ); -/* Releases CvMat header and deallocates matrix data - (reference counting is used for data) */ +/** @brief Deallocates a matrix. + +The function decrements the matrix data reference counter and deallocates matrix header. If the data +reference counter is 0, it also deallocates the data. : +@code + if(*mat ) + cvDecRefData(*mat); + cvFree((void**)mat); +@endcode +@param mat Double pointer to the matrix + */ CVAPI(void) cvReleaseMat( CvMat** mat ); -/* Decrements CvMat data reference counter and deallocates the data if - it reaches 0 */ +/** @brief Decrements an array data reference counter. + +The function decrements the data reference counter in a CvMat or CvMatND if the reference counter + +pointer is not NULL. If the counter reaches zero, the data is deallocated. In the current +implementation the reference counter is not NULL only if the data was allocated using the +cvCreateData function. The counter will be NULL in other cases such as: external data was assigned +to the header using cvSetData, header is part of a larger matrix or image, or the header was +converted from an image or n-dimensional matrix header. +@param arr Pointer to an array header + */ CV_INLINE void cvDecRefData( CvArr* arr ) { if( CV_IS_MAT( arr )) @@ -159,7 +315,12 @@ CV_INLINE void cvDecRefData( CvArr* arr ) } } -/* Increments CvMat data reference counter */ +/** @brief Increments array data reference counter. + +The function increments CvMat or CvMatND data reference counter and returns the new counter value if +the reference counter pointer is not NULL, otherwise it returns zero. +@param arr Array header + */ CV_INLINE int cvIncRefData( CvArr* arr ) { int refcount = 0; @@ -179,84 +340,205 @@ CV_INLINE int cvIncRefData( CvArr* arr ) } -/* Creates an exact copy of the input matrix (except, may be, step value) */ +/** Creates an exact copy of the input matrix (except, may be, step value) */ CVAPI(CvMat*) cvCloneMat( const CvMat* mat ); -/* Makes a new matrix from subrectangle of input array. - No data is copied */ +/** @brief Returns matrix header corresponding to the rectangular sub-array of input image or matrix. + +The function returns header, corresponding to a specified rectangle of the input array. In other + +words, it allows the user to treat a rectangular part of input array as a stand-alone array. ROI is +taken into account by the function so the sub-array of ROI is actually extracted. +@param arr Input array +@param submat Pointer to the resultant sub-array header +@param rect Zero-based coordinates of the rectangle of interest + */ CVAPI(CvMat*) cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect ); #define cvGetSubArr cvGetSubRect -/* Selects row span of the input array: arr(start_row:delta_row:end_row,:) - (end_row is not included into the span). */ +/** @brief Returns array row or row span. + +The functions return the header, corresponding to a specified row/row span of the input array. +cvGetRow(arr, submat, row) is a shortcut for cvGetRows(arr, submat, row, row+1). +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param start_row Zero-based index of the starting row (inclusive) of the span +@param end_row Zero-based index of the ending row (exclusive) of the span +@param delta_row Index step in the row span. That is, the function extracts every delta_row -th +row from start_row and up to (but not including) end_row . + */ CVAPI(CvMat*) cvGetRows( const CvArr* arr, CvMat* submat, int start_row, int end_row, int delta_row CV_DEFAULT(1)); +/** @overload +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param row Zero-based index of the selected row +*/ CV_INLINE CvMat* cvGetRow( const CvArr* arr, CvMat* submat, int row ) { return cvGetRows( arr, submat, row, row + 1, 1 ); } -/* Selects column span of the input array: arr(:,start_col:end_col) - (end_col is not included into the span) */ +/** @brief Returns one of more array columns. + +The functions return the header, corresponding to a specified column span of the input array. That + +is, no data is copied. Therefore, any modifications of the submatrix will affect the original array. +If you need to copy the columns, use cvCloneMat. cvGetCol(arr, submat, col) is a shortcut for +cvGetCols(arr, submat, col, col+1). +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param start_col Zero-based index of the starting column (inclusive) of the span +@param end_col Zero-based index of the ending column (exclusive) of the span + */ CVAPI(CvMat*) cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col ); +/** @overload +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param col Zero-based index of the selected column +*/ CV_INLINE CvMat* cvGetCol( const CvArr* arr, CvMat* submat, int col ) { return cvGetCols( arr, submat, col, col + 1 ); } -/* Select a diagonal of the input array. - (diag = 0 means the main diagonal, >0 means a diagonal above the main one, - <0 - below the main one). - The diagonal will be represented as a column (nx1 matrix). */ +/** @brief Returns one of array diagonals. + +The function returns the header, corresponding to a specified diagonal of the input array. +@param arr Input array +@param submat Pointer to the resulting sub-array header +@param diag Index of the array diagonal. Zero value corresponds to the main diagonal, -1 +corresponds to the diagonal above the main, 1 corresponds to the diagonal below the main, and so +forth. + */ CVAPI(CvMat*) cvGetDiag( const CvArr* arr, CvMat* submat, int diag CV_DEFAULT(0)); -/* low-level scalar <-> raw data conversion functions */ +/** low-level scalar <-> raw data conversion functions */ CVAPI(void) cvScalarToRawData( const CvScalar* scalar, void* data, int type, int extend_to_12 CV_DEFAULT(0) ); CVAPI(void) cvRawDataToScalar( const void* data, int type, CvScalar* scalar ); -/* Allocates and initializes CvMatND header */ +/** @brief Creates a new matrix header but does not allocate the matrix data. + +The function allocates a header for a multi-dimensional dense array. The array data can further be +allocated using cvCreateData or set explicitly to user-allocated data via cvSetData. +@param dims Number of array dimensions +@param sizes Array of dimension sizes +@param type Type of array elements, see cvCreateMat + */ CVAPI(CvMatND*) cvCreateMatNDHeader( int dims, const int* sizes, int type ); -/* Allocates and initializes CvMatND header and allocates data */ +/** @brief Creates the header and allocates the data for a multi-dimensional dense array. + +This function call is equivalent to the following code: +@code + CvMatND* mat = cvCreateMatNDHeader(dims, sizes, type); + cvCreateData(mat); +@endcode +@param dims Number of array dimensions. This must not exceed CV_MAX_DIM (32 by default, but can be +changed at build time). +@param sizes Array of dimension sizes. +@param type Type of array elements, see cvCreateMat . + */ CVAPI(CvMatND*) cvCreateMatND( int dims, const int* sizes, int type ); -/* Initializes preallocated CvMatND header */ +/** @brief Initializes a pre-allocated multi-dimensional array header. + +@param mat A pointer to the array header to be initialized +@param dims The number of array dimensions +@param sizes An array of dimension sizes +@param type Type of array elements, see cvCreateMat +@param data Optional data pointer assigned to the matrix header + */ CVAPI(CvMatND*) cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int type, void* data CV_DEFAULT(NULL) ); -/* Releases CvMatND */ +/** @brief Deallocates a multi-dimensional array. + +The function decrements the array data reference counter and releases the array header. If the +reference counter reaches 0, it also deallocates the data. : +@code + if(*mat ) + cvDecRefData(*mat); + cvFree((void**)mat); +@endcode +@param mat Double pointer to the array + */ CV_INLINE void cvReleaseMatND( CvMatND** mat ) { cvReleaseMat( (CvMat**)mat ); } -/* Creates a copy of CvMatND (except, may be, steps) */ +/** Creates a copy of CvMatND (except, may be, steps) */ CVAPI(CvMatND*) cvCloneMatND( const CvMatND* mat ); -/* Allocates and initializes CvSparseMat header and allocates data */ +/** @brief Creates sparse array. + +The function allocates a multi-dimensional sparse array. Initially the array contain no elements, +that is PtrND and other related functions will return 0 for every index. +@param dims Number of array dimensions. In contrast to the dense matrix, the number of dimensions is +practically unlimited (up to \f$2^{16}\f$ ). +@param sizes Array of dimension sizes +@param type Type of array elements. The same as for CvMat + */ CVAPI(CvSparseMat*) cvCreateSparseMat( int dims, const int* sizes, int type ); -/* Releases CvSparseMat */ +/** @brief Deallocates sparse array. + +The function releases the sparse array and clears the array pointer upon exit. +@param mat Double pointer to the array + */ CVAPI(void) cvReleaseSparseMat( CvSparseMat** mat ); -/* Creates a copy of CvSparseMat (except, may be, zero items) */ +/** Creates a copy of CvSparseMat (except, may be, zero items) */ CVAPI(CvSparseMat*) cvCloneSparseMat( const CvSparseMat* mat ); -/* Initializes sparse array iterator - (returns the first node or NULL if the array is empty) */ +/** @brief Initializes sparse array elements iterator. + +The function initializes iterator of sparse array elements and returns pointer to the first element, +or NULL if the array is empty. +@param mat Input array +@param mat_iterator Initialized iterator + */ CVAPI(CvSparseNode*) cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* mat_iterator ); -// returns next sparse array node (or NULL if there is no more nodes) +/** @brief Returns the next sparse matrix element + +The function moves iterator to the next sparse matrix element and returns pointer to it. In the +current version there is no any particular order of the elements, because they are stored in the +hash table. The sample below demonstrates how to iterate through the sparse matrix: +@code + // print all the non-zero sparse matrix elements and compute their sum + double sum = 0; + int i, dims = cvGetDims(sparsemat); + CvSparseMatIterator it; + CvSparseNode* node = cvInitSparseMatIterator(sparsemat, &it); + + for(; node != 0; node = cvGetNextSparseNode(&it)) + { + int* idx = CV_NODE_IDX(array, node); + float val = *(float*)CV_NODE_VAL(array, node); + printf("M"); + for(i = 0; i < dims; i++ ) + printf("[%d]", idx[i]); + printf("=%g\n", val); + + sum += val; + } + + printf("nTotal sum = %g\n", sum); +@endcode +@param mat_iterator Sparse array iterator + */ CV_INLINE CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator ) { if( mat_iterator->node->next ) @@ -277,18 +559,18 @@ CV_INLINE CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator ) } } -/**************** matrix iterator: used for n-ary operations on dense arrays *********/ #define CV_MAX_ARR 10 +/** matrix iterator: used for n-ary operations on dense arrays */ typedef struct CvNArrayIterator { - int count; /* number of arrays */ - int dims; /* number of dimensions to iterate */ - CvSize size; /* maximal common linear size: { width = size, height = 1 } */ - uchar* ptr[CV_MAX_ARR]; /* pointers to the array slices */ - int stack[CV_MAX_DIM]; /* for internal use */ - CvMatND* hdr[CV_MAX_ARR]; /* pointers to the headers of the + int count; /**< number of arrays */ + int dims; /**< number of dimensions to iterate */ + CvSize size; /**< maximal common linear size: { width = size, height = 1 } */ + uchar* ptr[CV_MAX_ARR]; /**< pointers to the array slices */ + int stack[CV_MAX_DIM]; /**< for internal use */ + CvMatND* hdr[CV_MAX_ARR]; /**< pointers to the headers of the matrices that are processed */ } CvNArrayIterator; @@ -297,7 +579,7 @@ CvNArrayIterator; #define CV_NO_CN_CHECK 2 #define CV_NO_SIZE_CHECK 4 -/* initializes iterator that traverses through several arrays simulteneously +/** initializes iterator that traverses through several arrays simulteneously (the function together with cvNextArraySlice is used for N-ari element-wise operations) */ CVAPI(int) cvInitNArrayIterator( int count, CvArr** arrs, @@ -305,92 +587,248 @@ CVAPI(int) cvInitNArrayIterator( int count, CvArr** arrs, CvNArrayIterator* array_iterator, int flags CV_DEFAULT(0) ); -/* returns zero value if iteration is finished, non-zero (slice length) otherwise */ +/** returns zero value if iteration is finished, non-zero (slice length) otherwise */ CVAPI(int) cvNextNArraySlice( CvNArrayIterator* array_iterator ); -/* Returns type of array elements: - CV_8UC1 ... CV_64FC4 ... */ +/** @brief Returns type of array elements. + +The function returns type of the array elements. In the case of IplImage the type is converted to +CvMat-like representation. For example, if the image has been created as: +@code + IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); +@endcode +The code cvGetElemType(img) will return CV_8UC3. +@param arr Input array + */ CVAPI(int) cvGetElemType( const CvArr* arr ); -/* Retrieves number of an array dimensions and - optionally sizes of the dimensions */ +/** @brief Return number of array dimensions + +The function returns the array dimensionality and the array of dimension sizes. In the case of +IplImage or CvMat it always returns 2 regardless of number of image/matrix rows. For example, the +following code calculates total number of array elements: +@code + int sizes[CV_MAX_DIM]; + int i, total = 1; + int dims = cvGetDims(arr, size); + for(i = 0; i < dims; i++ ) + total *= sizes[i]; +@endcode +@param arr Input array +@param sizes Optional output vector of the array dimension sizes. For 2d arrays the number of rows +(height) goes first, number of columns (width) next. + */ CVAPI(int) cvGetDims( const CvArr* arr, int* sizes CV_DEFAULT(NULL) ); -/* Retrieves size of a particular array dimension. - For 2d arrays cvGetDimSize(arr,0) returns number of rows (image height) - and cvGetDimSize(arr,1) returns number of columns (image width) */ +/** @brief Returns array size along the specified dimension. + +@param arr Input array +@param index Zero-based dimension index (for matrices 0 means number of rows, 1 means number of +columns; for images 0 means height, 1 means width) + */ CVAPI(int) cvGetDimSize( const CvArr* arr, int index ); -/* ptr = &arr(idx0,idx1,...). All indexes are zero-based, - the major dimensions go first (e.g. (y,x) for 2D, (z,y,x) for 3D */ +/** @brief Return pointer to a particular array element. + +The functions return a pointer to a specific array element. Number of array dimension should match +to the number of indices passed to the function except for cvPtr1D function that can be used for +sequential access to 1D, 2D or nD dense arrays. + +The functions can be used for sparse arrays as well - if the requested node does not exist they +create it and set it to zero. + +All these as well as other functions accessing array elements ( cvGetND , cvGetRealND , cvSet +, cvSetND , cvSetRealND ) raise an error in case if the element index is out of range. +@param arr Input array +@param idx0 The first zero-based component of the element index +@param type Optional output parameter: type of matrix elements + */ CVAPI(uchar*) cvPtr1D( const CvArr* arr, int idx0, int* type CV_DEFAULT(NULL)); +/** @overload */ CVAPI(uchar*) cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type CV_DEFAULT(NULL) ); +/** @overload */ CVAPI(uchar*) cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, int* type CV_DEFAULT(NULL)); - -/* For CvMat or IplImage number of indices should be 2 - (row index (y) goes first, column index (x) goes next). - For CvMatND or CvSparseMat number of infices should match number of and - indices order should match the array dimension order. */ +/** @overload +@param arr Input array +@param idx Array of the element indices +@param type Optional output parameter: type of matrix elements +@param create_node Optional input parameter for sparse matrices. Non-zero value of the parameter +means that the requested element is created if it does not exist already. +@param precalc_hashval Optional input parameter for sparse matrices. If the pointer is not NULL, +the function does not recalculate the node hash value, but takes it from the specified location. +It is useful for speeding up pair-wise operations (TODO: provide an example) +*/ CVAPI(uchar*) cvPtrND( const CvArr* arr, const int* idx, int* type CV_DEFAULT(NULL), int create_node CV_DEFAULT(1), unsigned* precalc_hashval CV_DEFAULT(NULL)); -/* value = arr(idx0,idx1,...) */ +/** @brief Return a specific array element. + +The functions return a specific array element. In the case of a sparse array the functions return 0 +if the requested node does not exist (no new node is created by the functions). +@param arr Input array +@param idx0 The first zero-based component of the element index + */ CVAPI(CvScalar) cvGet1D( const CvArr* arr, int idx0 ); +/** @overload */ CVAPI(CvScalar) cvGet2D( const CvArr* arr, int idx0, int idx1 ); +/** @overload */ CVAPI(CvScalar) cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 ); +/** @overload +@param arr Input array +@param idx Array of the element indices +*/ CVAPI(CvScalar) cvGetND( const CvArr* arr, const int* idx ); -/* for 1-channel arrays */ +/** @brief Return a specific element of single-channel 1D, 2D, 3D or nD array. + +Returns a specific element of a single-channel array. If the array has multiple channels, a runtime +error is raised. Note that Get?D functions can be used safely for both single-channel and +multiple-channel arrays though they are a bit slower. + +In the case of a sparse array the functions return 0 if the requested node does not exist (no new +node is created by the functions). +@param arr Input array. Must have a single channel. +@param idx0 The first zero-based component of the element index + */ CVAPI(double) cvGetReal1D( const CvArr* arr, int idx0 ); +/** @overload */ CVAPI(double) cvGetReal2D( const CvArr* arr, int idx0, int idx1 ); +/** @overload */ CVAPI(double) cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 ); +/** @overload +@param arr Input array. Must have a single channel. +@param idx Array of the element indices +*/ CVAPI(double) cvGetRealND( const CvArr* arr, const int* idx ); -/* arr(idx0,idx1,...) = value */ +/** @brief Change the particular array element. + +The functions assign the new value to a particular array element. In the case of a sparse array the +functions create the node if it does not exist yet. +@param arr Input array +@param idx0 The first zero-based component of the element index +@param value The assigned value + */ CVAPI(void) cvSet1D( CvArr* arr, int idx0, CvScalar value ); +/** @overload */ CVAPI(void) cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value ); +/** @overload */ CVAPI(void) cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value ); +/** @overload +@param arr Input array +@param idx Array of the element indices +@param value The assigned value +*/ CVAPI(void) cvSetND( CvArr* arr, const int* idx, CvScalar value ); -/* for 1-channel arrays */ +/** @brief Change a specific array element. + +The functions assign a new value to a specific element of a single-channel array. If the array has +multiple channels, a runtime error is raised. Note that the Set\*D function can be used safely for +both single-channel and multiple-channel arrays, though they are a bit slower. + +In the case of a sparse array the functions create the node if it does not yet exist. +@param arr Input array +@param idx0 The first zero-based component of the element index +@param value The assigned value + */ CVAPI(void) cvSetReal1D( CvArr* arr, int idx0, double value ); +/** @overload */ CVAPI(void) cvSetReal2D( CvArr* arr, int idx0, int idx1, double value ); +/** @overload */ CVAPI(void) cvSetReal3D( CvArr* arr, int idx0, int idx1, int idx2, double value ); +/** @overload +@param arr Input array +@param idx Array of the element indices +@param value The assigned value +*/ CVAPI(void) cvSetRealND( CvArr* arr, const int* idx, double value ); -/* clears element of ND dense array, +/** clears element of ND dense array, in case of sparse arrays it deletes the specified node */ CVAPI(void) cvClearND( CvArr* arr, const int* idx ); -/* Converts CvArr (IplImage or CvMat,...) to CvMat. - If the last parameter is non-zero, function can - convert multi(>2)-dimensional array to CvMat as long as - the last array's dimension is continous. The resultant - matrix will be have appropriate (a huge) number of rows */ +/** @brief Returns matrix header for arbitrary array. + +The function returns a matrix header for the input array that can be a matrix - CvMat, an image - +IplImage, or a multi-dimensional dense array - CvMatND (the third option is allowed only if +allowND != 0) . In the case of matrix the function simply returns the input pointer. In the case of +IplImage\* or CvMatND it initializes the header structure with parameters of the current image ROI +and returns &header. Because COI is not supported by CvMat, it is returned separately. + +The function provides an easy way to handle both types of arrays - IplImage and CvMat using the same +code. Input array must have non-zero data pointer, otherwise the function will report an error. + +@note If the input array is IplImage with planar data layout and COI set, the function returns the +pointer to the selected plane and COI == 0. This feature allows user to process IplImage structures +with planar data layout, even though OpenCV does not support such images. +@param arr Input array +@param header Pointer to CvMat structure used as a temporary buffer +@param coi Optional output parameter for storing COI +@param allowND If non-zero, the function accepts multi-dimensional dense arrays (CvMatND\*) and +returns 2D matrix (if CvMatND has two dimensions) or 1D matrix (when CvMatND has 1 dimension or +more than 2 dimensions). The CvMatND array must be continuous. +@sa cvGetImage, cvarrToMat. + */ CVAPI(CvMat*) cvGetMat( const CvArr* arr, CvMat* header, int* coi CV_DEFAULT(NULL), int allowND CV_DEFAULT(0)); -/* Converts CvArr (IplImage or CvMat) to IplImage */ +/** @brief Returns image header for arbitrary array. + +The function returns the image header for the input array that can be a matrix (CvMat) or image +(IplImage). In the case of an image the function simply returns the input pointer. In the case of +CvMat it initializes an image_header structure with the parameters of the input matrix. Note that +if we transform IplImage to CvMat using cvGetMat and then transform CvMat back to IplImage using +this function, we will get different headers if the ROI is set in the original image. +@param arr Input array +@param image_header Pointer to IplImage structure used as a temporary buffer + */ CVAPI(IplImage*) cvGetImage( const CvArr* arr, IplImage* image_header ); -/* Changes a shape of multi-dimensional array. - new_cn == 0 means that number of channels remains unchanged. - new_dims == 0 means that number and sizes of dimensions remain the same - (unless they need to be changed to set the new number of channels) - if new_dims == 1, there is no need to specify new dimension sizes - The resultant configuration should be achievable w/o data copying. - If the resultant array is sparse, CvSparseMat header should be passed - to the function else if the result is 1 or 2 dimensional, - CvMat header should be passed to the function - else CvMatND header should be passed */ +/** @brief Changes the shape of a multi-dimensional array without copying the data. + +The function is an advanced version of cvReshape that can work with multi-dimensional arrays as +well (though it can work with ordinary images and matrices) and change the number of dimensions. + +Below are the two samples from the cvReshape description rewritten using cvReshapeMatND: +@code + IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); + IplImage gray_img_hdr, *gray_img; + gray_img = (IplImage*)cvReshapeMatND(color_img, sizeof(gray_img_hdr), &gray_img_hdr, 1, 0, 0); + ... + int size[] = { 2, 2, 2 }; + CvMatND* mat = cvCreateMatND(3, size, CV_32F); + CvMat row_header, *row; + row = (CvMat*)cvReshapeMatND(mat, sizeof(row_header), &row_header, 0, 1, 0); +@endcode +In C, the header file for this function includes a convenient macro cvReshapeND that does away with +the sizeof_header parameter. So, the lines containing the call to cvReshapeMatND in the examples +may be replaced as follow: +@code + gray_img = (IplImage*)cvReshapeND(color_img, &gray_img_hdr, 1, 0, 0); + ... + row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0); +@endcode +@param arr Input array +@param sizeof_header Size of output header to distinguish between IplImage, CvMat and CvMatND +output headers +@param header Output header to be filled +@param new_cn New number of channels. new_cn = 0 means that the number of channels remains +unchanged. +@param new_dims New number of dimensions. new_dims = 0 means that the number of dimensions +remains the same. +@param new_sizes Array of new dimension sizes. Only new_dims-1 values are used, because the +total number of elements must remain the same. Thus, if new_dims = 1, new_sizes array is not +used. + */ CVAPI(CvArr*) cvReshapeMatND( const CvArr* arr, int sizeof_header, CvArr* header, int new_cn, int new_dims, int* new_sizes ); @@ -399,70 +837,184 @@ CVAPI(CvArr*) cvReshapeMatND( const CvArr* arr, cvReshapeMatND( (arr), sizeof(*(header)), (header), \ (new_cn), (new_dims), (new_sizes)) +/** @brief Changes shape of matrix/image without copying data. + +The function initializes the CvMat header so that it points to the same data as the original array +but has a different shape - different number of channels, different number of rows, or both. + +The following example code creates one image buffer and two image headers, the first is for a +320x240x3 image and the second is for a 960x240x1 image: +@code + IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); + CvMat gray_mat_hdr; + IplImage gray_img_hdr, *gray_img; + cvReshape(color_img, &gray_mat_hdr, 1); + gray_img = cvGetImage(&gray_mat_hdr, &gray_img_hdr); +@endcode +And the next example converts a 3x3 matrix to a single 1x9 vector: +@code + CvMat* mat = cvCreateMat(3, 3, CV_32F); + CvMat row_header, *row; + row = cvReshape(mat, &row_header, 0, 1); +@endcode +@param arr Input array +@param header Output header to be filled +@param new_cn New number of channels. 'new_cn = 0' means that the number of channels remains +unchanged. +@param new_rows New number of rows. 'new_rows = 0' means that the number of rows remains +unchanged unless it needs to be changed according to new_cn value. +*/ CVAPI(CvMat*) cvReshape( const CvArr* arr, CvMat* header, int new_cn, int new_rows CV_DEFAULT(0) ); -/* Repeats source 2d array several times in both horizontal and +/** Repeats source 2d array several times in both horizontal and vertical direction to fill destination array */ CVAPI(void) cvRepeat( const CvArr* src, CvArr* dst ); -/* Allocates array data */ +/** @brief Allocates array data + +The function allocates image, matrix or multi-dimensional dense array data. Note that in the case of +matrix types OpenCV allocation functions are used. In the case of IplImage they are used unless +CV_TURN_ON_IPL_COMPATIBILITY() has been called before. In the latter case IPL functions are used +to allocate the data. +@param arr Array header + */ CVAPI(void) cvCreateData( CvArr* arr ); -/* Releases array data */ +/** @brief Releases array data. + +The function releases the array data. In the case of CvMat or CvMatND it simply calls +cvDecRefData(), that is the function can not deallocate external data. See also the note to +cvCreateData . +@param arr Array header + */ CVAPI(void) cvReleaseData( CvArr* arr ); -/* Attaches user data to the array header. The step is reffered to - the pre-last dimension. That is, all the planes of the array - must be joint (w/o gaps) */ +/** @brief Assigns user data to the array header. + +The function assigns user data to the array header. Header should be initialized before using +cvCreateMatHeader, cvCreateImageHeader, cvCreateMatNDHeader, cvInitMatHeader, +cvInitImageHeader or cvInitMatNDHeader. +@param arr Array header +@param data User data +@param step Full row length in bytes + */ CVAPI(void) cvSetData( CvArr* arr, void* data, int step ); -/* Retrieves raw data of CvMat, IplImage or CvMatND. - In the latter case the function raises an error if - the array can not be represented as a matrix */ +/** @brief Retrieves low-level information about the array. + +The function fills output variables with low-level information about the array data. All output + +parameters are optional, so some of the pointers may be set to NULL. If the array is IplImage with +ROI set, the parameters of ROI are returned. + +The following example shows how to get access to array elements. It computes absolute values of the +array elements : +@code + float* data; + int step; + CvSize size; + + cvGetRawData(array, (uchar**)&data, &step, &size); + step /= sizeof(data[0]); + + for(int y = 0; y < size.height; y++, data += step ) + for(int x = 0; x < size.width; x++ ) + data[x] = (float)fabs(data[x]); +@endcode +@param arr Array header +@param data Output pointer to the whole image origin or ROI origin if ROI is set +@param step Output full row length in bytes +@param roi_size Output ROI size + */ CVAPI(void) cvGetRawData( const CvArr* arr, uchar** data, int* step CV_DEFAULT(NULL), CvSize* roi_size CV_DEFAULT(NULL)); -/* Returns width and height of array in elements */ +/** @brief Returns size of matrix or image ROI. + +The function returns number of rows (CvSize::height) and number of columns (CvSize::width) of the +input matrix or image. In the case of image the size of ROI is returned. +@param arr array header + */ CVAPI(CvSize) cvGetSize( const CvArr* arr ); -/* Copies source array to destination array */ +/** @brief Copies one array to another. + +The function copies selected elements from an input array to an output array: + +\f[\texttt{dst} (I)= \texttt{src} (I) \quad \text{if} \quad \texttt{mask} (I) \ne 0.\f] + +If any of the passed arrays is of IplImage type, then its ROI and COI fields are used. Both arrays +must have the same type, the same number of dimensions, and the same size. The function can also +copy sparse arrays (mask is not supported in this case). +@param src The source array +@param dst The destination array +@param mask Operation mask, 8-bit single channel array; specifies elements of the destination array +to be changed + */ CVAPI(void) cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL) ); -/* Sets all or "masked" elements of input array - to the same value*/ +/** @brief Sets every element of an array to a given value. + +The function copies the scalar value to every selected element of the destination array: +\f[\texttt{arr} (I)= \texttt{value} \quad \text{if} \quad \texttt{mask} (I) \ne 0\f] +If array arr is of IplImage type, then is ROI used, but COI must not be set. +@param arr The destination array +@param value Fill value +@param mask Operation mask, 8-bit single channel array; specifies elements of the destination +array to be changed + */ CVAPI(void) cvSet( CvArr* arr, CvScalar value, const CvArr* mask CV_DEFAULT(NULL) ); -/* Clears all the array elements (sets them to 0) */ +/** @brief Clears the array. + +The function clears the array. In the case of dense arrays (CvMat, CvMatND or IplImage), +cvZero(array) is equivalent to cvSet(array,cvScalarAll(0),0). In the case of sparse arrays all the +elements are removed. +@param arr Array to be cleared + */ CVAPI(void) cvSetZero( CvArr* arr ); #define cvZero cvSetZero -/* Splits a multi-channel array into the set of single-channel arrays or +/** Splits a multi-channel array into the set of single-channel arrays or extracts particular [color] plane */ CVAPI(void) cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3 ); -/* Merges a set of single-channel arrays into the single multi-channel array +/** Merges a set of single-channel arrays into the single multi-channel array or inserts one particular [color] plane to the array */ CVAPI(void) cvMerge( const CvArr* src0, const CvArr* src1, const CvArr* src2, const CvArr* src3, CvArr* dst ); -/* Copies several channels from input arrays to +/** Copies several channels from input arrays to certain channels of output arrays */ CVAPI(void) cvMixChannels( const CvArr** src, int src_count, CvArr** dst, int dst_count, const int* from_to, int pair_count ); -/* Performs linear transformation on every source array element: - dst(x,y,c) = scale*src(x,y,c)+shift. - Arbitrary combination of input and output array depths are allowed - (number of channels must be the same), thus the function can be used - for type conversion */ +/** @brief Converts one array to another with optional linear transformation. + +The function has several different purposes, and thus has several different names. It copies one +array to another with optional scaling, which is performed first, and/or optional type conversion, +performed after: + +\f[\texttt{dst} (I) = \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...)\f] + +All the channels of multi-channel arrays are processed independently. + +The type of conversion is done with rounding and saturation, that is if the result of scaling + +conversion can not be represented exactly by a value of the destination array element type, it is +set to the nearest representable value on the real axis. +@param src Source array +@param dst Destination array +@param scale Scale factor +@param shift Value added to the scaled source array elements + */ CVAPI(void) cvConvertScale( const CvArr* src, CvArr* dst, double scale CV_DEFAULT(1), double shift CV_DEFAULT(0) ); @@ -471,7 +1023,7 @@ CVAPI(void) cvConvertScale( const CvArr* src, CvArr* dst, #define cvConvert( src, dst ) cvConvertScale( (src), (dst), 1, 0 ) -/* Performs linear transformation on every source array element, +/** Performs linear transformation on every source array element, stores absolute value of the result: dst(x,y,c) = abs(scale*src(x,y,c)+shift). destination array must have 8u type. @@ -482,7 +1034,7 @@ CVAPI(void) cvConvertScaleAbs( const CvArr* src, CvArr* dst, #define cvCvtScaleAbs cvConvertScaleAbs -/* checks termination criteria validity and +/** checks termination criteria validity and sets eps to default_eps (if it is not set), max_iter to default_max_iters (if it is not set) */ @@ -494,19 +1046,19 @@ CVAPI(CvTermCriteria) cvCheckTermCriteria( CvTermCriteria criteria, * Arithmetic, logic and comparison operations * \****************************************************************************************/ -/* dst(mask) = src1(mask) + src2(mask) */ +/** dst(mask) = src1(mask) + src2(mask) */ CVAPI(void) cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(mask) = src(mask) + value */ +/** dst(mask) = src(mask) + value */ CVAPI(void) cvAddS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(mask) = src1(mask) - src2(mask) */ +/** dst(mask) = src1(mask) - src2(mask) */ CVAPI(void) cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(mask) = src(mask) - value = src(mask) + (-value) */ +/** dst(mask) = src(mask) - value = src(mask) + (-value) */ CV_INLINE void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)) { @@ -514,66 +1066,77 @@ CV_INLINE void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, dst, mask ); } -/* dst(mask) = value - src(mask) */ +/** dst(mask) = value - src(mask) */ CVAPI(void) cvSubRS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(idx) = src1(idx) * src2(idx) * scale +/** dst(idx) = src1(idx) * src2(idx) * scale (scaled element-wise multiplication of 2 arrays) */ CVAPI(void) cvMul( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale CV_DEFAULT(1) ); -/* element-wise division/inversion with scaling: +/** element-wise division/inversion with scaling: dst(idx) = src1(idx) * scale / src2(idx) or dst(idx) = scale / src2(idx) if src1 == 0 */ CVAPI(void) cvDiv( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale CV_DEFAULT(1)); -/* dst = src1 * scale + src2 */ +/** dst = src1 * scale + src2 */ CVAPI(void) cvScaleAdd( const CvArr* src1, CvScalar scale, const CvArr* src2, CvArr* dst ); #define cvAXPY( A, real_scalar, B, C ) cvScaleAdd(A, cvRealScalar(real_scalar), B, C) -/* dst = src1 * alpha + src2 * beta + gamma */ +/** dst = src1 * alpha + src2 * beta + gamma */ CVAPI(void) cvAddWeighted( const CvArr* src1, double alpha, const CvArr* src2, double beta, double gamma, CvArr* dst ); -/* result = sum_i(src1(i) * src2(i)) (results for all channels are accumulated together) */ +/** @brief Calculates the dot product of two arrays in Euclidean metrics. + +The function calculates and returns the Euclidean dot product of two arrays. + +\f[src1 \bullet src2 = \sum _I ( \texttt{src1} (I) \texttt{src2} (I))\f] + +In the case of multiple channel arrays, the results for all channels are accumulated. In particular, +cvDotProduct(a,a) where a is a complex vector, will return \f$||\texttt{a}||^2\f$. The function can +process multi-dimensional arrays, row by row, layer by layer, and so on. +@param src1 The first source array +@param src2 The second source array + */ CVAPI(double) cvDotProduct( const CvArr* src1, const CvArr* src2 ); -/* dst(idx) = src1(idx) & src2(idx) */ +/** dst(idx) = src1(idx) & src2(idx) */ CVAPI(void) cvAnd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(idx) = src(idx) & value */ +/** dst(idx) = src(idx) & value */ CVAPI(void) cvAndS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(idx) = src1(idx) | src2(idx) */ +/** dst(idx) = src1(idx) | src2(idx) */ CVAPI(void) cvOr( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(idx) = src(idx) | value */ +/** dst(idx) = src(idx) | value */ CVAPI(void) cvOrS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(idx) = src1(idx) ^ src2(idx) */ +/** dst(idx) = src1(idx) ^ src2(idx) */ CVAPI(void) cvXor( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(idx) = src(idx) ^ value */ +/** dst(idx) = src(idx) ^ value */ CVAPI(void) cvXorS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask CV_DEFAULT(NULL)); -/* dst(idx) = ~src(idx) */ +/** dst(idx) = ~src(idx) */ CVAPI(void) cvNot( const CvArr* src, CvArr* dst ); -/* dst(idx) = lower(idx) <= src(idx) < upper(idx) */ +/** dst(idx) = lower(idx) <= src(idx) < upper(idx) */ CVAPI(void) cvInRange( const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst ); -/* dst(idx) = lower <= src(idx) < upper */ +/** dst(idx) = lower <= src(idx) < upper */ CVAPI(void) cvInRangeS( const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst ); @@ -584,31 +1147,31 @@ CVAPI(void) cvInRangeS( const CvArr* src, CvScalar lower, #define CV_CMP_LE 4 #define CV_CMP_NE 5 -/* The comparison operation support single-channel arrays only. +/** The comparison operation support single-channel arrays only. Destination image should be 8uC1 or 8sC1 */ -/* dst(idx) = src1(idx) _cmp_op_ src2(idx) */ +/** dst(idx) = src1(idx) _cmp_op_ src2(idx) */ CVAPI(void) cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op ); -/* dst(idx) = src1(idx) _cmp_op_ value */ +/** dst(idx) = src1(idx) _cmp_op_ value */ CVAPI(void) cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op ); -/* dst(idx) = min(src1(idx),src2(idx)) */ +/** dst(idx) = min(src1(idx),src2(idx)) */ CVAPI(void) cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst ); -/* dst(idx) = max(src1(idx),src2(idx)) */ +/** dst(idx) = max(src1(idx),src2(idx)) */ CVAPI(void) cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst ); -/* dst(idx) = min(src(idx),value) */ +/** dst(idx) = min(src(idx),value) */ CVAPI(void) cvMinS( const CvArr* src, double value, CvArr* dst ); -/* dst(idx) = max(src(idx),value) */ +/** dst(idx) = max(src(idx),value) */ CVAPI(void) cvMaxS( const CvArr* src, double value, CvArr* dst ); -/* dst(x,y,c) = abs(src1(x,y,c) - src2(x,y,c)) */ +/** dst(x,y,c) = abs(src1(x,y,c) - src2(x,y,c)) */ CVAPI(void) cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst ); -/* dst(x,y,c) = abs(src(x,y,c) - value(c)) */ +/** dst(x,y,c) = abs(src(x,y,c) - value(c)) */ CVAPI(void) cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value ); #define cvAbs( src, dst ) cvAbsDiffS( (src), (dst), cvScalarAll(0)) @@ -616,51 +1179,68 @@ CVAPI(void) cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value ); * Math operations * \****************************************************************************************/ -/* Does cartesian->polar coordinates conversion. +/** Does cartesian->polar coordinates conversion. Either of output components (magnitude or angle) is optional */ CVAPI(void) cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude, CvArr* angle CV_DEFAULT(NULL), int angle_in_degrees CV_DEFAULT(0)); -/* Does polar->cartesian coordinates conversion. +/** Does polar->cartesian coordinates conversion. Either of output components (magnitude or angle) is optional. If magnitude is missing it is assumed to be all 1's */ CVAPI(void) cvPolarToCart( const CvArr* magnitude, const CvArr* angle, CvArr* x, CvArr* y, int angle_in_degrees CV_DEFAULT(0)); -/* Does powering: dst(idx) = src(idx)^power */ +/** Does powering: dst(idx) = src(idx)^power */ CVAPI(void) cvPow( const CvArr* src, CvArr* dst, double power ); -/* Does exponention: dst(idx) = exp(src(idx)). +/** Does exponention: dst(idx) = exp(src(idx)). Overflow is not handled yet. Underflow is handled. Maximal relative error is ~7e-6 for single-precision input */ CVAPI(void) cvExp( const CvArr* src, CvArr* dst ); -/* Calculates natural logarithms: dst(idx) = log(abs(src(idx))). +/** Calculates natural logarithms: dst(idx) = log(abs(src(idx))). Logarithm of 0 gives large negative number(~-700) Maximal relative error is ~3e-7 for single-precision output */ CVAPI(void) cvLog( const CvArr* src, CvArr* dst ); -/* Fast arctangent calculation */ +/** Fast arctangent calculation */ CVAPI(float) cvFastArctan( float y, float x ); -/* Fast cubic root calculation */ +/** Fast cubic root calculation */ CVAPI(float) cvCbrt( float value ); -/* Checks array values for NaNs, Infs or simply for too large numbers +#define CV_CHECK_RANGE 1 +#define CV_CHECK_QUIET 2 +/** Checks array values for NaNs, Infs or simply for too large numbers (if CV_CHECK_RANGE is set). If CV_CHECK_QUIET is set, no runtime errors is raised (function returns zero value in case of "bad" values). Otherwise cvError is called */ -#define CV_CHECK_RANGE 1 -#define CV_CHECK_QUIET 2 CVAPI(int) cvCheckArr( const CvArr* arr, int flags CV_DEFAULT(0), double min_val CV_DEFAULT(0), double max_val CV_DEFAULT(0)); #define cvCheckArray cvCheckArr #define CV_RAND_UNI 0 #define CV_RAND_NORMAL 1 + +/** @brief Fills an array with random numbers and updates the RNG state. + +The function fills the destination array with uniformly or normally distributed random numbers. +@param rng CvRNG state initialized by cvRNG +@param arr The destination array +@param dist_type Distribution type +> - **CV_RAND_UNI** uniform distribution +> - **CV_RAND_NORMAL** normal or Gaussian distribution +@param param1 The first parameter of the distribution. In the case of a uniform distribution it is +the inclusive lower boundary of the random numbers range. In the case of a normal distribution it +is the mean value of the random numbers. +@param param2 The second parameter of the distribution. In the case of a uniform distribution it +is the exclusive upper boundary of the random numbers range. In the case of a normal distribution +it is the standard deviation of the random numbers. +@sa randu, randn, RNG::fill. + */ CVAPI(void) cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2 ); @@ -676,10 +1256,10 @@ CVAPI(void) cvSort( const CvArr* src, CvArr* dst CV_DEFAULT(NULL), CvArr* idxmat CV_DEFAULT(NULL), int flags CV_DEFAULT(0)); -/* Finds real roots of a cubic equation */ +/** Finds real roots of a cubic equation */ CVAPI(int) cvSolveCubic( const CvMat* coeffs, CvMat* roots ); -/* Finds all real and complex roots of a polynomial equation */ +/** Finds all real and complex roots of a polynomial equation */ CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2, int maxiter CV_DEFAULT(20), int fig CV_DEFAULT(100)); @@ -687,47 +1267,56 @@ CVAPI(void) cvSolvePoly(const CvMat* coeffs, CvMat *roots2, * Matrix operations * \****************************************************************************************/ -/* Calculates cross product of two 3d vectors */ +/** @brief Calculates the cross product of two 3D vectors. + +The function calculates the cross product of two 3D vectors: +\f[\texttt{dst} = \texttt{src1} \times \texttt{src2}\f] +or: +\f[\begin{array}{l} \texttt{dst} _1 = \texttt{src1} _2 \texttt{src2} _3 - \texttt{src1} _3 \texttt{src2} _2 \\ \texttt{dst} _2 = \texttt{src1} _3 \texttt{src2} _1 - \texttt{src1} _1 \texttt{src2} _3 \\ \texttt{dst} _3 = \texttt{src1} _1 \texttt{src2} _2 - \texttt{src1} _2 \texttt{src2} _1 \end{array}\f] +@param src1 The first source vector +@param src2 The second source vector +@param dst The destination vector + */ CVAPI(void) cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst ); -/* Matrix transform: dst = A*B + C, C is optional */ +/** Matrix transform: dst = A*B + C, C is optional */ #define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( (src1), (src2), 1., (src3), 1., (dst), 0 ) #define cvMatMul( src1, src2, dst ) cvMatMulAdd( (src1), (src2), NULL, (dst)) #define CV_GEMM_A_T 1 #define CV_GEMM_B_T 2 #define CV_GEMM_C_T 4 -/* Extended matrix transform: +/** Extended matrix transform: dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T */ CVAPI(void) cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, const CvArr* src3, double beta, CvArr* dst, int tABC CV_DEFAULT(0)); #define cvMatMulAddEx cvGEMM -/* Transforms each element of source array and stores +/** Transforms each element of source array and stores resultant vectors in destination array */ CVAPI(void) cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec CV_DEFAULT(NULL)); #define cvMatMulAddS cvTransform -/* Does perspective transform on every element of input array */ +/** Does perspective transform on every element of input array */ CVAPI(void) cvPerspectiveTransform( const CvArr* src, CvArr* dst, const CvMat* mat ); -/* Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1) */ +/** Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1) */ CVAPI(void) cvMulTransposed( const CvArr* src, CvArr* dst, int order, const CvArr* delta CV_DEFAULT(NULL), double scale CV_DEFAULT(1.) ); -/* Tranposes matrix. Square matrices can be transposed in-place */ +/** Tranposes matrix. Square matrices can be transposed in-place */ CVAPI(void) cvTranspose( const CvArr* src, CvArr* dst ); #define cvT cvTranspose -/* Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part */ +/** Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part */ CVAPI(void) cvCompleteSymm( CvMat* matrix, int LtoR CV_DEFAULT(0) ); -/* Mirror array data around horizontal (flip=0), +/** Mirror array data around horizontal (flip=0), vertical (flip=1) or both(flip=-1) axises: cvFlip(src) flips images vertically and sequences horizontally (inplace) */ CVAPI(void) cvFlip( const CvArr* src, CvArr* dst CV_DEFAULT(NULL), @@ -739,11 +1328,11 @@ CVAPI(void) cvFlip( const CvArr* src, CvArr* dst CV_DEFAULT(NULL), #define CV_SVD_U_T 2 #define CV_SVD_V_T 4 -/* Performs Singular Value Decomposition of a matrix */ +/** Performs Singular Value Decomposition of a matrix */ CVAPI(void) cvSVD( CvArr* A, CvArr* W, CvArr* U CV_DEFAULT(NULL), CvArr* V CV_DEFAULT(NULL), int flags CV_DEFAULT(0)); -/* Performs Singular Value Back Substitution (solves A*X = B): +/** Performs Singular Value Back Substitution (solves A*X = B): flags must be the same as in cvSVD */ CVAPI(void) cvSVBkSb( const CvArr* W, const CvArr* U, const CvArr* V, const CvArr* B, @@ -756,23 +1345,23 @@ CVAPI(void) cvSVBkSb( const CvArr* W, const CvArr* U, #define CV_QR 4 #define CV_NORMAL 16 -/* Inverts matrix */ +/** Inverts matrix */ CVAPI(double) cvInvert( const CvArr* src, CvArr* dst, int method CV_DEFAULT(CV_LU)); #define cvInv cvInvert -/* Solves linear system (src1)*(dst) = (src2) +/** Solves linear system (src1)*(dst) = (src2) (returns 0 if src1 is a singular and CV_LU method is used) */ CVAPI(int) cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst, int method CV_DEFAULT(CV_LU)); -/* Calculates determinant of input matrix */ +/** Calculates determinant of input matrix */ CVAPI(double) cvDet( const CvArr* mat ); -/* Calculates trace of the matrix (sum of elements on the main diagonal) */ +/** Calculates trace of the matrix (sum of elements on the main diagonal) */ CVAPI(CvScalar) cvTrace( const CvArr* mat ); -/* Finds eigen values and vectors of a symmetric matrix */ +/** Finds eigen values and vectors of a symmetric matrix */ CVAPI(void) cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps CV_DEFAULT(0), int lowindex CV_DEFAULT(-1), @@ -782,32 +1371,42 @@ CVAPI(void) cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, //CVAPI(void) cvSelectedEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, // int lowindex, int highindex ); -/* Makes an identity matrix (mat_ij = i == j) */ +/** Makes an identity matrix (mat_ij = i == j) */ CVAPI(void) cvSetIdentity( CvArr* mat, CvScalar value CV_DEFAULT(cvRealScalar(1)) ); -/* Fills matrix with given range of numbers */ +/** Fills matrix with given range of numbers */ CVAPI(CvArr*) cvRange( CvArr* mat, double start, double end ); -/* Calculates covariation matrix for a set of vectors */ -/* transpose([v1-avg, v2-avg,...]) * [v1-avg,v2-avg,...] */ +/** @anchor core_c_CovarFlags +@name Flags for cvCalcCovarMatrix +@see cvCalcCovarMatrix + @{ +*/ + +/** flag for cvCalcCovarMatrix, transpose([v1-avg, v2-avg,...]) * [v1-avg,v2-avg,...] */ #define CV_COVAR_SCRAMBLED 0 -/* [v1-avg, v2-avg,...] * transpose([v1-avg,v2-avg,...]) */ +/** flag for cvCalcCovarMatrix, [v1-avg, v2-avg,...] * transpose([v1-avg,v2-avg,...]) */ #define CV_COVAR_NORMAL 1 -/* do not calc average (i.e. mean vector) - use the input vector instead +/** flag for cvCalcCovarMatrix, do not calc average (i.e. mean vector) - use the input vector instead (useful for calculating covariance matrix by parts) */ #define CV_COVAR_USE_AVG 2 -/* scale the covariance matrix coefficients by number of the vectors */ +/** flag for cvCalcCovarMatrix, scale the covariance matrix coefficients by number of the vectors */ #define CV_COVAR_SCALE 4 -/* all the input vectors are stored in a single matrix, as its rows */ +/** flag for cvCalcCovarMatrix, all the input vectors are stored in a single matrix, as its rows */ #define CV_COVAR_ROWS 8 -/* all the input vectors are stored in a single matrix, as its columns */ +/** flag for cvCalcCovarMatrix, all the input vectors are stored in a single matrix, as its columns */ #define CV_COVAR_COLS 16 +/** @} */ + +/** Calculates covariation matrix for a set of vectors +@see @ref core_c_CovarFlags "flags" +*/ CVAPI(void) cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* cov_mat, CvArr* avg, int flags ); @@ -823,7 +1422,7 @@ CVAPI(void) cvProjectPCA( const CvArr* data, const CvArr* mean, CVAPI(void) cvBackProjectPCA( const CvArr* proj, const CvArr* mean, const CvArr* eigenvects, CvArr* result ); -/* Calculates Mahalanobis(weighted) distance */ +/** Calculates Mahalanobis(weighted) distance */ CVAPI(double) cvMahalanobis( const CvArr* vec1, const CvArr* vec2, const CvArr* mat ); #define cvMahalonobis cvMahalanobis @@ -831,26 +1430,29 @@ CVAPI(double) cvMahalanobis( const CvArr* vec1, const CvArr* vec2, const CvArr* * Array Statistics * \****************************************************************************************/ -/* Finds sum of array elements */ +/** Finds sum of array elements */ CVAPI(CvScalar) cvSum( const CvArr* arr ); -/* Calculates number of non-zero pixels */ +/** Calculates number of non-zero pixels */ CVAPI(int) cvCountNonZero( const CvArr* arr ); -/* Calculates mean value of array elements */ +/** Calculates mean value of array elements */ CVAPI(CvScalar) cvAvg( const CvArr* arr, const CvArr* mask CV_DEFAULT(NULL) ); -/* Calculates mean and standard deviation of pixel values */ +/** Calculates mean and standard deviation of pixel values */ CVAPI(void) cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev, const CvArr* mask CV_DEFAULT(NULL) ); -/* Finds global minimum, maximum and their positions */ +/** Finds global minimum, maximum and their positions */ CVAPI(void) cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val, CvPoint* min_loc CV_DEFAULT(NULL), CvPoint* max_loc CV_DEFAULT(NULL), const CvArr* mask CV_DEFAULT(NULL) ); -/* types of array norm */ +/** @anchor core_c_NormFlags + @name Flags for cvNorm and cvNormalize + @{ +*/ #define CV_C 1 #define CV_L1 2 #define CV_L2 4 @@ -865,23 +1467,32 @@ CVAPI(void) cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val, #define CV_RELATIVE_C (CV_RELATIVE | CV_C) #define CV_RELATIVE_L1 (CV_RELATIVE | CV_L1) #define CV_RELATIVE_L2 (CV_RELATIVE | CV_L2) +/** @} */ -/* Finds norm, difference norm or relative difference norm for an array (or two arrays) */ +/** Finds norm, difference norm or relative difference norm for an array (or two arrays) +@see ref core_c_NormFlags "flags" +*/ CVAPI(double) cvNorm( const CvArr* arr1, const CvArr* arr2 CV_DEFAULT(NULL), int norm_type CV_DEFAULT(CV_L2), const CvArr* mask CV_DEFAULT(NULL) ); +/** @see ref core_c_NormFlags "flags" */ CVAPI(void) cvNormalize( const CvArr* src, CvArr* dst, double a CV_DEFAULT(1.), double b CV_DEFAULT(0.), int norm_type CV_DEFAULT(CV_L2), const CvArr* mask CV_DEFAULT(NULL) ); - +/** @anchor core_c_ReduceFlags + @name Flags for cvReduce + @{ +*/ #define CV_REDUCE_SUM 0 #define CV_REDUCE_AVG 1 #define CV_REDUCE_MAX 2 #define CV_REDUCE_MIN 3 +/** @} */ +/** @see @ref core_c_ReduceFlags "flags" */ CVAPI(void) cvReduce( const CvArr* src, CvArr* dst, int dim CV_DEFAULT(-1), int op CV_DEFAULT(CV_REDUCE_SUM) ); @@ -889,182 +1500,193 @@ CVAPI(void) cvReduce( const CvArr* src, CvArr* dst, int dim CV_DEFAULT(-1), * Discrete Linear Transforms and Related Functions * \****************************************************************************************/ +/** @anchor core_c_DftFlags + @name Flags for cvDFT, cvDCT and cvMulSpectrums + @{ + */ #define CV_DXT_FORWARD 0 #define CV_DXT_INVERSE 1 -#define CV_DXT_SCALE 2 /* divide result by size of array */ +#define CV_DXT_SCALE 2 /**< divide result by size of array */ #define CV_DXT_INV_SCALE (CV_DXT_INVERSE + CV_DXT_SCALE) #define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE -#define CV_DXT_ROWS 4 /* transform each row individually */ -#define CV_DXT_MUL_CONJ 8 /* conjugate the second argument of cvMulSpectrums */ +#define CV_DXT_ROWS 4 /**< transform each row individually */ +#define CV_DXT_MUL_CONJ 8 /**< conjugate the second argument of cvMulSpectrums */ +/** @} */ -/* Discrete Fourier Transform: +/** Discrete Fourier Transform: complex->complex, real->ccs (forward), - ccs->real (inverse) */ + ccs->real (inverse) +@see core_c_DftFlags "flags" +*/ CVAPI(void) cvDFT( const CvArr* src, CvArr* dst, int flags, int nonzero_rows CV_DEFAULT(0) ); #define cvFFT cvDFT -/* Multiply results of DFTs: DFT(X)*DFT(Y) or DFT(X)*conj(DFT(Y)) */ +/** Multiply results of DFTs: DFT(X)*DFT(Y) or DFT(X)*conj(DFT(Y)) +@see core_c_DftFlags "flags" +*/ CVAPI(void) cvMulSpectrums( const CvArr* src1, const CvArr* src2, CvArr* dst, int flags ); -/* Finds optimal DFT vector size >= size0 */ +/** Finds optimal DFT vector size >= size0 */ CVAPI(int) cvGetOptimalDFTSize( int size0 ); -/* Discrete Cosine Transform */ +/** Discrete Cosine Transform +@see core_c_DftFlags "flags" +*/ CVAPI(void) cvDCT( const CvArr* src, CvArr* dst, int flags ); /****************************************************************************************\ * Dynamic data structures * \****************************************************************************************/ -/* Calculates length of sequence slice (with support of negative indices). */ +/** Calculates length of sequence slice (with support of negative indices). */ CVAPI(int) cvSliceLength( CvSlice slice, const CvSeq* seq ); -/* Creates new memory storage. +/** Creates new memory storage. block_size == 0 means that default, somewhat optimal size, is used (currently, it is 64K) */ CVAPI(CvMemStorage*) cvCreateMemStorage( int block_size CV_DEFAULT(0)); -/* Creates a memory storage that will borrow memory blocks from parent storage */ +/** Creates a memory storage that will borrow memory blocks from parent storage */ CVAPI(CvMemStorage*) cvCreateChildMemStorage( CvMemStorage* parent ); -/* Releases memory storage. All the children of a parent must be released before +/** Releases memory storage. All the children of a parent must be released before the parent. A child storage returns all the blocks to parent when it is released */ CVAPI(void) cvReleaseMemStorage( CvMemStorage** storage ); -/* Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos) +/** Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos) to reuse memory allocated for the storage - cvClearSeq,cvClearSet ... do not free any memory. A child storage returns all the blocks to the parent when it is cleared */ CVAPI(void) cvClearMemStorage( CvMemStorage* storage ); -/* Remember a storage "free memory" position */ +/** Remember a storage "free memory" position */ CVAPI(void) cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos ); -/* Restore a storage "free memory" position */ +/** Restore a storage "free memory" position */ CVAPI(void) cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos ); -/* Allocates continuous buffer of the specified size in the storage */ +/** Allocates continuous buffer of the specified size in the storage */ CVAPI(void*) cvMemStorageAlloc( CvMemStorage* storage, size_t size ); -/* Allocates string in memory storage */ +/** Allocates string in memory storage */ CVAPI(CvString) cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len CV_DEFAULT(-1) ); -/* Creates new empty sequence that will reside in the specified storage */ +/** Creates new empty sequence that will reside in the specified storage */ CVAPI(CvSeq*) cvCreateSeq( int seq_flags, size_t header_size, size_t elem_size, CvMemStorage* storage ); -/* Changes default size (granularity) of sequence blocks. +/** Changes default size (granularity) of sequence blocks. The default size is ~1Kbyte */ CVAPI(void) cvSetSeqBlockSize( CvSeq* seq, int delta_elems ); -/* Adds new element to the end of sequence. Returns pointer to the element */ +/** Adds new element to the end of sequence. Returns pointer to the element */ CVAPI(schar*) cvSeqPush( CvSeq* seq, const void* element CV_DEFAULT(NULL)); -/* Adds new element to the beginning of sequence. Returns pointer to it */ +/** Adds new element to the beginning of sequence. Returns pointer to it */ CVAPI(schar*) cvSeqPushFront( CvSeq* seq, const void* element CV_DEFAULT(NULL)); -/* Removes the last element from sequence and optionally saves it */ +/** Removes the last element from sequence and optionally saves it */ CVAPI(void) cvSeqPop( CvSeq* seq, void* element CV_DEFAULT(NULL)); -/* Removes the first element from sequence and optioanally saves it */ +/** Removes the first element from sequence and optioanally saves it */ CVAPI(void) cvSeqPopFront( CvSeq* seq, void* element CV_DEFAULT(NULL)); #define CV_FRONT 1 #define CV_BACK 0 -/* Adds several new elements to the end of sequence */ +/** Adds several new elements to the end of sequence */ CVAPI(void) cvSeqPushMulti( CvSeq* seq, const void* elements, int count, int in_front CV_DEFAULT(0) ); -/* Removes several elements from the end of sequence and optionally saves them */ +/** Removes several elements from the end of sequence and optionally saves them */ CVAPI(void) cvSeqPopMulti( CvSeq* seq, void* elements, int count, int in_front CV_DEFAULT(0) ); -/* Inserts a new element in the middle of sequence. +/** Inserts a new element in the middle of sequence. cvSeqInsert(seq,0,elem) == cvSeqPushFront(seq,elem) */ CVAPI(schar*) cvSeqInsert( CvSeq* seq, int before_index, const void* element CV_DEFAULT(NULL)); -/* Removes specified sequence element */ +/** Removes specified sequence element */ CVAPI(void) cvSeqRemove( CvSeq* seq, int index ); -/* Removes all the elements from the sequence. The freed memory +/** Removes all the elements from the sequence. The freed memory can be reused later only by the same sequence unless cvClearMemStorage or cvRestoreMemStoragePos is called */ CVAPI(void) cvClearSeq( CvSeq* seq ); -/* Retrieves pointer to specified sequence element. +/** Retrieves pointer to specified sequence element. Negative indices are supported and mean counting from the end (e.g -1 means the last sequence element) */ CVAPI(schar*) cvGetSeqElem( const CvSeq* seq, int index ); -/* Calculates index of the specified sequence element. +/** Calculates index of the specified sequence element. Returns -1 if element does not belong to the sequence */ CVAPI(int) cvSeqElemIdx( const CvSeq* seq, const void* element, CvSeqBlock** block CV_DEFAULT(NULL) ); -/* Initializes sequence writer. The new elements will be added to the end of sequence */ +/** Initializes sequence writer. The new elements will be added to the end of sequence */ CVAPI(void) cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer ); -/* Combination of cvCreateSeq and cvStartAppendToSeq */ +/** Combination of cvCreateSeq and cvStartAppendToSeq */ CVAPI(void) cvStartWriteSeq( int seq_flags, int header_size, int elem_size, CvMemStorage* storage, CvSeqWriter* writer ); -/* Closes sequence writer, updates sequence header and returns pointer +/** Closes sequence writer, updates sequence header and returns pointer to the resultant sequence (which may be useful if the sequence was created using cvStartWriteSeq)) */ CVAPI(CvSeq*) cvEndWriteSeq( CvSeqWriter* writer ); -/* Updates sequence header. May be useful to get access to some of previously +/** Updates sequence header. May be useful to get access to some of previously written elements via cvGetSeqElem or sequence reader */ CVAPI(void) cvFlushSeqWriter( CvSeqWriter* writer ); -/* Initializes sequence reader. +/** Initializes sequence reader. The sequence can be read in forward or backward direction */ CVAPI(void) cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, int reverse CV_DEFAULT(0) ); -/* Returns current sequence reader position (currently observed sequence element) */ +/** Returns current sequence reader position (currently observed sequence element) */ CVAPI(int) cvGetSeqReaderPos( CvSeqReader* reader ); -/* Changes sequence reader position. It may seek to an absolute or +/** Changes sequence reader position. It may seek to an absolute or to relative to the current position */ CVAPI(void) cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative CV_DEFAULT(0)); -/* Copies sequence content to a continuous piece of memory */ +/** Copies sequence content to a continuous piece of memory */ CVAPI(void*) cvCvtSeqToArray( const CvSeq* seq, void* elements, CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ) ); -/* Creates sequence header for array. +/** Creates sequence header for array. After that all the operations on sequences that do not alter the content can be applied to the resultant sequence */ CVAPI(CvSeq*) cvMakeSeqHeaderForArray( int seq_type, int header_size, int elem_size, void* elements, int total, CvSeq* seq, CvSeqBlock* block ); -/* Extracts sequence slice (with or without copying sequence elements) */ +/** Extracts sequence slice (with or without copying sequence elements) */ CVAPI(CvSeq*) cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage CV_DEFAULT(NULL), int copy_data CV_DEFAULT(0)); @@ -1074,27 +1696,27 @@ CV_INLINE CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage CV_DEFAULT( return cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 ); } -/* Removes sequence slice */ +/** Removes sequence slice */ CVAPI(void) cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ); -/* Inserts a sequence or array into another sequence */ +/** Inserts a sequence or array into another sequence */ CVAPI(void) cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr ); -/* a < b ? -1 : a > b ? 1 : 0 */ +/** a < b ? -1 : a > b ? 1 : 0 */ typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata ); -/* Sorts sequence in-place given element comparison function */ +/** Sorts sequence in-place given element comparison function */ CVAPI(void) cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata CV_DEFAULT(NULL) ); -/* Finds element in a [sorted] sequence */ +/** Finds element in a [sorted] sequence */ CVAPI(schar*) cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func, int is_sorted, int* elem_idx, void* userdata CV_DEFAULT(NULL) ); -/* Reverses order of sequence elements in-place */ +/** Reverses order of sequence elements in-place */ CVAPI(void) cvSeqInvert( CvSeq* seq ); -/* Splits sequence into one or more equivalence classes using the specified criteria */ +/** Splits sequence into one or more equivalence classes using the specified criteria */ CVAPI(int) cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels, CvCmpFunc is_equal, void* userdata ); @@ -1103,15 +1725,15 @@ CVAPI(void) cvChangeSeqBlock( void* reader, int direction ); CVAPI(void) cvCreateSeqBlock( CvSeqWriter* writer ); -/* Creates a new set */ +/** Creates a new set */ CVAPI(CvSet*) cvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage* storage ); -/* Adds new element to the set and returns pointer to it */ +/** Adds new element to the set and returns pointer to it */ CVAPI(int) cvSetAdd( CvSet* set_header, CvSetElem* elem CV_DEFAULT(NULL), CvSetElem** inserted_elem CV_DEFAULT(NULL) ); -/* Fast variant of cvSetAdd */ +/** Fast variant of cvSetAdd */ CV_INLINE CvSetElem* cvSetNew( CvSet* set_header ) { CvSetElem* elem = set_header->free_elems; @@ -1126,7 +1748,7 @@ CV_INLINE CvSetElem* cvSetNew( CvSet* set_header ) return elem; } -/* Removes set element given its pointer */ +/** Removes set element given its pointer */ CV_INLINE void cvSetRemoveByPtr( CvSet* set_header, void* elem ) { CvSetElem* _elem = (CvSetElem*)elem; @@ -1137,10 +1759,10 @@ CV_INLINE void cvSetRemoveByPtr( CvSet* set_header, void* elem ) set_header->active_count--; } -/* Removes element from the set by its index */ +/** Removes element from the set by its index */ CVAPI(void) cvSetRemove( CvSet* set_header, int index ); -/* Returns a set element by index. If the element doesn't belong to the set, +/** Returns a set element by index. If the element doesn't belong to the set, NULL is returned */ CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int idx ) { @@ -1148,25 +1770,25 @@ CV_INLINE CvSetElem* cvGetSetElem( const CvSet* set_header, int idx ) return elem && CV_IS_SET_ELEM( elem ) ? elem : 0; } -/* Removes all the elements from the set */ +/** Removes all the elements from the set */ CVAPI(void) cvClearSet( CvSet* set_header ); -/* Creates new graph */ +/** Creates new graph */ CVAPI(CvGraph*) cvCreateGraph( int graph_flags, int header_size, int vtx_size, int edge_size, CvMemStorage* storage ); -/* Adds new vertex to the graph */ +/** Adds new vertex to the graph */ CVAPI(int) cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx CV_DEFAULT(NULL), CvGraphVtx** inserted_vtx CV_DEFAULT(NULL) ); -/* Removes vertex from the graph together with all incident edges */ +/** Removes vertex from the graph together with all incident edges */ CVAPI(int) cvGraphRemoveVtx( CvGraph* graph, int index ); CVAPI(int) cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ); -/* Link two vertices specifed by indices or pointers if they +/** Link two vertices specifed by indices or pointers if they are not connected or return pointer to already existing edge connecting the vertices. Functions return 1 if a new edge was created, 0 otherwise */ @@ -1180,12 +1802,12 @@ CVAPI(int) cvGraphAddEdgeByPtr( CvGraph* graph, const CvGraphEdge* edge CV_DEFAULT(NULL), CvGraphEdge** inserted_edge CV_DEFAULT(NULL) ); -/* Remove edge connecting two vertices */ +/** Remove edge connecting two vertices */ CVAPI(void) cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ); CVAPI(void) cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx ); -/* Find edge connecting two vertices */ +/** Find edge connecting two vertices */ CVAPI(CvGraphEdge*) cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ); CVAPI(CvGraphEdge*) cvFindGraphEdgeByPtr( const CvGraph* graph, const CvGraphVtx* start_vtx, @@ -1193,22 +1815,22 @@ CVAPI(CvGraphEdge*) cvFindGraphEdgeByPtr( const CvGraph* graph, #define cvGraphFindEdge cvFindGraphEdge #define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr -/* Remove all vertices and edges from the graph */ +/** Remove all vertices and edges from the graph */ CVAPI(void) cvClearGraph( CvGraph* graph ); -/* Count number of edges incident to the vertex */ +/** Count number of edges incident to the vertex */ CVAPI(int) cvGraphVtxDegree( const CvGraph* graph, int vtx_idx ); CVAPI(int) cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx ); -/* Retrieves graph vertex by given index */ +/** Retrieves graph vertex by given index */ #define cvGetGraphVtx( graph, idx ) (CvGraphVtx*)cvGetSetElem((CvSet*)(graph), (idx)) -/* Retrieves index of a graph vertex given its pointer */ +/** Retrieves index of a graph vertex given its pointer */ #define cvGraphVtxIdx( graph, vtx ) ((vtx)->flags & CV_SET_ELEM_IDX_MASK) -/* Retrieves index of a graph edge given its pointer */ +/** Retrieves index of a graph edge given its pointer */ #define cvGraphEdgeIdx( graph, edge ) ((edge)->flags & CV_SET_ELEM_IDX_MASK) #define cvGraphGetVtxCount( graph ) ((graph)->active_count) @@ -1226,7 +1848,7 @@ CVAPI(int) cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx ) #define CV_GRAPH_ALL_ITEMS -1 -/* flags for graph vertices and edges */ +/** flags for graph vertices and edges */ #define CV_GRAPH_ITEM_VISITED_FLAG (1 << 30) #define CV_IS_GRAPH_VERTEX_VISITED(vtx) \ (((CvGraphVtx*)(vtx))->flags & CV_GRAPH_ITEM_VISITED_FLAG) @@ -1248,22 +1870,22 @@ typedef struct CvGraphScanner } CvGraphScanner; -/* Creates new graph scanner. */ +/** Creates new graph scanner. */ CVAPI(CvGraphScanner*) cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx CV_DEFAULT(NULL), int mask CV_DEFAULT(CV_GRAPH_ALL_ITEMS)); -/* Releases graph scanner. */ +/** Releases graph scanner. */ CVAPI(void) cvReleaseGraphScanner( CvGraphScanner** scanner ); -/* Get next graph element */ +/** Get next graph element */ CVAPI(int) cvNextGraphItem( CvGraphScanner* scanner ); -/* Creates a copy of graph */ +/** Creates a copy of graph */ CVAPI(CvGraph*) cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ); -/* Does look-up transformation. Elements of the source array +/** Does look-up transformation. Elements of the source array (that should be 8uC1 or 8sC1) are used as indexes in lutarr 256-element table */ CVAPI(void) cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut ); @@ -1282,20 +1904,20 @@ CVAPI(void) cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator, CVAPI(void*) cvNextTreeNode( CvTreeNodeIterator* tree_iterator ); CVAPI(void*) cvPrevTreeNode( CvTreeNodeIterator* tree_iterator ); -/* Inserts sequence into tree with specified "parent" sequence. +/** Inserts sequence into tree with specified "parent" sequence. If parent is equal to frame (e.g. the most external contour), then added contour will have null pointer to parent. */ CVAPI(void) cvInsertNodeIntoTree( void* node, void* parent, void* frame ); -/* Removes contour from tree (together with the contour children). */ +/** Removes contour from tree (together with the contour children). */ CVAPI(void) cvRemoveNodeFromTree( void* node, void* frame ); -/* Gathers pointers to all the sequences, - accessible from the , to the single sequence */ +/** Gathers pointers to all the sequences, + accessible from the `first`, to the single sequence */ CVAPI(CvSeq*) cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage ); -/* The function implements the K-means algorithm for clustering an array of sample +/** The function implements the K-means algorithm for clustering an array of sample vectors in a specified number of classes */ #define CV_KMEANS_USE_INITIAL_LABELS 1 CVAPI(int) cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels, @@ -1307,7 +1929,7 @@ CVAPI(int) cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels, * System functions * \****************************************************************************************/ -/* Loads optimized functions from IPP, MKL etc. or switches back to pure C code */ +/** Loads optimized functions from IPP, MKL etc. or switches back to pure C code */ CVAPI(int) cvUseOptimized( int on_off ); typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader) @@ -1318,7 +1940,22 @@ typedef void (CV_STDCALL* Cv_iplDeallocate)(IplImage*,int); typedef IplROI* (CV_STDCALL* Cv_iplCreateROI)(int,int,int,int,int); typedef IplImage* (CV_STDCALL* Cv_iplCloneImage)(const IplImage*); -/* Makes OpenCV use IPL functions for IplImage allocation/deallocation */ +/** @brief Makes OpenCV use IPL functions for allocating IplImage and IplROI structures. + +Normally, the function is not called directly. Instead, a simple macro +CV_TURN_ON_IPL_COMPATIBILITY() is used that calls cvSetIPLAllocators and passes there pointers +to IPL allocation functions. : +@code + ... + CV_TURN_ON_IPL_COMPATIBILITY() + ... +@endcode +@param create_header pointer to a function, creating IPL image header. +@param allocate_data pointer to a function, allocating IPL image data. +@param deallocate pointer to a function, deallocating IPL image. +@param create_roi pointer to a function, creating IPL image ROI (i.e. Region of Interest). +@param clone_image pointer to a function, cloning an IPL image. + */ CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, Cv_iplAllocateImageData allocate_data, Cv_iplDeallocate deallocate, @@ -1335,72 +1972,347 @@ CVAPI(void) cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, /********************************** High-level functions ********************************/ -/* opens existing or creates new file storage */ +/** @brief Opens file storage for reading or writing data. + +The function opens file storage for reading or writing data. In the latter case, a new file is +created or an existing file is rewritten. The type of the read or written file is determined by the +filename extension: .xml for XML and .yml or .yaml for YAML. The function returns a pointer to the +CvFileStorage structure. If the file cannot be opened then the function returns NULL. +@param filename Name of the file associated with the storage +@param memstorage Memory storage used for temporary data and for +: storing dynamic structures, such as CvSeq or CvGraph . If it is NULL, a temporary memory + storage is created and used. +@param flags Can be one of the following: +> - **CV_STORAGE_READ** the storage is open for reading +> - **CV_STORAGE_WRITE** the storage is open for writing +@param encoding + */ CVAPI(CvFileStorage*) cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, int flags, const char* encoding CV_DEFAULT(NULL) ); -/* closes file storage and deallocates buffers */ +/** @brief Releases file storage. + +The function closes the file associated with the storage and releases all the temporary structures. +It must be called after all I/O operations with the storage are finished. +@param fs Double pointer to the released file storage + */ CVAPI(void) cvReleaseFileStorage( CvFileStorage** fs ); -/* returns attribute value or 0 (NULL) if there is no such attribute */ +/** returns attribute value or 0 (NULL) if there is no such attribute */ CVAPI(const char*) cvAttrValue( const CvAttrList* attr, const char* attr_name ); -/* starts writing compound structure (map or sequence) */ +/** @brief Starts writing a new structure. + +The function starts writing a compound structure (collection) that can be a sequence or a map. After +all the structure fields, which can be scalars or structures, are written, cvEndWriteStruct should +be called. The function can be used to group some objects or to implement the write function for a +some user object (see CvTypeInfo). +@param fs File storage +@param name Name of the written structure. The structure can be accessed by this name when the +storage is read. +@param struct_flags A combination one of the following values: +- **CV_NODE_SEQ** the written structure is a sequence (see discussion of CvFileStorage ), + that is, its elements do not have a name. +- **CV_NODE_MAP** the written structure is a map (see discussion of CvFileStorage ), that + is, all its elements have names. +One and only one of the two above flags must be specified +- **CV_NODE_FLOW** the optional flag that makes sense only for YAML streams. It means that + the structure is written as a flow (not as a block), which is more compact. It is + recommended to use this flag for structures or arrays whose elements are all scalars. +@param type_name Optional parameter - the object type name. In + case of XML it is written as a type_id attribute of the structure opening tag. In the case of + YAML it is written after a colon following the structure name (see the example in + CvFileStorage description). Mainly it is used with user objects. When the storage is read, the + encoded type name is used to determine the object type (see CvTypeInfo and cvFindType ). +@param attributes This parameter is not used in the current implementation + */ CVAPI(void) cvStartWriteStruct( CvFileStorage* fs, const char* name, int struct_flags, const char* type_name CV_DEFAULT(NULL), CvAttrList attributes CV_DEFAULT(cvAttrList())); -/* finishes writing compound structure */ +/** @brief Finishes writing to a file node collection. +@param fs File storage +@sa cvStartWriteStruct. + */ CVAPI(void) cvEndWriteStruct( CvFileStorage* fs ); -/* writes an integer */ +/** @brief Writes an integer value. + +The function writes a single integer value (with or without a name) to the file storage. +@param fs File storage +@param name Name of the written value. Should be NULL if and only if the parent structure is a +sequence. +@param value The written value + */ CVAPI(void) cvWriteInt( CvFileStorage* fs, const char* name, int value ); -/* writes a floating-point number */ +/** @brief Writes a floating-point value. + +The function writes a single floating-point value (with or without a name) to file storage. Special +values are encoded as follows: NaN (Not A Number) as .NaN, infinity as +.Inf or -.Inf. + +The following example shows how to use the low-level writing functions to store custom structures, +such as termination criteria, without registering a new type. : +@code + void write_termcriteria( CvFileStorage* fs, const char* struct_name, + CvTermCriteria* termcrit ) + { + cvStartWriteStruct( fs, struct_name, CV_NODE_MAP, NULL, cvAttrList(0,0)); + cvWriteComment( fs, "termination criteria", 1 ); // just a description + if( termcrit->type & CV_TERMCRIT_ITER ) + cvWriteInteger( fs, "max_iterations", termcrit->max_iter ); + if( termcrit->type & CV_TERMCRIT_EPS ) + cvWriteReal( fs, "accuracy", termcrit->epsilon ); + cvEndWriteStruct( fs ); + } +@endcode +@param fs File storage +@param name Name of the written value. Should be NULL if and only if the parent structure is a +sequence. +@param value The written value +*/ CVAPI(void) cvWriteReal( CvFileStorage* fs, const char* name, double value ); -/* writes a string */ +/** @brief Writes a text string. + +The function writes a text string to file storage. +@param fs File storage +@param name Name of the written string . Should be NULL if and only if the parent structure is a +sequence. +@param str The written text string +@param quote If non-zero, the written string is put in quotes, regardless of whether they are +required. Otherwise, if the flag is zero, quotes are used only when they are required (e.g. when +the string starts with a digit or contains spaces). + */ CVAPI(void) cvWriteString( CvFileStorage* fs, const char* name, const char* str, int quote CV_DEFAULT(0) ); -/* writes a comment */ +/** @brief Writes a comment. + +The function writes a comment into file storage. The comments are skipped when the storage is read. +@param fs File storage +@param comment The written comment, single-line or multi-line +@param eol_comment If non-zero, the function tries to put the comment at the end of current line. +If the flag is zero, if the comment is multi-line, or if it does not fit at the end of the current +line, the comment starts a new line. + */ CVAPI(void) cvWriteComment( CvFileStorage* fs, const char* comment, int eol_comment ); -/* writes instance of a standard type (matrix, image, sequence, graph etc.) - or user-defined type */ +/** @brief Writes an object to file storage. + +The function writes an object to file storage. First, the appropriate type info is found using +cvTypeOf. Then, the write method associated with the type info is called. + +Attributes are used to customize the writing procedure. The standard types support the following +attributes (all the dt attributes have the same format as in cvWriteRawData): + +-# CvSeq + - **header_dt** description of user fields of the sequence header that follow CvSeq, or + CvChain (if the sequence is a Freeman chain) or CvContour (if the sequence is a contour or + point sequence) + - **dt** description of the sequence elements. + - **recursive** if the attribute is present and is not equal to "0" or "false", the whole + tree of sequences (contours) is stored. +-# CvGraph + - **header_dt** description of user fields of the graph header that follows CvGraph; + - **vertex_dt** description of user fields of graph vertices + - **edge_dt** description of user fields of graph edges (note that the edge weight is + always written, so there is no need to specify it explicitly) + +Below is the code that creates the YAML file shown in the CvFileStorage description: +@code + #include "cxcore.h" + + int main( int argc, char** argv ) + { + CvMat* mat = cvCreateMat( 3, 3, CV_32F ); + CvFileStorage* fs = cvOpenFileStorage( "example.yml", 0, CV_STORAGE_WRITE ); + + cvSetIdentity( mat ); + cvWrite( fs, "A", mat, cvAttrList(0,0) ); + + cvReleaseFileStorage( &fs ); + cvReleaseMat( &mat ); + return 0; + } +@endcode +@param fs File storage +@param name Name of the written object. Should be NULL if and only if the parent structure is a +sequence. +@param ptr Pointer to the object +@param attributes The attributes of the object. They are specific for each particular type (see +the discussion below). + */ CVAPI(void) cvWrite( CvFileStorage* fs, const char* name, const void* ptr, CvAttrList attributes CV_DEFAULT(cvAttrList())); -/* starts the next stream */ +/** @brief Starts the next stream. + +The function finishes the currently written stream and starts the next stream. In the case of XML +the file with multiple streams looks like this: +@code{.xml} + + + + + + + ... +@endcode +The YAML file will look like this: +@code{.yaml} + %YAML:1.0 + # stream #1 data + ... + --- + # stream #2 data +@endcode +This is useful for concatenating files or for resuming the writing process. +@param fs File storage + */ CVAPI(void) cvStartNextStream( CvFileStorage* fs ); -/* helper function: writes multiple integer or floating-point numbers */ +/** @brief Writes multiple numbers. + +The function writes an array, whose elements consist of single or multiple numbers. The function +call can be replaced with a loop containing a few cvWriteInt and cvWriteReal calls, but a single +call is more efficient. Note that because none of the elements have a name, they should be written +to a sequence rather than a map. +@param fs File storage +@param src Pointer to the written array +@param len Number of the array elements to write +@param dt Specification of each array element, see @ref format_spec "format specification" + */ CVAPI(void) cvWriteRawData( CvFileStorage* fs, const void* src, int len, const char* dt ); -/* returns the hash entry corresponding to the specified literal key string or 0 - if there is no such a key in the storage */ +/** @brief Returns a unique pointer for a given name. + +The function returns a unique pointer for each particular file node name. This pointer can be then +passed to the cvGetFileNode function that is faster than cvGetFileNodeByName because it compares +text strings by comparing pointers rather than the strings' content. + +Consider the following example where an array of points is encoded as a sequence of 2-entry maps: +@code + points: + - { x: 10, y: 10 } + - { x: 20, y: 20 } + - { x: 30, y: 30 } + # ... +@endcode +Then, it is possible to get hashed "x" and "y" pointers to speed up decoding of the points. : +@code + #include "cxcore.h" + + int main( int argc, char** argv ) + { + CvFileStorage* fs = cvOpenFileStorage( "points.yml", 0, CV_STORAGE_READ ); + CvStringHashNode* x_key = cvGetHashedNode( fs, "x", -1, 1 ); + CvStringHashNode* y_key = cvGetHashedNode( fs, "y", -1, 1 ); + CvFileNode* points = cvGetFileNodeByName( fs, 0, "points" ); + + if( CV_NODE_IS_SEQ(points->tag) ) + { + CvSeq* seq = points->data.seq; + int i, total = seq->total; + CvSeqReader reader; + cvStartReadSeq( seq, &reader, 0 ); + for( i = 0; i < total; i++ ) + { + CvFileNode* pt = (CvFileNode*)reader.ptr; + #if 1 // faster variant + CvFileNode* xnode = cvGetFileNode( fs, pt, x_key, 0 ); + CvFileNode* ynode = cvGetFileNode( fs, pt, y_key, 0 ); + assert( xnode && CV_NODE_IS_INT(xnode->tag) && + ynode && CV_NODE_IS_INT(ynode->tag)); + int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); + int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); + #elif 1 // slower variant; does not use x_key & y_key + CvFileNode* xnode = cvGetFileNodeByName( fs, pt, "x" ); + CvFileNode* ynode = cvGetFileNodeByName( fs, pt, "y" ); + assert( xnode && CV_NODE_IS_INT(xnode->tag) && + ynode && CV_NODE_IS_INT(ynode->tag)); + int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); + int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); + #else // the slowest yet the easiest to use variant + int x = cvReadIntByName( fs, pt, "x", 0 ); + int y = cvReadIntByName( fs, pt, "y", 0 ); + #endif + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + printf(" + } + } + cvReleaseFileStorage( &fs ); + return 0; + } +@endcode +Please note that whatever method of accessing a map you are using, it is still much slower than +using plain sequences; for example, in the above example, it is more efficient to encode the points +as pairs of integers in a single numeric sequence. +@param fs File storage +@param name Literal node name +@param len Length of the name (if it is known apriori), or -1 if it needs to be calculated +@param create_missing Flag that specifies, whether an absent key should be added into the hash table +*/ CVAPI(CvStringHashNode*) cvGetHashedKey( CvFileStorage* fs, const char* name, int len CV_DEFAULT(-1), int create_missing CV_DEFAULT(0)); -/* returns file node with the specified key within the specified map - (collection of named nodes) */ +/** @brief Retrieves one of the top-level nodes of the file storage. + +The function returns one of the top-level file nodes. The top-level nodes do not have a name, they +correspond to the streams that are stored one after another in the file storage. If the index is out +of range, the function returns a NULL pointer, so all the top-level nodes can be iterated by +subsequent calls to the function with stream_index=0,1,..., until the NULL pointer is returned. +This function can be used as a base for recursive traversal of the file storage. +@param fs File storage +@param stream_index Zero-based index of the stream. See cvStartNextStream . In most cases, +there is only one stream in the file; however, there can be several. + */ CVAPI(CvFileNode*) cvGetRootFileNode( const CvFileStorage* fs, int stream_index CV_DEFAULT(0) ); -/* returns file node with the specified key within the specified map - (collection of named nodes) */ +/** @brief Finds a node in a map or file storage. + +The function finds a file node. It is a faster version of cvGetFileNodeByName (see +cvGetHashedKey discussion). Also, the function can insert a new node, if it is not in the map yet. +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. If both map and +key are NULLs, the function returns the root file node - a map that contains top-level nodes. +@param key Unique pointer to the node name, retrieved with cvGetHashedKey +@param create_missing Flag that specifies whether an absent node should be added to the map + */ CVAPI(CvFileNode*) cvGetFileNode( CvFileStorage* fs, CvFileNode* map, const CvStringHashNode* key, int create_missing CV_DEFAULT(0) ); -/* this is a slower version of cvGetFileNode that takes the key as a literal string */ +/** @brief Finds a node in a map or file storage. + +The function finds a file node by name. The node is searched either in map or, if the pointer is +NULL, among the top-level file storage nodes. Using this function for maps and cvGetSeqElem (or +sequence reader) for sequences, it is possible to navigate through the file storage. To speed up +multiple queries for a certain key (e.g., in the case of an array of structures) one may use a +combination of cvGetHashedKey and cvGetFileNode. +@param fs File storage +@param map The parent map. If it is NULL, the function searches in all the top-level nodes +(streams), starting with the first one. +@param name The file node name + */ CVAPI(CvFileNode*) cvGetFileNodeByName( const CvFileStorage* fs, const CvFileNode* map, const char* name ); +/** @brief Retrieves an integer value from a file node. + +The function returns an integer that is represented by the file node. If the file node is NULL, the +default_value is returned (thus, it is convenient to call the function right after cvGetFileNode +without checking for a NULL pointer). If the file node has type CV_NODE_INT, then node-\>data.i is +returned. If the file node has type CV_NODE_REAL, then node-\>data.f is converted to an integer +and returned. Otherwise the error is reported. +@param node File node +@param default_value The value that is returned if node is NULL + */ CV_INLINE int cvReadInt( const CvFileNode* node, int default_value CV_DEFAULT(0) ) { return !node ? default_value : @@ -1408,14 +2320,30 @@ CV_INLINE int cvReadInt( const CvFileNode* node, int default_value CV_DEFAULT(0) CV_NODE_IS_REAL(node->tag) ? cvRound(node->data.f) : 0x7fffffff; } +/** @brief Finds a file node and returns its value. +The function is a simple superposition of cvGetFileNodeByName and cvReadInt. +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. +@param name The node name +@param default_value The value that is returned if the file node is not found + */ CV_INLINE int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, int default_value CV_DEFAULT(0) ) { return cvReadInt( cvGetFileNodeByName( fs, map, name ), default_value ); } +/** @brief Retrieves a floating-point value from a file node. +The function returns a floating-point value that is represented by the file node. If the file node +is NULL, the default_value is returned (thus, it is convenient to call the function right after +cvGetFileNode without checking for a NULL pointer). If the file node has type CV_NODE_REAL , +then node-\>data.f is returned. If the file node has type CV_NODE_INT , then node-:math:\>data.f +is converted to floating-point and returned. Otherwise the result is not determined. +@param node File node +@param default_value The value that is returned if node is NULL + */ CV_INLINE double cvReadReal( const CvFileNode* node, double default_value CV_DEFAULT(0.) ) { return !node ? default_value : @@ -1423,21 +2351,43 @@ CV_INLINE double cvReadReal( const CvFileNode* node, double default_value CV_DEF CV_NODE_IS_REAL(node->tag) ? node->data.f : 1e300; } +/** @brief Finds a file node and returns its value. +The function is a simple superposition of cvGetFileNodeByName and cvReadReal . +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. +@param name The node name +@param default_value The value that is returned if the file node is not found + */ CV_INLINE double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, double default_value CV_DEFAULT(0.) ) { return cvReadReal( cvGetFileNodeByName( fs, map, name ), default_value ); } +/** @brief Retrieves a text string from a file node. +The function returns a text string that is represented by the file node. If the file node is NULL, +the default_value is returned (thus, it is convenient to call the function right after +cvGetFileNode without checking for a NULL pointer). If the file node has type CV_NODE_STR , then +node-:math:\>data.str.ptr is returned. Otherwise the result is not determined. +@param node File node +@param default_value The value that is returned if node is NULL + */ CV_INLINE const char* cvReadString( const CvFileNode* node, const char* default_value CV_DEFAULT(NULL) ) { return !node ? default_value : CV_NODE_IS_STRING(node->tag) ? node->data.str.ptr : 0; } +/** @brief Finds a file node by its name and returns its value. +The function is a simple superposition of cvGetFileNodeByName and cvReadString . +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. +@param name The node name +@param default_value The value that is returned if the file node is not found + */ CV_INLINE const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, const char* default_value CV_DEFAULT(NULL) ) { @@ -1445,11 +2395,31 @@ CV_INLINE const char* cvReadStringByName( const CvFileStorage* fs, const CvFileN } -/* decodes standard or user-defined object and returns it */ +/** @brief Decodes an object and returns a pointer to it. + +The function decodes a user object (creates an object in a native representation from the file +storage subtree) and returns it. The object to be decoded must be an instance of a registered type +that supports the read method (see CvTypeInfo). The type of the object is determined by the type +name that is encoded in the file. If the object is a dynamic structure, it is created either in +memory storage and passed to cvOpenFileStorage or, if a NULL pointer was passed, in temporary +memory storage, which is released when cvReleaseFileStorage is called. Otherwise, if the object is +not a dynamic structure, it is created in a heap and should be released with a specialized function +or by using the generic cvRelease. +@param fs File storage +@param node The root object node +@param attributes Unused parameter + */ CVAPI(void*) cvRead( CvFileStorage* fs, CvFileNode* node, CvAttrList* attributes CV_DEFAULT(NULL)); -/* decodes standard or user-defined object and returns it */ +/** @brief Finds an object by name and decodes it. + +The function is a simple superposition of cvGetFileNodeByName and cvRead. +@param fs File storage +@param map The parent map. If it is NULL, the function searches a top-level node. +@param name The node name +@param attributes Unused parameter + */ CV_INLINE void* cvReadByName( CvFileStorage* fs, const CvFileNode* map, const char* name, CvAttrList* attributes CV_DEFAULT(NULL) ) { @@ -1457,42 +2427,158 @@ CV_INLINE void* cvReadByName( CvFileStorage* fs, const CvFileNode* map, } -/* starts reading data from sequence or scalar numeric node */ +/** @brief Initializes the file node sequence reader. + +The function initializes the sequence reader to read data from a file node. The initialized reader +can be then passed to cvReadRawDataSlice. +@param fs File storage +@param src The file node (a sequence) to read numbers from +@param reader Pointer to the sequence reader + */ CVAPI(void) cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src, CvSeqReader* reader ); -/* reads multiple numbers and stores them to array */ +/** @brief Initializes file node sequence reader. + +The function reads one or more elements from the file node, representing a sequence, to a +user-specified array. The total number of read sequence elements is a product of total and the +number of components in each array element. For example, if dt=2if, the function will read total\*3 +sequence elements. As with any sequence, some parts of the file node sequence can be skipped or read +repeatedly by repositioning the reader using cvSetSeqReaderPos. +@param fs File storage +@param reader The sequence reader. Initialize it with cvStartReadRawData . +@param count The number of elements to read +@param dst Pointer to the destination array +@param dt Specification of each array element. It has the same format as in cvWriteRawData . + */ CVAPI(void) cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, int count, void* dst, const char* dt ); -/* combination of two previous functions for easier reading of whole sequences */ +/** @brief Reads multiple numbers. + +The function reads elements from a file node that represents a sequence of scalars. +@param fs File storage +@param src The file node (a sequence) to read numbers from +@param dst Pointer to the destination array +@param dt Specification of each array element. It has the same format as in cvWriteRawData . + */ CVAPI(void) cvReadRawData( const CvFileStorage* fs, const CvFileNode* src, void* dst, const char* dt ); -/* writes a copy of file node to file storage */ +/** @brief Writes a file node to another file storage. + +The function writes a copy of a file node to file storage. Possible applications of the function are +merging several file storages into one and conversion between XML and YAML formats. +@param fs Destination file storage +@param new_node_name New name of the file node in the destination file storage. To keep the +existing name, use cvcvGetFileNodeName +@param node The written node +@param embed If the written node is a collection and this parameter is not zero, no extra level of +hierarchy is created. Instead, all the elements of node are written into the currently written +structure. Of course, map elements can only be embedded into another map, and sequence elements +can only be embedded into another sequence. + */ CVAPI(void) cvWriteFileNode( CvFileStorage* fs, const char* new_node_name, const CvFileNode* node, int embed ); -/* returns name of file node */ +/** @brief Returns the name of a file node. + +The function returns the name of a file node or NULL, if the file node does not have a name or if +node is NULL. +@param node File node + */ CVAPI(const char*) cvGetFileNodeName( const CvFileNode* node ); /*********************************** Adding own types ***********************************/ +/** @brief Registers a new type. + +The function registers a new type, which is described by info . The function creates a copy of the +structure, so the user should delete it after calling the function. +@param info Type info structure + */ CVAPI(void) cvRegisterType( const CvTypeInfo* info ); + +/** @brief Unregisters the type. + +The function unregisters a type with a specified name. If the name is unknown, it is possible to +locate the type info by an instance of the type using cvTypeOf or by iterating the type list, +starting from cvFirstType, and then calling cvUnregisterType(info-\>typeName). +@param type_name Name of an unregistered type + */ CVAPI(void) cvUnregisterType( const char* type_name ); + +/** @brief Returns the beginning of a type list. + +The function returns the first type in the list of registered types. Navigation through the list can +be done via the prev and next fields of the CvTypeInfo structure. + */ CVAPI(CvTypeInfo*) cvFirstType(void); + +/** @brief Finds a type by its name. + +The function finds a registered type by its name. It returns NULL if there is no type with the +specified name. +@param type_name Type name + */ CVAPI(CvTypeInfo*) cvFindType( const char* type_name ); + +/** @brief Returns the type of an object. + +The function finds the type of a given object. It iterates through the list of registered types and +calls the is_instance function/method for every type info structure with that object until one of +them returns non-zero or until the whole list has been traversed. In the latter case, the function +returns NULL. +@param struct_ptr The object pointer + */ CVAPI(CvTypeInfo*) cvTypeOf( const void* struct_ptr ); -/* universal functions */ +/** @brief Releases an object. + +The function finds the type of a given object and calls release with the double pointer. +@param struct_ptr Double pointer to the object + */ CVAPI(void) cvRelease( void** struct_ptr ); + +/** @brief Makes a clone of an object. + +The function finds the type of a given object and calls clone with the passed object. Of course, if +you know the object type, for example, struct_ptr is CvMat\*, it is faster to call the specific +function, like cvCloneMat. +@param struct_ptr The object to clone + */ CVAPI(void*) cvClone( const void* struct_ptr ); -/* simple API for reading/writing data */ +/** @brief Saves an object to a file. + +The function saves an object to a file. It provides a simple interface to cvWrite . +@param filename File name +@param struct_ptr Object to save +@param name Optional object name. If it is NULL, the name will be formed from filename . +@param comment Optional comment to put in the beginning of the file +@param attributes Optional attributes passed to cvWrite + */ CVAPI(void) cvSave( const char* filename, const void* struct_ptr, const char* name CV_DEFAULT(NULL), const char* comment CV_DEFAULT(NULL), CvAttrList attributes CV_DEFAULT(cvAttrList())); + +/** @brief Loads an object from a file. + +The function loads an object from a file. It basically reads the specified file, find the first +top-level node and calls cvRead for that node. If the file node does not have type information or +the type information can not be found by the type name, the function returns NULL. After the object +is loaded, the file storage is closed and all the temporary buffers are deleted. Thus, to load a +dynamic structure, such as a sequence, contour, or graph, one should pass a valid memory storage +destination to the function. +@param filename File name +@param memstorage Memory storage for dynamic structures, such as CvSeq or CvGraph . It is not used +for matrices or images. +@param name Optional object name. If it is NULL, the first top-level object in the storage will be +loaded. +@param real_name Optional output parameter that will contain the name of the loaded object +(useful if name=NULL ) + */ CVAPI(void*) cvLoad( const char* filename, CvMemStorage* memstorage CV_DEFAULT(NULL), const char* name CV_DEFAULT(NULL), @@ -1500,7 +2586,7 @@ CVAPI(void*) cvLoad( const char* filename, /*********************************** Measuring Execution Time ***************************/ -/* helper functions for RNG initialization and accurate time measurement: +/** helper functions for RNG initialization and accurate time measurement: uses internal clock counter on x86 */ CVAPI(int64) cvGetTickCount( void ); CVAPI(double) cvGetTickFrequency( void ); @@ -1511,67 +2597,64 @@ CVAPI(int) cvCheckHardwareSupport(int feature); /*********************************** Multi-Threading ************************************/ -/* retrieve/set the number of threads used in OpenMP implementations */ +/** retrieve/set the number of threads used in OpenMP implementations */ CVAPI(int) cvGetNumThreads( void ); CVAPI(void) cvSetNumThreads( int threads CV_DEFAULT(0) ); -/* get index of the thread being executed */ +/** get index of the thread being executed */ CVAPI(int) cvGetThreadNum( void ); /********************************** Error Handling **************************************/ -/* Get current OpenCV error status */ +/** Get current OpenCV error status */ CVAPI(int) cvGetErrStatus( void ); -/* Sets error status silently */ +/** Sets error status silently */ CVAPI(void) cvSetErrStatus( int status ); #define CV_ErrModeLeaf 0 /* Print error and exit program */ #define CV_ErrModeParent 1 /* Print error and continue */ #define CV_ErrModeSilent 2 /* Don't print and continue */ -/* Retrives current error processing mode */ +/** Retrives current error processing mode */ CVAPI(int) cvGetErrMode( void ); -/* Sets error processing mode, returns previously used mode */ +/** Sets error processing mode, returns previously used mode */ CVAPI(int) cvSetErrMode( int mode ); -/* Sets error status and performs some additonal actions (displaying message box, +/** Sets error status and performs some additonal actions (displaying message box, writing message to stderr, terminating application etc.) depending on the current error mode */ CVAPI(void) cvError( int status, const char* func_name, const char* err_msg, const char* file_name, int line ); -/* Retrieves textual description of the error given its code */ +/** Retrieves textual description of the error given its code */ CVAPI(const char*) cvErrorStr( int status ); -/* Retrieves detailed information about the last error occured */ +/** Retrieves detailed information about the last error occured */ CVAPI(int) cvGetErrInfo( const char** errcode_desc, const char** description, const char** filename, int* line ); -/* Maps IPP error codes to the counterparts from OpenCV */ +/** Maps IPP error codes to the counterparts from OpenCV */ CVAPI(int) cvErrorFromIppStatus( int ipp_status ); typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ); -/* Assigns a new error-handling function */ +/** Assigns a new error-handling function */ CVAPI(CvErrorCallback) cvRedirectError( CvErrorCallback error_handler, void* userdata CV_DEFAULT(NULL), void** prev_userdata CV_DEFAULT(NULL) ); -/* - Output to: - cvNulDevReport - nothing - cvStdErrReport - console(fprintf(stderr,...)) - cvGuiBoxReport - MessageBox(WIN32) - */ +/** Output nothing */ CVAPI(int) cvNulDevReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ); +/** Output to console(fprintf(stderr,...)) */ CVAPI(int) cvStdErrReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ); +/** Output to MessageBox(WIN32) */ CVAPI(int) cvGuiBoxReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ); @@ -1588,7 +2671,7 @@ Func; \ } -/* CV_FUNCNAME macro defines icvFuncName constant which is used by CV_ERROR macro */ +/** CV_FUNCNAME macro defines icvFuncName constant which is used by CV_ERROR macro */ #ifdef CV_NO_FUNC_NAMES #define CV_FUNCNAME( Name ) #define cvFuncName "" @@ -1598,7 +2681,7 @@ static char cvFuncName[] = Name #endif -/* +/** CV_ERROR macro unconditionally raises error with passed code and message. After raising error, control will be transferred to the exit label. */ @@ -1608,7 +2691,7 @@ static char cvFuncName[] = Name __CV_EXIT__; \ } -/* +/** CV_CHECK macro checks error status after CV (or IPL) function call. If error detected, control will be transferred to the exit label. @@ -1620,7 +2703,7 @@ static char cvFuncName[] = Name } -/* +/** CV_CALL macro calls CV (or IPL) function, checks error status and signals a error if the function failed. Useful in "parent node" error procesing mode @@ -1632,7 +2715,7 @@ static char cvFuncName[] = Name } -/* Runtime assertion macro */ +/** Runtime assertion macro */ #define CV_ASSERT( Condition ) \ { \ if( !(Condition) ) \ @@ -1643,12 +2726,18 @@ static char cvFuncName[] = Name #define __CV_END__ goto exit; exit: ; } #define __CV_EXIT__ goto exit +/** @} core_c */ + #ifdef __cplusplus } // extern "C" #endif #ifdef __cplusplus -// class for automatic module/RTTI data registration/unregistration + +//! @addtogroup core_c_glue +//! @{ + +//! class for automatic module/RTTI data registration/unregistration struct CV_EXPORTS CvType { CvType( const char* type_name, @@ -1661,11 +2750,16 @@ struct CV_EXPORTS CvType static CvTypeInfo* last; }; +//! @} + #include "opencv2/core/utility.hpp" namespace cv { +//! @addtogroup core_c_glue +//! @{ + /////////////////////////////////////////// glue /////////////////////////////////////////// //! converts array (CvMat or IplImage) to cv::Mat @@ -2049,6 +3143,8 @@ template inline bool operator != (const SeqIterator<_Tp>& a, return !(a == b); } +//! @} + } // cv #endif diff --git a/modules/core/include/opencv2/core/cuda.hpp b/modules/core/include/opencv2/core/cuda.hpp index 4ae4301665e577725d60530e27ac58b78502439f..612b5dbd1dc75d6529a3fe7280c1356432ff3981 100644 --- a/modules/core/include/opencv2/core/cuda.hpp +++ b/modules/core/include/opencv2/core/cuda.hpp @@ -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 { -//////////////////////////////// GpuMat /////////////////////////////// +//! @addtogroup cuda_struct +//! @{ -// Smart pointer for GPU memory with reference counting. -// Its interface is mostly similar with cv::Mat. +//////////////////////////////// GpuMat /////////////////////////////// +//! 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 { diff --git a/modules/core/include/opencv2/core/cuda.inl.hpp b/modules/core/include/opencv2/core/cuda.inl.hpp index f111bc45ab7971b3af12e081edfecec1bb37d7e1..652bcfea2910a3a14205a08e9d88fb2e39ea19c9 100644 --- a/modules/core/include/opencv2/core/cuda.inl.hpp +++ b/modules/core/include/opencv2/core/cuda.inl.hpp @@ -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 inline GpuMat::operator PtrStepSz() const { @@ -236,7 +237,6 @@ GpuMat::operator PtrStep() const { return PtrStep((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__ diff --git a/modules/core/include/opencv2/core/cuda/block.hpp b/modules/core/include/opencv2/core/cuda/block.hpp index 0d596fd348f3cff5324e460963b788267ed261e5..8377adf213b2a78857d244a8c63fd5583c67401c 100644 --- a/modules/core/include/opencv2/core/cuda/block.hpp +++ b/modules/core/include/opencv2/core/cuda/block.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__ */ diff --git a/modules/core/include/opencv2/core/cuda/border_interpolate.hpp b/modules/core/include/opencv2/core/cuda/border_interpolate.hpp index e2128abd5a1d7b0ab8ff1e0c8a6433dd09d82201..3d639b4716333657329c1c67254e73f3dd91c335 100644 --- a/modules/core/include/opencv2/core/cuda/border_interpolate.hpp +++ b/modules/core/include/opencv2/core/cuda/border_interpolate.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__ diff --git a/modules/core/include/opencv2/core/cuda/color.hpp b/modules/core/include/opencv2/core/cuda/color.hpp index 69c68af7578f82baa2cdfa4e5cd6fc3edefc0f0e..524d2e2a478f2250e7b97725031849a5bdd26d38 100644 --- a/modules/core/include/opencv2/core/cuda/color.hpp +++ b/modules/core/include/opencv2/core/cuda/color.hpp @@ -47,6 +47,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ // All OPENCV_CUDA_IMPLEMENT_*_TRAITS(ColorSpace1_to_ColorSpace2, ...) macros implements // template 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__ diff --git a/modules/core/include/opencv2/core/cuda/common.hpp b/modules/core/include/opencv2/core/cuda/common.hpp index 5e5884153a3d02aed635a596efb0de1cc2ca5cbd..022b13ebb6c0d4bd4c99ac53d4e373bc0091def6 100644 --- a/modules/core/include/opencv2/core/cuda/common.hpp +++ b/modules/core/include/opencv2/core/cuda/common.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 static inline bool isAligned(const T* ptr, size_t size) { return reinterpret_cast(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(); cudaSafeCall( cudaBindTexture2D(0, tex, img.ptr(), &desc, img.cols, img.rows, img.step) ); } +//! @} } }} - - #endif // __OPENCV_CUDA_COMMON_HPP__ diff --git a/modules/core/include/opencv2/core/cuda/datamov_utils.hpp b/modules/core/include/opencv2/core/cuda/datamov_utils.hpp index aea88a35cd4713459b614f17eddb891340e0871c..4d4035a3a30081853401b8b0977dca1912487c29 100644 --- a/modules/core/include/opencv2/core/cuda/datamov_utils.hpp +++ b/modules/core/include/opencv2/core/cuda/datamov_utils.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__ diff --git a/modules/core/include/opencv2/core/cuda/detail/color_detail.hpp b/modules/core/include/opencv2/core/cuda/detail/color_detail.hpp index 095ca669e466c059ffb1d1f5e9e79567bad2764e..115180676499978dc5377e74cf9f5998428041b7 100644 --- a/modules/core/include/opencv2/core/cuda/detail/color_detail.hpp +++ b/modules/core/include/opencv2/core/cuda/detail/color_detail.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__ diff --git a/modules/core/include/opencv2/core/cuda/detail/reduce.hpp b/modules/core/include/opencv2/core/cuda/detail/reduce.hpp index c1ba68c8213b270ef7060173f27cb16dda6f36f9..0c35eaba65088a963de51f1a5c270f9706449997 100644 --- a/modules/core/include/opencv2/core/cuda/detail/reduce.hpp +++ b/modules/core/include/opencv2/core/cuda/detail/reduce.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__ diff --git a/modules/core/include/opencv2/core/cuda/detail/reduce_key_val.hpp b/modules/core/include/opencv2/core/cuda/detail/reduce_key_val.hpp index ed179ad78ca66f1495bb4d3f0c154143b364cbd1..bab85d70cd591dff321819540459385ac8893c8c 100644 --- a/modules/core/include/opencv2/core/cuda/detail/reduce_key_val.hpp +++ b/modules/core/include/opencv2/core/cuda/detail/reduce_key_val.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__ diff --git a/modules/core/include/opencv2/core/cuda/detail/transform_detail.hpp b/modules/core/include/opencv2/core/cuda/detail/transform_detail.hpp index a241e0bb382ba9dc097f357ca75414b08b64ef6c..96031c8cde3b1af567aca3faf9a232ff67955adf 100644 --- a/modules/core/include/opencv2/core/cuda/detail/transform_detail.hpp +++ b/modules/core/include/opencv2/core/cuda/detail/transform_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__ diff --git a/modules/core/include/opencv2/core/cuda/detail/type_traits_detail.hpp b/modules/core/include/opencv2/core/cuda/detail/type_traits_detail.hpp index 8324a31e0e914e1438c1230dcaee3531e0553338..3463c78fecd444f4b4671ea93067a4b641bc98d8 100644 --- a/modules/core/include/opencv2/core/cuda/detail/type_traits_detail.hpp +++ b/modules/core/include/opencv2/core/cuda/detail/type_traits_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__ diff --git a/modules/core/include/opencv2/core/cuda/detail/vec_distance_detail.hpp b/modules/core/include/opencv2/core/cuda/detail/vec_distance_detail.hpp index a62c51a57380c58b113d2834e238573866873e73..9ca85a539dfe224715a09218a35784a241f029d1 100644 --- a/modules/core/include/opencv2/core/cuda/detail/vec_distance_detail.hpp +++ b/modules/core/include/opencv2/core/cuda/detail/vec_distance_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__ diff --git a/modules/core/include/opencv2/core/cuda/dynamic_smem.hpp b/modules/core/include/opencv2/core/cuda/dynamic_smem.hpp index 269e18a8f08d5f17ca6d87cdd3af2ad5c1686bd6..8d71532ae7e99d0429b39ee1a43bc5f948f0a25a 100644 --- a/modules/core/include/opencv2/core/cuda/dynamic_smem.hpp +++ b/modules/core/include/opencv2/core/cuda/dynamic_smem.hpp @@ -45,6 +45,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template 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__ diff --git a/modules/core/include/opencv2/core/cuda/emulation.hpp b/modules/core/include/opencv2/core/cuda/emulation.hpp index 16fe2986bc6ca20d263e8e1d20fb09a9ff1556d3..3063266b7794425ece4f080bb70e193fc951406d 100644 --- a/modules/core/include/opencv2/core/cuda/emulation.hpp +++ b/modules/core/include/opencv2/core/cuda/emulation.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_ */ diff --git a/modules/core/include/opencv2/core/cuda/filters.hpp b/modules/core/include/opencv2/core/cuda/filters.hpp index f3cbf695895e6b1e4d8b6dfd89b2f5a00cdb12ae..8bec9fe261872bd605c9a918338e5fe2f23ee9dc 100644 --- a/modules/core/include/opencv2/core/cuda/filters.hpp +++ b/modules/core/include/opencv2/core/cuda/filters.hpp @@ -50,6 +50,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template 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__ diff --git a/modules/core/include/opencv2/core/cuda/funcattrib.hpp b/modules/core/include/opencv2/core/cuda/funcattrib.hpp index 7085cba0f6523e3fb0ed156f753fa0a246537f91..fa2039ab2b4cc595e52a484ecb7531938ec76d9f 100644 --- a/modules/core/include/opencv2/core/cuda/funcattrib.hpp +++ b/modules/core/include/opencv2/core/cuda/funcattrib.hpp @@ -47,6 +47,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template 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_ */ diff --git a/modules/core/include/opencv2/core/cuda/functional.hpp b/modules/core/include/opencv2/core/cuda/functional.hpp index bebb8bf070314e252bf0733bbe39b6bfbcee47a5..3060bbc680fb49cf01ade759025cf0d1d2a90b67 100644 --- a/modules/core/include/opencv2/core/cuda/functional.hpp +++ b/modules/core/include/opencv2/core/cuda/functional.hpp @@ -51,6 +51,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ // Function Objects template struct unary_function : public std::unary_function {}; template struct binary_function : public std::binary_function {}; @@ -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__ diff --git a/modules/core/include/opencv2/core/cuda/limits.hpp b/modules/core/include/opencv2/core/cuda/limits.hpp index abfdca36730d062fc44ecd73e9f5ec897374e7d5..e22d99d00bac3c38a3aa1f0edb0eb2dd942be0d2 100644 --- a/modules/core/include/opencv2/core/cuda/limits.hpp +++ b/modules/core/include/opencv2/core/cuda/limits.hpp @@ -49,7 +49,8 @@ namespace cv { namespace cuda { namespace device { - +//! @addtogroup cuda +//! @{ template struct numeric_limits; template <> struct numeric_limits @@ -116,7 +117,7 @@ template <> struct numeric_limits __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__ diff --git a/modules/core/include/opencv2/core/cuda/reduce.hpp b/modules/core/include/opencv2/core/cuda/reduce.hpp index 8112203e6c8ca4c5705ad1ae63dae61cd11a0309..0f18b1e4042a83d6c87e770f8dd4f24c4d191700 100644 --- a/modules/core/include/opencv2/core/cuda/reduce.hpp +++ b/modules/core/include/opencv2/core/cuda/reduce.hpp @@ -49,6 +49,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template __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__ diff --git a/modules/core/include/opencv2/core/cuda/saturate_cast.hpp b/modules/core/include/opencv2/core/cuda/saturate_cast.hpp index 84e19180755e9276ea7e9ea9c737581035ad1677..46927a50977593cf36a4f9ae6cdd1e9fa6db7e63 100644 --- a/modules/core/include/opencv2/core/cuda/saturate_cast.hpp +++ b/modules/core/include/opencv2/core/cuda/saturate_cast.hpp @@ -47,6 +47,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template __device__ __forceinline__ _Tp saturate_cast(uchar v) { return _Tp(v); } template __device__ __forceinline__ _Tp saturate_cast(schar v) { return _Tp(v); } template __device__ __forceinline__ _Tp saturate_cast(ushort v) { return _Tp(v); } @@ -279,6 +281,7 @@ namespace cv { namespace cuda { namespace device return saturate_cast((float)v); #endif } +//! @} }}} #endif /* __OPENCV_CUDA_SATURATE_CAST_HPP__ */ diff --git a/modules/core/include/opencv2/core/cuda/scan.hpp b/modules/core/include/opencv2/core/cuda/scan.hpp index 33cb62e9403e3dfd6b8f00bb9d950a5c54ce6d6d..e1dbb0059f910daa36775b1efd22ea873b4970dc 100644 --- a/modules/core/include/opencv2/core/cuda/scan.hpp +++ b/modules/core/include/opencv2/core/cuda/scan.hpp @@ -50,6 +50,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ enum ScanKind { EXCLUSIVE = 0, INCLUSIVE = 1 }; template struct WarpScan @@ -245,6 +247,7 @@ namespace cv { namespace cuda { namespace device return warpScanInclusive(idata, s_Data, tid); } } +//! @} }}} #endif // __OPENCV_CUDA_SCAN_HPP__ diff --git a/modules/core/include/opencv2/core/cuda/simd_functions.hpp b/modules/core/include/opencv2/core/cuda/simd_functions.hpp index 0a7889e00d612fa815c301620cc0d02092f004ef..d6b743541993608bce2712aae8c0b939280be06e 100644 --- a/modules/core/include/opencv2/core/cuda/simd_functions.hpp +++ b/modules/core/include/opencv2/core/cuda/simd_functions.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__ diff --git a/modules/core/include/opencv2/core/cuda/transform.hpp b/modules/core/include/opencv2/core/cuda/transform.hpp index 236af6690b3b8efdf5f85f6b34e8a0d3af26c118..bc86bd1e86e67c1658467a3ae5702d473189de94 100644 --- a/modules/core/include/opencv2/core/cuda/transform.hpp +++ b/modules/core/include/opencv2/core/cuda/transform.hpp @@ -49,6 +49,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template static inline void transform(PtrStepSz src, PtrStepSz dst, UnOp op, const Mask& mask, cudaStream_t stream) { @@ -62,6 +64,7 @@ namespace cv { namespace cuda { namespace device typedef TransformFunctorTraits ft; transform_detail::TransformDispatcher::cn == 1 && VecTraits::cn == 1 && VecTraits::cn == 1 && ft::smart_shift != 1>::call(src1, src2, dst, op, mask, stream); } +//! @} }}} #endif // __OPENCV_CUDA_TRANSFORM_HPP__ diff --git a/modules/core/include/opencv2/core/cuda/type_traits.hpp b/modules/core/include/opencv2/core/cuda/type_traits.hpp index d06a374c52dfe43dd3defe8863cc23e97ee731c0..a9e9180698a0f6238a3b1afff8d766d3bb8e5569 100644 --- a/modules/core/include/opencv2/core/cuda/type_traits.hpp +++ b/modules/core/include/opencv2/core/cuda/type_traits.hpp @@ -47,6 +47,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template struct IsSimpleParameter { enum {value = type_traits_detail::IsIntegral::value || type_traits_detail::IsFloat::value || @@ -77,6 +79,7 @@ namespace cv { namespace cuda { namespace device typedef typename type_traits_detail::Select::value, T, typename type_traits_detail::AddParameterType::type>::type ParameterType; }; +//! @} }}} #endif // __OPENCV_CUDA_TYPE_TRAITS_HPP__ diff --git a/modules/core/include/opencv2/core/cuda/utility.hpp b/modules/core/include/opencv2/core/cuda/utility.hpp index 841638725fb25737ba6c80dcc600ab7766dd5bf4..ad6c7094acbdf4c1fe5d3cf4a3f2c5c00b252e04 100644 --- a/modules/core/include/opencv2/core/cuda/utility.hpp +++ b/modules/core/include/opencv2/core/cuda/utility.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__ diff --git a/modules/core/include/opencv2/core/cuda/vec_distance.hpp b/modules/core/include/opencv2/core/cuda/vec_distance.hpp index 2a00303a334653d4d1c72f7d0278c2a8469ca2b6..4bad198e0cb968cde9549e48e045924bf303477b 100644 --- a/modules/core/include/opencv2/core/cuda/vec_distance.hpp +++ b/modules/core/include/opencv2/core/cuda/vec_distance.hpp @@ -49,6 +49,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template 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__ diff --git a/modules/core/include/opencv2/core/cuda/vec_math.hpp b/modules/core/include/opencv2/core/cuda/vec_math.hpp index 2b774d7f29d4c9c84baa07c03de2ad1886f8e293..ac4a493d683b5fa76c456ac7910921ebea221b9e 100644 --- a/modules/core/include/opencv2/core/cuda/vec_math.hpp +++ b/modules/core/include/opencv2/core/cuda/vec_math.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__ diff --git a/modules/core/include/opencv2/core/cuda/vec_traits.hpp b/modules/core/include/opencv2/core/cuda/vec_traits.hpp index 17f0ee746ada11d44c5108785c968bcb003b437f..6369112ffa4bbe275817c442f9fe219d1c487beb 100644 --- a/modules/core/include/opencv2/core/cuda/vec_traits.hpp +++ b/modules/core/include/opencv2/core/cuda/vec_traits.hpp @@ -47,6 +47,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template 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__ diff --git a/modules/core/include/opencv2/core/cuda/warp.hpp b/modules/core/include/opencv2/core/cuda/warp.hpp index c9659d6aa8e340aadb7cd517fd366b5715c99a98..67abd05728c74390cffd8f34fad2c037d7890a54 100644 --- a/modules/core/include/opencv2/core/cuda/warp.hpp +++ b/modules/core/include/opencv2/core/cuda/warp.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__ */ diff --git a/modules/core/include/opencv2/core/cuda/warp_reduce.hpp b/modules/core/include/opencv2/core/cuda/warp_reduce.hpp index 5f0f8dbf17069085f9f3c08c0fa0a6c1b45c6d4d..6df04bb028453fce03618c0677e0a82aebab8af3 100644 --- a/modules/core/include/opencv2/core/cuda/warp_reduce.hpp +++ b/modules/core/include/opencv2/core/cuda/warp_reduce.hpp @@ -45,6 +45,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template __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__ */ diff --git a/modules/core/include/opencv2/core/cuda/warp_shuffle.hpp b/modules/core/include/opencv2/core/cuda/warp_shuffle.hpp index e75e741395487ddeed03ecbc5c02d75b723b1563..f614946730f1b39713495e3b7f01cf0f6ffed2a9 100644 --- a/modules/core/include/opencv2/core/cuda/warp_shuffle.hpp +++ b/modules/core/include/opencv2/core/cuda/warp_shuffle.hpp @@ -45,6 +45,8 @@ namespace cv { namespace cuda { namespace device { +//! @addtogroup cuda +//! @{ template __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__ diff --git a/modules/core/include/opencv2/core/cuda_stream_accessor.hpp b/modules/core/include/opencv2/core/cuda_stream_accessor.hpp index 5b058fa45fb89f0b565db49a364a5db891879cf0..4eb4ba61ad5899a3fa386d6a6fa6e0c1ea96985a 100644 --- a/modules/core/include/opencv2/core/cuda_stream_accessor.hpp +++ b/modules/core/include/opencv2/core/cuda_stream_accessor.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); }; + +//! @} + } } diff --git a/modules/core/include/opencv2/core/cuda_types.hpp b/modules/core/include/opencv2/core/cuda_types.hpp index a82f8ac7382d31fd63440510f9546423a74eb29e..ec67ae08ba7479a22be448ea7e934552f2d13b17 100644 --- a/modules/core/include/opencv2/core/cuda_types.hpp +++ b/modules/core/include/opencv2/core/cuda_types.hpp @@ -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 PtrStepb; typedef PtrStep PtrStepf; typedef PtrStep PtrStepi; + +//! @} + } } diff --git a/modules/core/include/opencv2/core/cvdef.h b/modules/core/include/opencv2/core/cvdef.h index 1f64cd2ace0d851a3bccf13540b998fee2d40c90..482d97240b6f9e8e6c2b7db056c3ebd06da39425 100644 --- a/modules/core/include/opencv2/core/cvdef.h +++ b/modules/core/include/opencv2/core/cvdef.h @@ -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 * \****************************************************************************************/ diff --git a/modules/core/include/opencv2/core/cvstd.hpp b/modules/core/include/opencv2/core/cvstd.hpp index f15e6a93519e62095e2597766db97904eb37136a..800357bd21b0f747c07a5b152449437c894a5d1c 100644 --- a/modules/core/include/opencv2/core/cvstd.hpp +++ b/modules/core/include/opencv2/core/cvstd.hpp @@ -102,26 +102,26 @@ namespace cv namespace cv { -//////////////////////////// memory management functions //////////////////////////// +//! @addtogroup core_utils +//! @{ -/*! - Allocates memory buffer +//////////////////////////// memory management functions //////////////////////////// - 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. +/** @brief Allocates an aligned memory buffer. - \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. - - A Ptr 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. - - The interface of this class is mostly a subset of that of C++11's - std::shared_ptr. +//! @endcond + +//! @addtogroup core_basic +//! @{ + +/** @brief Template class for smart pointers with shared ownership + +A Ptr\ 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 +() 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\ 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 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::operator() for that type, like this: +@code + namespace cv { + template<> void DefaultDeleter::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 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 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\() 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 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 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(Ptr(), 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 Ptr(const Ptr& 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 Ptr(const Ptr& 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 Ptr& operator = (const Ptr& 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(p). */ + /** + `ptr.reset(...)` is equivalent to `ptr = Ptr(...)`. + @param p Pointer to own. + */ template void reset(Y* p); - /* Equivalent to assigning from Ptr(p, d). */ + /** @overload + @param d Deleter to use for the owned pointer. + @param p Pointer to own. + */ template 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::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 Ptr staticCast() const; - /* Ditto for const_cast. */ + /** Ditto for const_cast. */ template Ptr constCast() const; - /* Ditto for dynamic_cast. */ + /** Ditto for dynamic_cast. */ template Ptr 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 void swap(Ptr& ptr1, Ptr& ptr2); -/* Obvious comparisons. */ +/** Return whether ptr1.get() and ptr2.get() are equal and not equal, respectively. */ template bool operator == (const Ptr& ptr1, const Ptr& ptr2); template bool operator != (const Ptr& ptr1, const Ptr& ptr2); -/* Convenience creation functions. In the far future, there may be variadic templates here. */ +/** `makePtr(...)` is equivalent to `Ptr(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 Ptr makePtr(); +/** @overload */ template Ptr makePtr(const A1& a1); +/** @overload */ template Ptr makePtr(const A1& a1, const A2& a2); +/** @overload */ template Ptr makePtr(const A1& a1, const A2& a2, const A3& a3); +/** @overload */ template Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4); +/** @overload */ template Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5); +/** @overload */ template Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6); +/** @overload */ template Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7); +/** @overload */ template Ptr 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 Ptr 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 Ptr 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 diff --git a/modules/core/include/opencv2/core/cvstd.inl.hpp b/modules/core/include/opencv2/core/cvstd.inl.hpp index 724f2f3815afba33c7dc3352bed6d9406eefd562..03bac3729c0644449e710b70e5ea71d1e82bdf40 100644 --- a/modules/core/include/opencv2/core/cvstd.inl.hpp +++ b/modules/core/include/opencv2/core/cvstd.inl.hpp @@ -49,6 +49,8 @@ # include #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__ diff --git a/modules/core/include/opencv2/core/directx.hpp b/modules/core/include/opencv2/core/directx.hpp index d7e38a12a148c472e480fc948975e0790cea627d..837548e51be94ae2591eaa45cc05bbb000d9d55e 100644 --- a/modules/core/include/opencv2/core/directx.hpp +++ b/modules/core/include/opencv2/core/directx.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 diff --git a/modules/core/include/opencv2/core/eigen.hpp b/modules/core/include/opencv2/core/eigen.hpp index 3005bfbfd454d65ba17c5668fb814aa2964e30b0..44df04c506af1d79460956550ab1ddd480a4d357 100644 --- a/modules/core/include/opencv2/core/eigen.hpp +++ b/modules/core/include/opencv2/core/eigen.hpp @@ -56,6 +56,9 @@ namespace cv { +//! @addtogroup core_eigen +//! @{ + template 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 diff --git a/modules/core/include/opencv2/core/ippasync.hpp b/modules/core/include/opencv2/core/ippasync.hpp index e40a0aa2f131fa97c702f8f77bc5513949fe2f8f..2fce5d5b93947bd803282f3e2513fb487647a793 100644 --- a/modules/core/include/opencv2/core/ippasync.hpp +++ b/modules/core/include/opencv2/core/ippasync.hpp @@ -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 \ No newline at end of file +#endif diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index cc589a06758f4f20308d69152b14a04a7cad93ec..2e4abf40302085fd3256cf6b42a295d5190f7924 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -56,6 +56,9 @@ namespace cv { +//! @addtogroup core_basic +//! @{ + enum { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25, ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 }; @@ -63,8 +66,82 @@ class CV_EXPORTS _OutputArray; //////////////////////// Input/Output Array Arguments ///////////////////////////////// -/*! - Proxy datatype for passing Mat's and vector<>'s as input parameters +/** @brief This is the proxy class for passing read-only input arrays into OpenCV functions. + +It is defined as: +@code + typedef const _InputArray& InputArray; +@endcode +where _InputArray is a class that can be constructed from `Mat`, `Mat_`, `Matx`, +`std::vector`, `std::vector >` or `std::vector`. It can also be constructed +from a matrix expression. + +Since this is mostly implementation-level class, and its interface may change in future versions, we +do not describe it in details. There are a few key things, though, that should be kept in mind: + +- When you see in the reference manual or in OpenCV source code a function that takes + InputArray, it means that you can actually pass `Mat`, `Matx`, `vector` etc. (see above the + complete list). +- Optional input arguments: If some of the input arrays may be empty, pass cv::noArray() (or + simply cv::Mat() as you probably did before). +- The class is designed solely for passing parameters. That is, normally you *should not* + declare class members, local and global variables of this type. +- If you want to design your own function or a class method that can operate of arrays of + multiple types, you can use InputArray (or OutputArray) for the respective parameters. Inside + a function you should use _InputArray::getMat() method to construct a matrix header for the + array (without copying data). _InputArray::kind() can be used to distinguish Mat from + `vector<>` etc., but normally it is not needed. + +Here is how you can use a function that takes InputArray : +@code + std::vector vec; + // points or a circle + for( int i = 0; i < 30; i++ ) + vec.push_back(Point2f((float)(100 + 30*cos(i*CV_PI*2/5)), + (float)(100 - 30*sin(i*CV_PI*2/5)))); + cv::transform(vec, vec, cv::Matx23f(0.707, -0.707, 10, 0.707, 0.707, 20)); +@endcode +That is, we form an STL vector containing points, and apply in-place affine transformation to the +vector using the 2x3 matrix created inline as `Matx` instance. + +Here is how such a function can be implemented (for simplicity, we implement a very specific case of +it, according to the assertion statement inside) : +@code + void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m) + { + // get Mat headers for input arrays. This is O(1) operation, + // unless _src and/or _m are matrix expressions. + Mat src = _src.getMat(), m = _m.getMat(); + CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) ); + + // [re]create the output array so that it has the proper size and type. + // In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize. + _dst.create(src.size(), src.type()); + Mat dst = _dst.getMat(); + + for( int i = 0; i < src.rows; i++ ) + for( int j = 0; j < src.cols; j++ ) + { + Point2f pt = src.at(i, j); + dst.at(i, j) = Point2f(m.at(0, 0)*pt.x + + m.at(0, 1)*pt.y + + m.at(0, 2), + m.at(1, 0)*pt.x + + m.at(1, 1)*pt.y + + m.at(1, 2)); + } + } +@endcode +There is another related type, InputArrayOfArrays, which is currently defined as a synonym for +InputArray: +@code + typedef InputArray InputArrayOfArrays; +@endcode +It denotes function arguments that are either vectors of vectors or vectors of matrices. A separate +synonym is needed to generate Python/Java etc. wrappers properly. At the function implementation +level their use is similar, but _InputArray::getMat(idx) should be used to get header for the +idx-th component of the outer vector and _InputArray::size().area() should be used to find the +number of components (vectors/matrices) of the outer vector. */ class CV_EXPORTS _InputArray { @@ -152,8 +229,30 @@ protected: }; -/*! - Proxy datatype for passing Mat's and vector<>'s as input parameters +/** @brief This type is very similar to InputArray except that it is used for input/output and output function +parameters. + +Just like with InputArray, OpenCV users should not care about OutputArray, they just pass `Mat`, +`vector` etc. to the functions. The same limitation as for `InputArray`: *Do not explicitly +create OutputArray instances* applies here too. + +If you want to make your function polymorphic (i.e. accept different arrays as output parameters), +it is also not very difficult. Take the sample above as the reference. Note that +_OutputArray::create() needs to be called before _OutputArray::getMat(). This way you guarantee +that the output array is properly allocated. + +Optional output parameters. If you do not need certain output array to be computed and returned to +you, pass cv::noArray(), just like you would in the case of optional input array. At the +implementation level, use _OutputArray::needed() to check if certain output array needs to be +computed or not. + +There are several synonyms for OutputArray that are used to assist automatic Python/Java/... wrapper +generators: +@code + typedef OutputArray OutputArrayOfArrays; + typedef OutputArray InputOutputArray; + typedef OutputArray InputOutputArrayOfArrays; +@endcode */ class CV_EXPORTS _OutputArray : public _InputArray { @@ -286,9 +385,7 @@ enum UMatUsageFlags struct CV_EXPORTS UMatData; -/*! - Custom array allocator - +/** @brief Custom array allocator */ class CV_EXPORTS MatAllocator { @@ -323,8 +420,7 @@ public: //////////////////////////////// MatCommaInitializer ////////////////////////////////// -/*! - Comma-separated Matrix Initializer +/** @brief Comma-separated Matrix Initializer The class instances are usually not created explicitly. Instead, they are created on "matrix << firstValue" operator. @@ -429,255 +525,399 @@ protected: MatStep& operator = (const MatStep&); }; - /*! - The n-dimensional matrix class. - - The class represents an n-dimensional dense numerical array that can act as - a matrix, image, optical flow map, 3-focal tensor etc. - It is very similar to CvMat and CvMatND types from earlier versions of OpenCV, - and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism. - - There are many different ways to create cv::Mat object. Here are the some popular ones: -
    -
  • using cv::Mat::create(nrows, ncols, type) method or - the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor. - A new matrix of the specified size and specifed type will be allocated. - "type" has the same meaning as in cvCreateMat function, - e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex) - floating-point matrix etc: - - \code - // make 7x7 complex matrix filled with 1+3j. - cv::Mat M(7,7,CV_32FC2,Scalar(1,3)); - // and now turn M to 100x60 15-channel 8-bit matrix. - // The old content will be deallocated - M.create(100,60,CV_8UC(15)); - \endcode - - As noted in the introduction of this chapter, Mat::create() - will only allocate a new matrix when the current matrix dimensionality - or type are different from the specified. - -
  • by using a copy constructor or assignment operator, where on the right side it can - be a matrix or expression, see below. Again, as noted in the introduction, - matrix assignment is O(1) operation because it only copies the header - and increases the reference counter. cv::Mat::clone() method can be used to get a full - (a.k.a. deep) copy of the matrix when you need it. - -
  • by constructing a header for a part of another matrix. It can be a single row, single column, - several rows, several columns, rectangular region in the matrix (called a minor in algebra) or - a diagonal. Such operations are also O(1), because the new header will reference the same data. - You can actually modify a part of the matrix using this feature, e.g. - - \code - // add 5-th row, multiplied by 3 to the 3rd row - M.row(3) = M.row(3) + M.row(5)*3; - - // now copy 7-th column to the 1-st column - // M.col(1) = M.col(7); // this will not work - Mat M1 = M.col(1); - M.col(7).copyTo(M1); - - // create new 320x240 image - cv::Mat img(Size(320,240),CV_8UC3); - // select a roi - cv::Mat roi(img, Rect(10,10,100,100)); - // fill the ROI with (0,255,0) (which is green in RGB space); - // the original 320x240 image will be modified - roi = Scalar(0,255,0); - \endcode - - Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to - compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI(): - - \code - Mat A = Mat::eye(10, 10, CV_32S); - // extracts A columns, 1 (inclusive) to 3 (exclusive). - Mat B = A(Range::all(), Range(1, 3)); - // extracts B rows, 5 (inclusive) to 9 (exclusive). - // that is, C ~ A(Range(5, 9), Range(1, 3)) - Mat C = B(Range(5, 9), Range::all()); - Size size; Point ofs; - C.locateROI(size, ofs); - // size will be (width=10,height=10) and the ofs will be (x=1, y=5) - \endcode - - As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method - of the extracted sub-matrices. - -
  • by making a header for user-allocated-data. It can be useful for -
      -
    1. processing "foreign" data using OpenCV (e.g. when you implement - a DirectShow filter or a processing module for gstreamer etc.), e.g. - - \code - void process_video_frame(const unsigned char* pixels, - int width, int height, int step) - { - cv::Mat img(height, width, CV_8UC3, pixels, step); - cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5); - } - \endcode - -
    2. for quick initialization of small matrices and/or super-fast element access - - \code - double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; - cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv(); - \endcode -
    - - partial yet very common cases of this "user-allocated data" case are conversions - from CvMat and IplImage to cv::Mat. For this purpose there are special constructors - taking pointers to CvMat or IplImage and the optional - flag indicating whether to copy the data or not. - - Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators - cv::Mat::operator CvMat() an cv::Mat::operator IplImage(). - The operators do not copy the data. - - - \code - IplImage* img = cvLoadImage("greatwave.jpg", 1); - Mat mtx(img); // convert IplImage* -> cv::Mat - CvMat oldmat = mtx; // convert cv::Mat -> CvMat - CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height && - oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep); - \endcode - -
  • by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.: - - \code - // create a double-precision identity martix and add it to M. - M += Mat::eye(M.rows, M.cols, CV_64F); - \endcode - -
  • by using comma-separated initializer: - - \code - // create 3x3 double-precision identity matrix - Mat M = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1); - \endcode - - here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix, - and then we just put "<<" operator followed by comma-separated values that can be constants, - variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors. - -
- - Once matrix is created, it will be automatically managed by using reference-counting mechanism - (unless the matrix header is built on top of user-allocated data, - in which case you should handle the data by yourself). - The matrix data will be deallocated when no one points to it; - if you want to release the data pointed by a matrix header before the matrix destructor is called, - use cv::Mat::release(). - - The next important thing to learn about the matrix class is element access. Here is how the matrix is stored. - The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row, - cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member, - cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be - a part of another matrix or because there can some padding space in the end of each row for a proper alignment. - - Given these parameters, address of the matrix element M_{ij} is computed as following: - - addr(M_{ij})=M.data + M.step*i + j*M.elemSize() - - if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method: - - addr(M_{ij})=&M.at(i,j) - - (where & is used to convert the reference returned by cv::Mat::at() to a pointer). - if you need to process a whole row of matrix, the most efficient way is to get - the pointer to the row first, and then just use plain C operator []: - - \code - // compute sum of positive matrix elements - // (assuming that M is double-precision matrix) - double sum=0; - for(int i = 0; i < M.rows; i++) - { - const double* Mi = M.ptr(i); - for(int j = 0; j < M.cols; j++) - sum += std::max(Mi[j], 0.); - } - \endcode - - Some operations, like the above one, do not actually depend on the matrix shape, - they just process elements of a matrix one by one (or elements from multiple matrices - that are sitting in the same place, e.g. matrix addition). Such operations are called - element-wise and it makes sense to check whether all the input/output matrices are continuous, - i.e. have no gaps in the end of each row, and if yes, process them as a single long row: - - \code - // compute sum of positive matrix elements, optimized variant - double sum=0; - int cols = M.cols, rows = M.rows; - if(M.isContinuous()) - { - cols *= rows; - rows = 1; - } - for(int i = 0; i < rows; i++) - { - const double* Mi = M.ptr(i); - for(int j = 0; j < cols; j++) - sum += std::max(Mi[j], 0.); - } - \endcode - in the case of continuous matrix the outer loop body will be executed just once, - so the overhead will be smaller, which will be especially noticeable in the case of small matrices. - - Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: - \code - // compute sum of positive matrix elements, iterator-based variant - double sum=0; - MatConstIterator_ it = M.begin(), it_end = M.end(); - for(; it != it_end; ++it) - sum += std::max(*it, 0.); - \endcode - - The matrix iterators are random-access iterators, so they can be passed - to any STL algorithm, including std::sort(). +/** @example cout_mat.cpp +An example demonstrating the serial out capabilities of cv::Mat +*/ + + /** @brief n-dimensional dense array class + +The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array. It +can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel +volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms +may be better stored in a SparseMat ). The data layout of the array `M` is defined by the array +`M.step[]`, so that the address of element \f$(i_0,...,i_{M.dims-1})\f$, where \f$0\leq i_k= M.step[i+1]` (in fact, `M.step[i] >= M.step[i+1]*M.size[i+1]` ). This means +that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane, +and so on. M.step[M.dims-1] is minimal and always equal to the element size M.elemSize() . + +So, the data layout in Mat is fully compatible with CvMat, IplImage, and CvMatND types from OpenCV +1.x. It is also compatible with the majority of dense array types from the standard toolkits and +SDKs, such as Numpy (ndarray), Win32 (independent device bitmaps), and others, that is, with any +array that uses *steps* (or *strides*) to compute the position of a pixel. Due to this +compatibility, it is possible to make a Mat header for user-allocated data and process it in-place +using OpenCV functions. + +There are many different ways to create a Mat object. The most popular options are listed below: + +- Use the create(nrows, ncols, type) method or the similar Mat(nrows, ncols, type[, fillValue]) +constructor. A new array of the specified size and type is allocated. type has the same meaning as +in the cvCreateMat method. For example, CV_8UC1 means a 8-bit single-channel array, CV_32FC2 +means a 2-channel (complex) floating-point array, and so on. +@code + // make a 7x7 complex matrix filled with 1+3j. + Mat M(7,7,CV_32FC2,Scalar(1,3)); + // and now turn M to a 100x60 15-channel 8-bit matrix. + // The old content will be deallocated + M.create(100,60,CV_8UC(15)); +@endcode +As noted in the introduction to this chapter, create() allocates only a new array when the shape +or type of the current array are different from the specified ones. + +- Create a multi-dimensional array: +@code + // create a 100x100x100 8-bit array + int sz[] = {100, 100, 100}; + Mat bigCube(3, sz, CV_8U, Scalar::all(0)); +@endcode +It passes the number of dimensions =1 to the Mat constructor but the created array will be +2-dimensional with the number of columns set to 1. So, Mat::dims is always \>= 2 (can also be 0 +when the array is empty). + +- Use a copy constructor or assignment operator where there can be an array or expression on the +right side (see below). As noted in the introduction, the array assignment is an O(1) operation +because it only copies the header and increases the reference counter. The Mat::clone() method can +be used to get a full (deep) copy of the array when you need it. + +- Construct a header for a part of another array. It can be a single row, single column, several +rows, several columns, rectangular region in the array (called a *minor* in algebra) or a +diagonal. Such operations are also O(1) because the new header references the same data. You can +actually modify a part of the array using this feature, for example: +@code + // add the 5-th row, multiplied by 3 to the 3rd row + M.row(3) = M.row(3) + M.row(5)*3; + // now copy the 7-th column to the 1-st column + // M.col(1) = M.col(7); // this will not work + Mat M1 = M.col(1); + M.col(7).copyTo(M1); + // create a new 320x240 image + Mat img(Size(320,240),CV_8UC3); + // select a ROI + Mat roi(img, Rect(10,10,100,100)); + // fill the ROI with (0,255,0) (which is green in RGB space); + // the original 320x240 image will be modified + roi = Scalar(0,255,0); +@endcode +Due to the additional datastart and dataend members, it is possible to compute a relative +sub-array position in the main *container* array using locateROI(): +@code + Mat A = Mat::eye(10, 10, CV_32S); + // extracts A columns, 1 (inclusive) to 3 (exclusive). + Mat B = A(Range::all(), Range(1, 3)); + // extracts B rows, 5 (inclusive) to 9 (exclusive). + // that is, C \~ A(Range(5, 9), Range(1, 3)) + Mat C = B(Range(5, 9), Range::all()); + Size size; Point ofs; + C.locateROI(size, ofs); + // size will be (width=10,height=10) and the ofs will be (x=1, y=5) +@endcode +As in case of whole matrices, if you need a deep copy, use the `clone()` method of the extracted +sub-matrices. + +- Make a header for user-allocated data. It can be useful to do the following: + -# Process "foreign" data using OpenCV (for example, when you implement a DirectShow\* filter or + a processing module for gstreamer, and so on). For example: + @code + void process_video_frame(const unsigned char* pixels, + int width, int height, int step) + { + Mat img(height, width, CV_8UC3, pixels, step); + GaussianBlur(img, img, Size(7,7), 1.5, 1.5); + } + @endcode + -# Quickly initialize small matrices and/or get a super-fast element access. + @code + double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}}; + Mat M = Mat(3, 3, CV_64F, m).inv(); + @endcode + . +Partial yet very common cases of this *user-allocated data* case are conversions from CvMat and +IplImage to Mat. For this purpose, there are special constructors taking pointers to CvMat or +IplImage and the optional flag indicating whether to copy the data or not. Backward conversion from +Mat to CvMat or IplImage is provided via cast operators Mat::operator CvMat() const and +Mat::operator IplImage(). The operators do NOT copy the data. +@code + IplImage* img = cvLoadImage("greatwave.jpg", 1); + Mat mtx(img); // convert IplImage* -> Mat + CvMat oldmat = mtx; // convert Mat -> CvMat + CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height && + oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep); +@endcode + +- Use MATLAB-style array initializers, zeros(), ones(), eye(), for example: +@code + // create a double-precision identity martix and add it to M. + M += Mat::eye(M.rows, M.cols, CV_64F); +@endcode + +- Use a comma-separated initializer: +@code + // create a 3x3 double-precision identity matrix + Mat M = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1); +@endcode +With this approach, you first call a constructor of the Mat class with the proper parameters, and +then you just put `<< operator` followed by comma-separated values that can be constants, +variables, expressions, and so on. Also, note the extra parentheses required to avoid compilation +errors. + +Once the array is created, it is automatically managed via a reference-counting mechanism. If the +array header is built on top of user-allocated data, you should handle the data by yourself. The +array data is deallocated when no one points to it. If you want to release the data pointed by a +array header before the array destructor is called, use Mat::release(). + +The next important thing to learn about the array class is element access. This manual already +described how to compute an address of each array element. Normally, you are not required to use the +formula directly in the code. If you know the array element type (which can be retrieved using the +method Mat::type() ), you can access the element \f$M_{ij}\f$ of a 2-dimensional array as: +@code + M.at(i,j) += 1.f; +@endcode +assuming that `M` is a double-precision floating-point array. There are several variants of the method +at for a different number of dimensions. + +If you need to process a whole row of a 2D array, the most efficient way is to get the pointer to +the row first, and then just use the plain C operator [] : +@code + // compute sum of positive matrix elements + // (assuming that M isa double-precision matrix) + double sum=0; + for(int i = 0; i < M.rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < M.cols; j++) + sum += std::max(Mi[j], 0.); + } +@endcode +Some operations, like the one above, do not actually depend on the array shape. They just process +elements of an array one by one (or elements from multiple arrays that have the same coordinates, +for example, array addition). Such operations are called *element-wise*. It makes sense to check +whether all the input/output arrays are continuous, namely, have no gaps at the end of each row. If +yes, process them as a long single row: +@code + // compute the sum of positive matrix elements, optimized variant + double sum=0; + int cols = M.cols, rows = M.rows; + if(M.isContinuous()) + { + cols *= rows; + rows = 1; + } + for(int i = 0; i < rows; i++) + { + const double* Mi = M.ptr(i); + for(int j = 0; j < cols; j++) + sum += std::max(Mi[j], 0.); + } +@endcode +In case of the continuous matrix, the outer loop body is executed just once. So, the overhead is +smaller, which is especially noticeable in case of small matrices. + +Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows: +@code + // compute sum of positive matrix elements, iterator-based variant + double sum=0; + MatConstIterator_ it = M.begin(), it_end = M.end(); + for(; it != it_end; ++it) + sum += std::max(*it, 0.); +@endcode +The matrix iterators are random-access iterators, so they can be passed to any STL algorithm, +including std::sort(). */ class CV_EXPORTS Mat { public: - //! default constructor + /** + These are various constructors that form a matrix. As noted in the AutomaticAllocation, often + the default constructor is enough, and the proper matrix will be allocated by an OpenCV function. + The constructed matrix can further be assigned to another matrix or matrix expression or can be + allocated with Mat::create . In the former case, the old content is de-referenced. + */ Mat(); - //! constructs 2D matrix of the specified size and type - // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) + + /** @overload + @param rows Number of rows in a 2D array. + @param cols Number of columns in a 2D array. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + */ Mat(int rows, int cols, int type); + + /** @overload + @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the + number of columns go in the reverse order. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + */ Mat(Size size, int type); - //! constucts 2D matrix and fills it with the specified value _s. + + /** @overload + @param rows Number of rows in a 2D array. + @param cols Number of columns in a 2D array. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param s An optional value to initialize each matrix element with. To set all the matrix elements to + the particular value after the construction, use the assignment operator + Mat::operator=(const Scalar& value) . + */ Mat(int rows, int cols, int type, const Scalar& s); + + /** @overload + @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the + number of columns go in the reverse order. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param s An optional value to initialize each matrix element with. To set all the matrix elements to + the particular value after the construction, use the assignment operator + Mat::operator=(const Scalar& value) . + */ Mat(Size size, int type, const Scalar& s); - //! constructs n-dimensional matrix + /** @overload + @param ndims Array dimensionality. + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + */ Mat(int ndims, const int* sizes, int type); + + /** @overload + @param ndims Array dimensionality. + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param s An optional value to initialize each matrix element with. To set all the matrix elements to + the particular value after the construction, use the assignment operator + Mat::operator=(const Scalar& value) . + */ Mat(int ndims, const int* sizes, int type, const Scalar& s); - //! copy constructor + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + */ Mat(const Mat& m); - //! constructor for matrix headers pointing to user-allocated data + + /** @overload + @param rows Number of rows in a 2D array. + @param cols Number of columns in a 2D array. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param data Pointer to the user data. Matrix constructors that take data and step parameters do not + allocate matrix data. Instead, they just initialize the matrix header that points to the specified + data, which means that no data is copied. This operation is very efficient and can be used to + process external data using OpenCV functions. The external data is not automatically deallocated, so + you should take care of it. + @param step Number of bytes each matrix row occupies. The value should include the padding bytes at + the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed + and the actual step is calculated as cols*elemSize(). See Mat::elemSize. + */ Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP); + + /** @overload + @param size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the + number of columns go in the reverse order. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param data Pointer to the user data. Matrix constructors that take data and step parameters do not + allocate matrix data. Instead, they just initialize the matrix header that points to the specified + data, which means that no data is copied. This operation is very efficient and can be used to + process external data using OpenCV functions. The external data is not automatically deallocated, so + you should take care of it. + @param step Number of bytes each matrix row occupies. The value should include the padding bytes at + the end of each row, if any. If the parameter is missing (set to AUTO_STEP ), no padding is assumed + and the actual step is calculated as cols*elemSize(). See Mat::elemSize. + */ Mat(Size size, int type, void* data, size_t step=AUTO_STEP); + + /** @overload + @param ndims Array dimensionality. + @param sizes Array of integers specifying an n-dimensional array shape. + @param type Array type. Use CV_8UC1, ..., CV_64FC4 to create 1-4 channel matrices, or + CV_8UC(n), ..., CV_64FC(n) to create multi-channel (up to CV_CN_MAX channels) matrices. + @param data Pointer to the user data. Matrix constructors that take data and step parameters do not + allocate matrix data. Instead, they just initialize the matrix header that points to the specified + data, which means that no data is copied. This operation is very efficient and can be used to + process external data using OpenCV functions. The external data is not automatically deallocated, so + you should take care of it. + @param steps Array of ndims-1 steps in case of a multi-dimensional array (the last step is always + set to the element size). If not specified, the matrix is assumed to be continuous. + */ Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0); - //! creates a matrix header for a part of the bigger matrix + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + @param rowRange Range of the m rows to take. As usual, the range start is inclusive and the range + end is exclusive. Use Range::all() to take all the rows. + @param colRange Range of the m columns to take. Use Range::all() to take all the columns. + */ Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all()); + + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + @param roi Region of interest. + */ Mat(const Mat& m, const Rect& roi); + + /** @overload + @param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied + by these constructors. Instead, the header pointing to m data or its sub-array is constructed and + associated with it. The reference counter, if any, is incremented. So, when you modify the matrix + formed using such a constructor, you also modify the corresponding elements of m . If you want to + have an independent copy of the sub-array, use Mat::clone() . + @param ranges Array of selected ranges of m along each dimensionality. + */ Mat(const Mat& m, const Range* ranges); - //! builds matrix from std::vector with or without copying the data + + /** @overload + @param vec STL vector whose elements form the matrix. The matrix has a single column and the number + of rows equal to the number of vector elements. Type of the matrix matches the type of vector + elements. The constructor can handle arbitrary types, for which there is a properly declared + DataType . This means that the vector elements must be primitive numbers or uni-type numerical + tuples of numbers. Mixed-type structures are not supported. The corresponding constructor is + explicit. Since STL vectors are not automatically converted to Mat instances, you should write + Mat(vec) explicitly. Unless you copy the data into the matrix ( copyData=true ), no new elements + will be added to the vector because it can potentially yield vector data reallocation, and, thus, + the matrix data pointer will be invalid. + @param copyData Flag to specify whether the underlying data of the STL vector should be copied + to (true) or shared with (false) the newly constructed matrix. When the data is copied, the + allocated buffer is managed using Mat reference counting mechanism. While the data is shared, + the reference counter is NULL, and you should not deallocate the data until the matrix is not + destructed. + */ template explicit Mat(const std::vector<_Tp>& vec, bool copyData=false); - //! builds matrix from cv::Vec; the data is copied by default + + /** @overload + */ template explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); - //! builds matrix from cv::Matx; the data is copied by default + + /** @overload + */ template explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true); - //! builds matrix from a 2D point + + /** @overload + */ template explicit Mat(const Point_<_Tp>& pt, bool copyData=true); - //! builds matrix from a 3D point + + /** @overload + */ template explicit Mat(const Point3_<_Tp>& pt, bool copyData=true); - //! builds matrix from comma initializer + + /** @overload + */ template explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); //! download data from GpuMat @@ -685,84 +925,422 @@ public: //! destructor - calls release() ~Mat(); - //! assignment operators + + /** @brief assignment operators + + These are available assignment operators. Since they all are very different, make sure to read the + operator parameters description. + @param m Assigned, right-hand-side matrix. Matrix assignment is an O(1) operation. This means that + no data is copied but the data is shared and the reference counter, if any, is incremented. Before + assigning new data, the old data is de-referenced via Mat::release . + */ Mat& operator = (const Mat& m); + + /** @overload + @param expr Assigned matrix expression object. As opposite to the first form of the assignment + operation, the second form can reuse already allocated matrix if it has the right size and type to + fit the matrix expression result. It is automatically handled by the real function that the matrix + expressions is expanded to. For example, C=A+B is expanded to add(A, B, C), and add takes care of + automatic C reallocation. + */ Mat& operator = (const MatExpr& expr); //! retrieve UMat from Mat UMat getUMat(int accessFlags, UMatUsageFlags usageFlags = USAGE_DEFAULT) const; - //! returns a new matrix header for the specified row + /** @brief Creates a matrix header for the specified matrix row. + + The method makes a new header for the specified matrix row and returns it. This is an O(1) + operation, regardless of the matrix size. The underlying data of the new matrix is shared with the + original matrix. Here is the example of one of the classical basic matrix processing operations, + axpy, used by LU and many other algorithms: + @code + inline void matrix_axpy(Mat& A, int i, int j, double alpha) + { + A.row(i) += A.row(j)*alpha; + } + @endcode + @note In the current implementation, the following code does not work as expected: + @code + Mat A; + ... + A.row(i) = A.row(j); // will not work + @endcode + This happens because A.row(i) forms a temporary header that is further assigned to another header. + Remember that each of these operations is O(1), that is, no data is copied. Thus, the above + assignment is not true if you may have expected the j-th row to be copied to the i-th row. To + achieve that, you should either turn this simple assignment into an expression or use the + Mat::copyTo method: + @code + Mat A; + ... + // works, but looks a bit obscure. + A.row(i) = A.row(j) + 0; + // this is a bit longer, but the recommended method. + A.row(j).copyTo(A.row(i)); + @endcode + @param y A 0-based row index. + */ Mat row(int y) const; - //! returns a new matrix header for the specified column + + /** @brief Creates a matrix header for the specified matrix column. + + The method makes a new header for the specified matrix column and returns it. This is an O(1) + operation, regardless of the matrix size. The underlying data of the new matrix is shared with the + original matrix. See also the Mat::row description. + @param x A 0-based column index. + */ Mat col(int x) const; - //! ... for the specified row span + + /** @brief Creates a matrix header for the specified row span. + + The method makes a new header for the specified row span of the matrix. Similarly to Mat::row and + Mat::col , this is an O(1) operation. + @param startrow An inclusive 0-based start index of the row span. + @param endrow An exclusive 0-based ending index of the row span. + */ Mat rowRange(int startrow, int endrow) const; + + /** @overload + @param r Range structure containing both the start and the end indices. + */ Mat rowRange(const Range& r) const; - //! ... for the specified column span + + /** @brief Creates a matrix header for the specified column span. + + The method makes a new header for the specified column span of the matrix. Similarly to Mat::row and + Mat::col , this is an O(1) operation. + @param startcol An inclusive 0-based start index of the column span. + @param endcol An exclusive 0-based ending index of the column span. + */ Mat colRange(int startcol, int endcol) const; + + /** @overload + @param r Range structure containing both the start and the end indices. + */ Mat colRange(const Range& r) const; - //! ... for the specified diagonal - // (d=0 - the main diagonal, - // >0 - a diagonal from the lower half, - // <0 - a diagonal from the upper half) + + /** @brief Extracts a diagonal from a matrix + + The method makes a new header for the specified matrix diagonal. The new matrix is represented as a + single-column matrix. Similarly to Mat::row and Mat::col, this is an O(1) operation. + @param d index of the diagonal, with the following values: + - `d=0` is the main diagonal. + - `d>0` is a diagonal from the lower half. For example, d=1 means the diagonal is set + immediately below the main one. + - `d<0` is a diagonal from the upper half. For example, d=-1 means the diagonal is set + immediately above the main one. + */ Mat diag(int d=0) const; - //! constructs a square diagonal matrix which main diagonal is vector "d" + + /** @brief creates a diagonal matrix + + The method makes a new header for the specified matrix diagonal. The new matrix is represented as a + single-column matrix. Similarly to Mat::row and Mat::col, this is an O(1) operation. + @param d Single-column matrix that forms a diagonal matrix + */ static Mat diag(const Mat& d); - //! returns deep copy of the matrix, i.e. the data is copied + /** @brief Creates a full copy of the array and the underlying data. + + The method creates a full copy of the array. The original step[] is not taken into account. So, the + array copy is a continuous array occupying total()*elemSize() bytes. + */ Mat clone() const; - //! copies the matrix content to "m". - // It calls m.create(this->size(), this->type()). + + /** @brief Copies the matrix to another one. + + The method copies the matrix data to another matrix. Before copying the data, the method invokes : + @code + m.create(this->size(), this->type()); + @endcode + so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the + function does not handle the case of a partial overlap between the source and the destination + matrices. + + When the operation mask is specified, if the Mat::create call shown above reallocates the matrix, + the newly allocated matrix is initialized with all zeros before copying the data. + @param m Destination matrix. If it does not have a proper size or type before the operation, it is + reallocated. + */ void copyTo( OutputArray m ) const; - //! copies those matrix elements to "m" that are marked with non-zero mask elements. + + /** @overload + @param m Destination matrix. If it does not have a proper size or type before the operation, it is + reallocated. + @param mask Operation mask. Its non-zero elements indicate which matrix elements need to be copied. + */ void copyTo( OutputArray m, InputArray mask ) const; - //! converts matrix to another datatype with optional scalng. See cvConvertScale. + + /** @brief Converts an array to another data type with optional scaling. + + The method converts source pixel values to the target data type. saturate_cast\<\> is applied at + the end to avoid possible overflows: + + \f[m(x,y) = saturate \_ cast( \alpha (*this)(x,y) + \beta )\f] + @param m output matrix; if it does not have a proper size or type before the operation, it is + reallocated. + @param rtype desired output matrix type or, rather, the depth since the number of channels are the + same as the input has; if rtype is negative, the output matrix will have the same type as the input. + @param alpha optional scale factor. + @param beta optional delta added to the scaled values. + */ void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; + /** @brief Provides a functional form of convertTo. + + This is an internally used method called by the @ref MatrixExpressions engine. + @param m Destination array. + @param type Desired destination array depth (or -1 if it should be the same as the source type). + */ void assignTo( Mat& m, int type=-1 ) const; - //! sets every matrix element to s + /** @brief Sets all or some of the array elements to the specified value. + @param s Assigned scalar converted to the actual array type. + */ Mat& operator = (const Scalar& s); - //! sets some of the matrix elements to s, according to the mask + + /** @brief Sets all or some of the array elements to the specified value. + + This is an advanced variant of the Mat::operator=(const Scalar& s) operator. + @param value Assigned scalar converted to the actual array type. + @param mask Operation mask of the same size as \*this. + */ Mat& setTo(InputArray value, InputArray mask=noArray()); - //! creates alternative matrix header for the same data, with different - // number of channels and/or different number of rows. see cvReshape. + + /** @brief Changes the shape and/or the number of channels of a 2D matrix without copying the data. + + The method makes a new matrix header for \*this elements. The new matrix may have a different size + and/or different number of channels. Any combination is possible if: + - No extra elements are included into the new matrix and no elements are excluded. Consequently, + the product rows\*cols\*channels() must stay the same after the transformation. + - No data is copied. That is, this is an O(1) operation. Consequently, if you change the number of + rows, or the operation changes the indices of elements row in some other way, the matrix must be + continuous. See Mat::isContinuous . + + For example, if there is a set of 3D points stored as an STL vector, and you want to represent the + points as a 3xN matrix, do the following: + @code + std::vector vec; + ... + Mat pointMat = Mat(vec). // convert vector to Mat, O(1) operation + reshape(1). // make Nx3 1-channel matrix out of Nx1 3-channel. + // Also, an O(1) operation + t(); // finally, transpose the Nx3 matrix. + // This involves copying all the elements + @endcode + @param cn New number of channels. If the parameter is 0, the number of channels remains the same. + @param rows New number of rows. If the parameter is 0, the number of rows remains the same. + */ Mat reshape(int cn, int rows=0) const; + + /** @overload */ Mat reshape(int cn, int newndims, const int* newsz) const; - //! matrix transposition by means of matrix expressions + /** @brief Transposes a matrix. + + The method performs matrix transposition by means of matrix expressions. It does not perform the + actual transposition but returns a temporary matrix transposition object that can be further used as + a part of more complex matrix expressions or can be assigned to a matrix: + @code + Mat A1 = A + Mat::eye(A.size(), A.type())*lambda; + Mat C = A1.t()*A1; // compute (A + lambda*I)^t * (A + lamda*I) + @endcode + */ MatExpr t() const; - //! matrix inversion by means of matrix expressions + + /** @brief Inverses a matrix. + + The method performs a matrix inversion by means of matrix expressions. This means that a temporary + matrix inversion object is returned by the method and can be used further as a part of more complex + matrix expressions or can be assigned to a matrix. + @param method Matrix inversion method. One of cv::DecompTypes + */ MatExpr inv(int method=DECOMP_LU) const; - //! per-element matrix multiplication by means of matrix expressions + + /** @brief Performs an element-wise multiplication or division of the two matrices. + + The method returns a temporary object encoding per-element array multiplication, with optional + scale. Note that this is not a matrix multiplication that corresponds to a simpler "\*" operator. + + Example: + @code + Mat C = A.mul(5/B); // equivalent to divide(A, B, C, 5) + @endcode + @param m Another array of the same type and the same size as \*this, or a matrix expression. + @param scale Optional scale factor. + */ MatExpr mul(InputArray m, double scale=1) const; - //! computes cross-product of 2 3D vectors + /** @brief Computes a cross-product of two 3-element vectors. + + The method computes a cross-product of two 3-element vectors. The vectors must be 3-element + floating-point vectors of the same shape and size. The result is another 3-element vector of the + same shape and type as operands. + @param m Another cross-product operand. + */ Mat cross(InputArray m) const; - //! computes dot-product + + /** @brief Computes a dot-product of two vectors. + + The method computes a dot-product of two matrices. If the matrices are not single-column or + single-row vectors, the top-to-bottom left-to-right scan ordering is used to treat them as 1D + vectors. The vectors must have the same size and type. If the matrices have more than one channel, + the dot products from all the channels are summed together. + @param m another dot-product operand. + */ double dot(InputArray m) const; - //! Matlab-style matrix initialization + /** @brief Returns a zero array of the specified size and type. + + The method returns a Matlab-style zero array initializer. It can be used to quickly form a constant + array as a function parameter, part of a matrix expression, or as a matrix initializer. : + @code + Mat A; + A = Mat::zeros(3, 3, CV_32F); + @endcode + In the example above, a new matrix is allocated only if A is not a 3x3 floating-point matrix. + Otherwise, the existing matrix A is filled with zeros. + @param rows Number of rows. + @param cols Number of columns. + @param type Created matrix type. + */ static MatExpr zeros(int rows, int cols, int type); + + /** @overload + @param size Alternative to the matrix size specification Size(cols, rows) . + @param type Created matrix type. + */ static MatExpr zeros(Size size, int type); + + /** @overload + @param ndims Array dimensionality. + @param sz Array of integers specifying the array shape. + @param type Created matrix type. + */ static MatExpr zeros(int ndims, const int* sz, int type); + + /** @brief Returns an array of all 1's of the specified size and type. + + The method returns a Matlab-style 1's array initializer, similarly to Mat::zeros. Note that using + this method you can initialize an array with an arbitrary value, using the following Matlab idiom: + @code + Mat A = Mat::ones(100, 100, CV_8U)*3; // make 100x100 matrix filled with 3. + @endcode + The above operation does not form a 100x100 matrix of 1's and then multiply it by 3. Instead, it + just remembers the scale factor (3 in this case) and use it when actually invoking the matrix + initializer. + @param rows Number of rows. + @param cols Number of columns. + @param type Created matrix type. + */ static MatExpr ones(int rows, int cols, int type); + + /** @overload + @param size Alternative to the matrix size specification Size(cols, rows) . + @param type Created matrix type. + */ static MatExpr ones(Size size, int type); + + /** @overload + @param ndims Array dimensionality. + @param sz Array of integers specifying the array shape. + @param type Created matrix type. + */ static MatExpr ones(int ndims, const int* sz, int type); + + /** @brief Returns an identity matrix of the specified size and type. + + The method returns a Matlab-style identity matrix initializer, similarly to Mat::zeros. Similarly to + Mat::ones, you can use a scale operation to create a scaled identity matrix efficiently: + @code + // make a 4x4 diagonal matrix with 0.1's on the diagonal. + Mat A = Mat::eye(4, 4, CV_32F)*0.1; + @endcode + @param rows Number of rows. + @param cols Number of columns. + @param type Created matrix type. + */ static MatExpr eye(int rows, int cols, int type); + + /** @overload + @param size Alternative matrix size specification as Size(cols, rows) . + @param type Created matrix type. + */ static MatExpr eye(Size size, int type); - //! allocates new matrix data unless the matrix already has specified size and type. - // previous data is unreferenced if needed. + /** @brief Allocates new array data if needed. + + This is one of the key Mat methods. Most new-style OpenCV functions and methods that produce arrays + call this method for each output array. The method uses the following algorithm: + + -# If the current array shape and the type match the new ones, return immediately. Otherwise, + de-reference the previous data by calling Mat::release. + -# Initialize the new header. + -# Allocate the new data of total()\*elemSize() bytes. + -# Allocate the new, associated with the data, reference counter and set it to 1. + + Such a scheme makes the memory management robust and efficient at the same time and helps avoid + extra typing for you. This means that usually there is no need to explicitly allocate output arrays. + That is, instead of writing: + @code + Mat color; + ... + Mat gray(color.rows, color.cols, color.depth()); + cvtColor(color, gray, COLOR_BGR2GRAY); + @endcode + you can simply write: + @code + Mat color; + ... + Mat gray; + cvtColor(color, gray, COLOR_BGR2GRAY); + @endcode + because cvtColor, as well as the most of OpenCV functions, calls Mat::create() for the output array + internally. + @param rows New number of rows. + @param cols New number of columns. + @param type New matrix type. + */ void create(int rows, int cols, int type); + + /** @overload + @param size Alternative new matrix size specification: Size(cols, rows) + @param type New matrix type. + */ void create(Size size, int type); + + /** @overload + @param ndims New array dimensionality. + @param sizes Array of integers specifying a new array shape. + @param type New matrix type. + */ void create(int ndims, const int* sizes, int type); - //! increases the reference counter; use with care to avoid memleaks + /** @brief Increments the reference counter. + + The method increments the reference counter associated with the matrix data. If the matrix header + points to an external data set (see Mat::Mat ), the reference counter is NULL, and the method has no + effect in this case. Normally, to avoid memory leaks, the method should not be called explicitly. It + is called implicitly by the matrix assignment operator. The reference counter increment is an atomic + operation on the platforms that support it. Thus, it is safe to operate on the same matrices + asynchronously in different threads. + */ void addref(); - //! decreases reference counter; - // deallocates the data when reference counter reaches 0. + + /** @brief Decrements the reference counter and deallocates the matrix if needed. + + The method decrements the reference counter associated with the matrix data. When the reference + counter reaches 0, the matrix data is deallocated and the data and the reference counter pointers + are set to NULL's. If the matrix header points to an external data set (see Mat::Mat ), the + reference counter is NULL, and the method has no effect in this case. + + This method can be called manually to force the matrix data deallocation. But since this method is + automatically called in the destructor, or by any other method that changes the data pointer, it is + usually not needed. The reference counter decrement and check for 0 is an atomic operation on the + platforms that support it. Thus, it is safe to operate on the same matrices asynchronously in + different threads. + */ void release(); //! deallocates the matrix data @@ -770,29 +1348,123 @@ public: //! internal use function; properly re-allocates _size, _step arrays void copySize(const Mat& m); - //! reserves enough space to fit sz hyper-planes + /** @brief Reserves space for the certain number of rows. + + The method reserves space for sz rows. If the matrix already has enough space to store sz rows, + nothing happens. If the matrix is reallocated, the first Mat::rows rows are preserved. The method + emulates the corresponding method of the STL vector class. + @param sz Number of rows. + */ void reserve(size_t sz); - //! resizes matrix to the specified number of hyper-planes + + /** @brief Changes the number of matrix rows. + + The methods change the number of matrix rows. If the matrix is reallocated, the first + min(Mat::rows, sz) rows are preserved. The methods emulate the corresponding methods of the STL + vector class. + @param sz New number of rows. + */ void resize(size_t sz); - //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements + + /** @overload + @param sz New number of rows. + @param s Value assigned to the newly added elements. + */ void resize(size_t sz, const Scalar& s); + //! internal function void push_back_(const void* elem); - //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat) + + /** @brief Adds elements to the bottom of the matrix. + + The methods add one or more elements to the bottom of the matrix. They emulate the corresponding + method of the STL vector class. When elem is Mat , its type and the number of columns must be the + same as in the container matrix. + @param elem Added element(s). + */ template void push_back(const _Tp& elem); + + /** @overload + @param elem Added element(s). + */ template void push_back(const Mat_<_Tp>& elem); + + /** @overload + @param m Added line(s). + */ void push_back(const Mat& m); - //! removes several hyper-planes from bottom of the matrix + + /** @brief Removes elements from the bottom of the matrix. + + The method removes one or more rows from the bottom of the matrix. + @param nelems Number of removed rows. If it is greater than the total number of rows, an exception + is thrown. + */ void pop_back(size_t nelems=1); - //! locates matrix header within a parent matrix. See below + /** @brief Locates the matrix header within a parent matrix. + + After you extracted a submatrix from a matrix using Mat::row, Mat::col, Mat::rowRange, + Mat::colRange, and others, the resultant submatrix points just to the part of the original big + matrix. However, each submatrix contains information (represented by datastart and dataend + fields) that helps reconstruct the original matrix size and the position of the extracted + submatrix within the original matrix. The method locateROI does exactly that. + @param wholeSize Output parameter that contains the size of the whole matrix containing *this* + as a part. + @param ofs Output parameter that contains an offset of *this* inside the whole matrix. + */ void locateROI( Size& wholeSize, Point& ofs ) const; - //! moves/resizes the current matrix ROI inside the parent matrix. + + /** @brief Adjusts a submatrix size and position within the parent matrix. + + The method is complimentary to Mat::locateROI . The typical use of these functions is to determine + the submatrix position within the parent matrix and then shift the position somehow. Typically, it + can be required for filtering operations when pixels outside of the ROI should be taken into + account. When all the method parameters are positive, the ROI needs to grow in all directions by the + specified amount, for example: + @code + A.adjustROI(2, 2, 2, 2); + @endcode + In this example, the matrix size is increased by 4 elements in each direction. The matrix is shifted + by 2 elements to the left and 2 elements up, which brings in all the necessary pixels for the + filtering with the 5x5 kernel. + + adjustROI forces the adjusted ROI to be inside of the parent matrix that is boundaries of the + adjusted ROI are constrained by boundaries of the parent matrix. For example, if the submatrix A is + located in the first row of a parent matrix and you called A.adjustROI(2, 2, 2, 2) then A will not + be increased in the upward direction. + + The function is used internally by the OpenCV filtering functions, like filter2D , morphological + operations, and so on. + @param dtop Shift of the top submatrix boundary upwards. + @param dbottom Shift of the bottom submatrix boundary downwards. + @param dleft Shift of the left submatrix boundary to the left. + @param dright Shift of the right submatrix boundary to the right. + @sa copyMakeBorder + */ Mat& adjustROI( int dtop, int dbottom, int dleft, int dright ); - //! extracts a rectangular sub-matrix - // (this is a generalized form of row, rowRange etc.) + + /** @brief Extracts a rectangular submatrix. + + The operators make a new header for the specified sub-array of \*this . They are the most + generalized forms of Mat::row, Mat::col, Mat::rowRange, and Mat::colRange . For example, + `A(Range(0, 10), Range::all())` is equivalent to `A.rowRange(0, 10)`. Similarly to all of the above, + the operators are O(1) operations, that is, no matrix data is copied. + @param rowRange Start and end row of the extracted submatrix. The upper boundary is not included. To + select all the rows, use Range::all(). + @param colRange Start and end column of the extracted submatrix. The upper boundary is not included. + To select all the columns, use Range::all(). + */ Mat operator()( Range rowRange, Range colRange ) const; + + /** @overload + @param roi Extracted submatrix specified as a rectangle. + */ Mat operator()( const Rect& roi ) const; + + /** @overload + @param ranges Array of selected ranges along each array dimension. + */ Mat operator()( const Range* ranges ) const; // //! converts header to CvMat; no data is copied @@ -806,101 +1478,378 @@ public: template operator Vec<_Tp, n>() const; template operator Matx<_Tp, m, n>() const; - //! returns true iff the matrix data is continuous - // (i.e. when there are no gaps between successive rows). - // similar to CV_IS_MAT_CONT(cvmat->type) + /** @brief Reports whether the matrix is continuous or not. + + The method returns true if the matrix elements are stored continuously without gaps at the end of + each row. Otherwise, it returns false. Obviously, 1x1 or 1xN matrices are always continuous. + Matrices created with Mat::create are always continuous. But if you extract a part of the matrix + using Mat::col, Mat::diag, and so on, or constructed a matrix header for externally allocated data, + such matrices may no longer have this property. + + The continuity flag is stored as a bit in the Mat::flags field and is computed automatically when + you construct a matrix header. Thus, the continuity check is a very fast operation, though + theoretically it could be done as follows: + @code + // alternative implementation of Mat::isContinuous() + bool myCheckMatContinuity(const Mat& m) + { + //return (m.flags & Mat::CONTINUOUS_FLAG) != 0; + return m.rows == 1 || m.step == m.cols*m.elemSize(); + } + @endcode + The method is used in quite a few of OpenCV functions. The point is that element-wise operations + (such as arithmetic and logical operations, math functions, alpha blending, color space + transformations, and others) do not depend on the image geometry. Thus, if all the input and output + arrays are continuous, the functions can process them as very long single-row vectors. The example + below illustrates how an alpha-blending function can be implemented: + @code + template + void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst) + { + const float alpha_scale = (float)std::numeric_limits::max(), + inv_scale = 1.f/alpha_scale; + + CV_Assert( src1.type() == src2.type() && + src1.type() == CV_MAKETYPE(DataType::depth, 4) && + src1.size() == src2.size()); + Size size = src1.size(); + dst.create(size, src1.type()); + + // here is the idiom: check the arrays for continuity and, + // if this is the case, + // treat the arrays as 1D vectors + if( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() ) + { + size.width *= size.height; + size.height = 1; + } + size.width *= 4; + + for( int i = 0; i < size.height; i++ ) + { + // when the arrays are continuous, + // the outer loop is executed only once + const T* ptr1 = src1.ptr(i); + const T* ptr2 = src2.ptr(i); + T* dptr = dst.ptr(i); + + for( int j = 0; j < size.width; j += 4 ) + { + float alpha = ptr1[j+3]*inv_scale, beta = ptr2[j+3]*inv_scale; + dptr[j] = saturate_cast(ptr1[j]*alpha + ptr2[j]*beta); + dptr[j+1] = saturate_cast(ptr1[j+1]*alpha + ptr2[j+1]*beta); + dptr[j+2] = saturate_cast(ptr1[j+2]*alpha + ptr2[j+2]*beta); + dptr[j+3] = saturate_cast((1 - (1-alpha)*(1-beta))*alpha_scale); + } + } + } + @endcode + This approach, while being very simple, can boost the performance of a simple element-operation by + 10-20 percents, especially if the image is rather small and the operation is quite simple. + + Another OpenCV idiom in this function, a call of Mat::create for the destination array, that + allocates the destination array unless it already has the proper size and type. And while the newly + allocated arrays are always continuous, you still need to check the destination array because + Mat::create does not always allocate a new matrix. + */ bool isContinuous() const; //! returns true if the matrix is a submatrix of another matrix bool isSubmatrix() const; - //! returns element size in bytes, - // similar to CV_ELEM_SIZE(cvmat->type) + /** @brief Returns the matrix element size in bytes. + + The method returns the matrix element size in bytes. For example, if the matrix type is CV_16SC3 , + the method returns 3\*sizeof(short) or 6. + */ size_t elemSize() const; - //! returns the size of element channel in bytes. + + /** @brief Returns the size of each matrix element channel in bytes. + + The method returns the matrix element channel size in bytes, that is, it ignores the number of + channels. For example, if the matrix type is CV_16SC3 , the method returns sizeof(short) or 2. + */ size_t elemSize1() const; - //! returns element type, similar to CV_MAT_TYPE(cvmat->type) + + /** @brief Returns the type of a matrix element. + + The method returns a matrix element type. This is an identifier compatible with the CvMat type + system, like CV_16SC3 or 16-bit signed 3-channel array, and so on. + */ int type() const; - //! returns element type, similar to CV_MAT_DEPTH(cvmat->type) + + /** @brief Returns the depth of a matrix element. + + The method returns the identifier of the matrix element depth (the type of each individual channel). + For example, for a 16-bit signed element array, the method returns CV_16S . A complete list of + matrix types contains the following values: + - CV_8U - 8-bit unsigned integers ( 0..255 ) + - CV_8S - 8-bit signed integers ( -128..127 ) + - CV_16U - 16-bit unsigned integers ( 0..65535 ) + - CV_16S - 16-bit signed integers ( -32768..32767 ) + - CV_32S - 32-bit signed integers ( -2147483648..2147483647 ) + - CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN ) + - CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN ) + */ int depth() const; - //! returns element type, similar to CV_MAT_CN(cvmat->type) + + /** @brief Returns the number of matrix channels. + + The method returns the number of matrix channels. + */ int channels() const; - //! returns step/elemSize1() + + /** @brief Returns a normalized step. + + The method returns a matrix step divided by Mat::elemSize1() . It can be useful to quickly access an + arbitrary matrix element. + */ size_t step1(int i=0) const; - //! returns true if matrix data is NULL + + /** @brief Returns true if the array has no elements. + + The method returns true if Mat::total() is 0 or if Mat::data is NULL. Because of pop_back() and + resize() methods `M.total() == 0` does not imply that `M.data == NULL`. + */ bool empty() const; - //! returns the total number of matrix elements + + /** @brief Returns the total number of array elements. + + The method returns the number of array elements (a number of pixels if the array represents an + image). + */ size_t total() const; //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const; - //! returns pointer to i0-th submatrix along the dimension #0 + /** @brief Returns a pointer to the specified matrix row. + + The methods return `uchar*` or typed pointer to the specified matrix row. See the sample in + Mat::isContinuous to know how to use these methods. + @param i0 A 0-based row index. + */ uchar* ptr(int i0=0); + /** @overload */ const uchar* ptr(int i0=0) const; - //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1 + /** @overload */ uchar* ptr(int i0, int i1); + /** @overload */ const uchar* ptr(int i0, int i1) const; - //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2 + /** @overload */ uchar* ptr(int i0, int i1, int i2); + /** @overload */ const uchar* ptr(int i0, int i1, int i2) const; - //! returns pointer to the matrix element + /** @overload */ uchar* ptr(const int* idx); - //! returns read-only pointer to the matrix element + /** @overload */ const uchar* ptr(const int* idx) const; - + /** @overload */ template uchar* ptr(const Vec& idx); + /** @overload */ template const uchar* ptr(const Vec& idx) const; - //! template version of the above method + /** @overload */ template _Tp* ptr(int i0=0); + /** @overload */ template const _Tp* ptr(int i0=0) const; - + /** @overload */ template _Tp* ptr(int i0, int i1); + /** @overload */ template const _Tp* ptr(int i0, int i1) const; - + /** @overload */ template _Tp* ptr(int i0, int i1, int i2); + /** @overload */ template const _Tp* ptr(int i0, int i1, int i2) const; - + /** @overload */ template _Tp* ptr(const int* idx); + /** @overload */ template const _Tp* ptr(const int* idx) const; - + /** @overload */ template _Tp* ptr(const Vec& idx); + /** @overload */ template const _Tp* ptr(const Vec& idx) const; - //! the same as above, with the pointer dereferencing + /** @brief Returns a reference to the specified array element. + + The template methods return a reference to the specified array element. For the sake of higher + performance, the index range checks are only performed in the Debug configuration. + + Note that the variants with a single index (i) can be used to access elements of single-row or + single-column 2-dimensional arrays. That is, if, for example, A is a 1 x N floating-point matrix and + B is an M x 1 integer matrix, you can simply write `A.at(k+4)` and `B.at(2*i+1)` + instead of `A.at(0,k+4)` and `B.at(2*i+1,0)`, respectively. + + The example below initializes a Hilbert matrix: + @code + Mat H(100, 100, CV_64F); + for(int i = 0; i < H.rows; i++) + for(int j = 0; j < H.cols; j++) + H.at(i,j)=1./(i+j+1); + @endcode + @param i0 Index along the dimension 0 + */ template _Tp& at(int i0=0); + /** @overload + @param i0 Index along the dimension 0 + */ template const _Tp& at(int i0=0) const; - + /** @overload + @param i0 Index along the dimension 0 + @param i1 Index along the dimension 1 + */ template _Tp& at(int i0, int i1); + /** @overload + @param i0 Index along the dimension 0 + @param i1 Index along the dimension 1 + */ template const _Tp& at(int i0, int i1) const; + /** @overload + @param i0 Index along the dimension 0 + @param i1 Index along the dimension 1 + @param i2 Index along the dimension 2 + */ template _Tp& at(int i0, int i1, int i2); + /** @overload + @param i0 Index along the dimension 0 + @param i1 Index along the dimension 1 + @param i2 Index along the dimension 2 + */ template const _Tp& at(int i0, int i1, int i2) const; + /** @overload + @param idx Array of Mat::dims indices. + */ template _Tp& at(const int* idx); + /** @overload + @param idx Array of Mat::dims indices. + */ template const _Tp& at(const int* idx) const; + /** @overload */ template _Tp& at(const Vec& idx); + /** @overload */ template const _Tp& at(const Vec& idx) const; - //! special versions for 2D arrays (especially convenient for referencing image pixels) + /** @overload + special versions for 2D arrays (especially convenient for referencing image pixels) + @param pt Element position specified as Point(j,i) . + */ template _Tp& at(Point pt); + /** @overload + special versions for 2D arrays (especially convenient for referencing image pixels) + @param pt Element position specified as Point(j,i) . + */ template const _Tp& at(Point pt) const; - //! template methods for iteration over matrix elements. - // the iterators take care of skipping gaps in the end of rows (if any) + /** @brief Returns the matrix iterator and sets it to the first matrix element. + + The methods return the matrix read-only or read-write iterators. The use of matrix iterators is very + similar to the use of bi-directional STL iterators. In the example below, the alpha blending + function is rewritten using the matrix iterators: + @code + template + void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst) + { + typedef Vec VT; + + const float alpha_scale = (float)std::numeric_limits::max(), + inv_scale = 1.f/alpha_scale; + + CV_Assert( src1.type() == src2.type() && + src1.type() == DataType::type && + src1.size() == src2.size()); + Size size = src1.size(); + dst.create(size, src1.type()); + + MatConstIterator_ it1 = src1.begin(), it1_end = src1.end(); + MatConstIterator_ it2 = src2.begin(); + MatIterator_ dst_it = dst.begin(); + + for( ; it1 != it1_end; ++it1, ++it2, ++dst_it ) + { + VT pix1 = *it1, pix2 = *it2; + float alpha = pix1[3]*inv_scale, beta = pix2[3]*inv_scale; + *dst_it = VT(saturate_cast(pix1[0]*alpha + pix2[0]*beta), + saturate_cast(pix1[1]*alpha + pix2[1]*beta), + saturate_cast(pix1[2]*alpha + pix2[2]*beta), + saturate_cast((1 - (1-alpha)*(1-beta))*alpha_scale)); + } + } + @endcode + */ template MatIterator_<_Tp> begin(); - template MatIterator_<_Tp> end(); template MatConstIterator_<_Tp> begin() const; + + /** @brief Returns the matrix iterator and sets it to the after-last matrix element. + + The methods return the matrix read-only or read-write iterators, set to the point following the last + matrix element. + */ + template MatIterator_<_Tp> end(); template MatConstIterator_<_Tp> end() const; - //! template methods for for operation over all matrix elements. - // the operations take care of skipping gaps in the end of rows (if any) + /** @brief Invoke with arguments functor, and runs the functor over all matrix element. + + The methos runs operation in parallel. Operation is passed by arguments. Operation have to be a + function pointer, a function object or a lambda(C++11). + + All of below operation is equal. Put 0xFF to first channel of all matrix elements: + @code + Mat image(1920, 1080, CV_8UC3); + typedef cv::Point3_ Pixel; + + // first. raw pointer access. + for (int r = 0; r < image.rows; ++r) { + Pixel* ptr = image.ptr(0, r); + const Pixel* ptr_end = ptr + image.cols; + for (; ptr != ptr_end; ++ptr) { + ptr->x = 255; + } + } + + // Using MatIterator. (Simple but there are a Iterator's overhead) + for (Pixel &p : cv::Mat_(image)) { + p.x = 255; + } + + // Parallel execution with function object. + struct Operator { + void operator ()(Pixel &pixel, const int * position) { + pixel.x = 255; + } + }; + image.forEach(Operator()); + + // Parallel execution using C++11 lambda. + image.forEach([](Pixel &p, const int * position) -> void { + p.x = 255; + }); + @endcode + position parameter is index of current pixel: + @code + // Creating 3D matrix (255 x 255 x 255) typed uint8_t, + // and initialize all elements by the value which equals elements position. + // i.e. pixels (x,y,z) = (1,2,3) is (b,g,r) = (1,2,3). + + int sizes[] = { 255, 255, 255 }; + typedef cv::Point3_ Pixel; + + Mat_ image = Mat::zeros(3, sizes, CV_8UC3); + + image.forEachWithPosition([&](Pixel& pixel, const int position[]) -> void{ + pixel.x = position[0]; + pixel.y = position[1]; + pixel.z = position[2]; + }); + @endcode + */ template void forEach(const Functor& operation); + /** @overload */ template void forEach(const Functor& operation) const; enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG }; @@ -943,50 +1892,54 @@ protected: ///////////////////////////////// Mat_<_Tp> //////////////////////////////////// -/*! - Template matrix class derived from Mat - - The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields, - nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes - can be safely converted one to another. But do it with care, for example: - - \code - // create 100x100 8-bit matrix - Mat M(100,100,CV_8U); - // this will compile fine. no any data conversion will be done. - Mat_& M1 = (Mat_&)M; - // the program will likely crash at the statement below - M1(99,99) = 1.f; - \endcode - - While cv::Mat is sufficient in most cases, cv::Mat_ can be more convenient if you use a lot of element - access operations and if you know matrix type at compile time. Note that cv::Mat::at and - cv::Mat::operator() do absolutely the same thing and run at the same speed, but the latter is certainly shorter: +/** @brief Template matrix class derived from Mat - \code - Mat_ M(20,20); - for(int i = 0; i < M.rows; i++) - for(int j = 0; j < M.cols; j++) - M(i,j) = 1./(i+j+1); - Mat E, V; - eigen(M,E,V); - cout << E.at(0,0)/E.at(M.rows-1,0); - \endcode - - It is easy to use Mat_ for multi-channel images/matrices - just pass cv::Vec as cv::Mat_ template parameter: - - \code - // allocate 320x240 color image and fill it with green (in RGB space) - Mat_ img(240, 320, Vec3b(0,255,0)); - // now draw a diagonal white line - for(int i = 0; i < 100; i++) - img(i,i)=Vec3b(255,255,255); - // and now modify the 2nd (red) channel of each pixel - for(int i = 0; i < img.rows; i++) - for(int j = 0; j < img.cols; j++) - img(i,j)[2] ^= (uchar)(i ^ j); // img(y,x)[c] accesses c-th channel of the pixel (x,y) - \endcode -*/ +@code + template class Mat_ : public Mat + { + public: + // ... some specific methods + // and + // no new extra fields + }; +@endcode +The class `Mat_<_Tp>` is a *thin* template wrapper on top of the Mat class. It does not have any +extra data fields. Nor this class nor Mat has any virtual methods. Thus, references or pointers to +these two classes can be freely but carefully converted one to another. For example: +@code + // create a 100x100 8-bit matrix + Mat M(100,100,CV_8U); + // this will be compiled fine. no any data conversion will be done. + Mat_& M1 = (Mat_&)M; + // the program is likely to crash at the statement below + M1(99,99) = 1.f; +@endcode +While Mat is sufficient in most cases, Mat_ can be more convenient if you use a lot of element +access operations and if you know matrix type at the compilation time. Note that +`Mat::at(int y,int x)` and `Mat_::operator()(int y,int x)` do absolutely the same +and run at the same speed, but the latter is certainly shorter: +@code + Mat_ M(20,20); + for(int i = 0; i < M.rows; i++) + for(int j = 0; j < M.cols; j++) + M(i,j) = 1./(i+j+1); + Mat E, V; + eigen(M,E,V); + cout << E.at(0,0)/E.at(M.rows-1,0); +@endcode +To use Mat_ for multi-channel images/matrices, pass Vec as a Mat_ parameter: +@code + // allocate a 320x240 color image and fill it with green (in RGB space) + Mat_ img(240, 320, Vec3b(0,255,0)); + // now draw a diagonal white line + for(int i = 0; i < 100; i++) + img(i,i)=Vec3b(255,255,255); + // and now scramble the 2nd (red) channel of each pixel + for(int i = 0; i < img.rows; i++) + for(int j = 0; j < img.cols; j++) + img(i,j)[2] ^= (uchar)(i ^ j); +@endcode + */ template class Mat_ : public Mat { public: @@ -1161,6 +2114,7 @@ typedef Mat_ Mat2d; typedef Mat_ Mat3d; typedef Mat_ Mat4d; +/** @todo document */ class CV_EXPORTS UMat { public: @@ -1359,91 +2313,84 @@ protected: /////////////////////////// multi-dimensional sparse matrix ////////////////////////// -/*! - Sparse matrix class. - - The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements - of any type that cv::Mat is able to store. "Sparse" means that only non-zero elements - are stored (though, as a result of some operations on a sparse matrix, some of its stored elements - can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase(). - The non-zero elements are stored in a hash table that grows when it's filled enough, - so that the search time remains O(1) in average. Elements can be accessed using the following methods: - -
    -
  1. Query operations: cv::SparseMat::ptr() and the higher-level cv::SparseMat::ref(), - cv::SparseMat::value() and cv::SparseMat::find, for example: - \code - const int dims = 5; - int size[] = {10, 10, 10, 10, 10}; - SparseMat sparse_mat(dims, size, CV_32F); - for(int i = 0; i < 1000; i++) - { - int idx[dims]; - for(int k = 0; k < dims; k++) - idx[k] = rand()%sparse_mat.size(k); - sparse_mat.ref(idx) += 1.f; - } - \endcode - -
  2. Sparse matrix iterators. Like cv::Mat iterators and unlike cv::Mat iterators, the sparse matrix iterators are STL-style, - that is, the iteration is done as following: - \code - // prints elements of a sparse floating-point matrix and the sum of elements. - SparseMatConstIterator_ - it = sparse_mat.begin(), - it_end = sparse_mat.end(); - double s = 0; - int dims = sparse_mat.dims(); - for(; it != it_end; ++it) - { - // print element indices and the element value - const Node* n = it.node(); - printf("(") - for(int i = 0; i < dims; i++) - printf("%3d%c", n->idx[i], i < dims-1 ? ',' : ')'); - printf(": %f\n", *it); - s += *it; - } - printf("Element sum is %g\n", s); - \endcode - If you run this loop, you will notice that elements are enumerated - in no any logical order (lexicographical etc.), - they come in the same order as they stored in the hash table, i.e. semi-randomly. - - You may collect pointers to the nodes and sort them to get the proper ordering. - Note, however, that pointers to the nodes may become invalid when you add more - elements to the matrix; this is because of possible buffer reallocation. - -
  3. A combination of the above 2 methods when you need to process 2 or more sparse - matrices simultaneously, e.g. this is how you can compute unnormalized - cross-correlation of the 2 floating-point sparse matrices: - \code - double crossCorr(const SparseMat& a, const SparseMat& b) - { - const SparseMat *_a = &a, *_b = &b; - // if b contains less elements than a, - // it's faster to iterate through b - if(_a->nzcount() > _b->nzcount()) - std::swap(_a, _b); - SparseMatConstIterator_ it = _a->begin(), - it_end = _a->end(); - double ccorr = 0; - for(; it != it_end; ++it) - { - // take the next element from the first matrix - float avalue = *it; - const Node* anode = it.node(); - // and try to find element with the same index in the second matrix. - // since the hash value depends only on the element index, - // we reuse hashvalue stored in the node - float bvalue = _b->value(anode->idx,&anode->hashval); - ccorr += avalue*bvalue; - } - return ccorr; - } - \endcode -
-*/ +/** @brief The class SparseMat represents multi-dimensional sparse numerical arrays. + +Such a sparse array can store elements of any type that Mat can store. *Sparse* means that only +non-zero elements are stored (though, as a result of operations on a sparse matrix, some of its +stored elements can actually become 0. It is up to you to detect such elements and delete them +using SparseMat::erase ). The non-zero elements are stored in a hash table that grows when it is +filled so that the search time is O(1) in average (regardless of whether element is there or not). +Elements can be accessed using the following methods: +- Query operations (SparseMat::ptr and the higher-level SparseMat::ref, SparseMat::value and + SparseMat::find), for example: + @code + const int dims = 5; + int size[] = {10, 10, 10, 10, 10}; + SparseMat sparse_mat(dims, size, CV_32F); + for(int i = 0; i < 1000; i++) + { + int idx[dims]; + for(int k = 0; k < dims; k++) + idx[k] = rand() + sparse_mat.ref(idx) += 1.f; + } + @endcode +- Sparse matrix iterators. They are similar to MatIterator but different from NAryMatIterator. + That is, the iteration loop is familiar to STL users: + @code + // prints elements of a sparse floating-point matrix + // and the sum of elements. + SparseMatConstIterator_ + it = sparse_mat.begin(), + it_end = sparse_mat.end(); + double s = 0; + int dims = sparse_mat.dims(); + for(; it != it_end; ++it) + { + // print element indices and the element value + const SparseMat::Node* n = it.node(); + printf("("); + for(int i = 0; i < dims; i++) + printf("%d%s", n->idx[i], i < dims-1 ? ", " : ")"); + printf(": %g\n", it.value()); + s += *it; + } + printf("Element sum is %g\n", s); + @endcode + If you run this loop, you will notice that elements are not enumerated in a logical order + (lexicographical, and so on). They come in the same order as they are stored in the hash table + (semi-randomly). You may collect pointers to the nodes and sort them to get the proper ordering. + Note, however, that pointers to the nodes may become invalid when you add more elements to the + matrix. This may happen due to possible buffer reallocation. +- Combination of the above 2 methods when you need to process 2 or more sparse matrices + simultaneously. For example, this is how you can compute unnormalized cross-correlation of the 2 + floating-point sparse matrices: + @code + double cross_corr(const SparseMat& a, const SparseMat& b) + { + const SparseMat *_a = &a, *_b = &b; + // if b contains less elements than a, + // it is faster to iterate through b + if(_a->nzcount() > _b->nzcount()) + std::swap(_a, _b); + SparseMatConstIterator_ it = _a->begin(), + it_end = _a->end(); + double ccorr = 0; + for(; it != it_end; ++it) + { + // take the next element from the first matrix + float avalue = *it; + const Node* anode = it.node(); + // and try to find an element with the same index in the second matrix. + // since the hash value depends only on the element index, + // reuse the hash value stored in the node + float bvalue = _b->value(anode->idx,&anode->hashval); + ccorr += avalue*bvalue; + } + return ccorr; + } + @endcode + */ class CV_EXPORTS SparseMat { public: @@ -1479,19 +2426,29 @@ public: int idx[MAX_DIM]; }; - //! default constructor + /** @brief Various SparseMat constructors. + */ SparseMat(); - //! creates matrix of the specified size and type + + /** @overload + @param dims Array dimensionality. + @param _sizes Sparce matrix size on all dementions. + @param _type Sparse matrix data type. + */ SparseMat(int dims, const int* _sizes, int _type); - //! copy constructor + + /** @overload + @param m Source matrix for copy constructor. If m is dense matrix (ocvMat) then it will be converted + to sparse representation. + */ SparseMat(const SparseMat& m); - //! converts dense 2d matrix to the sparse form - /*! - \param m the input matrix + + /** @overload + @param m Source matrix for copy constructor. If m is dense matrix (ocvMat) then it will be converted + to sparse representation. */ explicit SparseMat(const Mat& m); - //! converts old-style sparse matrix to the new-style. All the data is copied - //SparseMat(const CvSparseMat* m); + //! the destructor ~SparseMat(); @@ -1570,19 +2527,16 @@ public: //! computes the element hash value (nD case) size_t hash(const int* idx) const; - //@{ + //!@{ /*! specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case. - return pointer to the matrix element. -
    -
  • if the element is there (it's non-zero), the pointer to it is returned -
  • if it's not there and createMissing=false, NULL pointer is returned -
  • if it's not there and createMissing=true, then the new element + - if the element is there (it's non-zero), the pointer to it is returned + - if it's not there and createMissing=false, NULL pointer is returned + - if it's not there and createMissing=true, then the new element is created and initialized with 0. Pointer to it is returned -
  • if the optional hashval pointer is not NULL, the element hash value is - not computed, but *hashval is taken instead. -
+ - if the optional hashval pointer is not NULL, the element hash value is + not computed, but *hashval is taken instead. */ //! returns pointer to the specified element (1D case) uchar* ptr(int i0, bool createMissing, size_t* hashval=0); @@ -1592,13 +2546,13 @@ public: uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0); //! returns pointer to the specified element (nD case) uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0); - //@} + //!@} - //@{ + //!@{ /*! return read-write reference to the specified sparse matrix element. - ref<_Tp>(i0,...[,hashval]) is equivalent to *(_Tp*)ptr(i0,...,true[,hashval]). + `ref<_Tp>(i0,...[,hashval])` is equivalent to `*(_Tp*)ptr(i0,...,true[,hashval])`. The methods always return a valid reference. If the element did not exist, it is created and initialiazed with 0. */ @@ -1610,17 +2564,16 @@ public: template _Tp& ref(int i0, int i1, int i2, size_t* hashval=0); //! returns reference to the specified element (nD case) template _Tp& ref(const int* idx, size_t* hashval=0); - //@} + //!@} - //@{ + //!@{ /*! return value of the specified sparse matrix element. - value<_Tp>(i0,...[,hashval]) is equivalent - - \code + `value<_Tp>(i0,...[,hashval])` is equivalent to + @code { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); } - \endcode + @endcode That is, if the element did not exist, the methods return 0. */ @@ -1632,13 +2585,13 @@ public: template _Tp value(int i0, int i1, int i2, size_t* hashval=0) const; //! returns value of the specified element (nD case) template _Tp value(const int* idx, size_t* hashval=0) const; - //@} + //!@} - //@{ + //!@{ /*! Return pointer to the specified sparse matrix element if it exists - find<_Tp>(i0,...[,hashval]) is equivalent to (_const Tp*)ptr(i0,...false[,hashval]). + `find<_Tp>(i0,...[,hashval])` is equivalent to `(_const Tp*)ptr(i0,...false[,hashval])`. If the specified element does not exist, the methods return NULL. */ @@ -1650,6 +2603,7 @@ public: template const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const; //! returns pointer to the specified element (nD case) template const _Tp* find(const int* idx, size_t* hashval=0) const; + //!@} //! erases the specified element (2D case) void erase(int i0, int i1, size_t* hashval=0); @@ -1658,7 +2612,7 @@ public: //! erases the specified element (nD case) void erase(const int* idx, size_t* hashval=0); - //@{ + //!@{ /*! return the sparse matrix iterator pointing to the first sparse matrix element */ @@ -1670,7 +2624,7 @@ public: SparseMatConstIterator begin() const; //! returns the read-only sparse matrix iterator at the matrix beginning template SparseMatConstIterator_<_Tp> begin() const; - //@} + //!@} /*! return the sparse matrix iterator pointing to the element following the last sparse matrix element */ @@ -1704,19 +2658,17 @@ public: ///////////////////////////////// SparseMat_<_Tp> //////////////////////////////////// -/*! - The Template Sparse Matrix class derived from cv::SparseMat +/** @brief Template sparse n-dimensional array class derived from SparseMat - The class provides slightly more convenient operations for accessing elements. - - \code - SparseMat m; - ... - SparseMat_ m_ = (SparseMat_&)m; - m_.ref(1)++; // equivalent to m.ref(1)++; - m_.ref(2) += m_(3); // equivalent to m.ref(2) += m.value(3); - \endcode -*/ +SparseMat_ is a thin wrapper on top of SparseMat created in the same way as Mat_ . It simplifies +notation of some operations: +@code + int sz[] = {10, 20, 30}; + SparseMat_ M(3, sz); + ... + M.ref(1, 2, 3) = M(4, 5, 6) + M(7, 8, 9); +@endcode + */ template class SparseMat_ : public SparseMat { public: @@ -1852,8 +2804,7 @@ public: ////////////////////////////////// MatConstIterator_ ///////////////////////////////// -/*! - Matrix read-only iterator +/** @brief Matrix read-only iterator */ template class MatConstIterator_ : public MatConstIterator @@ -1908,8 +2859,7 @@ public: //////////////////////////////////// MatIterator_ //////////////////////////////////// -/*! - Matrix read-write iterator +/** @brief Matrix read-write iterator */ template class MatIterator_ : public MatConstIterator_<_Tp> @@ -1960,8 +2910,8 @@ public: /////////////////////////////// SparseMatConstIterator /////////////////////////////// -/*! - Read-Only Sparse Matrix Iterator. +/** @brief Read-Only Sparse Matrix Iterator. + Here is how to use the iterator to compute the sum of floating-point sparse matrix elements: \code @@ -2011,8 +2961,7 @@ public: ////////////////////////////////// SparseMatIterator ///////////////////////////////// -/*! - Read-write Sparse Matrix Iterator +/** @brief Read-write Sparse Matrix Iterator The class is similar to cv::SparseMatConstIterator, but can be used for in-place modification of the matrix elements. @@ -2046,8 +2995,7 @@ public: /////////////////////////////// SparseMatConstIterator_ ////////////////////////////// -/*! - Template Read-Only Sparse Matrix Iterator Class. +/** @brief Template Read-Only Sparse Matrix Iterator Class. This is the derived from SparseMatConstIterator class that introduces more convenient operator *() for accessing the current element. @@ -2083,8 +3031,7 @@ public: ///////////////////////////////// SparseMatIterator_ ///////////////////////////////// -/*! - Template Read-Write Sparse Matrix Iterator Class. +/** @brief Template Read-Write Sparse Matrix Iterator Class. This is the derived from cv::SparseMatConstIterator_ class that introduces more convenient operator *() for accessing the current element. @@ -2120,56 +3067,58 @@ public: /////////////////////////////////// NAryMatIterator ////////////////////////////////// -/*! - n-Dimensional Dense Matrix Iterator Class. - - The class cv::NAryMatIterator is used for iterating over one or more n-dimensional dense arrays (cv::Mat's). - - The iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators. - It iterates through the slices (or planes), not the elements, where "slice" is a continuous part of the arrays. +/** @brief n-ary multi-dimensional array iterator. - Here is the example on how the iterator can be used to normalize 3D histogram: - - \code - void normalizeColorHist(Mat& hist) - { - #if 1 - // intialize iterator (the style is different from STL). - // after initialization the iterator will contain - // the number of slices or planes - // the iterator will go through - Mat* arrays[] = { &hist, 0 }; - Mat planes[1]; - NAryMatIterator it(arrays, planes); - double s = 0; - // iterate through the matrix. on each iteration - // it.planes[i] (of type Mat) will be set to the current plane of - // i-th n-dim matrix passed to the iterator constructor. - for(int p = 0; p < it.nplanes; p++, ++it) - s += sum(it.planes[0])[0]; - it = NAryMatIterator(hist); - s = 1./s; - for(int p = 0; p < it.nplanes; p++, ++it) - it.planes[0] *= s; - #elif 1 - // this is a shorter implementation of the above - // using built-in operations on Mat - double s = sum(hist)[0]; - hist.convertTo(hist, hist.type(), 1./s, 0); - #else - // and this is even shorter one - // (assuming that the histogram elements are non-negative) - normalize(hist, hist, 1, 0, NORM_L1); - #endif - } - \endcode +Use the class to implement unary, binary, and, generally, n-ary element-wise operations on +multi-dimensional arrays. Some of the arguments of an n-ary function may be continuous arrays, some +may be not. It is possible to use conventional MatIterator 's for each array but incrementing all of +the iterators after each small operations may be a big overhead. In this case consider using +NAryMatIterator to iterate through several matrices simultaneously as long as they have the same +geometry (dimensionality and all the dimension sizes are the same). On each iteration `it.planes[0]`, +`it.planes[1]`,... will be the slices of the corresponding matrices. - You can iterate through several matrices simultaneously as long as they have the same geometry - (dimensionality and all the dimension sizes are the same), which is useful for binary - and n-ary operations on such matrices. Just pass those matrices to cv::MatNDIterator. - Then, during the iteration it.planes[0], it.planes[1], ... will - be the slices of the corresponding matrices -*/ +The example below illustrates how you can compute a normalized and threshold 3D color histogram: +@code + void computeNormalizedColorHist(const Mat& image, Mat& hist, int N, double minProb) + { + const int histSize[] = {N, N, N}; + + // make sure that the histogram has a proper size and type + hist.create(3, histSize, CV_32F); + + // and clear it + hist = Scalar(0); + + // the loop below assumes that the image + // is a 8-bit 3-channel. check it. + CV_Assert(image.type() == CV_8UC3); + MatConstIterator_ it = image.begin(), + it_end = image.end(); + for( ; it != it_end; ++it ) + { + const Vec3b& pix = *it; + hist.at(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f; + } + + minProb *= image.rows*image.cols; + Mat plane; + NAryMatIterator it(&hist, &plane, 1); + double s = 0; + // iterate through the matrix. on each iteration + // it.planes[*] (of type Mat) will be set to the current plane. + for(int p = 0; p < it.nplanes; p++, ++it) + { + threshold(it.planes[0], it.planes[0], minProb, 0, THRESH_TOZERO); + s += sum(it.planes[0])[0]; + } + + s = 1./s; + it = NAryMatIterator(&hist, &plane, 1); + for(int p = 0; p < it.nplanes; p++, ++it) + it.planes[0] *= s; + } +@endcode + */ class CV_EXPORTS NAryMatIterator { public: @@ -2249,7 +3198,52 @@ public: virtual int type(const MatExpr& expr) const; }; - +/** @brief Matrix expression representation +@anchor MatrixExpressions +This is a list of implemented matrix operations that can be combined in arbitrary complex +expressions (here A, B stand for matrices ( Mat ), s for a scalar ( Scalar ), alpha for a +real-valued scalar ( double )): +- Addition, subtraction, negation: `A+B`, `A-B`, `A+s`, `A-s`, `s+A`, `s-A`, `-A` +- Scaling: `A*alpha` +- Per-element multiplication and division: `A.mul(B)`, `A/B`, `alpha/A` +- Matrix multiplication: `A*B` +- Transposition: `A.t()` (means AT) +- Matrix inversion and pseudo-inversion, solving linear systems and least-squares problems: + `A.inv([method]) (~ A-1)`, `A.inv([method])*B (~ X: AX=B)` +- Comparison: `A cmpop B`, `A cmpop alpha`, `alpha cmpop A`, where *cmpop* is one of + `>`, `>=`, `==`, `!=`, `<=`, `<`. The result of comparison is an 8-bit single channel mask whose + elements are set to 255 (if the particular element or pair of elements satisfy the condition) or + 0. +- Bitwise logical operations: `A logicop B`, `A logicop s`, `s logicop A`, `~A`, where *logicop* is one of + `&`, `|`, `^`. +- Element-wise minimum and maximum: `min(A, B)`, `min(A, alpha)`, `max(A, B)`, `max(A, alpha)` +- Element-wise absolute value: `abs(A)` +- Cross-product, dot-product: `A.cross(B)`, `A.dot(B)` +- Any function of matrix or matrices and scalars that returns a matrix or a scalar, such as norm, + mean, sum, countNonZero, trace, determinant, repeat, and others. +- Matrix initializers ( Mat::eye(), Mat::zeros(), Mat::ones() ), matrix comma-separated + initializers, matrix constructors and operators that extract sub-matrices (see Mat description). +- Mat_() constructors to cast the result to the proper type. +@note Comma-separated initializers and probably some other operations may require additional +explicit Mat() or Mat_() constructor calls to resolve a possible ambiguity. + +Here are examples of matrix expressions: +@code + // compute pseudo-inverse of A, equivalent to A.inv(DECOMP_SVD) + SVD svd(A); + Mat pinvA = svd.vt.t()*Mat::diag(1./svd.w)*svd.u.t(); + + // compute the new vector of parameters in the Levenberg-Marquardt algorithm + x -= (A.t()*A + lambda*Mat::eye(A.cols,A.cols,A.type())).inv(DECOMP_CHOLESKY)*(A.t()*err); + + // sharpen image using "unsharp mask" algorithm + Mat blurred; double sigma = 1, threshold = 5, amount = 1; + GaussianBlur(img, blurred, Size(), sigma, sigma); + Mat lowConstrastMask = abs(img - blurred) < threshold; + Mat sharpened = img*(1+amount) + blurred*(-amount); + img.copyTo(sharpened, lowContrastMask); +@endcode +*/ class CV_EXPORTS MatExpr { public: @@ -2287,7 +3281,10 @@ public: Scalar s; }; +//! @} core_basic +//! @relates cv::MatExpr +//! @{ CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b); CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s); CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a); @@ -2373,8 +3370,25 @@ CV_EXPORTS MatExpr max(const Mat& a, const Mat& b); CV_EXPORTS MatExpr max(const Mat& a, double s); CV_EXPORTS MatExpr max(double s, const Mat& a); +/** @brief Calculates an absolute value of each matrix element. + +abs is a meta-function that is expanded to one of absdiff or convertScaleAbs forms: +- C = abs(A-B) is equivalent to `absdiff(A, B, C)` +- C = abs(A) is equivalent to `absdiff(A, Scalar::all(0), C)` +- C = `Mat_ >(abs(A*alpha + beta))` is equivalent to `convertScaleAbs(A, C, alpha, +beta)` + +The output matrix has the same size and the same type as the input one except for the last case, +where C is depth=CV_8U . +@param m matrix. +@sa @ref MatrixExpressions, absdiff, convertScaleAbs + */ CV_EXPORTS MatExpr abs(const Mat& m); +/** @overload +@param e matrix expression. +*/ CV_EXPORTS MatExpr abs(const MatExpr& e); +//! @} relates cv::MatExpr } // cv diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 4f383686f6931b41b5befce841cf0a5eac81f1b4..24c6b453c1ebeffbf22ab9e7390476718e72ab75 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -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 diff --git a/modules/core/include/opencv2/core/matx.hpp b/modules/core/include/opencv2/core/matx.hpp index a35d47be01a2acf82048bb76fa90e3413af75f6a..5f94cccccf31b7800b7ce11decea7681e2f46d38 100644 --- a/modules/core/include/opencv2/core/matx.hpp +++ b/modules/core/include/opencv2/core/matx.hpp @@ -55,24 +55,12 @@ namespace cv { -////////////////////////////// Small Matrix /////////////////////////// - -/*! - A short numerical vector. +//! @addtogroup core_basic +//! @{ - 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, you can use shorter aliases - for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec. - */ +////////////////////////////// Small Matrix /////////////////////////// +//! @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 class Matx { public: @@ -242,8 +244,7 @@ public: }; }; -/*! - Comma-separated Matrix Initializer +/** @brief Comma-separated Matrix Initializer */ template class MatxCommaInitializer { @@ -256,7 +257,7 @@ public: int idx; }; -/*! +/* Utility methods */ template static double determinant(const Matx<_Tp, m, m>& a); @@ -268,20 +269,33 @@ template static double norm(const Matx<_Tp, m, n>& M /////////////////////// Vec (used as element of multi-channel images ///////////////////// -/*! - 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, you can use shorter aliases - for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec. +/** @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. + +The template takes 2 parameters: +@tparam _Tp element type +@tparam cn the number of elements + +In addition to the universal notation like Vec, you can use shorter aliases +for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec. + +It is possible to convert Vec\ to/from Point_, Vec\ to/from Point3_ , and Vec\ +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 class Vec : public Matx<_Tp, cn, 1> { @@ -337,8 +351,8 @@ public: template Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp); }; -/* \typedef - Shorter aliases for the most popular specializations of Vec +/** @name Shorter aliases for the most popular specializations of Vec + @{ */ typedef Vec Vec2b; typedef Vec Vec3b; @@ -367,6 +381,7 @@ typedef Vec Vec2d; typedef Vec Vec3d; typedef Vec Vec4d; typedef Vec Vec6d; +/** @} */ /*! traits @@ -387,8 +402,7 @@ public: }; }; -/*! - Comma-separated Vec Initializer +/** @brief Comma-separated Vec Initializer */ template class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> { @@ -398,12 +412,11 @@ public: Vec<_Tp, m> operator *() const; }; -/*! - Utility methods -*/ template 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 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 template inline Matx<_Tp, m, n>::operator Matx() 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 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 static inline Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b) { @@ -1352,6 +1369,8 @@ template inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const V return v1; } +//! @} + } // cv #endif // __OPENCV_CORE_MATX_HPP__ diff --git a/modules/core/include/opencv2/core/ocl.hpp b/modules/core/include/opencv2/core/ocl.hpp index 0ee492e097e1dd02bde0af92d16f0f63aec7e4ca..3b023fb09ed0944f2fc85538909ae93812e6be27 100644 --- a/modules/core/include/opencv2/core/ocl.hpp +++ b/modules/core/include/opencv2/core/ocl.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 diff --git a/modules/core/include/opencv2/core/ocl_genbase.hpp b/modules/core/include/opencv2/core/ocl_genbase.hpp index 4bf58693b614b7ffe6cfb6a1a863f9b10c4d4d73..d53bc1abb7faeceb7f0919ae021aa77777373f48 100644 --- a/modules/core/include/opencv2/core/ocl_genbase.hpp +++ b/modules/core/include/opencv2/core/ocl_genbase.hpp @@ -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 + } } diff --git a/modules/core/include/opencv2/core/opengl.hpp b/modules/core/include/opencv2/core/opengl.hpp index 19e5a629e584050b848377ea57ddbf010addbca6..15c635c8804b1b180ce17522c846f2d8be4ad906 100644 --- a/modules/core/include/opencv2/core/opengl.hpp +++ b/modules/core/include/opencv2/core/opengl.hpp @@ -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_ wndRect = Rect_(0.0, 0.0, 1.0, 1.0), - Rect_ texRect = Rect_(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_ wndRect = Rect_(0.0, 0.0, 1.0, 1.0), + Rect_ texRect = Rect_(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__ */ diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index d23090122e3ee082fe04979cb41027296e3e2040..c572d4eef365e1d112f10219a97923672cda65b5 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -49,6 +49,8 @@ #include +//! @cond IGNORED + namespace cv { @@ -525,17 +527,27 @@ void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter, Ptr<_Tp>& v (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); } +//! @endcond /****************************************************************************************\ * Auxiliary algorithms * \****************************************************************************************/ -// 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" +/** @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 + . 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 int partition( const std::vector<_Tp>& _vec, std::vector& labels, _EqPredicate predicate=_EqPredicate()) diff --git a/modules/core/include/opencv2/core/optim.hpp b/modules/core/include/opencv2/core/optim.hpp index 87377aafe0d0f6da0f712d28a46c9e05bed9687c..4f1749ec97494e1402748432e41e6843ef38e20c 100644 --- a/modules/core/include/opencv2/core/optim.hpp +++ b/modules/core/include/opencv2/core/optim.hpp @@ -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 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& 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 +. + +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\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 create(const Ptr& f=Ptr(), InputArray initStep=Mat_(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 ) 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 create(const Ptr& f=Ptr(), 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 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 diff --git a/modules/core/include/opencv2/core/persistence.hpp b/modules/core/include/opencv2/core/persistence.hpp index 8f515c54dd31b8cb179c4cb645830577f74dca2d..cc98e86c5deb3d49f319bf4910b80e01a657eb20 100644 --- a/modules/core/include/opencv2/core/persistence.hpp +++ b/modules/core/include/opencv2/core/persistence.hpp @@ -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 () or YAML () +formats. Below is an example of 3x3 floating-point identity matrix A, stored in XML and YAML files +using CXCore functions: +XML: +@code{.xml} + + + + 3 + 3 +
f
+ 1. 0. 0. 0. 1. 0. 0. 0. 1. +
+
+@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 () +or YAML () 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 + + 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_(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); + Mat distCoeffs = (Mat_(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 << << `) 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 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 fs; //!< the underlying C FileStorage structure @@ -228,21 +439,23 @@ public: template<> CV_EXPORTS void DefaultDeleter::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 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 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 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 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 static inline void operator >> (const FileNode& n, _Tp& value) { read( n, value, _Tp()); } +/** @brief Reads data from a file storage. + */ template 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__ diff --git a/modules/core/include/opencv2/core/private.cuda.hpp b/modules/core/include/opencv2/core/private.cuda.hpp index 6f0d90e955895eeb65ba886a8647cef9f06264fd..d97b4511b4418c86b85daaa8d68d2849978fa2ea 100644 --- a/modules/core/include/opencv2/core/private.cuda.hpp +++ b/modules/core/include/opencv2/core/private.cuda.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__ diff --git a/modules/core/include/opencv2/core/private.hpp b/modules/core/include/opencv2/core/private.hpp index d04b65e9b3c057935143420494b630a70e81b893..c9b2bf66d9dffc36ddc0ef6e146bf4aa27b8d930 100644 --- a/modules/core/include/opencv2/core/private.hpp +++ b/modules/core/include/opencv2/core/private.hpp @@ -71,6 +71,8 @@ # endif #endif +//! @cond IGNORED + namespace cv { #ifdef HAVE_TBB @@ -301,4 +303,6 @@ typedef enum CvStatus } CvStatus; +//! @endcond + #endif // __OPENCV_CORE_PRIVATE_HPP__ diff --git a/modules/core/include/opencv2/core/ptr.inl.hpp b/modules/core/include/opencv2/core/ptr.inl.hpp index 989724281f027b9f1efa8db3967830e928796aa1..65c09d1cb4f348f19ac597540888cedbc3da84ae 100644 --- a/modules/core/include/opencv2/core/ptr.inl.hpp +++ b/modules/core/include/opencv2/core/ptr.inl.hpp @@ -44,6 +44,8 @@ #include +//! @cond IGNORED + namespace cv { template @@ -335,4 +337,6 @@ Ptr makePtr(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& } // namespace cv +//! @endcond + #endif // __OPENCV_CORE_PTR_INL_HPP__ diff --git a/modules/core/include/opencv2/core/traits.hpp b/modules/core/include/opencv2/core/traits.hpp index 85a5132f0e0dec41fcbd2bc12cad253782de6ec0..49bc8440dd020c9eb0cd792fb5e2d073a4259cbe 100644 --- a/modules/core/include/opencv2/core/traits.hpp +++ b/modules/core/include/opencv2/core/traits.hpp @@ -49,16 +49,59 @@ namespace cv { -/*! - Informative template class for OpenCV "scalars". - - 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. +//! @addtogroup core_basic +//! @{ + +/** @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_\{U|S|F}C(\), 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 + { + 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 DataType > + { + 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::type); + + Mat B = Mat_ >(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\ \> . This mechanism is also +useful (and used in OpenCV this way) for generic algorithms implementations. */ template 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::value constant. +The class is specialized for each fundamental numerical data type supported by OpenCV. It provides +DataDepth::value constant. */ template class DataDepth { @@ -277,6 +319,8 @@ template<> class TypeDepth typedef double value_type; }; +//! @} + } // cv #endif // __OPENCV_CORE_TRAITS_HPP__ diff --git a/modules/core/include/opencv2/core/types.hpp b/modules/core/include/opencv2/core/types.hpp index 419c0473686f7ffdd7105166684b825c355f8a2d..74bd61e5c6cee7bf53cae60d5c936f74a4bb263b 100644 --- a/modules/core/include/opencv2/core/types.hpp +++ b/modules/core/include/opencv2/core/types.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. - - 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. +/** @brief Template class for 2D points specified by its coordinates `x` and `y`. + +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_ Point2i; + typedef Point2i Point; + typedef Point_ Point2f; + typedef Point_ 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 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_ Point3i; + typedef Point3_ Point3f; + typedef Point3_ Point3d; +@endcode +@see cv::Point3i, cv::Point3f and cv::Point3d */ template 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_ 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_ Size2i; + typedef Size2i Size; + typedef Size_ Size2f; +@endcode */ template class Size_ { @@ -285,11 +328,48 @@ public: //////////////////////////////// Rect_ //////////////////////////////// -/*! - The 2D up-right rectangle class - - The class represents a 2D rectangle with coordinates of the specified data type. - Normally, cv::Rect ~ cv::Rect_ is used. +/** @brief Template class for 2D rectangles + +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_\ ) 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 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 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. + +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); - 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. + 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 +![image](pics/rotatedrect.png) + +@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_ 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 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& keypoints, CV_OUT std::vector& points2f, const std::vector& keypointIndexes=std::vector()); - //! 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& points2f, CV_OUT std::vector& 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 @@ -664,7 +851,9 @@ public: typedef Vec 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__ diff --git a/modules/core/include/opencv2/core/types_c.h b/modules/core/include/opencv2/core/types_c.h index ecf5f597c7c78d65bbc07cffcd8de5434bdf796f..e824701801e236dd73e81efb0d5c35df8be61d6c 100644 --- a/modules/core/include/opencv2/core/types_c.h +++ b/modules/core/include/opencv2/core/types_c.h @@ -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 + +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. + +Each edge consists of: - Each edge consists of +- Two pointers to the starting and ending vertices (vtx[0] and vtx[1] respectively). - o Two pointers to the starting and ending vertices - (vtx[0] and vtx[1] respectively). + A graph may be oriented or not. In the latter case, edges between vertex i to vertex j are not +distinguished during search operations. - 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. - 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. +@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)<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 parameter is valid */ \ +/** assert gives some guarantee that 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 /** 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& 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. - - The function returns the number of ticks (as returned by cv::getTickCount()) per second. - The following code computes the execution time in milliseconds: +/** @brief Returns the number of ticks per second. - \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. - - 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. -*/ +/** @brief Returns the number of CPU ticks. + +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 - -/*! - 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)} +/** @brief Available CPU features. + +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 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("N"); + double fps = parser.get("fps"); + String path = parser.get("path"); + + use_time_stamp = parser.has("timestamp"); + + String img1 = parser.get(0); + String img2 = parser.get(1); + + int repeat = parser.get(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 inline @@ -615,6 +742,8 @@ template<> inline std::string CommandLineParser::get(const String& } #endif // OPENCV_NOSTL +//! @endcond + } //namespace cv #endif //__OPENCV_CORE_UTILITY_H__ diff --git a/modules/core/include/opencv2/core/wimage.hpp b/modules/core/include/opencv2/core/wimage.hpp index c7afa8c5de05e4497e1fee75259b46dc3d2bd50b..ef9d39833a8e7ad24cf8d86ff1c904a54e20da23 100644 --- a/modules/core/include/opencv2/core/wimage.hpp +++ b/modules/core/include/opencv2/core/wimage.hpp @@ -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 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 class WImage; template class WImageBuffer; template class WImageView; @@ -165,12 +110,63 @@ typedef WImageC WImage3_16u; typedef WImageViewC WImageView3_16u; typedef WImageBufferC 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 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 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 class WImageC : public WImage { @@ -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 class WImageBuffer : public WImage { @@ -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 class WImageBufferC : public WImageC { @@ -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 -class WImageView : public WImage +/** View into an image class which allows treating a subimage as an image or treating external data +as an image +*/ +template class WImageView : public WImage { public: typedef typename WImage::BaseType BaseType; @@ -518,15 +507,9 @@ inline int WImage::Depth() const {return IPL_DEPTH_32F; } template<> inline int WImage::Depth() const {return IPL_DEPTH_64F; } -// -// Pure virtual destructors still need to be defined. -// template inline WImage::~WImage() {} template inline WImageC::~WImageC() {} -// -// Allocate ImageData -// template inline void WImageBuffer::Allocate(int width, int height, int nchannels) { @@ -547,9 +530,6 @@ inline void WImageBufferC::Allocate(int width, int height) } } -// -// ImageView methods -// template WImageView::WImageView(WImage* img, int c, int r, int width, int height) : WImage(0) @@ -614,6 +594,8 @@ WImageViewC WImageC::View(int c, int r, int width, int height) { return WImageViewC(this, c, r, width, height); } +//! @} core + } // end of namespace #endif // __cplusplus diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index 09e15c6fb136291e2ee834d747756ac9a3b12bd1..2e693542e3818d6e4a527a8463b750bb8d0c5e40 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -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, @@ -1316,6 +1327,8 @@ CV_EXPORTS_W Size getTextSize(const String& text, int fontFace, double fontScale, int thickness, CV_OUT int* baseLine); +/** @} */ + } // cv #endif